admin管理员组

文章数量:1287785

Hello beloved SO munity.

I have a problem that tortures me for months with no solution.

I am trying to make a request at an HTTP/2 endpoint that uses some headers that start with a colon. Example:

:method: "POST"

I have tried with python(hyper, requests), php(guzzle) and js(fetch). I have managed, presumably, with js to achieve the required result but the CORS policy returns me an "opaque" result.

Any help will be great!

JS result presumbaly correct "opaque"

fetch("", 
        {
          "credentials":"include",
          "headers":{
            "accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
            "accept-language":"en-US,en;q=0.9,el;q=0.8",
            "cache-control":"max-age=0",
            "content-type":"application/x-www-form-urlencoded",
            "accept-encoding": "gzip, deflate, br",
            "content-length": 614,
            "origin": "",
            "sec-fetch-mode": "navigate",
            "sec-fetch-site": "same-origin",
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36",
          },
          "referrer":"",
          "referrerPolicy":"no-referrer-when-downgrade",
          "redirect": "follow",
          "body":"..."
          "method":"POST",
          "mode":"no-cors",
          ":authority": "www.example",
          ":method": "POST",
          ":path": "/users/sign_in",
          ":scheme": "https"
        })

Python result 500 or 404

 context = tls.init_context()
    context.check_hostname = False
    context.verify_mode = ssl.CERT_NONE
    with HTTP20Connection('www.example', port=443, ssl_context=context) as c:
        headers = {
            ":authority": "www.example",
            ":method": "GET",
            ":path": "/users/sign_in",
            ":scheme": "https",
            "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
            "accept-encoding": "gzip, deflate, br",
            "accept-language": "en-US,en;q=0.9,el;q=0.8",
            "sec-fetch-mode": "navigate",
            "sec-fetch-site": "none",
            "sec-fetch-user": "?1",
            "upgrade-insecure-requests": "1",
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36"
        }

        c.request('GET', 'www.example/users/sign_in', headers=headers)

PHP result 500 or curl error 55

$jar = new CookieJar;
    $client = new Client([
        // Base URI is used with relative requests
        'cookies' => $jar,
        'version' => 2.0,
        'debug' => fopen('php://stderr', 'w'),
    ]);

    $client->request('GET', '');

    $response = $client->request('POST', '', [
        'headers' => [
            ":authority"=> "www.example",
            ":method"=> "POST",
            ":path"=> "/users/sign_in",
            ":scheme"=> "https",
            "accept"=> "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
            "accept-encoding"=> "gzip, deflate, br",
            "accept-language"=> "en-US,en;q=0.9,el;q=0.8",
            "cache-control"=> "max-age=0",
            "content-length"=> "616",
            "content-type"=> "application/x-www-form-urlencoded",
            "origin"=> "",
            "referer"=> "",
            "sec-fetch-mode"=> "navigate",
            "sec-fetch-site"=> "same-origin",
            "sec-fetch-user"=> "?1",
            "upgrade-insecure-requests"=> "1",
            "user-agent"=> "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36"
        ],
        'form_params' => [ ... ],
        'version' => 2.0,
        'allow_redirects' => true
    ]);

Hello beloved SO munity.

I have a problem that tortures me for months with no solution.

I am trying to make a request at an HTTP/2 endpoint that uses some headers that start with a colon. Example:

:method: "POST"

I have tried with python(hyper, requests), php(guzzle) and js(fetch). I have managed, presumably, with js to achieve the required result but the CORS policy returns me an "opaque" result.

Any help will be great!

JS result presumbaly correct "opaque"

fetch("https://www.example./users/sign_in", 
        {
          "credentials":"include",
          "headers":{
            "accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
            "accept-language":"en-US,en;q=0.9,el;q=0.8",
            "cache-control":"max-age=0",
            "content-type":"application/x-www-form-urlencoded",
            "accept-encoding": "gzip, deflate, br",
            "content-length": 614,
            "origin": "https://www.example.",
            "sec-fetch-mode": "navigate",
            "sec-fetch-site": "same-origin",
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36",
          },
          "referrer":"https://www.example./users/sign_in",
          "referrerPolicy":"no-referrer-when-downgrade",
          "redirect": "follow",
          "body":"..."
          "method":"POST",
          "mode":"no-cors",
          ":authority": "www.example.",
          ":method": "POST",
          ":path": "/users/sign_in",
          ":scheme": "https"
        })

