# Possible bug http2 module

**URL:** <https://www.ruby-forum.com/t/possible-bug-http2-module/244021>\
**Category:** NGINX\
**Created:** [February 6, 2016, 6:14pm UTC](https://www.ruby-forum.com/t/possible-bug-http2-module/244021 "2016-02-06T18:14:13Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rafa\_F](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/958977/32.png) [@Rafa\_F](https://www.ruby-forum.com/u/Rafa_F)\
**Post date:** [February 6, 2016, 6:14pm UTC](https://www.ruby-forum.com/t/possible-bug-http2-module/244021/1 "2016-02-06T18:14:13Z")

</div>

Hello,

I am running a WordPress multisite install and recently turned off http2  
on the domain in order to use a third party module which evidently  
doesn’t play nicely with http2 (echo module). In testing I noticed that  
the site was still being served with http2 enabled according to both  
Chrome and Firefox. I confirmed with curl.

I recompiled nginx without any third party modules:

# nginx -V

nginx version: nginx/1.9.10  
built with OpenSSL 1.0.2f 28 Jan 2016  
TLS SNI support enabled  
configure arguments: --prefix=/usr/local/etc/nginx --with-cc-opt=‘-I  
/usr/local/include’ --with-ld-opt=‘-L /usr/local/lib’  
–conf-path=/usr/local/etc/nginx/nginx.conf  
–sbin-path=/usr/local/sbin/nginx --pid-path=/var/run/nginx.pid  
–error-log-path=/var/log/nginx-error.log --user=www --group=www  
–with-file-aio --with-ipv6  
–http-client-body-temp-path=/var/tmp/nginx/client\_body\_temp  
–http-fastcgi-temp-path=/var/tmp/nginx/fastcgi\_temp  
–http-proxy-temp-path=/var/tmp/nginx/proxy\_temp  
–http-scgi-temp-path=/var/tmp/nginx/scgi\_temp  
–http-uwsgi-temp-path=/var/tmp/nginx/uwsgi\_temp  
–http-log-path=/var/log/nginx-access.log --with-http\_stub\_status\_module  
–with-pcre --with-http\_v2\_module --with-http\_ssl\_module

I then adjusted the config files so as not to reference any third party  
modules and performed a binary “upgrade”.

I still see that http2 is in use on both Chrome and Firefox, and also  
via curl.

# curl -I -k [https://my.ip4.add.ress/](https://my.ip4.add.ress/)

HTTP/2.0 302  
server:nginx/1.9.10  
date:Sat, 06 Feb 2016 16:49:44 GMT  
content-type:text/html; charset=UTF-8

# curl -I https:/mydomain.net/

HTTP/2.0 200  
server:nginx/1.9.10  
date:Sat, 06 Feb 2016 16:50:41 GMT  
content-type:text/html; charset=UTF-8

There are other domains on that IPv4 which use http2. Disabling http2 on  
all of them resulted in the expected behavior in the browsers and in  
curl:

# curl -I -k https:///my.ip4.add.ress/

HTTP/1.1 302 Moved Temporarily  
Server: nginx/1.9.10  
Date: Sat, 06 Feb 2016 17:03:39 GMT  
Content-Type: text/html; charset=UTF-8  
Connection: keep-alive

# curl -I [https://mydomain.net/](https://mydomain.net/)

HTTP/1.1 200 OK  
Server: nginx/1.9.10  
Date: Sat, 06 Feb 2016 17:05:05 GMT  
Content-Type: text/html; charset=UTF-8  
Connection: keep-alive

I don’t see any reference to this at  
[Module ngx\_http\_v2\_module](http://nginx.org/en/docs/http/ngx_http_v2_module.html) so I am guessing  
this is unintended.

Obvious workaround is to place this domain on an IPv4 in which there are  
no http2 sites.

More permanent solution should be considered.

–  
Jim O.

“Never argue with a fool, onlookers may not be able to tell the  
difference.” - Mark Twain

---

<div class="post-metadata">

**Author:** ![joviyach](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/7bcc69/32.png) [@joviyach](https://www.ruby-forum.com/u/joviyach)\
**Post date:** [February 6, 2016, 6:22pm UTC](https://www.ruby-forum.com/t/possible-bug-http2-module/244021/2 "2016-02-06T18:22:24Z")

</div>

On Saturday 06 February 2016 12:13:52 Jim O. wrote:

> # nginx -V
> 
> –http-fastcgi-temp-path=/var/tmp/nginx/fastcgi\_temp  
> I still see that http2 is in use on both Chrome and Firefox, and also  
> server:nginx/1.9.10  
> Content-Type: text/html; charset=UTF-8  
> [Module ngx\_http\_v2\_module](http://nginx.org/en/docs/http/ngx_http_v2_module.html) so I am guessing  
> this is unintended.

[..]

A quote from the documentation:

| The http2 parameter (1.9.5) configures the port to accept HTTP/2  
| connections.

> **[Module ngx\_http\_core\_module](http://nginx.org/en/docs/http/ngx_http_core_module.html#listen)**
>
> This directive appeared in version 1.11.8.

wbr, Valentin V. Bartenev

---

<div class="post-metadata">

**Author:** ![joviyach](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/7bcc69/32.png) [@joviyach](https://www.ruby-forum.com/u/joviyach)\
**Post date:** [February 6, 2016, 6:44pm UTC](https://www.ruby-forum.com/t/possible-bug-http2-module/244021/3 "2016-02-06T18:44:36Z")

</div>

On 2/6/16 12:22 PM, Валентин Бартенев wrote:

> > –http-client-body-temp-path=/var/tmp/nginx/client\_body\_temp
> > 
> > HTTP/2.0 200  
> > Date: Sat, 06 Feb 2016 17:03:39 GMT  
> > I don’t see any reference to this at  
> > [Module ngx\_http\_core\_module](http://nginx.org/en/docs/http/ngx_http_core_module.html#listen)  
> > Ahh. That’s not in the http2 module documentation, where I looked and  
> > where it should perhaps also be mentioned, and it’s not clear that the  
> > above applies to every server.

So if I write:

listen 443 ssl http2;

in a server directive anywhere as dosumneted in  
[Module ngx\_http\_v2\_module](http://nginx.org/en/docs/http/ngx_http_v2_module.html#example), then  
http2 is enabled in all servers on all IP’s even if it’s not  
specifically enabled in a listen directive in a particular server? That  
seems wrong, intuitively. There are (more and more) times when shared  
IPv4’s are necessary, and dictating this behavior for all servers on a  
given IPv4 is probably less than optimal. If it’s technically a  
necessity it could perhaps be more explicitly documented.

–  
Jim O.

“Never argue with a fool, onlookers may not be able to tell the  
difference.” - Mark Twain

---

<div class="post-metadata">

**Author:** ![joviyach](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/7bcc69/32.png) [@joviyach](https://www.ruby-forum.com/u/joviyach)\
**Post date:** [February 6, 2016, 6:59pm UTC](https://www.ruby-forum.com/t/possible-bug-http2-module/244021/4 "2016-02-06T18:59:47Z")

</div>

On Saturday 06 February 2016 12:44:08 Jim O. wrote:

> > > I recompiled nginx without any third party modules:  
> > > –with-file-aio --with-ipv6  
> > > modules and performed a binary “upgrade”.
> > > 
> > > # curl -I https:/mydomain.net/
> > > 
> > > HTTP/1.1 302 Moved Temporarily  
> > > Connection: keep-alive
> 
> in a server directive anywhere as dosumneted in  
> [Module ngx\_http\_v2\_module](http://nginx.org/en/docs/http/ngx_http_v2_module.html#example), then  
> http2 is enabled in all servers on all IP’s even if it’s not  
> specifically enabled in a listen directive in a particular server? That  
> seems wrong, intuitively. There are (more and more) times when shared  
> IPv4’s are necessary, and dictating this behavior for all servers on a  
> given IPv4 is probably less than optimal. If it’s technically a  
> necessity it could perhaps be more explicitly documented.

It’s pretty much the same as “ssl” parameter works.

Ones connected an HTTP/2 client is able to request any host over the  
HTTP/2  
connection, and in fact browsers do. So there’s no proper way to  
disable  
HTTP/2 for one virtual server while keeping enable for others.

Could you suggest a good phrase to improve the docs?

wbr, Valentin V. Bartenev

---

<div class="post-metadata">

**Author:** ![joviyach](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/7bcc69/32.png) [@joviyach](https://www.ruby-forum.com/u/joviyach)\
**Post date:** [February 6, 2016, 8:51pm UTC](https://www.ruby-forum.com/t/possible-bug-http2-module/244021/5 "2016-02-06T20:51:57Z")

</div>

On 2/6/16 1:00 PM, Валентин Бартенев wrote:

[snip]

So if I write:

> > necessity it could perhaps be more explicitly documented.
> 
> It’s pretty much the same as “ssl” parameter works.

I thought of that but there’s a fundamental difference from the point of  
view of the server admin. If I enable SSL on one or more vhosts sharing  
an IP address and choose not to use SSL in another vhost sharing that  
same IP, I simply do not write an ssl server configuration for that  
vhost. There’s no certificate for it so pretty much any client will  
throw an error if a request is made for that vhost on 443. The user then  
can use http instead of https or s/he can choose to use an incorrect  
certificate. Most choose the former. With the advent of free certificate  
services like Letsencrypt, StartSSL and Wotan, I, like many server  
admins, am shifting more and more to https (and http2). But as we’ve  
seen, there are times when http2 cannot be used (or is undesirable) but  
we still prefer SSL, or we’ve long ago enabled HSTS and pretty much can  
no longer back out, at least not without significant disruption.

In my use case, the server in question is a FreeBSD KVM in a large Linux  
machine that hosts many other KVM’s and LXC’s. Each of my customers  
needs at least one IPv4 and most want more than one. The host will only  
provide me with a finite number of IPv4 addresses per physical server.  
If IPv6 were ubiquitous I would not have a problem as I have a /64 on  
each machine. I try to limit my own use of IPv4’s so as to have them  
available. With SNI that really isn’t a problem. I no longer worry  
whether my sites support ancient clients, so I host many SSL domains on  
the same IP. If I want to use http2 on all but one, and I _cannot_ use  
http2 on that one, then I cannot use http2 on any, as I have come to  
find out.

> Ones connected an HTTP/2 client is able to request any host over the HTTP/2  
> connection, and in fact browsers do. So there’s no proper way to disable  
> HTTP/2 for one virtual server while keeping enable for others.

The most elegant solution (if it’s possible - my programming skills  
start and end with shell scripts) would be a programmatic one where a  
directive is optionally turned on in the http context of the nginx  
configuation file. Something like:

check\_http2 (on|off);

with a default of “off”. Such a directive could check for explicit http2  
enabling in a vhost where SSL is also enabled, and downgrade connections  
to those where it is not enabled. Of course this would probably violate  
half a dozen RFC’s, but it would be helpful in the use case I just  
described, which is in fact a real world situation. A server admin who  
does not want to spend the CPU cycles on such a check simply does not  
enable it, but one who needs it can use it.

> Could you suggest a good phrase to improve the docs?

Something like the following in the http2 and core module documentation:

NOTE: Enabling http2 globally (via “listen 443 ssl http2;” in ANY server  
block), or on any single IP (via “listen 1.2.3.4:443 ssl http2;”),  
enables http2 on ALL vhosts using SSL, either globally or on that  
specific IP. If this is not the desired behavior use one IP for vhosts  
using http2 and a different IP for vhosts using SSL but for which you do  
not want to enable http2. Enable http2 only for the IP’s where it is  
desired.

–  
Jim O.

“Never argue with a fool, onlookers may not be able to tell the  
difference.” - Mark Twain
