0

I am configuring nginx as a reverse proxy (in front of some http/1.1 servers). I initially set up an origin server on the nginx instance. As expected it returned content exclusively over HTTP/2. However when I configured nginx to provide a proxy service, it returned a mixture of HTTP2 and HTTP/1.1 responses.

 server {
    listen 443 ssl http2;
    server_name www.example.com;

    ssl_certificate /etc/nginx/ssl/example.com/cert.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com/cert.key;
    include snippets/ssldefaults.conf;

    location / {
         proxy_http_version      1.1;
         proxy_set_header        Host $host;
         proxy_set_header        X-Real-IP $remote_addr;
         proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

         proxy_ssl_verify off;
         proxy_pass  https://192.168.23.12/
    }
 }

(I am using Chrome 76.0.3809.132 and nginx 1.14 to test this)

The different protocols seen coming from nginx are being sourced from the same origin server. My test case (for example) includes multiple cacheable CSS files - some arrive via HTTP2, some via 1.1.

What could be causing the difference?

symcbean
  • 21,009
  • 1
  • 31
  • 52

1 Answers1

2

It is not possible to serve HTTP/2 and HTTP/1.1 over the same connection.

So I would suggest one of the following is at play here:

  1. You are requesting resources over different domains and they are not all going via your nginx server.
  2. You are looking at third party requests (e.g. Google Analytics) rather than requests for your site.
  3. You are viewing cached resources and they were originally downloaded over HTTP/1.1.
  4. You are using a ServiceWorker and Chrome does not report the protocol for them correctly.
  5. You’ve found a bug in Chrome!

I would suggest you add $server_protocol to your nginx log_format so you can trace on the server side which protocol was actually used for the request:

log_format my_log_format '$remote_addr - $remote_user [$time_local] '
      '$server_protocol "$request" $status $body_bytes_sent '
      '"$http_referer" "$http_user_agent"';
access_log /usr/local/nginx/nginx-access.log my_log_format;
Barry Pollard
  • 4,591
  • 15
  • 26
  • 1) no. 2) no (and same as 1) 3) no - this is a clean build of the server / tested with different backends so all the content is being seen by the proxy for the first time 4) possible 5) possibly - I'll try the log changes. – symcbean Sep 04 '19 at 20:45
  • For 3) I meant it being cached in the browser not in the proxy. Reload to ensure its actually requested from the server and not being read from HTTP Cache. Guessing not that either based on your other answers but have seen people confused about that before... – Barry Pollard Sep 04 '19 at 20:49