/* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2000 The Apache Software Foundation. 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. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" 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 name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``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 SOFTWARE FOUNDATION 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 Software Foundation. For more * information on the Apache Software Foundation, please see * . * * Portions of this software are based upon public domain software * originally written at the National Center for Supercomputing Applications, * University of Illinois, Urbana-Champaign. */ /* MOD_GZIP 2.0.26a */ /* NOTE: This modules is written for the Apache 2.x series only */ /* and will not compile correctly against the Apache 1.x series. */ #include "httpd.h" #include "http_config.h" #include "http_log.h" #include "apr_strings.h" #include "apr_general.h" #include "util_filter.h" #include "apr_buckets.h" #include "http_request.h" #include "http_protocol.h" /* NOTE: Since Apache 2.0 is using APRLIB then we now have to */ /* manually include certain system headers that would have been */ /* included automatically at this point in a pre-2.0 compile... */ #include /* For stat() call */ /* Version information... */ char mod_gzip_version[] = "2.0.26.1a"; #define MOD_GZIP_VERSION_INFO_STRING "mod_gzip/2.0.26.1a" /* For now just use ZLIB... */ #define MOD_GZIP_USES_ZLIB #ifdef MOD_GZIP_USES_ZLIB /* The ZLIB/LIBPNG Public License... ZLIB (C) 1995-1998 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu */ #include "zlib.h" /* Standard ZLIB header */ /* NOTE: ZUTIL.H is not normally found in binary only distributions */ /* of ZLIB. It comes from the ZLIB source directories. */ /* The only real dependency on ZUTIL.H is for the OS_CODE define */ /* ( which is part of the LZ77 deflate() header ) but the OS_CODE */ /* definitions are complex so for now, ZUTIL.H has to be required. */ #include "zutil.h" /* Contains OS_CODE definition(s) */ #define MOD_GZIP_ZLIB_WINDOWSIZE -15 #define MOD_GZIP_ZLIB_CFACTOR 9 #define MOD_GZIP_ZLIB_BSIZE 8096 /* ZLIB's deflate() compression algorithm uses the same */ /* 0-9 based scale that GZIP does where '1' is 'Best speed' */ /* and '9' is 'Best compression'. Testing has proved level '6' */ /* to be about the best level to use in an HTTP Server. */ #define MOD_GZIP_DEFLATE_DEFAULT_COMPRESSION_LEVEL 6 static int zlib_gzip_magic[2] = { 0x1f, 0x8b }; typedef struct zlib_context { z_stream strm; char buffer[MOD_GZIP_ZLIB_BSIZE]; unsigned long crc; }zlib_context; #endif /* MOD_GZIP_USES_ZLIB */ /* * Declare the internal module 'name'... */ module AP_MODULE_DECLARE_DATA gzip_module; /* * Apache 2.x filters need a NAME... */ static const char mod_gzip_filter_name[] = "GZIP"; /* * Turn MOD_GZIP_USES_APACHE_LOGS switch ON to include the * code that can update Apache logs with compression information. */ #define MOD_GZIP_USES_APACHE_LOGS /* * Turn MOD_GZIP_DEBUG1 switch ON to include debug code. * This is normally OFF by default and should only be * used for diagnosing problems. The log output is * VERY detailed and the log files will be HUGE. */ #define MOD_GZIP_DEBUG1 /* * Turn this 'define' on to send all DEBUG log output to * Apache error_log instead of a flat file. "LogLevel debug" * must be set in httpd.conf for log output to appear in error_log. */ /* #define MOD_GZIP_DEBUG_LOG_IS_APACHE_LOG */ /* * Other globals... */ #ifndef MOD_GZIP_MAX_PATH_LEN #define MOD_GZIP_MAX_PATH_LEN 512 #endif #ifdef WIN32 char mod_gzip_dirsep[]="\\"; #else char mod_gzip_dirsep[]="/"; #endif #define MOD_GZIP_IMAP_MAXNAMES 256 #define MOD_GZIP_IMAP_MAXNAMELEN 90 #define MOD_GZIP_IMAP_ISNONE 0 #define MOD_GZIP_IMAP_ISMIME 1 #define MOD_GZIP_IMAP_ISHANDLER 2 #define MOD_GZIP_IMAP_ISFILE 3 #define MOD_GZIP_IMAP_ISURI 4 #define MOD_GZIP_IMAP_ISREQHEADER 5 #define MOD_GZIP_IMAP_ISRSPHEADER 6 #define MOD_GZIP_IMAP_ISPORT 7 #define MOD_GZIP_IMAP_ISADDRESS 8 #define MOD_GZIP_IMAP_STATIC1 9001 #define MOD_GZIP_IMAP_DYNAMIC1 9002 #define MOD_GZIP_IMAP_DYNAMIC2 9003 #define MOD_GZIP_IMAP_DECLINED1 9004 #define MOD_GZIP_REQUEST 9005 #define MOD_GZIP_RESPONSE 9006 typedef struct { int include; int type; int action; int direction; unsigned port; int len1; regex_t *pregex; char name[ MOD_GZIP_IMAP_MAXNAMELEN + 2 ]; int namelen; } mod_gzip_imap; int mod_gzip_imap_size = (int) sizeof( mod_gzip_imap ); #define MOD_GZIP_CONFIG_MODE_SERVER 1 #define MOD_GZIP_CONFIG_MODE_DIRECTORY 2 #define MOD_GZIP_CONFIG_MODE_COMBO 3 typedef struct { int cmode; char *loc; int is_on; int is_on_set; int keep_workfiles; int keep_workfiles_set; int dechunk; int dechunk_set; int add_header_count; int add_header_count_set; int min_http; int min_http_set; long minimum_file_size; int minimum_file_size_set; long maximum_file_size; int maximum_file_size_set; long maximum_inmem_size; int maximum_inmem_size_set; int deflate_compression_level; int deflate_compression_level_set; char temp_dir[256]; /* Length is safety-checked during startup */ int temp_dir_set; int imap_total_entries; int imap_total_ismime; int imap_total_isfile; int imap_total_isuri; int imap_total_ishandler; int imap_total_isreqheader; int imap_total_isrspheader; mod_gzip_imap imap[ MOD_GZIP_IMAP_MAXNAMES + 1 ]; #define MOD_GZIP_COMMAND_VERSION_USED #ifdef MOD_GZIP_COMMAND_VERSION_USED #define MOD_GZIP_COMMAND_VERSION 8001 #define MOD_GZIP_COMMAND_VERSION_MAXLEN 128 char command_version[ MOD_GZIP_COMMAND_VERSION_MAXLEN + 1 ]; int command_version_set; #endif #define MOD_GZIP_CAN_NEGOTIATE #ifdef MOD_GZIP_CAN_NEGOTIATE int can_negotiate; int can_negotiate_set; #endif } mod_gzip_conf; #ifdef MOD_GZIP_DEBUG1 server_rec *mod_gzip_server_now = 0; #endif #ifdef MOD_GZIP_DEBUG_LOG_IS_APACHE_LOG void mod_gzip_printf( const char *fmt, ... ) { int l; va_list ap; char log_line[2048]; va_start( ap, fmt ); l = vsprintf( log_line, fmt, ap ); va_end(ap); ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, 0, mod_gzip_server_now, log_line ); return; } #else /* !MOD_GZIP_DEBUG_LOG_IS_APACHE_LOG */ void mod_gzip_printf( const char *fmt, ... ) { int l; char *p1; FILE *log; va_list ap; char logname[256]; char log_line[4096]; #ifdef WIN32 long pid = GetCurrentProcessId(); #else long pid = (long) getpid(); #endif #ifdef WIN32 sprintf( logname, "c:\\temp\\t%ld.log",(long)pid); #else sprintf( logname, "/tmp/t%ld.log",(long)pid); #endif // WARNING: Keep in mind that depending on the 'temp' // directory permissions for UNIX the fact that PID is // being used as part of the log filename in order to // separate the request logs means that someone MAY be // able to see the actual PID of the Sever process when // DEBUG is running and (perhaps) do some of the weird // hacks that are always possible under UNIX when you // know a given process ID. Run debug only in a secure // environment if you are prone to worry about such things. return; log = fopen( logname,"a" ); if ( !log ) { return; } else { fclose(log); return; } va_start( ap, fmt ); l = vsprintf(log_line, fmt, ap); p1=log_line; while((*p1!=0)&&(*p1!=13)&&(*p1!=10)) p1++; *p1=0; fprintf( log, "%s\n", log_line ); fclose( log ); va_end(ap); return; } #endif /* MOD_GZIP_DEBUG_LOG_IS_APACHE_LOG */ /* Thread safe FAST string handlers... */ int mod_gzip_strncmp( char *s1, char *s2, int len1 ); int mod_gzip_strnicmp( char *s1, char *s2, int len1 ); int mod_gzip_strcpy( char *s1, char *s2 ); int mod_gzip_strcat( char *s1, char *s2 ); int mod_gzip_strlen( char *s1 ); int mod_gzip_stringcontains( char *source, char *substring ); int mod_gzip_strendswith( char *s1, char *s2, int ignorcase ); int mod_gzip_strncmp( char *s1, char *s2, int len1 ) { int i; char ch1; char ch2; if ( ( s1 == 0 ) || ( s2 == 0 ) ) { return 1; } for ( i=0; i 96 ) ch1 -= 32; if ( ch2 > 96 ) ch2 -= 32; if ( ch1 == '/' ) ch1 = '\\'; if ( ch2 == '/' ) ch2 = '\\'; if ( ch1 != ch2 ) return 1; s1++; s2++; } return 0; } int mod_gzip_strendswith( char *s1, char *s2, int ignorcase ) { int len1; int len2; if ( ( s1 == 0 ) || ( s2 == 0 ) ) { return 0; } len1 = mod_gzip_strlen( s1 ); len2 = mod_gzip_strlen( s2 ); if ( len1 < len2 ) { /* Source string is shorter than search string */ /* so no match is possible */ return 0; } s1 += ( len1 - len2 ); if ( ignorcase ) { if ( mod_gzip_strnicmp( s1, s2, len2 ) == 0 ) return 1; /* TRUE */ } else { if ( mod_gzip_strncmp( s1, s2, len2 ) == 0 ) return 1; /* TRUE */ } return 0; /* FALSE */ } int mod_gzip_strlen( char *s1 ) { int len = 0; if ( s1 != 0 ) { while( *s1 != 0 ) { s1++; len++; } } return len; } int mod_gzip_strcpy( char *s1, char *s2 ) { int len = 0; if ( ( s1 != 0 )&&( s2 != 0 ) ) { while( *s2 != 0 ) { *s1++ = *s2++; len++; } *s1=0; } return len; } int mod_gzip_strcat( char *s1, char *s2 ) { int len = 0; if ( s1 != 0 ) { while( *s1 != 0 ) { s1++; len++; } if ( s2 != 0 ) { while( *s2 != 0 ) { *s1++ = *s2++; len++; } *s1 = 0; } } return len; } int mod_gzip_stringcontains( char *source, char *substring ) { int i; int len1; int len2; int len3; int offset=1; char *source1; char *substring1; if ( source == NULL ) { return 0; } if ( substring == NULL ) { return 0; } source1 = source; substring1 = substring; len1 = mod_gzip_strlen( source ); len2 = mod_gzip_strlen( substring ); if ( len1 < len2 ) { return 0; } len3 = len1 - len2; for ( i=0; i<=len3; i++ ) { if ( mod_gzip_strnicmp( source, substring, len2 ) == 0 ) { source = source1; substring = substring1; return offset; } source++; offset++; } source = source1; substring = substring1; return 0; } const char *mod_gzip_npp( const char *s ) { /* NOTE: This 'Null Pointer Protection' call is really only */ /* needed for the Solaris Operating System which seems to have */ /* some kind of problem handling NULL pointers passed to certain */ /* STDLIB calls. Sloaris will GP fault where all other OS's are OK. */ if ( s ) return s; else return "NULL"; } #ifdef MOD_GZIP_DEBUG1 int mod_gzip_dump_a_table( request_rec *r, apr_table_t *t ) { /* Print the contents of an Apache standard 'table' */ /* such as 'r->headers_in' or 'r->headers_out' */ int i; apr_table_entry_t *elts; #ifdef MOD_GZIP_DEBUG1 char cn[]="mod_gzip_dump_a_table()"; #endif /* Start... */ elts = ( apr_table_entry_t * ) t->a.elts; #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Entry...",cn); mod_gzip_printf( "%s: t->a.nelts = %d",cn,(int)t->a.nelts); #endif for ( i = 0; i < t->a.nelts; i++ ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: %3.3d key=[%s] val=[%s]", cn,i,elts[i].key,elts[i].val); #endif }/* End 'i' loop */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Exit > return( 0 ) >",cn); #endif return 0; }/* End of mod_gzip_dump_a_table() */ void mod_gzip_hexdump( char *buffer, int buflen ) { int i,o1,o2,o3; int len1; int len2; char ch1; char ch2; char s[40]; char l1[129]; char l2[129]; char l3[300]; long offset1=0L; o1=0; o2=0; o3=0; l1[0] = 0; l2[0] = 0; l3[0] = 0; offset1 = 0; for ( i=0; i 126) ch2 = DUMPIT_LAPOSTROPHE; else if ( ch1 == 37 ) ch2 = DUMPIT_ASTERISK; else if ( ch1 == 92 ) ch2 = DUMPIT_ASTERISK; else ch2 = ch1; #endif l2[o2++] = ch2; sprintf( s, "%02X", ch1 ); if ( mod_gzip_strlen(s) > 2 ) s[2]=0; len1 = mod_gzip_strlen(s); len2 = mod_gzip_strlen(l1); if ( mod_gzip_strlen(l1) < (int)(sizeof(l1) - (len1+1)) ) { strcat( l1, s ); strcat( l1, " " ); } if ( o2 >= 16 ) { l2[o2]=0; mod_gzip_printf( "%6lu| %-49.49s| %-16.16s |", offset1, l1, l2 ); offset1 += o2; o1=0; o2=0; o3=0; l1[0] = 0; l2[0] = 0; l3[0] = 0; } } if ( o2 > 0 ) { l2[o2]=0; mod_gzip_printf( "%6lu| %-49.49s| %-16.16s |", offset1, l1, l2 ); offset1 += o2; o1 = o2 = o3 = 0; l1[0] = 0; l2[0] = 0; l3[0] = 0; } }/* End of mod_gzip_hexdump() */ #endif //MOD_GZIP_DEBUG1 /* ITEM INCLUSION/EXCLUSION MAPPING SUPPORT... */ static const char * mod_gzip_imap_add_item( cmd_parms *parms, mod_gzip_conf *mgc, char *a1, char *a2, int flag1 ) { int x; char *p1; int ignorecase=0; int this_include=flag1; int this_type=0; int this_action=0; int this_direction=0; unsigned this_port=0; int this_len1=0; regex_t *this_pregex=NULL; char *regex; /* Diagnostic only #define MOD_GZIP_TEST_REGEX1 */ #ifdef MOD_GZIP_TEST_REGEX1 char string[129]; int regex_error; #endif #ifdef MOD_GZIP_DEBUG1 char cn[]="mod_gzip_imap_add_item()"; #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( " "); /* Feed down 1 line */ mod_gzip_printf( "%s: Entry", cn ); mod_gzip_printf( "%s: 1 a1=[%s]", cn, mod_gzip_npp(a1)); mod_gzip_printf( "%s: 1 a2=[%s]", cn, mod_gzip_npp(a2)); mod_gzip_printf( "%s: mgc->imap_total_entries = %d", cn, mgc->imap_total_entries ); mod_gzip_printf( "%s: mgc->imap_total_ismime = %d", cn, mgc->imap_total_ismime ); mod_gzip_printf( "%s: mgc->imap_total_isfile = %d", cn, mgc->imap_total_isfile ); mod_gzip_printf( "%s: mgc->imap_total_isuri = %d", cn, mgc->imap_total_isuri ); mod_gzip_printf( "%s: mgc->imap_total_ishandler = %d", cn, mgc->imap_total_ishandler ); mod_gzip_printf( "%s: mgc->imap_total_isreqheader = %d", cn, mgc->imap_total_isreqheader ); mod_gzip_printf( "%s: mgc->imap_total_isrspheader = %d", cn, mgc->imap_total_isrspheader ); if ( flag1 == 1 ) { mod_gzip_printf( "%s: flag1 = %d = INCLUDE", cn, flag1 ); } else if ( flag1 == 0 ) { mod_gzip_printf( "%s: flag1 = %d = EXCLUDE", cn, flag1 ); } else { mod_gzip_printf( "%s: flag1 = %d = ??? Unknown value", cn, flag1 ); } #endif this_type = MOD_GZIP_IMAP_ISNONE; if ( mod_gzip_strnicmp( a1, "mime", 4 ) == 0 ) { this_type = MOD_GZIP_IMAP_ISMIME; #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: this_type = MOD_GZIP_IMAP_ISMIME", cn); #endif } else if ( mod_gzip_strnicmp( a1, "file", 4 ) == 0 ) { this_type = MOD_GZIP_IMAP_ISFILE; #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: this_type = MOD_GZIP_IMAP_ISFILE",cn); #endif } else if ( mod_gzip_strnicmp( a1, "ur", 2 ) == 0 ) { /* Allow user to specify EITHER 'uri' or 'url' for this 'type' */ this_type = MOD_GZIP_IMAP_ISURI; #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: this_type = MOD_GZIP_IMAP_ISURI",cn); #endif } else if ( mod_gzip_strnicmp( a1, "hand", 4 ) == 0 ) { this_type = MOD_GZIP_IMAP_ISHANDLER; #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: this_type = MOD_GZIP_IMAP_ISHANDLER",cn); #endif } else if ( mod_gzip_strnicmp( a1, "reqh", 4 ) == 0 ) { this_type = MOD_GZIP_IMAP_ISREQHEADER; this_direction = MOD_GZIP_REQUEST; #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: this_type = MOD_GZIP_IMAP_ISREQHEADER",cn); #endif } else if ( mod_gzip_strnicmp( a1, "rsph", 4 ) == 0 ) { this_type = MOD_GZIP_IMAP_ISRSPHEADER; this_direction = MOD_GZIP_RESPONSE; #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: this_type = MOD_GZIP_IMAP_ISRSPHEADER",cn); #endif } if ( this_type == MOD_GZIP_IMAP_ISNONE ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: this_type = ?? UNKNOWN ??",cn); mod_gzip_printf( "%s: Exit > return( ERRORSTRING ) >",cn); #endif return "mod_gzip: ERROR: Valid item types are mime,file,uri,handler,reqheader or rspheader"; } p1 = a2; if ( ( this_type == MOD_GZIP_IMAP_ISREQHEADER ) || ( this_type == MOD_GZIP_IMAP_ISRSPHEADER ) ) { while((*p1!=0)&&(*p1!=':')) { p1++; this_len1++; } if (*p1==':') { if ( this_len1 < 1 ) { return "mod_gzip: ERROR: Missing HTTP field name."; } p1++; } else { return "mod_gzip: ERROR: Missing HTTP field name. No colon found."; } while((*p1!=0)&&(*p1<33)) p1++; } regex = p1; #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: regex = [%s]", cn, mod_gzip_npp(regex) ); #endif if ( !*regex ) { return "mod_gzip: ERROR: Missing regular expression string."; } ignorecase = 1; #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: ignorecase = %d",cn,ignorecase); mod_gzip_printf( "%s: Call ap_pregcomp(%s)...",cn,mod_gzip_npp(regex)); #endif this_pregex = ap_pregcomp(parms->pool, regex, (REG_EXTENDED | REG_NOSUB | (ignorecase ? REG_ICASE : 0))); if ( this_pregex == NULL ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: .... ap_pregcomp(%s) FAILED...",cn,mod_gzip_npp(regex)); mod_gzip_printf( "%s: regex 'pre-compile' FAILED...", cn ); mod_gzip_printf( "%s: Exit > return( ERRORSTRING ) >",cn); #endif return "mod_gzip: ERROR: Regular expression compile failed."; } #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: .... ap_pregcomp(%s) SUCCEEDED...",cn,mod_gzip_npp(regex)); mod_gzip_printf( "%s: regex 'pre-compiled' OK", cn ); #endif #ifdef MOD_GZIP_TEST_REGEX1 if ( ( this_type == MOD_GZIP_IMAP_ISREQHEADER ) || ( this_type == MOD_GZIP_IMAP_ISRSPHEADER ) ) { mod_gzip_strcpy( string, "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt; TUCOWS)" ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Call ap_regexec( regex=[%s], string=[%s] )", cn, mod_gzip_npp(regex), mod_gzip_npp(string) ); #endif regex_error = ap_regexec(this_pregex, string, 0, (regmatch_t *)NULL,0); #ifdef MOD_GZIP_DEBUG1 if ( regex_error != 0 ) mod_gzip_printf( "%s: regex_error = %d = NO MATCH!", cn, regex_error ); else mod_gzip_printf( "%s: regex_error = %d = MATCH!", cn, regex_error ); #endif } #endif /* MOD_GZIP_TEST_REGEX1 */ this_action = MOD_GZIP_IMAP_STATIC1; #ifdef FUTURE_USE if ( ( this_action != MOD_GZIP_IMAP_DYNAMIC1 ) && ( this_action != MOD_GZIP_IMAP_DYNAMIC2 ) && ( this_action != MOD_GZIP_IMAP_STATIC1 ) ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: this_action = %d = MOD_GZIP_IMAP_??? Unknown action",cn,this_action); mod_gzip_printf( "%s: return( mod_gzip: ERROR: Unrecognized item 'action'",cn); #endif return( "mod_gzip: ERROR: Unrecognized item 'action'" ); } #endif /* FUTURE_USE */ if ( mgc->imap_total_entries < MOD_GZIP_IMAP_MAXNAMES ) { if ( mod_gzip_strlen( a2 ) < MOD_GZIP_IMAP_MAXNAMELEN ) { x = mgc->imap_total_entries; p1 = a2; mod_gzip_strcpy( mgc->imap[x].name, p1 ); mgc->imap[x].namelen = mod_gzip_strlen( mgc->imap[x].name ); mgc->imap[x].include = this_include; mgc->imap[x].type = this_type; mgc->imap[x].action = this_action; mgc->imap[x].direction = this_direction; mgc->imap[x].port = this_port; mgc->imap[x].len1 = this_len1; mgc->imap[x].pregex = this_pregex; mgc->imap_total_entries++; if ( this_type == MOD_GZIP_IMAP_ISMIME ) { mgc->imap_total_ismime++; } else if ( this_type == MOD_GZIP_IMAP_ISFILE ) { mgc->imap_total_isfile++; } else if ( this_type == MOD_GZIP_IMAP_ISURI ) { mgc->imap_total_isuri++; } else if ( this_type == MOD_GZIP_IMAP_ISHANDLER ) { mgc->imap_total_ishandler++; } else if ( this_type == MOD_GZIP_IMAP_ISREQHEADER ) { mgc->imap_total_isreqheader++; } else if ( this_type == MOD_GZIP_IMAP_ISRSPHEADER ) { mgc->imap_total_isrspheader++; } } else { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: return( mod_gzip: ERROR: Item name is too long",cn); #endif return( "mod_gzip: ERROR: Item name is too long" ); } } else { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: return( mod_gzip: ERROR: Item index is full",cn); #endif return( "mod_gzip: ERROR: Item index is full" ); } #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: mgc->imap_total_entries = %d", cn, mgc->imap_total_entries ); mod_gzip_printf( "%s: mgc->imap_total_ismime = %d", cn, mgc->imap_total_ismime ); mod_gzip_printf( "%s: mgc->imap_total_isfile = %d", cn, mgc->imap_total_isfile ); mod_gzip_printf( "%s: mgc->imap_total_isuri = %d", cn, mgc->imap_total_isuri ); mod_gzip_printf( "%s: mgc->imap_total_ishandler = %d", cn, mgc->imap_total_ishandler ); mod_gzip_printf( "%s: mgc->imap_total_isreqheader = %d", cn, mgc->imap_total_isreqheader ); mod_gzip_printf( "%s: mgc->imap_total_isrspheader = %d", cn, mgc->imap_total_isrspheader ); mod_gzip_printf( "%s: Exit > return( NULL ) >",cn); #endif return NULL; } int mod_gzip_validate1( request_rec *r, mod_gzip_conf *mgc, char *r__filename, char *r__uri, char *r__content_type, char *r__handler, char *fieldkey, char *fieldstring, int direction ) { int x = 0; int clen = 0; int hlen = 0; int flen = 0; int ulen = 0; int pass = 0; int passes = 2; char *this_name = 0; int this_type = 0; int this_len1 = 0; int this_action = 0; int this_include = 0; char *checktarget = 0; int pass_result = 0; int action_value = 0; int filter_value = 0; int type_to_match = 0; int ok_to_check_it = 0; int http_field_check = 0; int item_is_included = 0; int item_is_excluded = 0; int type_is_included = 0; regex_t *this_pregex = NULL; int regex_error = 0; #ifdef MOD_GZIP_DEBUG1 char cn[]="mod_gzip_validate1()"; #endif if ( r__filename ) flen = mod_gzip_strlen( (char *) r__filename ); if ( r__uri ) ulen = mod_gzip_strlen( (char *) r__uri ); if ( r__content_type ) clen = mod_gzip_strlen( (char *) r__content_type ); if ( r__handler ) hlen = mod_gzip_strlen( (char *) r__handler ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Entry...",cn); mod_gzip_printf( "%s: r__filename = [%s]",cn,mod_gzip_npp(r__filename)); mod_gzip_printf( "%s: flen = %d", cn,flen); mod_gzip_printf( "%s: r__uri = [%s]",cn,mod_gzip_npp(r__uri)); mod_gzip_printf( "%s: ulen = %d", cn,ulen); mod_gzip_printf( "%s: r__content_type = [%s]",cn,mod_gzip_npp(r__content_type)); mod_gzip_printf( "%s: clen = %d", cn,clen); mod_gzip_printf( "%s: r__handler = [%s]",cn,mod_gzip_npp(r__handler)); mod_gzip_printf( "%s: hlen = %d", cn,hlen); mod_gzip_printf( "%s: fieldkey = [%s]",cn,mod_gzip_npp(fieldkey)); mod_gzip_printf( "%s: fieldstring = [%s]",cn,mod_gzip_npp(fieldstring)); mod_gzip_printf( "%s: direction = %d", cn,direction); #endif if ( ( fieldkey ) && ( fieldstring ) ) { http_field_check = 1; passes = 1; if ( direction == MOD_GZIP_REQUEST ) { type_to_match = MOD_GZIP_IMAP_ISREQHEADER; } else if ( direction == MOD_GZIP_RESPONSE ) { type_to_match = MOD_GZIP_IMAP_ISRSPHEADER; } else { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Invalid 'direction' value.",cn); mod_gzip_printf( "%s: Must be MOD_GZIP_REQUEST or MOD_GZIP_RESPONSE",cn); mod_gzip_printf( "%s: Exit > return( MOD_GZIP_IMAP_DECLINED1 ) >",cn); #endif return( MOD_GZIP_IMAP_DECLINED1 ); } } else if ( ( hlen == 0 ) && ( clen == 0 ) && ( flen == 0 ) ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: hlen = 0 = No handler name passed...",cn); mod_gzip_printf( "%s: clen = 0 = No valid content-type passed",cn); mod_gzip_printf( "%s: flen = 0 = No valid filename passed",cn); mod_gzip_printf( "%s: There is nothing we can use to search",cn); mod_gzip_printf( "%s: for a match in the inclusion/exclusion list.",cn); mod_gzip_printf( "%s: Exit > return( MOD_GZIP_IMAP_DECLINED1 ) >",cn); #endif return( MOD_GZIP_IMAP_DECLINED1 ); } #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: passes = %d", cn, (int) passes ); mod_gzip_printf( "%s: http_field_check = %d", cn, (int) http_field_check ); mod_gzip_printf( "%s: mgc->imap_total_entries = %d", cn, (int) mgc->imap_total_entries ); #endif for ( pass=0; passimap_total_entries = %d", cn, (int) mgc->imap_total_entries ); #endif #endif for ( x=0; x < mgc->imap_total_entries; x++ ) { this_include = mgc->imap[x].include; this_type = mgc->imap[x].type; this_action = mgc->imap[x].action; #ifdef MOD_GZIP_DEBUG1_VALIDATE1_VERBOSE1 #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: --------------------------------------------",cn); mod_gzip_printf( "%s: http_field_check = %d", cn,http_field_check ); if ( http_field_check ) { mod_gzip_printf( "%s: fieldkey = [%s]",cn,mod_gzip_npp(fieldkey)); mod_gzip_printf( "%s: fieldstring = [%s]",cn,mod_gzip_npp(fieldstring)); } else { mod_gzip_printf( "%s: r__filename = [%s]",cn,mod_gzip_npp(r__filename)); mod_gzip_printf( "%s: r__uri = [%s]",cn,mod_gzip_npp(r__uri)); mod_gzip_printf( "%s: r__content_type = [%s]",cn,mod_gzip_npp(r__content_type)); mod_gzip_printf( "%s: r__handler = [%s]",cn,mod_gzip_npp(r__handler)); } if ( this_include == 0 ) { mod_gzip_printf( "%s: mgc->imap[%3.3d].include = %d EXCLUDE",cn,x,this_include); } else if ( this_include == 1 ) { mod_gzip_printf( "%s: mgc->imap[%3.3d].include = %d INCLUDE",cn,x,this_include); } else { mod_gzip_printf( "%s: mgc->imap[%3.3d].include = %d ??? UNKNOWN VALUE",cn,x,this_include); } if ( mgc->imap[x].type == MOD_GZIP_IMAP_ISMIME ) { mod_gzip_printf( "%s: mgc->imap[%3.3d].type = %d MOD_GZIP_IMAP_ISMIME", cn,x,this_type); } else if ( mgc->imap[x].type == MOD_GZIP_IMAP_ISHANDLER ) { mod_gzip_printf( "%s: mgc->imap[%3.3d].type = %d MOD_GZIP_IMAP_ISHANDLER", cn,x,this_type); } else if ( mgc->imap[x].type == MOD_GZIP_IMAP_ISFILE ) { mod_gzip_printf( "%s: mgc->imap[%3.3d].type = %d MOD_GZIP_IMAP_ISFILE", cn,x,this_type); } else if ( mgc->imap[x].type == MOD_GZIP_IMAP_ISURI ) { mod_gzip_printf( "%s: mgc->imap[%3.3d].type = %d MOD_GZIP_IMAP_ISURI", cn,x,this_type); } else if ( mgc->imap[x].type == MOD_GZIP_IMAP_ISREQHEADER ) { mod_gzip_printf( "%s: mgc->imap[%3.3d].type = %d MOD_GZIP_IMAP_ISREQHEADER", cn,x,this_type); } else if ( mgc->imap[x].type == MOD_GZIP_IMAP_ISRSPHEADER ) { mod_gzip_printf( "%s: mgc->imap[%3.3d].type = %d MOD_GZIP_IMAP_ISRSPHEADER", cn,x,this_type); } else { mod_gzip_printf( "%s: mgc->imap[%3.3d].type = %d MOD_GZIP_IMAP_IS??? Unknown type", cn,x,this_type); } if ( mgc->imap[x].action == MOD_GZIP_IMAP_STATIC1 ) { mod_gzip_printf( "%s: mgc->imap[%3.3d].action = %d MOD_GZIP_IMAP_STATIC1", cn,x,this_action); } else if ( mgc->imap[x].action == MOD_GZIP_IMAP_DYNAMIC1 ) { mod_gzip_printf( "%s: mgc->imap[%3.3d].action = %d MOD_GZIP_IMAP_DYNAMIC1", cn,x,this_action); } else if ( mgc->imap[x].action == MOD_GZIP_IMAP_DYNAMIC2 ) { mod_gzip_printf( "%s: mgc->imap[%3.3d].action = %d MOD_GZIP_IMAP_DYNAMIC2", cn,x,this_action); } else { mod_gzip_printf( "%s: mgc->imap[%3.3d].action = %d MOD_GZIP_IMAP_??? Unknown action", cn,x,this_action); } mod_gzip_printf( "%s: mgc->imap[%3.3d].name = [%s]",cn,x,mod_gzip_npp(mgc->imap[x].name)); mod_gzip_printf( "%s: mgc->imap[%3.3d].namelen = %d", cn,x,mgc->imap[x].namelen); #endif #endif if ( this_include == filter_value ) { #ifdef MOD_GZIP_DEBUG1_VALIDATE1_VERBOSE1 #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: This record matches filter_value %d", cn, filter_value ); mod_gzip_printf( "%s: The record will be checked...",cn); #endif #endif type_is_included = 0; checktarget = 0; if ( http_field_check ) { if ( this_type == type_to_match ) { type_is_included = 1; checktarget = (char *) fieldstring; } } else { if ( ( this_type == MOD_GZIP_IMAP_ISMIME ) && ( clen > 0 ) ) { type_is_included = 1; checktarget = r__content_type; } else if ( ( this_type == MOD_GZIP_IMAP_ISFILE ) && ( flen > 0 ) ) { type_is_included = 1; checktarget = r__filename; } else if ( ( this_type == MOD_GZIP_IMAP_ISURI ) && ( ulen > 0 ) ) { type_is_included = 1; checktarget = r__uri; } else if ( ( this_type == MOD_GZIP_IMAP_ISHANDLER ) && ( hlen > 0 ) ) { type_is_included = 1; checktarget = r__handler; } } if ( type_is_included ) { #ifdef MOD_GZIP_DEBUG1_VALIDATE1_VERBOSE1 #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: type_is_included = %d = YES",cn,type_is_included); #endif #endif this_name = mgc->imap[x].name; this_len1 = mgc->imap[x].len1; this_pregex = mgc->imap[x].pregex; ok_to_check_it = 1; if ( http_field_check ) { #ifdef MOD_GZIP_DEBUG1_VALIDATE1_VERBOSE1 #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: fieldkey = [%s]",cn,mod_gzip_npp(fieldkey)); mod_gzip_printf( "%s: this_name = [%s]",cn,mod_gzip_npp(this_name)); mod_gzip_printf( "%s: this_len1 = %d", cn,this_len1); mod_gzip_printf( "%s: Call mod_gzip_strnicmp(fieldkey,this_name,this_len1)...",cn); #endif #endif if ( mod_gzip_strnicmp( fieldkey, this_name, this_len1 )==0) { #ifdef MOD_GZIP_DEBUG1_VALIDATE1_VERBOSE1 #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: .... mod_gzip_strnicmp() = TRUE",cn); mod_gzip_printf( "%s: .... Field key name MATCHES",cn); #endif #endif } else { #ifdef MOD_GZIP_DEBUG1_VALIDATE1_VERBOSE1 #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: .... mod_gzip_strnicmp() = FALSE",cn); mod_gzip_printf( "%s: .... Field key name does NOT MATCH",cn); #endif #endif ok_to_check_it = 0; } } if ( ok_to_check_it ) { #ifdef MOD_GZIP_DEBUG1_VALIDATE1_VERBOSE1 #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: ok_to_check_it = %d = YES",cn,ok_to_check_it); #endif #endif if ( ( this_pregex ) && ( checktarget ) ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: 'this_pregex' is NON-NULL",cn); mod_gzip_printf( "%s: Performing regular expression check...",cn); mod_gzip_printf( "%s: Call ap_regexec( this_name=[%s], checktarget=[%s] )", cn, mod_gzip_npp(this_name), mod_gzip_npp(checktarget) ); #endif regex_error = ap_regexec( this_pregex, checktarget, 0, (regmatch_t *) NULL, 0 ); if ( regex_error == 0 ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: YYYY regex_error = %d = MATCH!",cn,regex_error); #endif pass_result = 1; action_value = this_action; break; } else { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: NNNN regex_error = %d = NO MATCH!",cn,regex_error); #endif } } else { #ifdef MOD_GZIP_DEBUG1 if ( !this_pregex ) { mod_gzip_printf( "%s: 'this_pregex' is NULL",cn); } if ( !checktarget ) { mod_gzip_printf( "%s: 'checktarget' is NULL",cn); } mod_gzip_printf( "%s: No regular expression check performed",cn); #endif } } else { #ifdef MOD_GZIP_DEBUG1_VALIDATE1_VERBOSE1 #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: ok_to_check_it = %d = NO",cn,ok_to_check_it); mod_gzip_printf( "%s: The record has been SKIPPED...",cn); #endif #endif } } else { #ifdef MOD_GZIP_DEBUG1_VALIDATE1_VERBOSE1 #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: type_is_included = %d = NO",cn,type_is_included); mod_gzip_printf( "%s: The record has been SKIPPED...",cn); #endif #endif } } else { #ifdef MOD_GZIP_DEBUG1_VALIDATE1_VERBOSE1 #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: This record does NOT match filter_value %d", cn, filter_value ); mod_gzip_printf( "%s: The record has been SKIPPED...",cn); #endif #endif } } #ifdef MOD_GZIP_DEBUG1_VALIDATE1_VERBOSE1 #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: --------------------------------------------",cn); mod_gzip_printf( "%s: pass_result = %d",cn,pass_result); #endif #endif if ( pass_result ) { if ( pass == 0 ) item_is_excluded = 1; else item_is_included = 1; break; } }/* End 'for ( pass=0; pass return( MOD_GZIP_IMAP_DECLINED1 ) >",cn); #endif return( MOD_GZIP_IMAP_DECLINED1 ); } else if ( item_is_included ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: The item is INCLUDED...",cn); mod_gzip_printf( "%s: Exit > return( 1 ) >",cn); #endif return action_value; } if ( http_field_check ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: ?? Status unknown ?? Default is to 'accept'...",cn); mod_gzip_printf( "%s: Exit > return( MOD_GZIP_IMAP_STATIC1 ) >",cn); #endif return MOD_GZIP_IMAP_STATIC1; } #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Exit > return( MOD_GZIP_IMAP_DECLINED1 ) >",cn); #endif return( MOD_GZIP_IMAP_DECLINED1 ); } /* ELIGIBILITY CHECKS... */ int mod_gzip_echeck1( request_rec *r, mod_gzip_conf *dconf ) { /* Primary eligibility checks... */ int i = 0; int rc = 0; int field_ok = 0; int action_flag = 0; const char *tablekey = 0; const char *tablestring = 0; int accept_encoding_gzip_seen = 0; apr_table_t *t = 0; apr_table_entry_t *elts = 0; #ifdef MOD_GZIP_DEBUG1 char cn[]="mod_gzip_echeck1()"; mod_gzip_conf *sconf = 0; #endif /* Start... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( " " ); mod_gzip_printf( "%s: #### Entry...",cn); mod_gzip_printf( "%s: r = %ld", cn,(long)r); mod_gzip_printf( "%s: r->main = %ld", cn,(long)r->main); mod_gzip_printf( "%s: r->next = %ld", cn,(long)r->next); mod_gzip_printf( "%s: r->prev = %ld", cn,(long)r->prev); mod_gzip_printf( "%s: r->header_only = %ld", cn,(long)r->header_only ); mod_gzip_printf( "%s: r->method_number = %ld", cn,(long)r->method_number ); mod_gzip_printf( "%s: r->method = [%s]",cn,mod_gzip_npp(r->method)); mod_gzip_printf( "%s: r->unparsed_uri = [%s]",cn,mod_gzip_npp(r->unparsed_uri)); mod_gzip_printf( "%s: r->uri = [%s]",cn,mod_gzip_npp(r->uri)); mod_gzip_printf( "%s: r->filename = [%s]",cn,mod_gzip_npp(r->filename)); mod_gzip_printf( "%s: r->handler = [%s]",cn,mod_gzip_npp(r->handler)); mod_gzip_printf( "%s: r->content_type = [%s]",cn,mod_gzip_npp(r->content_type)); sconf = ( mod_gzip_conf * ) ap_get_module_config( r->server->module_config, &gzip_module ); mod_gzip_printf( "%s: r->server->server_hostname = [%s]", cn,mod_gzip_npp(r->server->server_hostname)); if ( sconf ) { mod_gzip_printf( "%s: sconf = %ld", cn,(long)sconf); mod_gzip_printf( "%s: sconf->loc = [%s]",cn,mod_gzip_npp(sconf->loc)); mod_gzip_printf( "%s: sconf->is_on = %ld", cn,(long)sconf->is_on); } if ( dconf) { mod_gzip_printf( "%s: dconf = %ld", cn,(long)dconf); mod_gzip_printf( "%s: dconf->loc = [%s]",cn,mod_gzip_npp(dconf->loc)); mod_gzip_printf( "%s: dconf->is_on = %ld", cn,(long)dconf->is_on); } /* Show the request headers at this point in time... */ mod_gzip_printf( "%s: REQUEST HEADERS",cn); mod_gzip_dump_a_table( (request_rec *) r, (apr_table_t *) r->headers_in ); /* Show the response headers at this point in time... */ mod_gzip_printf( "%s: RESPONSE HEADERS",cn); mod_gzip_dump_a_table( (request_rec *) r, (apr_table_t *) r->headers_out ); #endif /* MOD_GZIP_DEBUG1 */ /* Begin checks... */ /* Do the quickest checks first... */ if ( !dconf ) { #ifdef MOD_GZIP_USES_APACHE_LOGS apr_table_setn( r->notes,"mod_gzip_result", apr_pstrdup(r->pool,"DECLINED:NO_DCONF")); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: 'dconf' is NULL. Unable to continue.",cn); mod_gzip_printf( "%s: Exit > return( DECLINED ) >", cn); #endif return DECLINED; } if ( !dconf->is_on ) { #ifdef MOD_GZIP_USES_APACHE_LOGS apr_table_setn( r->notes,"mod_gzip_result", apr_pstrdup(r->pool,"DECLINED:OFF")); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: 'dconf->is_on' is FALSE",cn); mod_gzip_printf( "%s: mod_gzip is not turned ON for this location...",cn); mod_gzip_printf( "%s: This transaction will be ignored...",cn); mod_gzip_printf( "%s: Exit > return( DECLINED ) >",cn); #endif return DECLINED; } /* Only accept HTTP 'GET' or 'POST' requests for now... */ if ( ( r->method_number != M_GET ) && ( r->method_number != M_POST ) ) { #ifdef MOD_GZIP_USES_APACHE_LOGS apr_table_setn( r->notes,"mod_gzip_result", apr_pstrdup(r->pool,"DECLINED:NOT_GET_OR_POST")); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: r->method_number is NOT M_GET or M_POST",cn); mod_gzip_printf( "%s: Ignoring this request...",cn); mod_gzip_printf( "%s: Exit > return( DECLINED ) >",cn); #endif return DECLINED; } /* Always include a specific check of the 'r->header_only' flag... */ /* NOTE: Sometimes 'r->header_only' is used by certain modules */ /* as an internal flag regardless of the value of 'r->method_number'. */ if ( r->header_only ) { #ifdef MOD_GZIP_USES_APACHE_LOGS apr_table_setn( r->notes,"mod_gzip_result", apr_pstrdup(r->pool,"DECLINED:HEAD_REQUEST")); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: r->header_only is TRUE...",cn); mod_gzip_printf( "%s: Ignoring this HEAD request...",cn); mod_gzip_printf( "%s: Exit > return( DECLINED ) >",cn); #endif return DECLINED; } /* Verify the HTTP protocol version setting(s)... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: dconf->min_http = %ld", cn, (long) dconf->min_http ); mod_gzip_printf( "%s: r->proto_num = %ld", cn, (long) r->proto_num ); #endif if ( ( dconf->min_http > 0 ) && ( r->proto_num > 0 ) ) { if ( r->proto_num < dconf->min_http ) { #ifdef MOD_GZIP_USES_APACHE_LOGS apr_table_setn( r->notes,"mod_gzip_result", apr_pstrdup(r->pool,"DECLINED:HTTP_LEVEL_TOO_LOW")); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: HTTP protocol version level is TOO LOW", cn); mod_gzip_printf( "%s: Exit > return( DECLINED ) >", cn); #endif return DECLINED; } else { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: HTTP protocol version level is OK", cn); #endif } } /* Check for pre-compressed static file requests... */ if ( r->filename ) { if ( mod_gzip_strendswith( r->filename, ".gz", 1 ) ) { apr_table_setn( r->notes,"mod_gzip_result", apr_pstrdup(r->pool,"DECLINED:FEXT_GZ")); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: r->filename ends with '.gz'...",cn); mod_gzip_printf( "%s: Exit > return( DECLINED ) >",cn); #endif return DECLINED; } #ifdef MOD_GZIP_DEBUG1 else { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: r->filename does NOT end with '.gz'...",cn); mod_gzip_printf( "%s: OK to continue...",cn); #endif } #endif } /* Check for 'Accept-Encoding: gzip, deflate'... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Checking for [Accept-Encoding: gzip]", cn ); #endif tablestring = apr_table_get( r->headers_in, "Accept-Encoding" ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: r->headers_in->Accept-Encoding = [%s]", cn,mod_gzip_npp(tablestring)); #endif if ( tablestring ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: 'Accept-Encoding' field seen...", cn); mod_gzip_printf( "%s: Checking for 'gzip' value...", cn); #endif if ( mod_gzip_stringcontains( (char *)tablestring, "gzip" ) ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: 'gzip' value seen...", cn); #endif accept_encoding_gzip_seen = 1; } else { #ifdef MOD_GZIP_USES_APACHE_LOGS apr_table_setn( r->notes,"mod_gzip_result", apr_pstrdup(r->pool,"DECLINED:NO_GZIP")); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: 'gzip' value NOT seen...", cn); mod_gzip_printf( "%s: Exit > return( DECLINED ) >", cn); #endif return DECLINED; } } else /* No 'Accept-encoding:' field present... */ { #ifdef MOD_GZIP_USES_APACHE_LOGS apr_table_setn( r->notes,"mod_gzip_result", apr_pstrdup(r->pool,"DECLINED:NO_ACCEPT_ENCODING")); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: 'Accept-Encoding' field NOT seen...", cn); mod_gzip_printf( "%s: Exit > return( DECLINED ) >", cn); #endif return DECLINED; } #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: accept_encoding_gzip_seen = %ld", cn, accept_encoding_gzip_seen ); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: dconf->imap_total_entries = %d", cn, (int) dconf->imap_total_entries ); #endif /* There must be at least 1 IMAP inclusion/exclusion record... */ if ( dconf->imap_total_entries < 1 ) { #ifdef MOD_GZIP_USES_APACHE_LOGS apr_table_setn( r->notes,"mod_gzip_result", apr_pstrdup(r->pool,"DECLINED:NO_ITEMS_DEFINED")); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: There are no IMAP entries. Unable to include/exclude",cn); mod_gzip_printf( "%s: Exit > return( DECLINED ) >", cn); #endif return DECLINED; } #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: dconf->imap_total_isreqheader = %d", cn, (int) dconf->imap_total_isreqheader ); #endif /* See if we need to examine 'special' input request headers... */ if ( dconf->imap_total_isreqheader > 0 ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Checking inbound REQUEST header fields...", cn ); #endif t = ( apr_table_t * ) r->headers_in; elts = ( apr_table_entry_t * ) t->a.elts; for ( i = 0; i < t->a.nelts; i++ ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: %3.3d key=[%s] val=[%s]", cn,i,mod_gzip_npp(elts[i].key),mod_gzip_npp(elts[i].val)); #endif tablekey = elts[i].key; tablestring = elts[i].val; if (( tablekey && tablestring )) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Checking key[%s] string[%s]", cn,mod_gzip_npp(tablekey),mod_gzip_npp(tablestring)); mod_gzip_printf( "%s: Call mod_gzip_validate1()...",cn); #endif field_ok = mod_gzip_validate1( (request_rec *) r, (mod_gzip_conf *) dconf, NULL, /* r->filename (Not used here) */ NULL, /* r->uri (Not used here) */ NULL, /* r->content_type (Not used here) */ NULL, /* r->handler (Not used here) */ (char *) tablekey, /* (Field key ) */ (char *) tablestring, /* (Field string ) */ MOD_GZIP_REQUEST /* (Direction ) */ ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Back mod_gzip_validate1()...",cn); mod_gzip_printf( "%s: field_ok = %d",cn,field_ok); #endif if ( field_ok == MOD_GZIP_IMAP_DECLINED1 ) { #ifdef MOD_GZIP_USES_APACHE_LOGS apr_table_setn( r->notes,"mod_gzip_result", apr_pstrdup(r->pool,"DECLINED:REQ_HEADER_FIELD_EXCLUDED")); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: This request is EXCLUDED...",cn); mod_gzip_printf( "%s: Exit > return( DECLINED ) >", cn); #endif return DECLINED; } }/* End 'if(( tablekey && tablestring ))' */ }/* End 'i' loop */ }/* End 'if ( dconf->imap_total_isreqheader > 0 )' */ #ifdef MOD_GZIP_DEBUG1 else { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: NO CHECK required on inbound REQUEST header fields...", cn ); #endif } #endif /* Validate the request... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: 1 ***: r->uri =[%s]", cn, mod_gzip_npp(r->uri )); mod_gzip_printf( "%s: 1 ***: r->unparsed_uri=[%s]", cn, mod_gzip_npp(r->unparsed_uri )); mod_gzip_printf( "%s: 1 ***: r->filename =[%s]", cn, mod_gzip_npp(r->filename )); mod_gzip_printf( "%s: 1 ***: r->handler =[%s]", cn, mod_gzip_npp(r->handler )); mod_gzip_printf( "%s: 1 ***: r->content_type=[%s]", cn, mod_gzip_npp(r->content_type )); mod_gzip_printf( "%s: 2 ***: r->uri =[%s]", cn, mod_gzip_npp(r->uri )); mod_gzip_printf( "%s: 2 ***: r->unparsed_uri=[%s]", cn, mod_gzip_npp(r->unparsed_uri )); mod_gzip_printf( "%s: 2 ***: r->filename =[%s]", cn, mod_gzip_npp(r->filename )); mod_gzip_printf( "%s: 2 ***: r->content_type=[%s]", cn, mod_gzip_npp(r->content_type )); mod_gzip_printf( "%s: 2 ***: r->handler =[%s]", cn, mod_gzip_npp(r->handler )); mod_gzip_printf( "%s: Call mod_gzip_validate1()...",cn); #endif /* MOD_GZIP_DEBUG1 */ action_flag = mod_gzip_validate1( (request_rec *) r, (mod_gzip_conf *) dconf, (char *) r->filename, (char *) r->uri, (char *) r->content_type, (char *) r->handler, NULL, /* Field key (Not used here) */ NULL, /* Field string (Not used here) */ 0 /* Direction (Not used here) */ ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Back mod_gzip_validate1()...",cn); mod_gzip_printf( "%s: action_flag = %d",cn,action_flag); if ( action_flag == MOD_GZIP_IMAP_DYNAMIC1 ) { mod_gzip_printf( "%s: action_flag = MOD_GZIP_IMAP_DYNAMIC1",cn); } else if ( action_flag == MOD_GZIP_IMAP_DYNAMIC2 ) { mod_gzip_printf( "%s: action_flag = MOD_GZIP_IMAP_DYNAMIC2",cn); } else if ( action_flag == MOD_GZIP_IMAP_STATIC1 ) { mod_gzip_printf( "%s: action_flag = MOD_GZIP_IMAP_STATIC1",cn); } else if ( action_flag == MOD_GZIP_IMAP_DECLINED1 ) { mod_gzip_printf( "%s: action_flag = MOD_GZIP_IMAP_DECLINED1",cn); } else { mod_gzip_printf( "%s: action_flag = MOD_GZIP_IMAP_??? Unknown action",cn); } #endif /* MOD_GZIP_DEBUG1 */ if ( action_flag != MOD_GZIP_IMAP_DECLINED1 ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: This transaction is a valid candidate...",cn); mod_gzip_printf( "%s: Exit > return( OK ) >", cn ); mod_gzip_printf( " " ); #endif return OK; } else /* 'action_flag' is 'MOD_GZIP_IMAP_DECLINED1' */ { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: This transaction is NOT a valid candidate...",cn); #endif #ifdef MOD_GZIP_USES_APACHE_LOGS apr_table_setn( r->notes,"mod_gzip_result", apr_pstrdup(r->pool,"DECLINED:EXCLUDED")); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Exit > return( DECLINED ) >", cn ); mod_gzip_printf( " " ); #endif return DECLINED; } }/* End of mod_gzip_echeck1() */ int mod_gzip_echeck2( request_rec *r, mod_gzip_conf *dconf ) { /* Secondary eligibility checks... */ /* NOTE: This routine should only be called following the */ /* primary eligibility check(s) and only when the 'r->headers_out' */ /* table is valid and the response headers are available for */ /* examination... */ int i = 0; int rc = 0; int field_ok = 0; int action_flag = 0; const char *tablekey = 0; const char *tablestring = 0; apr_table_t *t = 0; apr_table_entry_t *elts = 0; #ifdef MOD_GZIP_DEBUG1 char cn[]="mod_gzip_echeck2()"; mod_gzip_conf *sconf = 0; #endif /* Start... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( " " ); mod_gzip_printf( "%s: #### Entry...",cn); mod_gzip_printf( "%s: r = %ld", cn,(long)r); mod_gzip_printf( "%s: r->main = %ld", cn,(long)r->main); mod_gzip_printf( "%s: r->next = %ld", cn,(long)r->next); mod_gzip_printf( "%s: r->prev = %ld", cn,(long)r->prev); mod_gzip_printf( "%s: r->header_only = %ld", cn,(long)r->header_only ); mod_gzip_printf( "%s: r->method_number = %ld", cn,(long)r->method_number ); mod_gzip_printf( "%s: r->method = [%s]",cn,mod_gzip_npp(r->method)); mod_gzip_printf( "%s: r->unparsed_uri = [%s]",cn,mod_gzip_npp(r->unparsed_uri)); mod_gzip_printf( "%s: r->uri = [%s]",cn,mod_gzip_npp(r->uri)); mod_gzip_printf( "%s: r->filename = [%s]",cn,mod_gzip_npp(r->filename)); mod_gzip_printf( "%s: r->handler = [%s]",cn,mod_gzip_npp(r->handler)); mod_gzip_printf( "%s: r->content_type = [%s]",cn,mod_gzip_npp(r->content_type)); sconf = ( mod_gzip_conf * ) ap_get_module_config( r->server->module_config, &gzip_module ); mod_gzip_printf( "%s: r->server->server_hostname = [%s]", cn,mod_gzip_npp(r->server->server_hostname)); if ( sconf ) { mod_gzip_printf( "%s: sconf = %ld", cn,(long)sconf); mod_gzip_printf( "%s: sconf->loc = [%s]",cn,mod_gzip_npp(sconf->loc)); mod_gzip_printf( "%s: sconf->is_on = %ld", cn,(long)sconf->is_on); } if ( dconf) { mod_gzip_printf( "%s: dconf = %ld", cn,(long)dconf); mod_gzip_printf( "%s: dconf->loc = [%s]",cn,mod_gzip_npp(dconf->loc)); mod_gzip_printf( "%s: dconf->is_on = %ld", cn,(long)dconf->is_on); } /* Show the request headers at this point in time... */ mod_gzip_printf( "%s: REQUEST HEADERS",cn); mod_gzip_dump_a_table( (request_rec *) r, (apr_table_t *) r->headers_in ); /* Show the response headers at this point in time... */ mod_gzip_printf( "%s: RESPONSE HEADERS",cn); mod_gzip_dump_a_table( (request_rec *) r, (apr_table_t *) r->headers_out ); #endif /* MOD_GZIP_DEBUG1 */ /* Begin checks... */ if ( !dconf ) /* Sanity check... */ { #ifdef MOD_GZIP_USES_APACHE_LOGS apr_table_setn( r->notes,"mod_gzip_result", apr_pstrdup(r->pool,"DECLINED:NO_DCONF")); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: 'dconf' is NULL. Unable to continue.",cn); mod_gzip_printf( "%s: Exit > return( DECLINED ) >", cn); #endif return DECLINED; } if ( !dconf->is_on ) /* Sanity check... */ { #ifdef MOD_GZIP_USES_APACHE_LOGS apr_table_setn( r->notes,"mod_gzip_result", apr_pstrdup(r->pool,"DECLINED:OFF")); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: 'dconf->is_on' is FALSE",cn); mod_gzip_printf( "%s: mod_gzip is not turned ON for this location...",cn); mod_gzip_printf( "%s: This transaction will be ignored...",cn); mod_gzip_printf( "%s: Exit > return( DECLINED ) >",cn); #endif return DECLINED; } /* Check for pre-existing Content-Encodings... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Checking for [Content-Encoding: xxx]", cn ); #endif tablestring = apr_table_get( r->headers_out, "Content-Encoding" ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: r->headers_out->Content-Encoding = [%s]", cn,mod_gzip_npp(tablestring)); #endif if ( tablestring ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: 'Content-Encoding' field seen...", cn); #endif /* There is no need to check the field value(s). */ /* As of this writing no browser can handle multiple */ /* Content-Encodings of any kind. */ /* Just DECLINE and don't add multiple Content-Encdodings... */ #ifdef MOD_GZIP_USES_APACHE_LOGS apr_table_setn( r->notes,"mod_gzip_result", apr_pstrdup(r->pool,"DECLINED:HAS_CE")); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Exit > return( DECLINED ) >", cn); #endif return DECLINED; } else /* No 'Content-Encoding:' field present... */ { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: 'Content-Encoding' field NOT seen...", cn); #endif } /* Check for pre-existing Transfer-Encodings... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Checking for [Transfer-Encoding: xxx]", cn ); #endif tablestring = apr_table_get( r->headers_out, "Transfer-Encoding" ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: r->headers_out->Transfer-Encoding = [%s]", cn,mod_gzip_npp(tablestring)); #endif if ( tablestring ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: 'Transfer-Encoding' field seen...", cn); mod_gzip_printf( "%s: Checking header value...", cn); #endif if ( mod_gzip_stringcontains( (char *)tablestring, "chunked" ) ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: 'chunked' value seen...", cn); mod_gzip_printf( "%s: dconf->dechunk = %d", cn, (int)dconf->dechunk ); #endif #ifdef MOD_GZIP_CAN_DECHUNK /* If we are able to strip pre-existing 'chunking' information */ /* then check the flag to see if we should do so... */ if ( dconf->dechunk == 1 ) { /* The configuration says it's OK to remove any */ /* pre-existing chunking information so the response */ /* can be compressed... continue... */ } else /* dechunk flag is FALSE */ { /* We are unable to remove the pre-existing chunking */ /* information so EXCLUDE this response from compression... */ #ifdef MOD_GZIP_USES_APACHE_LOGS apr_table_setn( r->notes,"mod_gzip_result", apr_pstrdup(r->pool,"DECLINED:TE_CHUNKED")); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Exit > return( DECLINED ) >", cn); #endif return DECLINED; } #else /* !MOD_GZIP_CAN_DECHUNK */ /* ZLIB is unable to remove the pre-existing chunking information */ /* if it exists so just EXCLUDE this request for now... */ /* TODO: Add code to strip pre-existing Transfer_Encoding */ /* prior to ZLIB deflate() calls in the filter itself. */ #ifdef MOD_GZIP_USES_APACHE_LOGS apr_table_setn( r->notes,"mod_gzip_result", apr_pstrdup(r->pool,"DECLINED:TE_CHUNKED")); #endif #endif /* MOD_GZIP_CAN_DECHUNK */ }/* End 'if TE chunked' */ else /* Other TE encodings... */ { /* For now other Transfer-Encodings other than */ /* 'chunked' will not disqualify this request. */ /* Just fall-through and continue checks... */ } } else /* No 'Transfer-Encoding:' field present... */ { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: 'Transfer-Encoding' field NOT seen...", cn); #endif } /* See if we need to validate any response headers... */ if ( dconf->imap_total_isrspheader > 0 ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Checking RESPONSE header fields...", cn ); #endif t = ( apr_table_t * ) r->headers_out; elts = ( apr_table_entry_t * ) t->a.elts; for ( i = 0; i < t->a.nelts; i++ ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: %3.3d key=[%s] val=[%s]", cn,i,mod_gzip_npp(elts[i].key),mod_gzip_npp(elts[i].val)); #endif tablekey = elts[i].key; tablestring = elts[i].val; if (( tablekey && tablestring )) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Checking key[%s] string[%s]", cn,mod_gzip_npp(tablekey),mod_gzip_npp(tablestring)); mod_gzip_printf( "%s: Call mod_gzip_validate1()...",cn); #endif field_ok = mod_gzip_validate1( (request_rec *) r, (mod_gzip_conf *) dconf, NULL, /* r->filename (Not used here) */ NULL, /* r->uri (Not used here) */ NULL, /* r->content_type (Not used here) */ NULL, /* r->handler (Not used here) */ (char *) tablekey, /* (Field key ) */ (char *) tablestring, /* (Field string ) */ MOD_GZIP_RESPONSE /* (Direction ) */ ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Back mod_gzip_validate1()...",cn); mod_gzip_printf( "%s: field_ok = %d",cn,field_ok); #endif if ( field_ok == MOD_GZIP_IMAP_DECLINED1 ) { #ifdef MOD_GZIP_USES_APACHE_LOGS apr_table_setn( r->notes,"mod_gzip_result", apr_pstrdup(r->pool,"DECLINED:RSP_HEADER_FIELD_EXCLUDED")); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: This response is EXCLUDED...",cn); mod_gzip_printf( "%s: Exit > return( DECLINED ) >", cn); #endif return DECLINED; } }/* End 'if(( tablekey && tablestring ))' */ }/* End 'i' loop */ }/* End 'if ( dconf->imap_total_isrspheader > 0 )' */ #ifdef MOD_GZIP_DEBUG1 else { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: NO CHECK required on RESPONSE header fields...", cn ); #endif } #endif return OK; /* We passed the secondary eligibility check(s)... */ }/* End of mod_gzip_echeck2() */ /* SPECIAL COMMAND HANDLERS... */ #ifdef MOD_GZIP_COMMAND_VERSION_USED int mod_gzip_do_command( int this_command, /* MOD_GZIP_COMMAND_XXXX */ request_rec *r, /* Request record */ mod_gzip_conf *dconf /* Directory config pointer */ ) { /* Generic command response transmitter... */ char tmpbuf[2048]; /* Fill/flush as needed. Don't overflow */ char *tmp=tmpbuf; char s1[90]; #ifdef MOD_GZIP_DEBUG1 int tmplen=0; char cn[]="mod_gzip.c: mod_gzip_do_command()"; #endif /* Start... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Entry...",cn); mod_gzip_printf( "%s: this_command = (int) %d",cn,(int)this_command); mod_gzip_printf( "%s: r->uri = [%s]",cn,mod_gzip_npp(r->uri)); mod_gzip_printf( "%s: r->unparsed_uri = [%s]",cn,mod_gzip_npp(r->unparsed_uri)); #endif if ( this_command == MOD_GZIP_COMMAND_VERSION ) { mod_gzip_strcpy(s1,"No"); if ( dconf ) { if ( dconf->is_on == 1 ) mod_gzip_strcpy(s1,"Yes"); } sprintf( tmp, "" "mod_gzip is available...
\r\n" "mod_gzip_version = %s
\r\n" "mod_gzip_on = %s
\r\n" "", mod_gzip_version, /* Global version string */ s1 ); #ifdef MOD_GZIP_DEBUG1 tmplen = strlen( tmp ); mod_gzip_printf( "%s: HEXDUMP( tmp, tmplen=%d )",cn,(int)tmplen); mod_gzip_hexdump( tmp, tmplen ); #endif #ifdef MOD_GZIP_USES_APACHE_LOGS apr_table_setn( r->notes,"mod_gzip_result", apr_pstrdup(r->pool,"COMMAND:VERSION")); #endif r->content_type = "text/html"; ap_rputs( tmp, r ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Exit > return( OK ) >",cn); #endif return OK; } else /* Invalid command... */ { /* Might be a valid URL or CGI command so just continue */ /* and let Apache decide... */ #ifdef MOD_GZIP_USES_APACHE_LOGS apr_table_setn( r->notes,"mod_gzip_result", apr_pstrdup(r->pool,"DECLINED:INVALID_COMMAND")); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Exit > return( DECLINED ) >",cn); #endif return( DECLINED ); } }/* End of mod_gzip_do_command() */ #endif /* MOD_GZIP_COMMAND_VERSION_USED */ /* FILTERING SUPPORT... */ static void mod_gzip_insert_output_filter( request_rec *r ) { /* NOTE: At the time the Apache engine calls this routine */ /* there will not be any valid r->headers_out response header */ /* values to examine yet. */ int rc; /* Generic return code */ mod_gzip_conf *mgc; /* Location/Directory configuration pointer */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_conf *dconf = 0; /* Directory\Location configuration */ mod_gzip_conf *sconf = 0; /* Server configuration */ char cn[]="mod_gzip_insert_output_filter()"; #endif /* Start... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( " "); mod_gzip_printf( "%s: ````Entry...",cn); mod_gzip_printf( "%s: r->uri = [%s]",cn,mod_gzip_npp(r->uri)); mod_gzip_printf( "%s: r->unparsed_uri = [%s]",cn,mod_gzip_npp(r->unparsed_uri)); /* Show some configuration information... */ dconf = ( mod_gzip_conf * ) ap_get_module_config( r->per_dir_config, &gzip_module ); sconf = ( mod_gzip_conf * ) ap_get_module_config( r->server->module_config, &gzip_module ); mod_gzip_printf( "%s: r->server->server_hostname = [%s]", cn,mod_gzip_npp(r->server->server_hostname)); mod_gzip_printf( "%s: sconf = %ld", cn,(long)sconf); if ( sconf ) { mod_gzip_printf( "%s: sconf->loc = [%s]",cn,mod_gzip_npp(sconf->loc)); mod_gzip_printf( "%s: sconf->is_on = %ld", cn,(long)sconf->is_on); mod_gzip_printf( "%s: sconf->deflate_compression_level = %ld", cn,(long)sconf->deflate_compression_level); mod_gzip_printf( "%s: sconf->deflate_compression_level_set = %ld", cn,(long)sconf->deflate_compression_level_set); } mod_gzip_printf( "%s: dconf = %ld", cn,(long)dconf); if ( dconf ) { mod_gzip_printf( "%s: dconf->loc = [%s]",cn,mod_gzip_npp(dconf->loc)); mod_gzip_printf( "%s: dconf->is_on = %ld", cn,(long)dconf->is_on); mod_gzip_printf( "%s: dconf->deflate_compression_level = %ld", cn,(long)dconf->deflate_compression_level); mod_gzip_printf( "%s: dconf->deflate_compression_level_set = %ld", cn,(long)dconf->deflate_compression_level_set); } #endif /* MOD_GZIP_DEBUG1 */ /* Set a pointer to the specific Directory\Location */ /* configuration record for this request... */ mgc = ( mod_gzip_conf * ) ap_get_module_config( r->per_dir_config, &gzip_module ); /* Primary eligibility checks... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Call rc = mod_gzip_echeck1( r, mgc )...",cn); #endif rc = mod_gzip_echeck1( (request_rec *) r, (mod_gzip_conf *) mgc ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Back rc = mod_gzip_echeck1( r, mgc )...",cn); mod_gzip_printf( "%s: .... rc = %d",cn,(int)rc); #endif if ( rc == DECLINED ) { /* This request is not eligible for compression... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: .... rc = DECLINED",cn,(int)rc); mod_gzip_printf( "%s: Exit > return( void ) >",cn); #endif return; /* Don't add the filter... just return... */ } /* If we passed all the tests go ahead and add the filter... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Adding filter NOW...",cn); mod_gzip_printf( "%s: Call ap_add_output_filter( mod_gzip_filter_name=[%s], NULL, r, r->connection )...", cn,mod_gzip_npp(mod_gzip_filter_name)); #endif ap_add_output_filter( mod_gzip_filter_name, NULL, r, r->connection ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Back ap_add_output_filter( mod_gzip_filter_name=[%s], NULL, r, r->connection )...", cn,mod_gzip_npp(mod_gzip_filter_name)); #endif /* Once the filter is added set some default operational values... */ #ifdef MOD_GZIP_USES_APACHE_LOGS /* Set some default 'note' values in case the filtering bombs */ /* out so we know what 'type' of request we started to filter... */ if ( r->main ) { apr_table_setn( r->notes,"mod_gzip_result",apr_pstrdup(r->pool,"FILTER:SUBREQ")); } else if ( r->prev ) { apr_table_setn( r->notes,"mod_gzip_result",apr_pstrdup(r->pool,"FILTER:REDIR")); } else { apr_table_setn( r->notes,"mod_gzip_result",apr_pstrdup(r->pool,"FILTER:INIT1")); } /* Reset the final result values to default(s) of ZERO... */ apr_table_setn( r->notes,"mod_gzip_input_size", apr_pstrdup(r->pool,"0")); apr_table_setn( r->notes,"mod_gzip_output_size",apr_pstrdup(r->pool,"0")); apr_table_setn( r->notes,"mod_gzip_compression_ratio",apr_pstrdup(r->pool,"0")); #endif /* MOD_GZIP_USES_APACHE_LOGS */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Exit > return( void ) >",cn); #endif return; /* VOID return */ }/* End of mod_gzip_insert_output_filter() */ /* PRIMARY OUTPUT FILTER... */ static apr_status_t mod_gzip_output_filter( ap_filter_t *f, apr_bucket_brigade *brigade_in ) { /* This is the primary output filter for this module */ /* The primary ELIGIBILITY tests should have already been */ /* performed in the routine that decides whether or not to */ /* actually 'add' this filter to the current transaction. */ /* Any eligibility tests that involve the RESPONSE headers must */ /* wait until this routine is called since 'r->headers_out' will */ /* usually be blank at the time the filter 'insertion' takes place. */ /* NOTE: If the request was a static file then the brigade */ /* should contain a FILE bucket and the 'Content-Length:' response */ /* header will have already been set to the length of the file. */ /* Example... */ /* If the request was for a 454,443 byte local file then upon */ /* entry 'r->headers_out' will normally already be... */ /* 000 key=[Last-Modified] val=[Wed, 31 Jan 2001 20:58:52 GMT] */ /* 001 key=[ETag] val=["0-6ef2b-fa6f3b00"] */ /* 002 key=[Accept-Ranges] val=[bytes] */ /* 003 key=[Content-Length] val=[454443] */ int i; /* Generic loop counter */ int rc; /* Generic integer return code */ unsigned int len; /* Generic length variable */ /* BRIGADE work variables... */ apr_bucket_brigade *brigade_out; /* BUCKET work variables... */ apr_bucket *bucket_in; apr_bucket *bucket_out; apr_bucket *bucket_eos; /* REQUEST work variables... */ request_rec *r = f->r; char *token = NULL; /* ZLIB work variables... */ zlib_context *zlib_ctx; char *zlib_gzip_header; int zlib_gzip_header_length = 10; /* 10 byte LZ77 deflate header */ char *zlib_gzip_footer; int zlib_gzip_footer_length = 8; /* 8 byte LZ77 deflate footer */ /* Work variables for APR_BRIGADE_FOREACH() loop... */ char socl[4]; /* deflate() OCL (Original Content Length) placeholder */ char scrc[4]; /* deflate() CRC placeholder */ const char *idata; /* Input data */ apr_size_t ilen; /* Input length */ apr_size_t bcopied; /* Bytes copied */ int done = 0; /* Completion flag */ /* Other scratch variables... */ int compression_level = 0; long compression_ratio = 0; long total_bytes_read = 0; long total_bytes_written = 0; long total_bytes_saved = 0; mod_gzip_conf *dconf = 0; /* Directory/Location configuration */ mod_gzip_conf *sconf = 0; /* Server configuration */ #ifdef MOD_GZIP_USES_APACHE_LOGS char *log_info; /* For updating ACCESS_LOG */ #endif #ifdef MOD_GZIP_DEBUG1 char cn[]="mod_gzip_output_filter()"; int bytes_to_dump; /* Controls debug hexdump output length */ #endif /* Start... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( " " ); mod_gzip_printf( "%s: ''''Entry...",cn); mod_gzip_printf( "%s: r = %ld", cn,(long)r); mod_gzip_printf( "%s: r->main = %ld", cn,(long)r->main); mod_gzip_printf( "%s: r->next = %ld", cn,(long)r->next); mod_gzip_printf( "%s: r->prev = %ld", cn,(long)r->prev); mod_gzip_printf( "%s: r->header_only = %ld", cn,(long)r->header_only ); mod_gzip_printf( "%s: r->method_number = %ld", cn,(long)r->method_number ); mod_gzip_printf( "%s: r->method = [%s]",cn,mod_gzip_npp(r->method)); mod_gzip_printf( "%s: r->unparsed_uri = [%s]",cn,mod_gzip_npp(r->unparsed_uri)); mod_gzip_printf( "%s: r->uri = [%s]",cn,mod_gzip_npp(r->uri)); mod_gzip_printf( "%s: r->filename = [%s]",cn,mod_gzip_npp(r->filename)); /* TODO: Apache 2.x bug or feature?... At this point... r->handler name prints out same as r->content_type ( text/html ) even when it's a CGI script or ColdFusion request? Is this new? */ mod_gzip_printf( "%s: r->handler = [%s]",cn,mod_gzip_npp(r->handler)); mod_gzip_printf( "%s: r->content_type = [%s]",cn,mod_gzip_npp(r->content_type)); /* Show the request headers at this point in time... */ mod_gzip_printf( "%s: REQUEST HEADERS",cn); mod_gzip_dump_a_table( (request_rec *) r, (apr_table_t *) r->headers_in ); /* Show the response headers at this point in time... */ mod_gzip_printf( "%s: RESPONSE HEADERS",cn); mod_gzip_dump_a_table( (request_rec *) r, (apr_table_t *) r->headers_out ); #endif /* MOD_GZIP_DEBUG1 */ /* Set a pointer to the specific Directory/Location */ /* configuration record for this request... */ dconf = ( mod_gzip_conf * ) ap_get_module_config( r->per_dir_config, &gzip_module ); /* Secondary eligibility checks... */ /* NOTE: There are some eligibility checks that can only be */ /* performed at this point when the 'r->headers_out' table */ /* has been updated and contains valid response headers. */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Call rc = mod_gzip_echeck2( r, mgc )...",cn); #endif rc = mod_gzip_echeck2( (request_rec *) r, (mod_gzip_conf *) dconf ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Back rc = mod_gzip_echeck2( r, mgc )...",cn); mod_gzip_printf( "%s: .... rc = %d",cn,(int)rc); #endif if ( rc == DECLINED ) { /* This request is not eligible for compression... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: .... rc = DECLINED",cn,(int)rc); mod_gzip_printf( "%s: Exit > return( ap_pass_brigade( f->next, brigade_in ) ) >",cn); #endif return ap_pass_brigade( f->next, brigade_in ); } /* We have passed the secondary eligibility check(s)... */ /* Create the output brigade... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Call brigade_out = apr_brigade_create( f->r->pool )",cn); #endif brigade_out = apr_brigade_create( f->r->pool , f->c->bucket_alloc); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Back brigade_out = apr_brigade_create( f->r->pool )",cn); if ( brigade_out ) { mod_gzip_printf( "%s: .... brigade_out = %ld",cn,(long)brigade_out); } mod_gzip_printf( "%s: f->ctx = %ld",cn,(long)f->ctx); #endif /* MOD_GZIP_DEBUG1 */ /* Create the context if it doesn't already exist... */ if ( !f->ctx ) { /* Create a new context... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: 'f->ctx' pointer is NOT VALID...",cn); mod_gzip_printf( "%s: NEW_CONTEXT_INIT: START",cn); mod_gzip_printf( "%s: Allocating new f->ctx memory...",cn); mod_gzip_printf( "%s: sizeof(*zlib_ctx) = %ld",cn,(long)sizeof(*zlib_ctx)); mod_gzip_printf( "%s: Call f->ctx = apr_pcalloc(f->c->pool,sizeof(*zlib_ctx))...",cn); #endif f->ctx = apr_pcalloc( f->c->pool, sizeof(*zlib_ctx) ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Back f->ctx = apr_pcalloc(f->c->pool,sizeof(*zlib_ctx))...",cn); #endif zlib_ctx = f->ctx; zlib_ctx->strm.zalloc = (alloc_func) 0; zlib_ctx->strm.zfree = (free_func) 0; zlib_ctx->strm.opaque = (voidpf) 0; zlib_ctx->crc = 0L; /* Create a new ZLIB compression context... */ #ifdef REFERENCE /* Some default compression levels from ZLIB.H... */ _define Z_NO_COMPRESSION 0 _define Z_BEST_SPEED 1 _define Z_BEST_COMPRESSION 9 _define Z_DEFAULT_COMPRESSION (-1) #endif /* REFERENCE */ /* Get the Server/Virtual Host configuration... */ sconf = ( mod_gzip_conf * ) ap_get_module_config( r->server->module_config, &gzip_module ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: r->server->server_hostname = [%s]", cn,mod_gzip_npp(r->server->server_hostname)); mod_gzip_printf( "%s: sconf = %ld", cn,(long)sconf); if ( sconf ) { mod_gzip_printf( "%s: sconf->loc = [%s]",cn,mod_gzip_npp(sconf->loc)); mod_gzip_printf( "%s: sconf->is_on = %ld", cn,(long)sconf->is_on); mod_gzip_printf( "%s: sconf->deflate_compression_level = %ld", cn,(long)sconf->deflate_compression_level); mod_gzip_printf( "%s: sconf->deflate_compression_level_set = %ld", cn,(long)sconf->deflate_compression_level_set); } mod_gzip_printf( "%s: dconf = %ld", cn,(long)dconf); if ( dconf ) { mod_gzip_printf( "%s: dconf->loc = [%s]",cn,mod_gzip_npp(dconf->loc)); mod_gzip_printf( "%s: dconf->is_on = %ld", cn,(long)dconf->is_on); mod_gzip_printf( "%s: dconf->deflate_compression_level = %ld", cn,(long)dconf->deflate_compression_level); mod_gzip_printf( "%s: dconf->deflate_compression_level_set = %ld", cn,(long)dconf->deflate_compression_level_set); } #endif /* MOD_GZIP_DEBUG1 */ /* LZ77 DEFLATE COMPRESSION LEVEL */ compression_level = -1; if ( dconf ) { /* Use the more specfic value for this location... */ compression_level = (int) dconf->deflate_compression_level; } else if ( sconf ) { /* Use the relative Server config value for this location... */ compression_level = (int) sconf->deflate_compression_level; }/* End 'else if( sconf )' */ /* Sanity check... */ if ( ( compression_level < 0 ) || ( compression_level > 9 ) ) { compression_level = MOD_GZIP_DEFLATE_DEFAULT_COMPRESSION_LEVEL; } #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: MOD_GZIP_DEFLATE_DEFAULT_COMPRESSION_LEVEL = %d", cn, MOD_GZIP_DEFLATE_DEFAULT_COMPRESSION_LEVEL ); mod_gzip_printf( "%s: compression_level = %d", cn, compression_level ); mod_gzip_printf( "%s: Call rc = deflateInit2()...",cn); #endif rc = deflateInit2( &zlib_ctx->strm, compression_level, Z_DEFLATED, MOD_GZIP_ZLIB_WINDOWSIZE, MOD_GZIP_ZLIB_CFACTOR, Z_DEFAULT_STRATEGY ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Back rc = deflateInit2()...",cn); mod_gzip_printf( "%s: .... rc = %ld",cn,(long)rc); #endif if ( rc != Z_OK ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: ERROR: rc != Z_OK",cn); #endif f->ctx = NULL; #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: f->ctx reset to NULL...",cn); mod_gzip_printf( "%s: Logging error via ap_log_rerror()...",cn); #endif ap_log_rerror( APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r, "mod_gzip: ZLIB deflateInit2(): ERROR %d: URL %s", rc, r->uri ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Exit > return( ap_pass_brigade( f->next, brigade_in ) >",cn); #endif return ap_pass_brigade( f->next, brigade_in ); } #ifdef MOD_GZIP_DEBUG1 else { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: .... rc = Z_OK ( Call SUCCEEDED )...",cn); #endif } #endif /* Build the ZLIB GZIP header... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Re-creating fixed ZLIB GZIP header...",cn); #endif zlib_gzip_header = apr_psprintf( r->pool, "%c%c%c%c%c%c%c%c%c%c", zlib_gzip_magic[0], /* Signature byte 1 */ zlib_gzip_magic[1], /* Signature byte 2 */ Z_DEFLATED, /* Same as GZIP_DEFLATE */ 0, /* Flags ORIG_NAME, etc. */ 0, /* Future use */ 0, /* Future use */ 0, /* Future use */ 0, /* Time */ 0, /* xflags ( deflate flags ) */ OS_CODE /* From ZUTIL.H */ ); /* Create a bucket containing the fixed format ZLIB GZIP header... */ /* NOTE: Use variables for header/footer length so they can be */ /* added to the compression output stream byte total(s). The */ /* Apache logs must reflect the total stream data + header length(s) */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: zlib_gzip_header_length = %ld",cn,(int)zlib_gzip_header_length); mod_gzip_printf( "%s: Call bucket_out = apr_bucket_pool_create( buf, zlib_gzip_header_length, r->pool )...",cn); #endif bucket_out = apr_bucket_pool_create( zlib_gzip_header, zlib_gzip_header_length, r->pool, f->c->bucket_alloc ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Back bucket_out = apr_bucket_pool_create( buf, zlib_gzip_header_length, r->pool )...",cn); mod_gzip_printf( "%s: Call APR_BRIGADE_INSERT_TAIL( brigade_out, bucket_out )...",cn); #endif /* Add the ZLIB GZIP header bucket to the brigade... */ APR_BRIGADE_INSERT_TAIL( brigade_out, bucket_out ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Back APR_BRIGADE_INSERT_TAIL( brigade_out, bucket_out )...",cn); #endif /* Set some response headers... */ /* NOTE: For a static FILE bucket the 'r->headers_out' response */ /* header table will already contain a 'Content-Length: xxxx' field */ /* where 'xxxx' is the length of the original (uncompressed) data. */ /* We do NOT have to remove this 'Content-Length:' header because */ /* it should update automatically to reflect the (smaller) */ /* compressed length. */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Call apr_table_setn( r->headers_out, 'Content-Encoding: gzip'",cn); #endif apr_table_setn( r->headers_out, "Content-Encoding", "gzip" ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Call apr_table_setn( r->headers_out, 'Vary: Accept-Encoding'",cn); #endif apr_table_setn( r->headers_out, "Vary", "Accept-Encoding" ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: NEW_CONTEXT_INIT: DONE",cn); #endif }/* End 'if ( !f->ctx )' */ else /* f->ctx is already allocated... */ { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: 'f->ctx' pointer is already VALID...",cn); mod_gzip_printf( "%s: Setting 'zlib_ctx = f->ctx'...",cn); #endif zlib_ctx = f->ctx; } /* Spin through the input brigade and process the buckets... */ /* A brigade is chain of bucket pointers. */ /* Brigade pointer passed in = (apr_bucket_brigade *) brigade_in. */ /* Each call to APR_BRIGADE_FOREACH sets 'bucket_in' pointer to */ /* the 'next' bucket in the current brigade... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Entering APR_BRIGADE_FOREACH() loop...",cn); #endif APR_BRIGADE_FOREACH( bucket_in, brigade_in ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: APR_BRIGADE_FOREACH(): Processing next BUCKET",cn); #endif /* Process according to bucket TYPE... */ #ifdef REFERENCE /* The possible brigade bucket types as of 2.0.25... */ /* From ../srclib/apr-util/include/apr_buckets.h */ /* These are read-only macros and safe to call at any time... */ _define APR_BUCKET_IS_FLUSH(e) (e->type == &apr_bucket_type_flush) _define APR_BUCKET_IS_EOS(e) (e->type == &apr_bucket_type_eos) _define APR_BUCKET_IS_FILE(e) (e->type == &apr_bucket_type_file) _define APR_BUCKET_IS_PIPE(e) (e->type == &apr_bucket_type_pipe) _define APR_BUCKET_IS_SOCKET(e) (e->type == &apr_bucket_type_socket) _define APR_BUCKET_IS_HEAP(e) (e->type == &apr_bucket_type_heap) _define APR_BUCKET_IS_TRANSIENT(e) (e->type == &apr_bucket_type_transient) _define APR_BUCKET_IS_IMMORTAL(e) (e->type == &apr_bucket_type_immortal) _define APR_BUCKET_IS_MMAP(e) (e->type == &apr_bucket_type_mmap) _define APR_BUCKET_IS_POOL(e) (e->type == &apr_bucket_type_pool) #endif /* REFERENCE */ #ifdef MOD_GZIP_DEBUG1 #ifdef REFERENCE /* From ../srclib/apr-util/include/apr_bucket.h */ /* APR_BRIGADE_FOREACH() returns an 'apr_bucket' pointer */ /* to the next bucket in the brigade which is going to */ /* allow access to the following... */ struct apr_bucket { APR_RING_ENTRY(apr_bucket) link; /* Links to the rest of the brigade */ const apr_bucket_type_t *type; /* Bucket TYPE info ( See below ) */ apr_size_t length; /* Length of data in the bucket */ apr_off_t start; /* Start of the data in the bucket (offset) */ void *data; /* Type-dependent data for this bucket */ void (*free)(void *e); /* Function used to FREE the bucket */ }; /* The bucket TYPE info is as follows... */ typedef struct apr_bucket_type_t apr_bucket_type_t; struct apr_bucket_type_t { const char *name; /* Bucket type name... */ int num_func; /* Number of functions the bucket 'understands' */ /* Function to free data... */ void (*destroy)(void *data); /* Function to free data */ /* Function to read data into the bucket... */ apr_status_t (*read)(apr_bucket *b, const char **str, apr_size_t *len, apr_read_type_e block); /* Function to set aside data... */ apr_status_t (*setaside)(apr_bucket *e, apr_pool_t *pool); /* Function to split the bucket in two... */ apr_status_t (*split)(apr_bucket *e, apr_size_t point); /* Function to copy the bucket structure ( not the data )... */ apr_status_t (*copy)(apr_bucket *e, apr_bucket **c); }; #endif /* REFERENCE */ /* Show the bucket type NAME and number of functions... */ mod_gzip_printf( "%s: bucket_in->type->name = [%s]", cn,mod_gzip_npp(bucket_in->type->name)); mod_gzip_printf( "%s: bucket_in->type->num_func = %d", cn,(int)bucket_in->type->num_func); #endif /* MOD_GZIP_DEBUG1 */ /* Process the bucket... */ if ( APR_BUCKET_IS_EOS( bucket_in ) ) { /* End Of Stream (EOS) input bucket detected... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: APR_BUCKET_IS_EOS(bucket_in) = TRUE",cn); mod_gzip_printf( "%s: Call bucket_eos = apr_bucket_eos_create()...",cn); #endif bucket_eos = (apr_bucket *) apr_bucket_eos_create( f->c->bucket_alloc); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Back bucket_eos = apr_bucket_eos_create()...",cn); #endif zlib_ctx->strm.avail_in = 0; /* Reset */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: zlib_ctx->strm.avail_in reset to ZERO",cn); mod_gzip_printf( "%s: Entering 'for(;;)' loop...",cn); #endif for (;;) { len = ( MOD_GZIP_ZLIB_BSIZE - zlib_ctx->strm.avail_out ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: TOP of for(;;) loop: len = %ld",cn,(long)len); #endif if ( len != 0 ) { /* Create a new heap output bucket.. */ #ifdef REFERENCE /* From ../srclib/include/apr_bucket.h */ APU_DECLARE(apr_bucket *) apr_bucket_heap_create( const char *buf, /* The data to turn into a HEAP bucket */ apr_size_t nbyte, /* The length of the data */ int copy, /* 1=Copy data to bucket 0=No */ apr_size_t *w /* Number of bytes copied to bucket */ ); #endif /* REFERENCE */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Call bucket_out = apr_bucket_heap_create( zlib_ctx->buffer, len=%ld, 1, &bcopied )...",cn,(long)len); #endif bucket_out = apr_bucket_heap_create( zlib_ctx->buffer, len, NULL, f->c->bucket_alloc); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Back bucket_out = apr_bucket_heap_create( zlib_ctx->buffer, len=%ld, 1, &bcopied )...",cn,(long)len); mod_gzip_printf( "%s: bcopied = %ld",cn,(long)bcopied); mod_gzip_printf( "%s: Call APR_BRIGADE_INSERT_TAIL( brigade_out, bucket_out )...",cn); #endif APR_BRIGADE_INSERT_TAIL( brigade_out, bucket_out ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Back APR_BRIGADE_INSERT_TAIL( brigade_out, bucket_out )...",cn); #endif zlib_ctx->strm.next_out = zlib_ctx->buffer; zlib_ctx->strm.avail_out = MOD_GZIP_ZLIB_BSIZE; #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: 'zlib_ctx->strm.next_out' set to 'zlib_ctx->buffer'",cn); mod_gzip_printf( "%s: 'zlib_ctx->strm.avail_out' set to %ld",cn,(long)zlib_ctx->strm.avail_out); #endif }/* End 'if( len != 0 )' */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: done = %ld",cn,(long)done); #endif if ( done ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: done = %ld = YES",cn,(long)done); mod_gzip_printf( "%s: Issuing 'break'...",cn); #endif break; } /* Compress the next segment... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Call rc = deflate( &zlib_ctx->strm, Z_FINISH )...",cn); #endif rc = deflate( &zlib_ctx->strm, Z_FINISH ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Back rc = deflate( &zlib_ctx->strm, Z_FINISH )...",cn); mod_gzip_printf( "%s: .... rc = %ld",cn,(long)rc); if ( rc == Z_OK ) mod_gzip_printf( "%s: .... rc = Z_OK",cn); else if ( rc == Z_BUF_ERROR ) mod_gzip_printf( "%s: .... rc = Z_BUF_ERROR",cn); else if ( rc == Z_STREAM_END ) mod_gzip_printf( "%s: .... rc = Z_STREAM_END",cn); else mod_gzip_printf( "%s: .... rc = Z_??? (Not Z_OK or Z_BUF_ERROR or Z_STREAM_END)",cn); #endif /* MOD_GZIP_DEBUG1 */ if ( len == 0 && rc == Z_BUF_ERROR ) { rc = Z_OK; #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: WARNING: rc forced to Z_OK",cn); #endif } done = ( zlib_ctx->strm.avail_out != 0 || rc == Z_STREAM_END ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: done = %ld",cn,(long)done); #endif if ( rc != Z_OK && rc != Z_STREAM_END ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: rc != Z_OK && rc != Z_STREAM_END",cn); mod_gzip_printf( "%s: Breaking out of for(;;) loop NOW...",cn); #endif break; } #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Returning to top of for(;;) loop...",cn); #endif }/* End 'for(;;)' loop */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Out of 'for(;;)' loop...",cn); mod_gzip_printf( "%s: zlib_ctx->strm.total_in = %ld",cn,(long)zlib_ctx->strm.total_in); mod_gzip_printf( "%s: zlib_ctx->strm.total_out = %ld",cn,(long)zlib_ctx->strm.total_out); mod_gzip_printf( "%s: zlib_gzip_header_length = %ld",cn,(int)zlib_gzip_header_length); mod_gzip_printf( "%s: zlib_gzip_footer_length = %ld",cn,(int)zlib_gzip_footer_length); mod_gzip_printf( "%s: zlib_ctx->crc = %ld",cn,(long)zlib_ctx->crc); #endif /* Save the stream byte counts to work variables since */ /* the ucpoming bit shifts will change the context values... */ total_bytes_read = (long) zlib_ctx->strm.total_in; total_bytes_written = (long) zlib_ctx->strm.total_out; /* Add the fixed header and footer lengths which are */ /* also added to the output brigade so that the totals */ /* in the logs match the actual output count... */ total_bytes_written += ( zlib_gzip_header_length + zlib_gzip_footer_length ); total_bytes_saved = (long) total_bytes_read - total_bytes_written; /* Prepare the CRC value... */ for ( i=0; i<4; i++) { scrc[i] = (int) ((unsigned long)( zlib_ctx->crc & 0xFF )); zlib_ctx->crc >>= 8; } /* Prepare the OCL ( Original Content Length ) value... */ for ( i=0; i<4; i++) { socl[i] = (int) ((unsigned long)( zlib_ctx->strm.total_in & 0xFF )); zlib_ctx->strm.total_in >>= 8; } /* Create the footer... */ zlib_gzip_footer = apr_psprintf( r->pool, "%c%c%c%c%c%c%c%c", scrc[0], scrc[1], scrc[2], scrc[3], socl[0], socl[1], socl[2], socl[3] ); /* Make an 8 byte bucket out of it... */ bucket_out = apr_bucket_pool_create( zlib_gzip_footer, 8, r->pool , f->c->bucket_alloc); /* Add it to the end of the brigade... */ APR_BRIGADE_INSERT_TAIL( brigade_out, bucket_out ); /* Record results... */ compression_ratio = 0; if ( ( total_bytes_read > 0 ) && ( total_bytes_written > 0 ) ) { compression_ratio = 100 - (int) ( total_bytes_written * 100L / total_bytes_read ); } #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: total_bytes_read = %ld",cn, (long) total_bytes_read ); mod_gzip_printf( "%s: total_bytes_written = %ld",cn, (long) total_bytes_written ); mod_gzip_printf( "%s: total_bytes_saved = %ld",cn, (long) total_bytes_saved ); mod_gzip_printf( "%s: Compression ratio = %ld percent",cn, (long) compression_ratio ); #endif ap_log_rerror( APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r, "mod_gzip: In: %ld Out: %ld Savings: %ld ( %d pct ): URL %s", (long) total_bytes_read, (long) total_bytes_written, (long) total_bytes_saved, (long) compression_ratio, mod_gzip_npp(r->uri) ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: In: %ld Out: %ld Savings: %ld ( %d pct ): URL %s", cn, (long) total_bytes_read, (long) total_bytes_written, (long) total_bytes_saved, (long) compression_ratio, mod_gzip_npp(r->uri) ); #endif /* MOD_GZIP_DEBUG1 */ #ifdef MOD_GZIP_USES_APACHE_LOGS /* If Apache log 'notes' are used then update them */ /* with the final results.. */ /* Let the log reflect what TYPE of request this was... */ if ( r->main ) { apr_table_setn( r->notes,"mod_gzip_result",apr_pstrdup(r->pool,"OK:SUBREQ")); } else if ( r->prev ) { apr_table_setn( r->notes,"mod_gzip_result",apr_pstrdup(r->pool,"OK:REDIR")); } else /* Normally the request will be a 'primary' one... */ { apr_table_setn( r->notes,"mod_gzip_result",apr_pstrdup(r->pool,"OK")); } log_info = apr_psprintf( r->pool, "%ld", (long) total_bytes_read ); apr_table_setn( r->notes,"mod_gzip_input_size", apr_pstrdup(r->pool,log_info)); log_info = apr_psprintf( r->pool, "%ld", (long) total_bytes_written ); apr_table_setn( r->notes,"mod_gzip_output_size",apr_pstrdup(r->pool,log_info)); log_info = apr_psprintf( r->pool, "%ld", (long) compression_ratio ); apr_table_setn( r->notes,"mod_gzip_compression_ratio",apr_pstrdup(r->pool,log_info)); #endif /* MOD_GZIP_USES_APACHE_LOGS */ /* Cleanup... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Call deflateEnd( &zlib_ctx->strm )...",cn); #endif deflateEnd( &zlib_ctx->strm ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Back deflateEnd( &zlib_ctx->strm )...",cn); #endif /* Reset the filter context pointer... */ f->ctx = NULL; /* Add EOS bucket to the output brigade... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Issuing APR_BRIGADE_INSERT_TAIL( brigade_out, bucket_eos )...",cn); #endif APR_BRIGADE_INSERT_TAIL( brigade_out, bucket_eos ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Issuing 'break' because of EOS bucket...",cn); #endif /* When the next bucket type is EOS then we can break */ /* out of the APR_BRIGADE_FOREACH() loop. We are done... */ break; /* Break out of the APR_BRIGADE_FOREACH() loop now */ }/* End 'if ( APR_BUCKET_IS_EOS( bucket_in ) )' */ else if ( APR_BUCKET_IS_FLUSH( bucket_in ) ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: APR_BUCKET_IS_FLUSH( bucket_in ) = TRUE",cn); #endif #ifdef REFERENCE /* From ../srclib/apr-util/buckets/apr_buckets_flush.c */ APU_DECLARE_DATA const apr_bucket_type_t apr_bucket_type_flush = { "FLUSH", 5, apr_bucket_destroy_noop, flush_read, apr_bucket_setaside_noop, apr_bucket_split_notimpl, flush_copy }; #endif /* REFERENCE */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: FLUSH buckets are being ignored at this time.",cn); #endif /* Fall through and loop back to next APR_BRIGADE_FOREACH()... */ } else /* Process DATA bucket... */ { /* Next BUCKET type is not EOS or FLUSH so process the DATA... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Next BUCKET is not EOS or FLUSH...",cn); mod_gzip_printf( "%s: Reading BUCKET data now...",cn); mod_gzip_printf( "%s: read: Call apr_bucket_read( bucket_in, &data, *ilen, APR_BLOCK_READ )...",cn); #endif apr_bucket_read( bucket_in, &idata, &ilen, APR_BLOCK_READ ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: read: Back apr_bucket_read( bucket_in, &idata, *ilen, APR_BLOCK_READ )...",cn); mod_gzip_printf( "%s: read: ilen = %ld",cn,(long)ilen); if ( idata && ( ilen > 0 ) ) { bytes_to_dump = 100; /* Set this to 'ilen' to dump everything */ /* TODO: Loop the dump if ilen > 65k for 1 bucket */ if ( ilen < (unsigned) bytes_to_dump ) bytes_to_dump = (int) ilen; mod_gzip_hexdump( (char *) idata, bytes_to_dump ); } #endif /* MOD_GZIP_DEBUG1 */ zlib_ctx->crc = crc32( zlib_ctx->crc, (const Bytef *) idata, ilen ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: write: Writing bucket data now...",cn); #endif zlib_ctx->strm.next_in = (char *) idata; zlib_ctx->strm.avail_in = ilen; zlib_ctx->strm.next_out = zlib_ctx->buffer; zlib_ctx->strm.avail_out = MOD_GZIP_ZLIB_BSIZE; #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: write: zlib_ctx->strm.avail_in = %ld",cn,(long)zlib_ctx->strm.avail_in); mod_gzip_printf( "%s: write: Entering while( zlib_ctx->strm.avail_in != 0 ) loop...",cn); #endif while ( zlib_ctx->strm.avail_in != 0 ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: write: ",cn); /* Separator */ mod_gzip_printf( "%s: write: Top of while( zlib_ctx->strm.avail_in != 0 ) loop...",cn); mod_gzip_printf( "%s: write: zlib_ctx->strm.avail_in = %ld",cn,(long)zlib_ctx->strm.avail_in); mod_gzip_printf( "%s: write: zlib_ctx->strm.avail_out = %ld",cn,(long)zlib_ctx->strm.avail_out); #endif if ( zlib_ctx->strm.avail_out == 0 ) { zlib_ctx->strm.next_out = zlib_ctx->buffer; len = ( MOD_GZIP_ZLIB_BSIZE - zlib_ctx->strm.avail_out ); /* Create a new heap bucket... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: write: Call bucket_out = apr_bucket_heap_create( zlib_ctx->buffer, len=%ld, 1, &bcopied )...",cn,(long)len); #endif bucket_out = apr_bucket_heap_create( zlib_ctx->buffer, len, NULL, f->c->bucket_alloc); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: write: Back bucket_out = apr_bucket_heap_create( zlib_ctx->buffer, len=%ld, 1, &bcopied )...",cn,(long)len); mod_gzip_printf( "%s: write: bcopied = %ld",cn,(long)bcopied); mod_gzip_printf( "%s: write: Call APR_BRIGADE_INSERT_TAIL( brigade_out, bucket_out )...",cn); #endif APR_BRIGADE_INSERT_TAIL( brigade_out, bucket_out ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: write: Back APR_BRIGADE_INSERT_TAIL( brigade_out, bucket_out )...",cn); mod_gzip_printf( "%s: write: MOD_GZIP_ZLIB_BSIZE = %ld",cn,(long)MOD_GZIP_ZLIB_BSIZE); mod_gzip_printf( "%s: write: Issuing 'zlib_ctx->strm.avail_out = MOD_GZIP_ZLIB_BSIZE'",cn); #endif zlib_ctx->strm.avail_out = MOD_GZIP_ZLIB_BSIZE; #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: write: zlib_ctx->strm.avail_out is now = %ld",cn,(long)zlib_ctx->strm.avail_out); #endif }/* End 'if ( zlib_ctx->strm.avail_out == 0 )' */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: write: Call rc = deflate( &zlib_ctx->strm, Z_NO_FLUSH )...",cn); #endif rc = deflate( &(zlib_ctx->strm), Z_NO_FLUSH ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: write: Back rc = deflate( &zlib_ctx->strm, Z_NO_FLUSH )...",cn); mod_gzip_printf( "%s: write: .... rc = %ld",cn,(long)rc); #endif if ( rc != Z_OK ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: write: ERROR: rc != Z_OK",cn); mod_gzip_printf( "%s: write: Issuing 'break'...",cn); #endif break; /* Break out of 'while()' loop now... */ } }/* End 'while ( zlib_ctx->strm.avail_in != 0 )' */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: write: Out of while( zlib_ctx->strm.avail_in != 0 ) loop...",cn); #endif }/* End 'else( Process DATA bucket )' */ /* Loop back and process the next bucket in the current brigade... */ }/* End of 'APR_BRIGADE_FOREACH( bucket_in, brigade_in )' */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Out of APR_BRIGADE_FOREACH()...",cn); mod_gzip_printf( "%s: Exit > return( ap_pass_brigade( f->next, brigade_out ) ) >",cn); #endif return ap_pass_brigade( f->next, brigade_out ); }/* End of mod_gzip_output_filter() */ /* MODULE INITIALIZATION... */ static void mod_gzip_init( apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *server ) { /* Primary module initialization routine */ int add_version_info = 1; #ifdef MOD_GZIP_DEBUG1 char cn[]="mod_gzip_init()"; #endif mod_gzip_conf *mgc; /* Start... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_server_now = server; mod_gzip_printf( " " ); mod_gzip_printf( "%s: Entry...", cn ); #endif mgc = ( mod_gzip_conf * ) ap_get_module_config( server->module_config, &gzip_module ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: MODULE_MAGIC_NUMBER = %ld", cn, (long) MODULE_MAGIC_NUMBER ); #endif if ( add_version_info ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: add_version_info = TRUE", cn ); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Call ap_add_version_component(p,%s)...", cn, mod_gzip_npp(MOD_GZIP_VERSION_INFO_STRING)); #endif /* Apache 2.0 has added 'pool' pointer to the version API call... */ ap_add_version_component( p, MOD_GZIP_VERSION_INFO_STRING ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Back ap_add_version_component(p,%s)...", cn, mod_gzip_npp(MOD_GZIP_VERSION_INFO_STRING)); #endif } #ifdef MOD_GZIP_DEBUG1 else { mod_gzip_printf( "%s: add_version_info = FALSE", cn ); mod_gzip_printf( "%s: ap_add_version_component() NOT called.", cn ); } #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Initialization completed...", cn ); mod_gzip_printf( "%s: Exit > return( void ) >", cn ); mod_gzip_printf( " " ); #endif }/* End of mod_gzip_init() */ /* PRIMARY MODULE HANDLER... */ static int mod_gzip_handler( request_rec *r ) { mod_gzip_conf *mgc; /* Location/Directory configuration */ #ifdef MOD_GZIP_DEBUG1 char cn[]="mod_gzip_handler()"; #endif /* Start... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_server_now = r->server; mod_gzip_printf( " " ); mod_gzip_printf( "%s: **** Entry...",cn); mod_gzip_printf( "%s: r = %ld", cn,(long)r); mod_gzip_printf( "%s: r->main = %ld", cn,(long)r->main); mod_gzip_printf( "%s: r->next = %ld", cn,(long)r->next); mod_gzip_printf( "%s: r->prev = %ld", cn,(long)r->prev); mod_gzip_printf( "%s: r->unparsed_uri = [%s]",cn,mod_gzip_npp(r->unparsed_uri)); mod_gzip_printf( "%s: r->uri = [%s]",cn,mod_gzip_npp(r->uri)); mod_gzip_printf( "%s: r->filename = [%s]",cn,mod_gzip_npp(r->filename)); mod_gzip_printf( "%s: r->handler = [%s]",cn,mod_gzip_npp(r->handler)); #endif mgc = ( mod_gzip_conf * ) ap_get_module_config( r->per_dir_config, &gzip_module ); #ifdef MOD_GZIP_COMMAND_VERSION_USED /* NOTE: Certain mod_gzip 'commands' should return a response */ /* even if mod_gzip is OFF in the current location. Make sure */ /* the checks for these commands take place BEFORE checking */ /* the actual mod_gzip on/off status... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: mgc->command_version = [%s]", cn,mod_gzip_npp(mgc->command_version)); #endif /* NOTE: Check for mod_gzip commands in the 'r->unparsed_uri' request */ /* line so the commands can actually be part of query parms that */ /* follow the '?'. 'r->uri' is simply he URI itself with any/all */ /* additional query arguments removed already... */ if ( mgc->command_version[0] != 0 ) { if ( mod_gzip_stringcontains( r->unparsed_uri, mgc->command_version ) ) { #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Call mod_gzip_do_command( MOD_GZIP_COMMAND_VERSION, r )...",cn); #endif /* mod_gzip_do_command() returns the correct command */ /* response page and (normally) just returns 'OK'... */ mod_gzip_do_command( MOD_GZIP_COMMAND_VERSION, r, mgc ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Back mod_gzip_do_command( MOD_GZIP_COMMAND_VERSION, r )...",cn); mod_gzip_printf( "%s: Exit > return( OK ) >",cn); #endif /* This transaction has been handled so return OK... */ return OK; }/* End 'if ( mod_gzip_stringcontains(...))' */ }/* if ( mgc->command_version[0] != 0 ) */ #endif /* MOD_GZIP_COMMAND_VERSION_USED */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Exit > return( DECLINED ) >",cn); #endif return DECLINED; }/* End of mod_gzip_handler() */ #define MOD_GZIP_HOOKALL1 #ifdef MOD_GZIP_HOOKALL1 /* Hook all the Apache 2.0 user exits... */ int mod_gzip_post_read_request( request_rec *r ) { /* [1] post read_request handling ap_hook_post_read_request( mod_gzip_post_read_request, NULL, NULL, APR_HOOK_MIDDLE); */ #ifdef MOD_GZIP_DEBUG1 char cn[]="mod_gzip_post_read_request()"; #endif /* Start... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Entry...",cn); mod_gzip_printf( "%s: r->unparsed_uri = [%s]",cn,r->unparsed_uri); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Exit > return( DECLINED ) >",cn); #endif return DECLINED; }/* End of mod_gzip_post_read_request() */ int mod_gzip_translate_name( request_rec *r ) { /* [2] filename-to-URI translation ap_hook_translate_name(mod_gzip_translate_name, NULL, NULL, APR_HOOK_MIDDLE); */ #ifdef MOD_GZIP_DEBUG1 char cn[]="mod_gzip_translate_name()"; #endif /* Start... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Entry...",cn); mod_gzip_printf( "%s: r->unparsed_uri = [%s]",cn,r->unparsed_uri); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Exit > return( DECLINED ) >",cn); #endif return DECLINED; }/* End of mod_gzip_translate_name() */ int mod_gzip_header_parser( request_rec *r ) { /* [3] header parser ap_hook_header_parser(mod_gzip_header_parser, NULL, NULL, APR_HOOK_MIDDLE); */ #ifdef MOD_GZIP_DEBUG1 char cn[]="mod_gzip_header_parser()"; #endif /* Start... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Entry...",cn); mod_gzip_printf( "%s: r->unparsed_uri = [%s]",cn,r->unparsed_uri); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Exit > return( DECLINED ) >",cn); #endif return DECLINED; }/* End of mod_gzip_header_parser() */ int mod_gzip_access_checker( request_rec *r ) { /* [4] check access by host address ap_hook_access_checker(mod_gzip_access_checker, NULL, NULL, APR_HOOK_MIDDLE); */ #ifdef MOD_GZIP_DEBUG1 char cn[]="mod_gzip_access_checker()"; #endif /* Start... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Entry...",cn); mod_gzip_printf( "%s: r->unparsed_uri = [%s]",cn,r->unparsed_uri); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Exit > return( DECLINED ) >",cn); #endif return DECLINED; }/* End of mod_gzip_access_checker() */ int mod_gzip_check_user_id( request_rec *r ) { /* [5] check/validate user_id ap_hook_check_user_id(mod_gzip_check_user_id, NULL, NULL, APR_HOOK_MIDDLE); */ #ifdef MOD_GZIP_DEBUG1 char cn[]="mod_gzip_check_user_id()"; #endif /* Start... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Entry...",cn); mod_gzip_printf( "%s: r->unparsed_uri = [%s]",cn,r->unparsed_uri); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Exit > return( DECLINED ) >",cn); #endif return DECLINED; }/* End of mod_gzip_check_user_id() */ int mod_gzip_auth_checker( request_rec *r ) { /* [6] check user_id is valid *here* ap_hook_auth_checker(mod_gzip_auth_checker, NULL, NULL, APR_HOOK_MIDDLE); */ #ifdef MOD_GZIP_DEBUG1 char cn[]="mod_gzip_auth_checker()"; #endif /* Start... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Entry...",cn); mod_gzip_printf( "%s: r->unparsed_uri = [%s]",cn,r->unparsed_uri); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Exit > return( DECLINED ) >",cn); #endif return DECLINED; }/* End of mod_gzip_auth_checker() */ int mod_gzip_type_checker( request_rec *r ) { /* [7] MIME type checker/setter ap_hook_type_checker(mod_gzip_type_checker, NULL, NULL, APR_HOOK_MIDDLE); */ #ifdef MOD_GZIP_DEBUG1 char cn[]="mod_gzip_type_checker()"; #endif /* Start... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Entry...",cn); mod_gzip_printf( "%s: r->unparsed_uri = [%s]",cn,r->unparsed_uri); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Exit > return( DECLINED ) >",cn); #endif return DECLINED; }/* End of mod_gzip_type_checker() */ int mod_gzip_fixer_upper( request_rec *r ) { /* [8] fixups ap_hook_fixups(mod_gzip_fixer_upper, NULL, NULL, APR_HOOK_MIDDLE); */ #ifdef MOD_GZIP_DEBUG1 char cn[]="mod_gzip_fixer_upper()"; #endif /* Start... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Entry...",cn); mod_gzip_printf( "%s: r->unparsed_uri = [%s]",cn,r->unparsed_uri); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Exit > return( DECLINED ) >",cn); #endif return DECLINED; }/* End of mod_gzip_fixer_upper() */ /* [9] is for the handlers; see below */ int mod_gzip_logger( request_rec *r ) { /* [10] logger ap_hook_log_transaction(mod_gzip_logger, NULL, NULL, APR_HOOK_MIDDLE); */ #ifdef MOD_GZIP_DEBUG1 char cn[]="mod_gzip_logger()"; #endif /* Start... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Entry...",cn); mod_gzip_printf( "%s: r->unparsed_uri = [%s]",cn,r->unparsed_uri); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Exit > return( DECLINED ) >",cn); #endif return DECLINED; }/* End of mod_gzip_logger() */ static void mod_gzip_child_init(apr_pool_t *p, server_rec *s) { /* process initializer ap_hook_child_init(mod_gzip_child_init, NULL, NULL, APR_HOOK_MIDDLE); */ /* This HOOK does not supply a 'request' record... */ #ifdef MOD_GZIP_DEBUG1 char cn[]="mod_gzip_child_init()"; #endif /* Start... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Entry...",cn); mod_gzip_printf( "%s: server_rec *s = %ld",cn,(long) s ); #endif #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Exit > return( VOID ) >",cn); #endif return; /* VOID return */ }/* End of mod_gzip_child_init() */ #endif /* MOD_GZIP_HOOKALL1 */ /* Apache 2.x hook registration(s)... */ static void mod_gzip_register_hooks(apr_pool_t * p) { #ifdef MOD_GZIP_DEBUG1 char cn[]="mod_gzip_register_hooks()"; #endif /* Start... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Entry...",cn); mod_gzip_printf( "%s: Call ap_hook_post_config (mod_gzip_init,NULL,NULL,APR_HOOK_MIDDLE)...",cn); #endif /* Equivalent of pre-2.0 'init' hook... */ ap_hook_post_config(mod_gzip_init, NULL, NULL, APR_HOOK_MIDDLE); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Back ap_hook_post_config (mod_gzip_init,NULL,NULL,APR_HOOK_MIDDLE)...",cn); mod_gzip_printf( "%s: Call ap_hook_type_checker(mod_gzip_type_checker,NULL,NULL,APR_HOOK_MIDDLE)...",cn); #endif /* Equivalent of pre-2.0 'type checker' hook... */ /* WARNING: The type_checker hook should fire right after */ /* the 'access_checker' hook but if you use APR_HOOK_MIDDLE */ /* you might not get called because the built in system */ /* type_checker ( or other installed type_checkers ) might */ /* deny other type_checker hooks from running. Use APR_HOOK_FIRST */ /* Might not get called... ap_hook_type_checker(mod_gzip_type_checker, NULL, NULL, APR_HOOK_MIDDLE); */ /* APR_HOOK_FIRST should guarantee that it gets called... */ ap_hook_type_checker(mod_gzip_type_checker, NULL, NULL, APR_HOOK_FIRST); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Back ap_hook_type_checker(mod_gzip_type_checker,NULL,NULL,APR_HOOK_MIDDLE)...",cn); #endif /* MAIN HANDLER */ /* With Apache 2.x we just call ap_hook_handler() to register */ /* the main 'handler' callback for this module. 'handler_rec' */ /* is not used anymore to define the 'handler' callback... */ #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Call ap_hook_handler(mod_gzip_handler,NULL,NULL,APR_HOOK_MIDDLE)...",cn); #endif ap_hook_handler( mod_gzip_handler, NULL, NULL, APR_HOOK_MIDDLE ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Back ap_hook_handler(mod_gzip_handler,NULL,NULL,APR_HOOK_MIDDLE)...",cn); #endif /* EXTRA HANDLERS ( FUTURE USE )... */ #ifdef MOD_GZIP_HOOKALL1 #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: HOOKALL1 is defined...",cn); mod_gzip_printf( "%s: Establishing hooks for all user exits...",cn); #endif /* [1] post read_request handling */ ap_hook_post_read_request( mod_gzip_post_read_request, NULL, NULL, APR_HOOK_MIDDLE); /* [2] filename-to-URI translation */ ap_hook_translate_name(mod_gzip_translate_name, NULL, NULL, APR_HOOK_MIDDLE); /* [3] header parser */ ap_hook_header_parser(mod_gzip_header_parser, NULL, NULL, APR_HOOK_MIDDLE); /* [4] check access by host address */ ap_hook_access_checker(mod_gzip_access_checker, NULL, NULL, APR_HOOK_MIDDLE); /* [5] check/validate user_id */ ap_hook_check_user_id(mod_gzip_check_user_id, NULL, NULL, APR_HOOK_MIDDLE); /* [6] check user_id is valid *here* */ ap_hook_auth_checker(mod_gzip_auth_checker, NULL, NULL, APR_HOOK_MIDDLE); /* [7] MIME type checker/setter */ ap_hook_type_checker(mod_gzip_type_checker, NULL, NULL, APR_HOOK_MIDDLE); /* [8] fixups */ ap_hook_fixups(mod_gzip_fixer_upper, NULL, NULL, APR_HOOK_MIDDLE); /* [9] is for the handlers; see below */ /* [10] logger */ ap_hook_log_transaction(mod_gzip_logger, NULL, NULL, APR_HOOK_MIDDLE); /* Process initializer */ ap_hook_child_init(mod_gzip_child_init, NULL, NULL, APR_HOOK_MIDDLE); #endif /* MOD_GZIP_HOOKALL1 */ /* Apache 2.x output filter insertion hook... */ ap_hook_insert_filter( mod_gzip_insert_output_filter, NULL, NULL, APR_HOOK_MIDDLE ); /* Apache 2.x output filter registration... */ ap_register_output_filter( mod_gzip_filter_name, mod_gzip_output_filter, AP_FTYPE_CONTENT_SET ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: Exit > return( void ) >",cn); #endif return; /* VOID return */ }/* End of mod_gzip_register_hooks() */ int mod_gzip_set_defaults1( mod_gzip_conf *cfg ) { int i; cfg->is_on = 0; cfg->is_on_set = 0; cfg->keep_workfiles = 0; cfg->keep_workfiles_set = 0; cfg->add_header_count = 0; cfg->add_header_count_set = 0; cfg->dechunk = 0; cfg->dechunk_set = 0; cfg->min_http = 0; cfg->min_http_set = 0; cfg->minimum_file_size = 300; cfg->minimum_file_size_set = 0; cfg->maximum_file_size = 0; cfg->maximum_file_size_set = 0; cfg->maximum_inmem_size = 0; cfg->maximum_inmem_size_set = 0; cfg->deflate_compression_level = MOD_GZIP_DEFLATE_DEFAULT_COMPRESSION_LEVEL; cfg->deflate_compression_level_set = 0; #ifdef WIN32 mod_gzip_strcpy( cfg->temp_dir, "c:\\temp\\" ); #else mod_gzip_strcpy( cfg->temp_dir, "/tmp/" ); #endif cfg->temp_dir_set = 0; cfg->imap_total_entries = 0; cfg->imap_total_ismime = 0; cfg->imap_total_isfile = 0; cfg->imap_total_isuri = 0; cfg->imap_total_ishandler = 0; cfg->imap_total_isreqheader = 0; cfg->imap_total_isrspheader = 0; for ( i=0; iimap[i]), 0, mod_gzip_imap_size ); } #ifdef MOD_GZIP_COMMAND_VERSION_USED memset( cfg->command_version, 0, MOD_GZIP_COMMAND_VERSION_MAXLEN ); cfg->command_version_set = 0; #endif #ifdef MOD_GZIP_CAN_NEGOTIATE cfg->can_negotiate = 0; cfg->can_negotiate_set = 0; #endif return 0; } int mod_gzip_merge1( apr_pool_t *p, mod_gzip_conf *merged_config, mod_gzip_conf *pconf, mod_gzip_conf *nconf ) { #ifdef MOD_GZIP_DEBUG1 char cn[]="mod_gzip_merge1():::::::"; char ch1 = 0; #endif char *p1 = 0; char *p2 = 0; int i = 0; int ii = 0; int l1 = 0; int l2 = 0; int match = 0; int total = 0; int total_ismime = 0; int total_isfile = 0; int total_isuri = 0; int total_ishandler = 0; int total_isreqheader = 0; int total_isrspheader = 0; #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( " "); mod_gzip_printf( "%s: ",cn); #endif #ifdef MOD_GZIP_DEBUG1 if ( nconf->is_on_set ) { merged_config->is_on = nconf->is_on; ch1='!'; } else { merged_config->is_on = pconf->is_on; ch1='='; } mod_gzip_printf( "%s: pconf %c= nconf : merged_config->is_on = %ld", cn, ch1, (long) merged_config->is_on ); #else merged_config->is_on = ( nconf->is_on_set) ? nconf->is_on : pconf->is_on; #endif #ifdef MOD_GZIP_DEBUG1 if ( pconf->cmode == nconf->cmode ) { merged_config->cmode = pconf->cmode; ch1='='; } else { merged_config->cmode = MOD_GZIP_CONFIG_MODE_COMBO; ch1='!'; } mod_gzip_printf( "%s: pconf %c= nconf : merged_config->cmode = %ld", cn, ch1, (long) merged_config->cmode ); #else merged_config->cmode = (pconf->cmode == nconf->cmode) ? pconf->cmode : MOD_GZIP_CONFIG_MODE_COMBO; #endif merged_config->loc = (char *) apr_pstrdup( p, nconf->loc ); #ifdef MOD_GZIP_DEBUG1 mod_gzip_printf( "%s: .............. : merged_config->loc = [%s]", cn, mod_gzip_npp(merged_config->loc)); #endif #ifdef MOD_GZIP_DEBUG1 if ( !nconf->add_header_count_set ) { merged_config->add_header_count = pconf->add_header_count; ch1='='; } else { merged_config->add_header_count = nconf->add_header_count; ch1='!'; } mod_gzip_printf( "%s: pconf %c= nconf : merged_config->add_header_count = %ld", cn, ch1, (long) merged_config->add_header_count ); #else merged_config->add_header_count = ( !nconf->add_header_count_set ) ? pconf->add_header_count : nconf->add_header_count; #endif #ifdef MOD_GZIP_DEBUG1 if ( !nconf->keep_workfiles_set ) { merged_config->keep_workfiles = pconf->keep_workfiles; ch1='='; } else { merged_config->keep_workfiles = nconf->keep_workfiles; ch1='!'; } mod_gzip_printf( "%s: pconf %c= nconf : merged_config->keep_workfiles = %ld", cn, ch1, (long) merged_config->keep_workfiles ); #else merged_config->keep_workfiles = ( !nconf->keep_workfiles_set ) ? pconf->keep_workfiles : nconf->keep_workfiles; #endif #ifdef MOD_GZIP_CAN_NEGOTIATE #ifdef MOD_GZIP_DEBUG1 if ( !nconf->can_negotiate_set ) { merged_config->can_negotiate = pconf->can_negotiate; ch1='='; } else { merged_config->can_negotiate = nconf->can_negotiate; ch1='!'; } mod_gzip_printf( "%s: pconf %c= nconf : merged_config->can_negotiate = %ld", cn, ch1, (long) merged_config->can_negotiate ); #else merged_config->can_negotiate = ( !nconf->can_negotiate_set ) ? pconf->can_negotiate : nconf->can_negotiate; #endif #endif #ifdef MOD_GZIP_DEBUG1 if ( !nconf->dechunk_set ) { merged_config->dechunk = pconf->dechunk; ch1='='; } else { merged_config->dechunk = nconf->dechunk; ch1='!'; } mod_gzip_printf( "%s: pconf %c= nconf : merged_config->dechunk = %ld", cn, ch1, (long) merged_config->dechunk ); #else merged_config->dechunk = ( !nconf->dechunk_set ) ? pconf->dechunk : nconf->dechunk; #endif #ifdef MOD_GZIP_DEBUG1 if ( !nconf->min_http_set ) { merged_config->min_http = pconf->min_http; ch1='='; } else { merged_config->min_http = nconf->min_http; ch1='!'; } mod_gzip_printf( "%s: pconf %c= nconf : merged_config->min_http = %ld", cn, ch1, (long) merged_config->min_http ); #else merged_config->min_http = ( !nconf->min_http_set ) ? pconf->min_http : nconf->min_http; #endif #ifdef MOD_GZIP_DEBUG1 if ( !nconf->minimum_file_size_set ) { merged_config->minimum_file_size = pconf->minimum_file_size; ch1='='; } else { merged_config->minimum_file_size = nconf->minimum_file_size; ch1='!'; } mod_gzip_printf( "%s: pconf %c= nconf : merged_config->minimum_file_size = %ld", cn, ch1, (long) merged_config->minimum_file_size ); #else merged_config->minimum_file_size = ( !nconf->minimum_file_size_set ) ? pconf->minimum_file_size : nconf->minimum_file_size; #endif #ifdef MOD_GZIP_DEBUG1 if ( !nconf->maximum_file_size_set ) { merged_config->maximum_file_size = pconf->maximum_file_size; ch1='='; } else { merged_config->maximum_file_size = nconf->maximum_file_size; ch1='!'; } mod_gzip_printf( "%s: pconf %c= nconf : merged_config->maximum_file_size = %ld", cn, ch1, (long) merged_config->maximum_file_size ); #else merged_config->maximum_file_size = ( !nconf->maximum_file_size_set ) ? pconf->maximum_file_size : nconf->maximum_file_size; #endif #ifdef MOD_GZIP_DEBUG1 if ( !nconf->maximum_inmem_size_set ) { merged_config->maximum_inmem_size = pconf->maximum_inmem_size; ch1='='; } else { merged_config->maximum_inmem_size = nconf->maximum_inmem_size; ch1='!'; } mod_gzip_printf( "%s: pconf %c= nconf : merged_config->maximum_inmem_size = %ld", cn, ch1, (long) merged_config->maximum_inmem_size ); #else merged_config->maximum_inmem_size = ( !nconf->maximum_inmem_size_set ) ? pconf->maximum_inmem_size : nconf->maximum_inmem_size; #endif #ifdef MOD_GZIP_DEBUG1 if ( !nconf->deflate_compression_level_set ) { merged_config->deflate_compression_level = pconf->deflate_compression_level; ch1='='; } else { merged_config->deflate_compression_level = nconf->deflate_compression_level; ch1='!'; } mod_gzip_printf( "%s: pconf %c= nconf : merged_config->deflate_compression_level = %ld", cn, ch1, (long) merged_config->deflate_compression_level ); #else merged_config->deflate_compression_level = ( !nconf->deflate_compression_level_set ) ? pconf->deflate_compression_level : nconf->deflate_compression_level; #endif #ifdef MOD_