Bug #67352 [Fbk]: HTTP 1.1 causes timeouts for series of files
| From: | aharvey@php.net | Date: | Wed, 28 May 2014 06:46:19 +0000 |
| Subject: | Bug #67352 [Fbk]: HTTP 1.1 causes timeouts for series of files | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-185945@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=67352&edit=1
ID: 67352
Updated by: aharvey@php.net
Reported by: Andy_Schmidt at HM-Software dot com
Summary: HTTP 1.1 causes timeouts for series of files
Status: Feedback
Type: Bug
Package: Streams related
Operating System: Windows 2012
PHP Version: 5.4.28
Block user comment: N
Private report: N
New Comment:
I believe this is a duplicate of request #65634 â it was implemented on PHP-5.6 and master, but
I elected not to backport it due to the (slight) behavioural change.
Previous Comments:
------------------------------------------------------------------------
[2014-05-28 04:22:08] rasmus@php.net
I really don't think this is a PHP issue. You are most likely hitting the fact that HTTP/1.1
connections default to be persistent (keep-alive) so they are sitting there waiting for the
keep-alive timeout. Send a "Connection: close" header to test that theory.
------------------------------------------------------------------------
[2014-05-28 02:59:07] Andy_Schmidt at HM-Software dot com
Description:
------------
The manual states in the first sentence: "Allows read-only access to files/resources via HTTP
1.0, using the HTTP GET method", however, the HTTP context options "method" and
"protocol_version" clearly allow setting a HEAD method and version 1.1.
However, when a series of files is processed with a fsopen() "HEAD" request (to obtain
file name, file type and timestamp, followed by a "GET" request, then for some web
servers, the script will eventually start timing out for each file.
I don't know enough about the internals of PHP, but I wonder if the problem is that with each
successive HTTP 1.1 request, another connection is opened - and then kept open (in line with
protocol version 1.1) - preventing subsequent acesses until that previsouly used connection has
timed out.
Just commenting out protocol_version => 1.1 will circumvent the problem.
Test script:
---------------
$arrValidTypes = array ( 'gif', 'jpg', 'jpeg', 'png',
'psd', 'bmp',
'tiff', 'tif', 'jpc', 'jp2', 'jpf',
'jb2', 'swc',
'aiff', 'wbmp', 'xbm');
// Make HEAD request to get just metadata on submitted file
$arrRequestHeaders = array(
'http'=>array(
'method' =>'HEAD',
'protocol_version' =>1.1,
'follow_location' =>1,
'header'=> "User-Agent: Anamera-Feed/1.0\r\n" .
"Referer: $source\r\n"
)
);
$rc = @fopen( $fURI, 'r', false, stream_context_create($arrRequestHeaders) );
if ( $http_response_header ) {
for ( $i = sizeof($http_response_header) - 1; $i >= 0; $i-- ) {
if ( preg_match('@^http/\S+ (\S{3,}) (.+)$@i', $http_response_header[$i], $http_status)
> 0 ) {
// HTTP Status header means we have reached beginning of response headers for last request
break;
}
elseif ( preg_match('/^(\S+):\s*(.+)\s*$/', $http_response_header[$i], $arrHeader) >
0 ) {
switch ( $arrHeader[1] ) {
case 'Content-Type':
if ( !isset($http_content_image_type) ) {
if ( preg_match('@^image/(\w+)@ims', $arrHeader[2], $arrTokens) > 0 ) {
if ( in_array(strtolower($arrTokens[1]), $arrValidTypes)) {
$http_content_image_type = $arrTokens[1];
break;
}
}
throw new Exception( "Error inspecting file: $fURI; invalid content type:
$arrHeader[2]", 2);
}
break;
case 'Content-Disposition':
if ( !isset($http_content_filename) &&
preg_match('/filename\\s*=\\s*(?|"([^"]+)"|([\\S]+));?/ims', $arrHeader[2],
$arrTokens) > 0 ) {
$http_content_filename = basename($arrTokens[1]);
}
break;
}
}
}
}
// Generate target file name
$path_parts = pathinfo( $http_content_filename );
$fName = $path_parts['filename'];
if ( in_array(strtolower($path_parts['extension']), $arrValidTypes) ) {
$fExt = $path_parts['extension'];
if ( !$fExt ) {
// Default extension to Content-Type header, or 'jpg' as last resort
$fExt = isset($http_content_image_type) ? $http_content_image_type : 'jpg';
}
$arrRequestHeaders = array(
'http'=>array(
'method' =>'GET',
'protocol_version' =>1.1,
'follow_location' =>1,
'header'=> "User-Agent: Anamera-Feed/1.0\r\n" .
"Referer: $source\r\n"
)
);
$rc = copy( $fURI, $target_file, stream_context_create($arrRequestHeaders) );
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=67352&edit=1