Python result 500 or 404

 context = tls.init_context()
    context.check_hostname = False
    context.verify_mode = ssl.CERT_NONE
    with HTTP20Connection('www.example.', port=443, ssl_context=context) as c:
        headers = {
            ":authority": "www.example.",
            ":method": "GET",
            ":path": "/users/sign_in",
            ":scheme": "https",
            "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
            "accept-encoding": "gzip, deflate, br",
            "accept-language": "en-US,en;q=0.9,el;q=0.8",
            "sec-fetch-mode": "navigate",
            "sec-fetch-site": "none",
            "sec-fetch-user": "?1",
            "upgrade-insecure-requests": "1",
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36"
        }

        c.request('GET', 'www.example./users/sign_in', headers=headers)

PHP result 500 or curl error 55

$jar = new CookieJar;
    $client = new Client([
        // Base URI is used with relative requests
        'cookies' => $jar,
        'version' => 2.0,
        'debug' => fopen('php://stderr', 'w'),
    ]);

    $client->request('GET', 'https://www.example./users/sign_in');

    $response = $client->request('POST', 'https://www.example./users/sign_in', [
        'headers' => [
            ":authority"=> "www.example.",
            ":method"=> "POST",
            ":path"=> "/users/sign_in",
            ":scheme"=> "https",
            "accept"=> "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
            "accept-encoding"=> "gzip, deflate, br",
            "accept-language"=> "en-US,en;q=0.9,el;q=0.8",
            "cache-control"=> "max-age=0",
            "content-length"=> "616",
            "content-type"=> "application/x-www-form-urlencoded",
            "origin"=> "https://www.example.",
            "referer"=> "https://www.example./users/sign_in",
            "sec-fetch-mode"=> "navigate",
            "sec-fetch-site"=> "same-origin",
            "sec-fetch-user"=> "?1",
            "upgrade-insecure-requests"=> "1",
            "user-agent"=> "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36"
        ],
        'form_params' => [ ... ],
        'version' => 2.0,
        'allow_redirects' => true
    ]);
Share Improve this question asked Aug 13, 2019 at 19:45 TseTse 1331 gold badge2 silver badges8 bronze badges 6
  • I don't think header fields can begin with :. That's the delimiter between the header name and value. – Barmar Commented Aug 13, 2019 at 20:16
  • It looks like those headers you're attempting to use simply duplicate fields in the URL. What makes you think this is necessary? – Barmar Commented Aug 13, 2019 at 20:17
  • Thank you both for the replies. As you can see in the screenshot from devtools here imgur./MKuSvar the headers are included in the request. With out the headers the request returns either a 404 or a 500 response. – Tse Commented Aug 14, 2019 at 9:04
  • 2 Those aren't real headers, it's just the way Developer Tools displays the details of the HTTP request line. The colon at the beginning is its way of indicating that they're not real. – Barmar Commented Aug 14, 2019 at 15:18
  • @Barmar then why with the JS script when they are not present i get a 500 response and when present the request goes through just fine? – Tse Commented Aug 15, 2019 at 9:22
 |  Show 1 more ment

1 Answer 1

Reset to default 10

These are HTTP/2 pseudo-headers that apply to requests and responses within an HTTP/2 stream. HTTP/2 creates a single persistent connection from each distinct origin end-point to a server. That connection transmits multiple requests and responses to and from the end-point; these are parsed into "frames" and transmitted as "streams". HTTP/2 can interleave frames from multiple request and response streams simultaneously to get huge performance benefits. intro to http/2

Pseudo-headers apply to streams; a different set of headers apply to the connection itself. Four pseudo-headers are defined for requests: :method, :scheme, :authority, and :path. No others are allowed. These 4 must be included in every request header block and they must precede any other headers:

"All pseudo-header fields MUST appear in the header block before regular header fields. Any request or response that contains a pseudo-header field that appears in a header block after a regular header field MUST be treated as malformed (Section 8.1.2.6)." http2 spec

I'm not familiar with how 'fetch' implements the headers, but in your code above you seem to have the pseudo-headers outside the header block, and they are placed at the end. Might be screwing up the fetch.

本文标签: javascriptHTTP2 requests and headers starting with colonStack Overflow