Bug 47693

Summary: GET request has race condition w.r.t. replacement of file being served
Product: Apache httpd-2 Reporter: alex
Component: AllAssignee: Apache HTTPD Bugs Mailing List <bugs>
Status: RESOLVED DUPLICATE    
Severity: normal CC: poirier
Priority: P2    
Version: 2.5-HEAD   
Target Milestone: ---   
Hardware: All   
OS: All   

Description alex 2009-08-13 05:23:12 UTC
When a GET request is received by Apache, it first opens the file to determine the length, then closes it, then reopens it to serve the file.

An interesting use case is to replace a file (using an atomic rename) and have Apache give consistent results: always return either the old file or the new file.

However, the current implementation will give inconsistent results when the length of the file changes between the first and second time Apache opens the files.

If the new file is longer, Apache returns the content of the new file truncated to the length of the first file. If the new file is shorter, Apache returns an error response.
Comment 1 Dan Poirier 2009-08-14 04:34:41 UTC
That's all true, but are there are any feasible ways to fix the behavior?  For that matter, what is the right behavior if a file changes in the middle of a request?

The server could ensure consistency by making a complete copy of every file before beginning to serve it, but that's not reasonable for any significant load.  There might be some operating systems where the server could get an exclusive lock on the file before beginning to serve it, but not on most OSes.

Practically speaking, the solution is not to change files under a running server.  Or serve the content from a database or other source with true atomic changes.
Comment 2 alex 2009-09-29 01:38:29 UTC
Perhaps it won't be feasible in terms of internal state management inside the server, but the solution would be to use the following sequence:

open the file, get it's length, read the file, close the file

instead of:

open the file, get it's length, close the file, open the file, read the file, close the file.

Note that the interference with file that I'm talking about is not an arbitrary modification to the file, but only the case where the file is replaced by another file. This is a typical filesystem operation for doing a "clean" / "atomic" modification to a file: write a new copy of the file content to a temporary file, then replace the target file by the temporary file.

Reopening to get feedback on the feasibility of the proposed solution...
Comment 3 Joe Orton 2020-10-22 08:37:27 UTC

*** This bug has been marked as a duplicate of bug 54962 ***