Sorry regarding my previous curl – I didn’t use --http2 in my curl request, but 
result is the same (with negotiated http2 protocol), I’ve removed the TLSv1.2 
output since it’s useless in this case:

===================================

$ curl 'https://dashboard.domain.com/js/app.js?v=1' -H 'User-Agent: Mozilla/5.0 
(Macintosh; Intel Mac OS X 10.13; rv:57.0) Gecko/20100101 Firefox/57.0' 
--compressed -H 'Connection: keep-alive' -vo /dev/null --http2
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* 
  Trying 178.63.183.xx...
* TCP_NODELAY set
* Connected to dashboard.domain.com (178.63.183.xx) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject: OU=Domain Control Validated; CN=*.domain.com
*  start date: Jan  3 11:17:55 2017 GMT
*  expire date: Jan  4 11:17:55 2018 GMT
*  subjectAltName: host "dashboard.domain.com" matched cert's "*.domain.com"
*  issuer: C=BE; O=GlobalSign nv-sa; CN=AlphaSSL CA - SHA256 - G2
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7f860b005800)
> GET /js/app.js?v=1 HTTP/2
> Host: dashboard.domain.com
> Accept: */*
> Accept-Encoding: deflate, gzip
> User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:57.0) 
> Gecko/20100101 Firefox/57.0
> Connection: keep-alive
>
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2 200
< server: nginx/1.13.5
< date: Thu, 28 Dec 2017 10:43:31 GMT
< content-type: application/javascript; charset=utf-8
< last-modified: Sun, 25 Jun 2017 17:17:05 GMT
< vary: Accept-Encoding
< etag: W/"594ff011-7b7"
< content-encoding: gzip
<
{ [683 bytes data]
100   683    0   683    0     0   3749      0 --:--:-- --:--:-- --:--:--  3752
* Connection #0 to host dashboard.domain.com left intact

===================================

So as you can see, I’m sending a “Connection: keep-alive” request from the 
client (like Firefox does), protocol is http2, and the response is the 
javascript file I’ve requested.

And when it’s requested in Firefox: 
https://snaps.hcdn.dk/3uaT06s2RJmAqMu5TqSJYAxBHjSzHOJGiHjfK0qcrV.png 

Best Regards,
Lucas Rolff


On 28/12/2017, 11.39, "Willy Tarreau" <w...@1wt.eu> wrote:

    On Thu, Dec 28, 2017 at 10:27:28AM +0000, Lucas Rolff wrote:
    > In that case, haproxy should be consistent in it's way of handling clients
    > sending connection-specific headers:
    > 
    > $ curl 'https://dashboard.domain.com/js/app.js?v=1' -H 'User-Agent: 
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:57.0) Gecko/20100101 
Firefox/57.0' --compressed -H 'Connection: keep-alive' -o /dev/null -vvv
    >   % Total    % Received % Xferd  Average Speed   Time    Time     Time  
Current
    >                                  Dload  Upload   Total   Spent    Left  
Speed
    >   0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--  
   0*   Trying 178.63.183.40...
    > * TCP_NODELAY set
    > * Connected to dashboard.domain.com (178.63.183.xxx) port 443 (#0)
    > * ALPN, offering h2
    > * ALPN, offering http/1.1
    > * Cipher selection: 
ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
    > * successfully set certificate verify locations:
    > *   CAfile: /etc/ssl/cert.pem
    >   CApath: none
    > * TLSv1.2 (OUT), TLS handshake, Client hello (1):
    > } [512 bytes data]
    > * TLSv1.2 (IN), TLS handshake, Server hello (2):
    > { [93 bytes data]
    >   0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--  
   0* TLSv1.2 (IN), TLS handshake, Certificate (11):
    > { [3000 bytes data]
    > * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    > { [333 bytes data]
    > * TLSv1.2 (IN), TLS handshake, Server finished (14):
    > { [4 bytes data]
    > * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    > } [70 bytes data]
    > * TLSv1.2 (OUT), TLS change cipher, Client hello (1):
    > } [1 bytes data]
    > * TLSv1.2 (OUT), TLS handshake, Finished (20):
    > } [16 bytes data]
    > * TLSv1.2 (IN), TLS change cipher, Client hello (1):
    > { [1 bytes data]
    > * TLSv1.2 (IN), TLS handshake, Finished (20):
    > { [16 bytes data]
    > * SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
    > * ALPN, server did not agree to a protocol
    > * Server certificate:
    > *  subject: OU=Domain Control Validated; CN=*.domain.com
    > *  start date: Jan  3 11:17:55 2017 GMT
    > *  expire date: Jan  4 11:17:55 2018 GMT
    > *  subjectAltName: host "dashboard.domain.com" matched cert's 
"*.domain.com"
    > *  issuer: C=BE; O=GlobalSign nv-sa; CN=AlphaSSL CA - SHA256 - G2
    > *  SSL certificate verify ok.
    > > GET /js/app.js?v=1 HTTP/1.1
    > > Host: dashboard.domain.com
    > > Accept: */*
    > > Accept-Encoding: deflate, gzip
    > > User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:57.0) 
Gecko/20100101 Firefox/57.0
    > > Connection: keep-alive
    > >
    > < HTTP/1.1 200 OK
    > < Server: nginx/1.13.5
    > < Date: Thu, 28 Dec 2017 10:11:34 GMT
    > < Content-Type: application/javascript; charset=utf-8
    > < Last-Modified: Sun, 25 Jun 2017 17:17:05 GMT
    > < Transfer-Encoding: chunked
    > < Vary: Accept-Encoding
    > < ETag: W/"594ff011-7b7"
    > < Content-Encoding: gzip
    > <
    > { [695 bytes data]
    > 100   683    0   683    0     0   3936      0 --:--:-- --:--:-- --:--:--  
3925
    > * Connection #0 to host dashboard.domain.com left intact
    > 
    > 
    > Making a GET request (and sending Connection: keep-alive) continues to 
work,
    > and haproxy doesn't handle it as malformed according to the specification.
    
    But in this example, you're using HTTP/1.1, The "Connection" header is
    perfectly valid for 1.1. It's HTTP/2 which forbids it. There is no
    inconsistency here.
    
    > I agree that if the specification says it cannot be done, it shouldn't, 
but
    > then at least it should be consistent.
    
    It *is*, the code makes no distinction based on the request. Any of the
    following headers coming from a decoded HTTP/2 request will make it
    immediately fail : connection, proxy-connection, keep-alive, upgrade,
    transfer-encoding.
    
    > Fyi, in that case - nginx isn't compliant with the http2 specification.
    
    I find this a bit strange, maybe they had to relax it during an early
    implementation to accomodate other incompatible ones.
    
    > I'm creating a bug report with Mozilla to see if they can change the
    > behaviour of their browser to not send a Connection header at all, maybe 
this
    > will resolve the issue.
    
    OK thank you.
    
    > > I still have no idea what this "quantum" is by the way ;-)
    > 
    > It's the 2017 version of "We released a better version of Firefox that is
    > faster".. Let's call it Firefox Quantum.
    
    Ah, so they changed numbering and naming again and again ? It becomes
    quite painful to follow. How one may consider that Quantum is greater
    than 52 for me is equivalent to saying that Monday is greater than blue.
    When one will think about using a count down of the estimated life left
    to their project to name them ? You could have version 2 billion to
    indicate that you estimate 60 years left for example.
    
    > Haproxy 2.0 could be named "haproxy Quantum 1.5" just for the giggles.
    
    I'd rather not fall into such idiocies, you see.
    
    Cheers,
    Willy
    

Reply via email to