Bug #81487 [NEW]: feof() should return true after reading last chunk for HTTP requests

From: Date: Wed, 29 Sep 2021 08:36:23 +0000
Subject: Bug #81487 [NEW]: feof() should return true after reading last chunk for HTTP requests
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-236908@lists.php.net to get a copy of this message
From: public+php dot net at bastelstu dot be Operating system: Ubuntu 20.04 + Docker PHP version: 8.0.11 Package: HTTP related Bug Type: Bug Bug description:feof() should return true after reading last chunk for HTTP requests Description: ------------ When performing HTTP requests using fopen(), feof() will not return true until the server closes the connection, even if the full body has already been received. According to RFC 7230#6.6 (https://httpwg.org/specs/rfc7230.html#persistent.tear-down): > A client that sends a "close" connection option MUST NOT send further requests > on that connection (after the one containing "close") and MUST close the > connection after reading the final response message corresponding to this request. PHP should detect that the full response message has been read and close the socket. --------------------- In my real world use case, I am using Guzzles StreamHandler (https://github.com/guzzle/guzzle/blob/master/src/Handler/StreamHandler.php) to perform HTTP requests, reading Open Graph metadata. In one case I was apparently hitting a NetScaler load balancer (https://www.nextthing.org/archives/2005/08/07/fun-with-http-headers#comment-24970). These appear to ignore any Connection: close headers within the request and keep the connection open (for minutes). This is in violation of section RFC7230#6.6: > A server that receives a "close" connection option MUST initiate a close of > the connection (see below) after it sends the final response to the request > that contained "close". The server SHOULD send a "close" connection option > in its final response on that connection. The server MUST NOT process any > further requests received on that connection. *Nonetheless* PHP should also honor its side of RFC7230 and also actually close the connection after receiving the response. cURL on the command line and HTTPie both will close the connection on their own. Test script: --------------- <?php // Reproducer server in C: // https://gist.github.com/TimWolla/0a94abd5c3a9e4c75f317910ac56fa80 $fd = fopen("http://172.17.0.1:8080", "r"); while (!feof($fd)) { var_dump(fread($fd, 2)); } Expected result: ---------------- I expected the while loop to terminate after reading the 9 within the response, like cURL does: $ curl -v 'localhost:8080' * Trying 127.0.0.1:8080... * TCP_NODELAY set * Connected to localhost (127.0.0.1) port 8080 (#0) > GET / HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/7.68.0 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 200 Ok < Connection: keep-alive < Transfer-Encoding: chunked < * Connection #0 to host localhost left intact 0123456789 Actual result: -------------- The loop / script did not terminate until I terminated the HTTP server, thus implicitly closing the socket: $ php test.php string(2) "01" string(2) "23" string(2) "45" string(2) "67" string(2) "89" *hangs at this point* -- Edit bug report at https://bugs.php.net/bug.php?id=81487&edit=1 -- Fix committed: https://bugs.php.net/fix.php?id=81487&r=fixed Fixed in release: https://bugs.php.net/fix.php?id=81487&r=alreadyfixed Need backtrace: https://bugs.php.net/fix.php?id=81487&r=needtrace Need Reproduce Script: https://bugs.php.net/fix.php?id=81487&r=needscript Try newer version: https://bugs.php.net/fix.php?id=81487&r=oldversion Not developer issue: https://bugs.php.net/fix.php?id=81487&r=support Expected behavior: https://bugs.php.net/fix.php?id=81487&r=notwrong Not enough info: https://bugs.php.net/fix.php?id=81487&r=notenoughinfo Submitted twice: https://bugs.php.net/fix.php?id=81487&r=submittedtwice register_globals: https://bugs.php.net/fix.php?id=81487&r=globals PHP version support discontinued: https://bugs.php.net/fix.php?id=81487&r=phptooold Daylight Savings: https://bugs.php.net/fix.php?id=81487&r=dst IIS Stability: https://bugs.php.net/fix.php?id=81487&r=isapi Install GNU Sed: https://bugs.php.net/fix.php?id=81487&r=gnused Floating point limitations: https://bugs.php.net/fix.php?id=81487&r=float No Zend Extensions: https://bugs.php.net/fix.php?id=81487&r=nozend MySQL Configuration Error: https://bugs.php.net/fix.php?id=81487&r=mysqlcfg

« previous php.bugs (#236908) next »