/* ====================================================================
 * Copyright (c) 1995-2000 The Apache Group.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the Apache Group
 *    for use in the Apache HTTP server project (http://www.apache.org/)."
 *
 * 4. The names "Apache Server" and "Apache Group" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the Apache Group
 *    for use in the Apache HTTP server project (http://www.apache.org/)."
 *
 * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Group and was originally based
 * on public domain software written at the National Center for
 * Supercomputing Applications, University of Illinois, Urbana-Champaign.
 * For more information on the Apache Group and the Apache HTTP server
 * project, please see <http://www.apache.org/>.
 *
 */

/* 
 * mod_gzip.c
 *
 * Apache gzip compression module.
 *
 * This module adds 'on the fly' compression of HTTP content to
 * any Apache Web Server. It uses the IETF Content-encoding standard(s).
 *
 * It will compress both static files and the output of any CGI
 * program inclding shell scripts, perl scripts, executables,
 * PHP used as CGI, etc.
 *
 * There is NO client-side software required for using this module
 * other than any fully HTTP 1.1 compliant user agent.
 *
 * Any fully HTTP 1.1 compliant user agent will be able to receive and
 * automatically decode the compressed content.
 *
 * All fully HTTP 1.1 compliant user agents that are capable of receiving
 * gzip encoded data will indicate their ability to do so by adding the
 * standard "Accept-Encoding: gzip" field to the inbound request header.
 * 
 * This module may be compiled as a stand-alone external 'plug-in'
 * or be compiled into the Apache core server as a 'built-in' module.
 *
 * Sponsor: Remote Communications, Inc. http://www.RemoteCommunications.com/
 * Authors: Konstantin Balashov, Alex Kosobrukhov and Kevin Kiley.
 * Contact: info@RemoteCommunications.com
 *
 * Initial public release date: 13-Oct-2000
 *
 * Miscellaneous release notes:
 *
 * THIS IS A COMPLETELY SELF-CONTAINED MODULE. MOD_GZIP.C IS THE
 * ONY SOURCE CODE FILE THERE IS AND THERE ARE NO MODULE SPECIFIC
 * HEADER FILES OR THE NEED FOR ANY 3RD PARTY COMPRESSION LIBRARIES.
 * ALL OF THE COMPRESSION CODE NEEDED BY THIS MODULE IS CONTAINED
 * WITHIN THIS SINGLE SOURCE FILE.
 *
 * Many standard compression libraries are not designed or optimized
 * for use as real-time compression codecs nor are they guaranteed
 * to be 'thread-safe'. The internal compression code used by mod_gzip
 * is all of those things. It is a highly-optimized and thread-safe
 * implementation of the standard LZ77 + Huffman compression
 * technique that has come to be known as GZIP.
 *
 * MOD_GZIP LOG FORMATS...
 *
 * mod_gzip makes a number of statistical items for each transaction
 * available through the use of Apache's 'LogFormat' directives which
 * can be specified in the httpd.conf Apache config file
 *
 * mod_gzip uses the standard Apache NOTES interface to allow compression
 * information to be added to the Apache Web Server log files.
 *
 * Standard NOTES may be added to Apache logs using the following syntax
 * in any LogFormat directive...
 * * %...{Foobar}n:  The contents of note "Foobar" from another module.
 *
 * Additional notes about logging compression information...
 *
 * The Apache LogFormat directive is unable to actually display
 * the 'percent' symbol since it is used exclusively as a 'pickup'
 * character in the formatting string and cannot be 'escaped' so
 * all logging of compression ratios cannot use the PERCENT symbol.
 * Use ASCII 'pct.' designation instead for all PERCENTAGE values.
 *
 * Example: This will display the compression ratio percentage along
 * with the standard CLF ( Common Log Format ) information...
 *
 * Available 'mod_gzip' compression information 'notes'...
 *
 * %{mod_gzip_result}n - A short 'result' message. Could be OK or DECLINED, etc.
 * %{mod_gzip_input_size}n - The size ( in bytes ) of the requested object.
 * %{mod_gzip_output_size}n - The size ( in bytes ) of the compressed version.
 * %{mod_gzip_compression_ration}n - The compression rate achieved.
 *
 *  LogFormat "%h %l %u %t \"%r\" %>s %b mod_gzip: %{mod_gzip_compression_ratio}npct." common_with_mod_gzip_info1
 *  LogFormat "%h %l %u %t \"%r\" %>s %b mod_gzip: %{mod_gzip_result}n In:%{mod_gzip_input_size}n Out:%{mod_gzip_output_size}n:%{mod_gzip_compression_ratio}npct." common_with_mod_gzip_info2
 *
 * If you create your own custom 'LogFormat' lines don't forget that
 * the entire LogFormat line must be encased in quote marks or you
 * won't get the right results. The visible effect of there not being
 * and end-quote on a LogFormat line is that the NAME you are choosing
 * for the LogFormat line is the only thing that will appear in the
 * log file that tries to use the unbalanced line.
 *
 * Also... when using the %{mod_gzip_xxxxx}n note references in your
 * LogFormat line don't forget to add the lowercase letter 'n' after
 * the closing bracket to indicate that this is a module 'note' value.
 *
 * Once a LogFormat directive has been added to your httpd.conf file
 * which displays whatever level of compression information desired
 * simply use the 'name' associated with that LogFormat line in
 * the 'CustomLog' directive for 'access.log'.
 *
 * Example: The line below simply changes the default access.log format
 * for Apache to the special mog_gzip information record defined above...
 * CustomLog logs/access.log common
 *
 *  CustomLog logs/access.log common_with_mod_gzip_info2
 *
 * Using the 'common_with_mod_gzip_info1' LogFormat line for Apache's
 * normal access.log file produces the following results in the access.log
 * file when a gigantic 679,188 byte online CD music collection HTML
 * document called 'music.htm' is requested and the Server delivers the
 * file via mod_gzip compressed 93 percent down to only 48,951 bytes...
 *
 * 216.20.10.1 [12/Oct...] "GET /music.htm HTTP/1.1" 200 48951 mod_gzip: 93pct.
 *
 * The line below shows what will appear in the Apache access.log file
 * if the more detailed 'common_with_mod_gzip_info2' LogFormat line is used.
 * The line has been intentionally 'wrapped' for better display below
 * but would normally appear as a single line entry in access.log.
 *
 * 216.20.10.1 [12/Oct...] "GET /music.htm HTTP/1.1" 200 48951
 *                          mod_gzip: OK In:679188 Out:48951:93pct.
 *
 * The 'OK' result string shows that the compression was successful.
 * The 'In:' value is the size (in bytes) of the requested file and
 * the 'Out:' value is the size (in bytes) after compression followed
 * by a colon and a number showing that the document was compressed
 * 93 percent before being returned to the user.
 *
 * Please NOTE that if you add any ASCII strings to your LogFormat
 * string then they will appear in your log file regardless of
 * whether this module was actually 'called' to process the
 * transaction or not. If the module was not called to handle the
 * transaction then the places where the statistical information
 * associated with the 'NOTES' references would normally appear
 * will be filled in with 'dashes' to denote 'no value available'.
 *
 * MOD_GZIP RUNTIME DEBUG...
 *
 * If you set your default Apache logging level to 'LogLevel debug'
 * in your httpd.conf file then this module will add certain
 * diagnostic debug messages to your error log for each and every
 * transaction that is actually passed to the module.
 *
 * If Apache does not 'call' this module to handle a particular
 * transaction then no special log information will appear in
 * your error log(s) for that transaction.
 *
 * MOD_GZIP CONFIGURATION DIRECTIVES...
 *

# mod_gzip configuration directives...

# mod_gzip_on
# Master Control Switch
# If 'Yes' then mod_gzip will compress the specified objects.
# If 'No'  then mod_gzip will not perform any compression.
#
#mod_gzip_on Yes

# mod_gzip_do_cgi
# If 'Yes' then mod_gzip will compress all CGI script output.
# If 'No'  then mod_gzip will not compress CGI script output.
#
#mod_gzip_do_cgi Yes

# mod_gzip_do_static_files
# If 'Yes' then mod_gzip will compress all static files.
# If 'No'  then mod_gzip will not compress static files.
#
#mod_gzip_do_static_files Yes

# mod_gzip_minimum_file_size
# The size ( in bytes ) of the smallest file that mod_gzip will
# ever make an attempt to compress. The default is 300 bytes.
#
#mod_gzip_minimum_file_size  300

# mod_gzip_maximum_inmem_size
# The size ( in bytes ) of the largest file that will ever be
# compressed directly 'in memory' without using a temporary file.
# The default is 60,000 bytes.
#
#mod_gzip_maximum_inmem_size 60000

# mod_gzip_keep_workfiles
# If 'Yes' then mod_gzip will not erase temporary workfiles.
# If 'No'  then mod_gzip will erase all temporary workfiles.
#
#mod_gzip_keep_workfiles No

# mod_gzip_temp_dir
# The name of the directory to use for temporary work files.
# This directory MUST be readable/writable by the Server itself.
# If the directive is not used then the default is 'ServerRoot'.
# If specified, the directory is not assumed to be a 'relative'
# location from 'ServerRoot' and must be a complete pathname
# It should not have a trailing slash on the end.
# For now, you must either use an existing directory or be
# sure to create the directory yourself with the correct
# read/write permissions for the Server group ID.
# Next version will automatically create the directory for
# you if it doesn't already exist.
#
#mod_gzip_temp_dir "C:/Program Files/Apache Group/Apache/temp"
#
# INCLUDE these items in the list of valid compression types.
#
# This inclusion list has a lower priority than the exclusion list.
# Wildcards are only allowed for MIME strings such as 'text/*'.
# File extension names must begin with a period such as '.js'.
# Handler names must match exactly such as 'cgi-script'.
# Anything that is actually DYNAMIC output must be preceded with
# a BANG character '!' and no spaces after it such as '!cgi-script'.
#
# IMPORTANT: For the time being all dynamic include lines
# must come BEFORE static items, especially !cgi-script, if used.
#
#mod_gzip_item_include !cgi-script
#mod_gzip_item_include text/*
#mod_gzip_item_include image/*
#
# EXCLUDE these items from the list of valid compression types.
#
# This exclusion list has a higher priority than the inclusion list.
# The same syntax rules apply as for the inclusion list.
#
# Exclude Style Sheets ( .css ) for now.
#
# This MUST not be on if compressing PHP...
#mod_gzip_item_exclude application/*
#mod_gzip_item_exclude .js
#mod_gzip_item_exclude .css
#
#
# Exclusions... HTTP support levels...
#
# By specifying a certain minimum level of HTTP support
# certain older user agents ( browsers ) can be
# automatically excluded from receiving compressed data.
#
# The item value should be in the same HTTP numeric format
# that Apache uses to designate HTTP version levels.
#
# 1001 = HTTP/1.1
#
# So 'mod_gzip_min_http 1001' means that a requesting
# user agent ( browser ) must report a minimum HTTP support
# level of 1.1 or it will not receive any compressed data.
#
#mod_gzip_min_http 1001
#
#

 * The section that follows is a sample mod_gzip configuration
 * section that will provide basic compression of all static
 * TEXT and HTML files as well as dynamic compression of most
 * standard CGI including Shell scripts, Perl, PHP, etc.
 *
 * You should be able to simply 'cut and paste' the follwing section
 * directly into the BOTTOM of your current httpd.conf Apache
 * configuration file and be able to start using mod_gzip immediately.
 *

#
# MOD_GZIP Configuration Directives
#
# All you should have to do to get up and running using
# mod_gzip with some basic STATIC and DYNAMIC compression
# capabilites is copy the mod_gzip dynamic library to your
# ../modules directory and then add this entire example
# configuration section to the BOTTOM of your httpd.conf file.
#
# Add this entire section including all lines down to where
# it says '# End of MOD_GZIP Configuration Directives'.
#
# The LoadModule command is included here for clarity
# but you may want to move it the the BOTTOM of your
# current LoadModule list in httpd.conf.
#
# Change the 'mod_gzip_temp_dir' to the name of a directory
# on your machine where temporary workfiles can be created
# and destroyed. This directory MUST be readable/writable
# by the Server itself while it is running. If the directory
# does not exist you must create it yourself with the right
# permissions before running the Server.
#
# If no 'mod_gzip_temp_dir' is specified then the default location
# for temporary workfiles will be 'ServerRoot' directory.
#
# The special mod_gzip log formats are, of course, optional.
#
# You must, of course, load the right module name for your OS
# so make sure the correct 'LoadModule' command is uncommented
# directly below...

# Load Win32 module...
LoadModule gzip_module modules/ApacheModuleGzip.dll

# Load UNIX module...
# LoadModule gzip_module modules/mod_gzip.so

LogFormat "%h %l %u %t \"%r\" %>s %b mod_gzip: %{mod_gzip_compression_ratio}npct." common_with_mod_gzip_info1
LogFormat "%h %l %u %t \"%r\" %>s %b mod_gzip: %{mod_gzip_result}n In:%{mod_gzip_input_size}n Out:%{mod_gzip_output_size}n:%{mod_gzip_compression_ratio}npct." common_with_mod_gzip_info2

# NOTE: This 'CustomLog' directive shows how to set your access.log file
# to use the mod_gzip format but please remember that for every 'CustomLog'
# directive that Apache finds in httpd.conf there will be corresponding
# line of output in the access.log file. If you only want ONE line of
# results in access.log for each transaction then be sure to comment out
# any other 'CustomLog' directives so that this is the only one.

CustomLog logs/access.log common_with_mod_gzip_info2

# Runtime control directives...

mod_gzip_on                 Yes
mod_gzip_do_cgi             Yes
mod_gzip_do_static_files    Yes
mod_gzip_minimum_file_size  300
mod_gzip_maximum_inmem_size 60000
mod_gzip_keep_workfiles     No
mod_gzip_temp_dir           "C:/Program Files/Apache Group/Apache/temp"

# Item lists...
#
# Item names can be any one of the following...
#
# cgi-script - A valid 'handler' name
# text/*     - A valid MIME type name ( '*' wildcard allowed )
# .phtml     - A valid file type extension

# Dynamic items...
#
# The items listed here are the types of dynamic
# output that will be compressed...
#
# Dynamic items MUST have the "!" BANG character
# on the front of the item name.
#
# NOTE: FOR NOW ALL DYNAMIC ITEMS SHOULD BE
# DECLARED BEFORE ANY STATIC ITEMS TO PREVENT
# PICKUP CONFLICTS. IF YOU USE !cgi-script
# BE SURE IT IS DECLARED BEFORE ANY text/*
# MIME TYPE ENTRIES.
#
mod_gzip_item_include !cgi-script
mod_gzip_item_include !.php
mod_gzip_item_include !.php3
mod_gzip_item_include !.phtml

# Static items...
#
# The items listed here are the types of static
# files that will be compressed...
#
# NOTE: FOR NOW ALL STATIC INCLUDES MUST
# COME AFTER DYNAMIC INCLUDES TO PREVENT
# PICKUP CONFLICTS
#
mod_gzip_item_include text/*

# Uncomment this line to compress graphics
# if the graphic compression option is available
#mod_gzip_item_include image/*


# Exclusions... MIME types and FILE types...
#
# The items listed here will be EXCLUDED from
# any attempt to apply compression...
#
mod_gzip_item_exclude .js
mod_gzip_item_exclude .css

# Exclusions... HTTP support levels...
#
# By specifying a certain minimum level of HTTP support
# certain older user agents ( browsers ) can be
# automatically excluded from receiving compressed data.
#
# The item value should be in the same HTTP numeric format
# that Apache uses to designate HTTP version levels.
#
# 1001 = HTTP/1.1
#
# So 'mod_gzip_min_http 1001' means that a requesting
# user agent ( browser ) must report a minimum HTTP support
# level of 1.1 or it will not receive any compressed data.
#
mod_gzip_min_http 1001

# Debugging...
#
# If your Apache 'LogLevel' is set to 'debug' then
# mod_gzip will add some diagnostic and compression
# information to your error.log file for each request
# that is processed by mod_gzip.
#
# LogLevel debug

# End of MOD_GZIP Configuration Directives
