New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Varnish send Transfer-Encoding and Content-Length header to backend, if POST request with HTTP/2. #2247

Closed
xcir opened this Issue Mar 6, 2017 · 3 comments

Comments

Projects
None yet
6 participants
@xcir
Contributor

xcir commented Mar 6, 2017

Expected Behavior

Send either "Transfer-Encoding: chunked" or "Content-Length".

Current Behavior

vcl

vcl 4.0;

import std;
backend default {.host = "other varnish server(4.1.4)";}
sub vcl_recv{
  return(pass);
}

varnishlog

*   << BeReq    >> 32769
-   Begin          bereq 2 pass
-   Timestamp      Start: 1488819809.457129 0.000000 0.000000
-   BereqMethod    POST
-   BereqURL       /x.html
-   BereqProtocol  HTTP/2.0
-   BereqHeader    host: *****
-   BereqHeader    scheme: https
-   BereqHeader    content-length: 5                                          <-----------------
-   BereqHeader    cache-control: max-age=0
-   BereqHeader    origin: https://*****
-   BereqHeader    upgrade-insecure-requests: 1
-   BereqHeader    user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
-   BereqHeader    content-type: application/x-www-form-urlencoded
-   BereqHeader    accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
-   BereqHeader    referer: https://*****/x.html
-   BereqHeader    accept-encoding: gzip, deflate, br
-   BereqHeader    accept-language: ja,en-US;q=0.8,en;q=0.6
-   BereqHeader    cookie: ***
-   BereqHeader    cookie: ***
-   BereqHeader    cookie: ***
-   BereqHeader    X-Forwarded-For: *****
-   BereqProtocol  HTTP/1.1
-   BereqHeader    X-Varnish: 32769
-   VCL_call       BACKEND_FETCH
-   VCL_return     fetch
-   BackendOpen    27 boot.default ***** 80 ***** 43138
-   BereqHeader    Transfer-Encoding: chunked                                <-----------------
-   BackendStart   ***** 80
-   Timestamp      Bereq: 1488819809.460913 0.003784 0.003784
-   Timestamp      Beresp: 1488819809.464861 0.007733 0.003948
-   BerespProtocol HTTP/1.1
-   BerespStatus   400                                                                         <-----------------
-   BerespReason   Bad Request
-   BerespHeader   Date: Mon, 06 Mar 2017 17:03:29 GMT
-   VCL_call       BACKEND_RESPONSE
-   VCL_return     deliver
-   Storage        malloc Transient
-   ObjProtocol    HTTP/1.1
-   ObjStatus      400
-   ObjReason      Bad Request
-   ObjHeader      Date: Mon, 06 Mar 2017 17:03:29 GMT
-   Fetch_Body     4 eof stream
-   BackendReuse   27 boot.default
-   Timestamp      BerespBody: 1488819809.465021 0.007892 0.000160
-   Length         0
-   BereqAcct      764 5 769 28 0 28
-   End

*   << Request  >> 2
-   Begin          req 1 rxreq
-   Timestamp      Start: 1488819809.456986 0.000000 0.000000
-   ReqProtocol    HTTP/2.0
-   Timestamp      Req: 1488819809.456986 0.000000 0.000000
-   ReqStart       ***** 64015
-   ReqMethod      POST
-   ReqURL         /x.html
-   ReqProtocol    HTTP/2.0
-   ReqHeader      host: *****
-   ReqHeader      scheme: https
-   ReqHeader      content-length: 5
-   ReqHeader      cache-control: max-age=0
-   ReqHeader      origin: https://*****
-   ReqHeader      upgrade-insecure-requests: 1
-   ReqHeader      user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
-   ReqHeader      content-type: application/x-www-form-urlencoded
-   ReqHeader      accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
-   ReqHeader      referer: https://*****/x.html
-   ReqHeader      accept-encoding: gzip, deflate, br
-   ReqHeader      accept-language: ja,en-US;q=0.8,en;q=0.6
-   ReqHeader      cookie: ***
-   ReqHeader      cookie: ***
-   ReqHeader      cookie: ***
-   ReqHeader      X-Forwarded-For: *****
-   VCL_call       RECV
-   VCL_return     pass
-   VCL_call       HASH
-   VCL_return     lookup
-   VCL_call       PASS
-   VCL_return     fetch
-   Link           bereq 32769 pass
-   Storage        malloc Transient
-   Timestamp      ReqBody: 1488819809.460871 0.003885 0.003885
-   Timestamp      Fetch: 1488819809.465106 0.008121 0.004236
-   RespProtocol   HTTP/1.1
-   RespStatus     400
-   RespReason     Bad Request
-   RespHeader     Date: Mon, 06 Mar 2017 17:03:29 GMT
-   RespHeader     X-Varnish: 2
-   RespHeader     Age: 0
-   RespHeader     Via: 1.1 varnish (Varnish/5.0)
-   VCL_call       DELIVER
-   VCL_return     deliver
-   Timestamp      Process: 1488819809.465133 0.008147 0.000027
-   RespHeader     Content-Length: 0
-   Debug          "H2: Deliver"
-   Debug          "HP {33, "date:", ""} <Date: Mon, 06 Mar 2017 17:03:29 GMT>"
-   Debug          "HP {21, "age:", ""} <Age: 0>"
-   Debug          "HP {60, "via:", ""} <Via: 1.1 varnish (Varnish/5.0)>"
-   Debug          "HP {28, "content-length:", ""} <Content-Length: 0>"
-   Timestamp      Resp: 1488819809.465395 0.008410 0.000262
-   ReqAcct        0 5 5 0 0 0
-   End

