The processing logic of gzip_cnc
Order of the main program's operation
- Do we have a value for the path name of the file to be served?
(in the Environment variablePATH_TRANSLATED
- this one is set by the web server for each Apache handler.)- no => perform the self-test function.
(We cannot have been invoked as a handler, for we don't just know what we have to do.)
- no => perform the self-test function.
- Do the Environment variables
PATH_INFO
andREDIRECT_URL
contain the same value?- no => reject the request with the HTTP status 403.
(This seems to have been an attempt to invoke the script directly and thus avoid existing Apache access control mechanisms; this test has been added in version 1.11.)
- no => reject the request with the HTTP status 403.
- Do we have a URL value for the file to be served?
(in the Environment variablePATH_INFO
- this one is set by the web server for each Apache handler.)- no => serve the content of the original file (described by
PATH_TRANSLATED
).
(We don't know how to construct the name of the cache file.)
- no => serve the content of the original file (described by
- Compute the name of the corresponding cache file from the values of these two Environment variables.
(PATH_INFO
provides the path name,PATH_TRANSLATION
the file name which may be the result of a Content Negotiation already performed by the Apache server, whereasPATH_INFO
still contains the original URL of the request.) - Read the attributes of the original file.
(using the system functionstat()
)
Did this work?- no => perform a processing for a missing page.
(We cannot access this file - it makes no difference for the visitor whether this file doesn't exist or whether any kind of system error has occurred.)
- no => perform a processing for a missing page.
- Did the UserAgent allow the serving of compressed data?
(i. e. supplied the valuegzip
within theAccept-Encoding
HTTP header)- no => serve the content of the original file.
(We must not overtax the browser with data it cannot understand.)
- no => serve the content of the original file.
- Read the attributes of the compressed file in the cache.
(using the system functionstat()
)
Did this work?- no => try to create the cache file.
- Is the last modification date for the cache file newer than the one for the original file?
- Is the content of the cache file smaller than the one for the original file?
- no => serve the content of the original file.
(The compressed version is good for nothing - but it doesn't make sense to remove it because it would then have to be created again during the next access to recognize that it is worthless.)
- no => serve the content of the original file.
- Serve the content of the cache file.
Creating (or updating the content of) a cache file
It makes no difference whether
- a cache file doesn't exist or
- contains an outdated content
- in both cases it is necessary to fill this cache file with a compressed form of the current content of the original file.
- Split the path name of the cache file into directory part and file part.
Did this work?- no => serve the content of the original file.
(The path name isn't structured the way we expected as to be able to handle it.)
- no => serve the content of the original file.
- Compute the name of the cache directory for the compressed version of the requested file from the directory part.
- If this directory doesn't exist already, try to create it.
Did this work?- no => serve the content of the original file.
(Without cache directory we cannot create a cache file.)
- no => serve the content of the original file.
- Create a random but unique name of a temporary file inside the cache directory.
- Compress the content of the original file into this temporary file.
Did this work?- no => remove the temporary file and serve the content of the original file.
(The result of this compression we would have wanted to store within the cache.)
- no => remove the temporary file and serve the content of the original file.
- Rename the temporary file to the name of the cache file.
Did this work?- no => remove the temporary file and serve the content of the original file.
(We possibly might have served the version but something strange has been gone wrong here, so we rather play it safe.)
- no => remove the temporary file and serve the content of the original file.
- Read the attributes of the compressed file from the cache
(using the system functionstat()
).
Did this work?- no => remove the cache file and serve the content of the original file.
(The cache file isn't usable anyhow, so off with it.)
- no => remove the cache file and serve the content of the original file.
Serving a file content
Whether the content of a file is to be served in compressed or uncompressed form is a relatively small difference, therefore both processes are handled by the same function.
- Open the file to be sent.
If this did work then- Send the HTTP status
200
showing the successful processing. - Send the HTTP header
Date
describing the current server time. - Send the HTTP header
Vary
describing the Content Negotiation performed
(as mark of the conditional serving of the file content depending on the content of the received HTTP headerAccept-Encoding
- a proxy server ought to be informed that it must not cache and serve such pages as response to subsequent requests for the same URL without hesitation). - Send the HTTP header
Last-Modified
describing the last modification date of the content.
(The browser will send this value back to the server if it wants to check the validity of its cache content.) - Send the HTTP header
Content-Type
describing the data type of the served file content. - Send the HTTP header
Content-Length
describing the length of the served file content. - On request send the HTTP headers
Expires
describing the guaranteed validity of the content inside the browser cache of a HTTP/1.0 client andCache-Control
describing the guaranteed validity of the content inside the browser cache of a HTTP/1.1 client.
- Are we about to serve compressed data?
- Send the HTTP header
Content-Encoding
describing the encoding of the served file content. - On request send our own HTTP headers:
X-Gzipcnc-Original-File-Size
describing the size of the original file,X-Gzipcnc-Version
describing the program version used,X-Gzipcnc-Path-Info
describing the URL of the requested document (in active self test mode only) andX-Gzipcnc-Path-Translated
describing the file name of the requested document (in active self test mode only).
- Send the HTTP header
- Send the file content.
- Close the file.
- Perform the termination processing
- Send the HTTP status
- If we were about to serve a compressed cache file (but failed doing so)
- then at least serve the content of the original file,
- otherwise perform a processing for a missing page.
Processing for a missing page
- If a user specific error document has been defined in gzip_cnc
- as an URL then send a
Location
HTTP header to redirect to this URL. - as a path name then serve this file's content.
- as an URL then send a
- Otherwise display our own error document.
- perform the termination processing.
Termination processing
- If a log file has been defined then
- Compute a formatted representation of the current date and time.
- Compute the used CPU time.
- Compute the data volume saved.
- Write a message into the log file.
- Terminate the program's processing.
(Michael Schröpl, 2002-09-08)