Bug->Doc #77889 [Nab]: URL in Location header not used

From: Date: Tue, 16 Feb 2021 17:00:41 +0000
Subject: Bug->Doc #77889 [Nab]: URL in Location header not used
References: 1  Groups: php.doc.bugs 
Request: Send a blank email to doc-bugs+get-18557@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=77889&edit=1 ID: 77889 User updated by: ASchmidt at Anamera dot net Reported by: ASchmidt at Anamera dot net Summary: URL in Location header not used Status: Not a bug -Type: Bug +Type: Documentation Problem Package: Streams related Operating System: Windows x64 PHP Version: 7.2.17 Assigned To: cmb Block user comment: N Private report: N New Comment: Dear "rtrtrtrtrt@dfdfdfdf.dfd35", thatnk you for your comment. >> there is no point to set a Host-Header and a Location-Header with different values << There appears to be confusion on how HTTP works. The "Host" header is a REQUEST header, set by the application (the PHP script). The "Location" header is a RESPONSE header set by the contacted host. The whole POINT of a server's "Location" response is to advise the client of a DIFFERENT URL (possibly involving a different "Host"!) that should be contacted. The Location response being different from the originally requested is not "garbage in/out", but intended behavior!? A PHP script does not know in advance that it will receive a "Location" response. The net effect of this issue is that the "Host" header and the "follow_location" option are mutually exclusive, which should be explicitly stated. Previous Comments: ------------------------------------------------------------------------ [2021-02-16 16:44:24] cmb@php.net The documentation states[1]: | Values in this option will override other values (such as | User-agent:, Host:, and Authentication:). In other words, as soon as you set any custom headers, it is your responsibility that they are suitable. [1] <https://www.php.net/manual/en/context.http.php#refsect1-context.http-options> ------------------------------------------------------------------------ [2021-02-16 16:40:15] rtrtrtrtrt at dfdfdfdf dot dfd35 > it would mean that PHP is responsible for replacing > any previous, obsolete "Host" header, with the correct, > valid Host header to match the "Location" response no, it's a programming language garbage in, garbage out there is no point to set a Host-Header and a Location-Header with different values and a programming language is expected to do what you say - even if it's wrong ------------------------------------------------------------------------ [2021-02-16 16:23:57] ASchmidt at Anamera dot net Since this is not intuitive (and the default setting of follow-location=true effectively bars the use of the "Host:" header), I have submitted a comment to the manual page https://www.php.net/manual/en/context.http.php. However, as far as the PHP behavior NOT being a bug, HTTP 1.1 made "Host" headers mandatory, and more than ONE Host header is explicitly disallowed (https://tools.ietf.org/html/rfc7230#section-5.4). Standards further explicitly require that "Host" headers are to be replaced, e.g., the original "Host" must NOT not be forwarded (the example of Proxy servers is being cited.) While I understand/appreciate the "explanation" (work-around), I believe the old PHP behavior is both unexpected, and not consistent with the RFC: - Since every HTTP 1.1 request must have exactly ONE, and VALID, "Host" header that matches the intended target host, and - since PHP creates the secondary HTTP request to "follow-location", - it would mean that PHP is responsible for replacing any previous, obsolete "Host" header, with the correct, valid Host header to match the "Location" response. Otherwise the resulting "follow-location" request is not compliant with HTTP 1.1 standards. ------------------------------------------------------------------------ [2021-02-16 14:59:41] cmb@php.net Since you're explicitly setting the Host, finecars.cc is used for all requests, resulting in the undesired behavior. Just remove that entry from the headers array. ------------------------------------------------------------------------ [2019-04-14 04:06:57] ASchmidt at Anamera dot net Description: ------------ For $host = 'www.finecars.cc', the HTML content is correctly received. For $host = 'finecars.cc', the initial response is: HTTP/1.1 301 Moved Permanently Location: http://www.finecars.cc/ However, after that, PHP does NOT actually retrieve "www.finecars.cc" as defined in the Location header, but continues to retry the original URL "finecars.cc" until 'max_redirects' is exhausted. Test script: --------------- <?php declare(strict_types=1); $host = 'finecars.cc'; $headers = array( 'Host' => $host, 'User-Agent' => 'Anamera/2.0', 'Accept-Charset' => 'UTF-8', 'Referer' => ( '0' == $_SERVER['SERVER_PORT_SECURE'] ? 'http' : 'https' )."://{$_SERVER['SERVER_NAME']}{$_SERVER['REQUEST_URI']}", 'Connection' => 'close', 'Origin' => ( '0' == $_SERVER['SERVER_PORT_SECURE'] ? 'http' : 'https' )."://{$_SERVER['SERVER_NAME']}", ); $header_lines = []; foreach ( $headers as $name => $entry ) $header_lines[] = "{$name}: {$entry}"; $http_options = array( 'http' => array( 'protocol_version' => 1.1, 'timeout' => 30, // float: seconds. 'follow_location' => 1, 'max_redirects' => 5, 'ignore_errors' => true, // fetch content even on failure status codes. 'method' => 'GET', 'header' => $header_lines, // 'user_agent' => '', // use: 'header'['User-Agent']. // 'content' => '', // for POST and PUT. ), ); $http_context = stream_context_create( $http_options ); $file = file_get_contents( "http://{$host}", false, $http_context ); var_dump( $http_options, $http_response_header ); die( 'Current PHP version: ' . phpversion() ); ?> Expected result: ---------------- 0 => string 'HTTP/1.1 301 Moved Permanently' (length=30) 1 => string 'Content-Type: text/html; charset=UTF-8' (length=38) 2 => string 'Location: http://www.finecars.cc/' (length=33) 3 => string 'Connection: close' (length=17) 4 => string 'Content-Length: 146' (length=19) 5 => string 'HTTP/1.1 200 OK' (length=15) 6 => string 'Content-Type: text/html;charset=iso-8859-1' (length=42) 7 => string 'Connection: close' (length=17) 8 => string 'Content-Length: 87608' (length=21) Actual result: -------------- 0 => string 'HTTP/1.1 301 Moved Permanently' (length=30) 1 => string 'Content-Type: text/html; charset=UTF-8' (length=38) 2 => string 'Location: http://www.finecars.cc/' (length=33) 3 => string 'Connection: close' (length=17) 4 => string 'Content-Length: 146' (length=19) 5 => string 'HTTP/1.1 301 Moved Permanently' (length=30) 6 => string 'Content-Type: text/html; charset=UTF-8' (length=38) 7 => string 'Location: http://www.finecars.cc/' (length=33) 8 => string 'Connection: close' (length=17) 9 => string 'Content-Length: 146' (length=19) 10 => string 'HTTP/1.1 301 Moved Permanently' (length=30) 11 => string 'Content-Type: text/html; charset=UTF-8' (length=38) 12 => string 'Location: http://www.finecars.cc/' (length=33) 13 => string 'Connection: close' (length=17) 14 => string 'Content-Length: 146' (length=19) etc. ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=77889&edit=1

« previous php.doc.bugs (#18557) next »