Varnish send content-length and transfer-encoding header.

Possible Solution

Not append "Transfer-Encoding: chunked", if have Content-Length.

Steps to Reproduce (for bugs)

See the Current Behavior above.

Context

Some middle-ware(varnish...) can't process request.(400 Bad Request)

Your Environment

  • Version used: hitch1.4.4 + varnish-trunk revision 2b94cd5
  • Operating System and version: Ubuntu 16.04.2 LTS (4.4.0-64-generic)
@nigoroll

This comment has been minimized.

Show comment
Hide comment
@nigoroll

nigoroll Mar 17, 2017

Contributor

https://tools.ietf.org/html/rfc7230#section-3.3.2

A sender MUST NOT send a Content-Length header field in any message that contains a Transfer-Encoding header field.

Contributor

nigoroll commented Mar 17, 2017

https://tools.ietf.org/html/rfc7230#section-3.3.2

A sender MUST NOT send a Content-Length header field in any message that contains a Transfer-Encoding header field.

@MattBlissett

This comment has been minimized.

Show comment
Hide comment
@MattBlissett

MattBlissett Mar 29, 2017

My backend receives what I assume is transfer encoding 'junk' for POST requests over HTTP2. POST requests from web browsers fail, but nghttp has an option not to set a content-length.

echo '{}' | nghttp -d - 'https://demo.gbif-uat.org:2/api/feedback/bug'

POST /api/feedback/bug HTTP/1.1
scheme: https
accept: */*
accept-encoding: gzip, deflate
content-length: 3
user-agent: nghttp2/1.7.1
X-Forwarded-For: 130.225.98.120
X-Varnish: 131073
Host: portal.gbif-dev.org
Transfer-Encoding: chunked

003
{}

0

Which fails.

echo '{}' | nghttp -d - 'https://demo.gbif-uat.org:2/api/feedback/bug' --no-content-length

POST /api/feedback/bug HTTP/1.1
scheme: https
accept: */*
accept-encoding: gzip, deflate
user-agent: nghttp2/1.7.1
X-Forwarded-For: 130.225.98.120
X-Varnish: 98305
Host: portal.gbif-dev.org
Transfer-Encoding: chunked

003
{}

0

This works.

The output from Varnishlog is the same as xcir's.

Hitch 1.4.4 + Varnish 5.1.1.

MattBlissett commented Mar 29, 2017

My backend receives what I assume is transfer encoding 'junk' for POST requests over HTTP2. POST requests from web browsers fail, but nghttp has an option not to set a content-length.

echo '{}' | nghttp -d - 'https://demo.gbif-uat.org:2/api/feedback/bug'

POST /api/feedback/bug HTTP/1.1
scheme: https
accept: */*
accept-encoding: gzip, deflate
content-length: 3
user-agent: nghttp2/1.7.1
X-Forwarded-For: 130.225.98.120
X-Varnish: 131073
Host: portal.gbif-dev.org
Transfer-Encoding: chunked

003
{}

0

Which fails.

echo '{}' | nghttp -d - 'https://demo.gbif-uat.org:2/api/feedback/bug' --no-content-length

POST /api/feedback/bug HTTP/1.1
scheme: https
accept: */*
accept-encoding: gzip, deflate
user-agent: nghttp2/1.7.1
X-Forwarded-For: 130.225.98.120
X-Varnish: 98305
Host: portal.gbif-dev.org
Transfer-Encoding: chunked

003
{}

0

This works.

The output from Varnishlog is the same as xcir's.

Hitch 1.4.4 + Varnish 5.1.1.

@xcir

This comment has been minimized.

Show comment
Hide comment
@xcir

xcir Mar 29, 2017

Contributor

I'm adding this vcl for h2 instance.
I think that I can avoid this issue.

sub vcl_recv{
  if(req.proto ~ "HTTP/2" && req.http.content-length){
    unset req.http.content-length;
  }
}
Contributor

xcir commented Mar 29, 2017

I'm adding this vcl for h2 instance.
I think that I can avoid this issue.

sub vcl_recv{
  if(req.proto ~ "HTTP/2" && req.http.content-length){
    unset req.http.content-length;
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment