Bug #67351 [PATCH]: copy() should handle HTTP 304 response

From: Date: Mon, 21 Sep 2020 14:06:54 +0000
Subject: Bug #67351 [PATCH]: copy() should handle HTTP 304 response
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-229113@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=67351&edit=1

 ID:                 67351
 Patch added by:     cmb@php.net
 Reported by:        Andy_Schmidt at HM-Software dot com
 Summary:            copy() should handle HTTP 304 response
 Status:             Verified
 Type:               Bug
 Package:            Streams related
 Operating System:   Windows 2012
 PHP Version:        5.4.28
 Assigned To:        cmb
 Block user comment: N
 Private report:     N

 New Comment:

The following pull request has been associated:

Patch Name: Fix #67351: copy() should handle HTTP 304 response
On GitHub:  https://github.com/php/php-src/pull/6177
Patch:      https://github.com/php/php-src/pull/6177.patch


Previous Comments:
------------------------------------------------------------------------
[2020-09-08 15:22:30] cmb@php.net

> Sorry - I thought I had already posted this:

You had.  Sorry.

Anyhow, the behavior of copy() and file_get_contents() are clearly
in error here, and not copying/fetching but returning false seems
appropriate.

------------------------------------------------------------------------
[2020-09-08 00:09:41] Andy_Schmidt at HM-Software dot com

Sorry - I thought I had already posted this:

Expected result:
----------------
When a HTTP 304 response is returned, the copy() function must NOT touch the target file. 
Suggestion: copy() could return a FALSE (indicating that nothing was copied), in case the script
wishes to check the HTTP response to decide on any specialized processing, if any.


As far as your follow-up question regarding file_get_contents(): The HTTP 304 response can only
possibly occur because the caller had explicitly/intentionally produced an
"If-Modified-Since" header. Consequently, I feel it is unlikely to break existing code, if
file_get_contents() were to return FALSE rather than an empty string.  This implies to the caller
correctly that NO data was returned, rather than falsely implying that the file has NEW data and the
data is an empty file. 
When the caller receives FALSE to an "If-Modified-Since", then their logic has the choice
how to handle the FALSE condition (e.g., by short circuiting non-applicable code blocks if there is
no new data.)

------------------------------------------------------------------------
[2020-09-07 13:17:31] cmb@php.net

I agree that the current handling of 304 Not Modified doesn't make
much sense, but I wonder how that should be handled.  Just do
nothing, but return true?  And how to handle file_get_contents()
etc.?

------------------------------------------------------------------------
[2014-05-28 02:23:56] Andy_Schmidt at HM-Software dot com

Description:
------------
Using the "If-Modified-Since" header is desirable when copying from a remote web server,
to avoid unnecessarily copying unmodified files across the Internet.

However, the copy() function does not handle a HTTP 304 response, which indicates that the file on
the web server is NOT newer than the local file. It ignores the response code, uses the (empty)
content from the HTTP response and overwrites the existing local file with a zero length file. This
is not a useful course of action.

Since the copy() function DOES handle other 3xx return codes appropriately (such as following
permanent and temporary redirects), it would make particular sense to also handle 304.

Test script:
---------------
<?php
// $fURI: 		URL to a file located on a web server
// $target_file:	Path to a local file	

$arrRequestHeaders = array(
	'http'=>array(
		'method'		=>'GET',
		'protocol_version'	=>1.1,
		'follow_location'	=>1,
		'header'		=>'If-Modified-Since: '.date( 'r', filemtime(
$target_file ) )."\r\n"
			)
		);
$rc = copy( $fURI, $target_file, stream_context_create($arrRequestHeaders) );
?>

Expected result:
----------------
When a HTTP 304 response is returned, the copy() function must NOT touch the target file. copy()
could return a FALSE (indicating that nothing was copied), and the script could check the HTTP
response to decide on any specialized processing.

Actual result:
--------------
When a HTTP 304 response is returned, the copy() function returns TRUE and overrides the target file
with a 0 length file.


------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=67351&edit=1


Thread (5 messages)

« previous php.bugs (#229113) next »