I’m still a bit new to Docker so forgive me if I don’t know the correct terminology for some of this.
I am in the process of switching multiple PHP projects over to Docker containers, all of which are written in PHP. I have noticed that Docker seems to break PHPs HTTP(S) stream wrappers.
For example, doing this:
file_get_contents('http://www.google.com'); will cause execution to hang.
This is because prior to PHP8 by default, the HTTP stream wrapper uses HTTP/1.0 along with a “Connection: close” when making HTTP requests. I’ve noticed that Docker, for some reason, changes this to (or forwards as) HTTP/1.1, but doesn’t modify how the connection is handled. So the server thinks the request is a HTTP/1.1 request and responds with chunked transfer-encoding, which in-turn relies on the client to close the connection, but the client thinks the request was HTTP/1.0 and sits there waiting for the server to close the connection causing the program to hand either indefinitely or until timeout is reached.
For versions >= PHP8, there is a bug that triggers the same behavior despite HTTP/1.1 being requested. See: PHP :: Bug #80931 :: file_get_contents() hangs with HTTP/1.1 if server doesn't close connection
This seems pretty bad to me. I now have 3 PHP apps that just don’t work because Docker wants to force me to use HTTP/1.1.
I’ve confirmed this behavior with direct socket writes hard-coded to HTTP/1.0 along with Wireshark sniffing packets on the host to confirm the request protocol is being changed. I have also confirmed that this only happens on port 80 (and 443 i’m assuming, I can’t sniff SSL). If I change the port used then HTTP/1.0 is requested.
Is anyone else experiencing this issue? Is this a known problem that I’m just not finding the right search results for? Is there a setting that needs to be turned on/off somewhere? I’m feeling pretty stuck here and I can’t figure out why Docker would feel the need to interfere with HTTP requests, so any light someone can shine on this issue for me would be greatly appreciated.