/* ====================================================================
 * 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
 * <http://www.apache.org/>.
 *
 * 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 <sys/stat.h> /* 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<len1; i++ )
    {
     if ( ( *s1 == 0 ) || ( *s2 == 0 ) ) return( 1 ); 

     ch1 = *s1;
     ch2 = *s2;

     if ( ch1 == '/' ) ch1 = '\\';
     if ( ch2 == '/' ) ch2 = '\\';

     if ( ch1 != ch2 ) return 1;

     s1++;
     s2++;
    }

 return 0;
}

int mod_gzip_strnicmp( char *s1, char *s2, int len1 )
{
 int  i;
 char ch1;
 char ch2;

 if ( ( s1 == 0 ) || ( s2 == 0 ) )
   {
    return 1;
   }

 for ( i=0; i<len1; i++ )
    {
     if ( ( *s1 == 0 ) || ( *s2 == 0 ) ) return( 1 ); 

     ch1 = *s1;
     ch2 = *s2;

     if ( ch1 > 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<buflen; i++ )
    {
     ch1 = (char) *buffer++;

     #define DUMPIT_ASTERISK    42
     #define DUMPIT_LAPOSTROPHE 96
     #define DUMPIT_RAPOSTROPHE 39
     #define DUMPIT_PERIOD      46
     #define DUMPIT_CR          67
     #define DUMPIT_LF          76

     #ifdef MASK_ONLY_CERTAIN_CHARS
          if ( ch1 ==  0 ) ch2 = DUMPIT_PERIOD;
     else if ( ch1 == 13 ) ch2 = DUMPIT_CR;
     else if ( ch1 == 10 ) ch2 = DUMPIT_LF;
     else if ( ch1 ==  9 ) ch2 = DUMPIT_LAPOSTROPHE;
     else                  ch2 = ch1;
     #endif

     #define MASK_ALL_NON_PRINTABLE_CHARS
     #ifdef  MASK_ALL_NON_PRINTABLE_CHARS

          if ( ch1 == 13 ) ch2 = DUMPIT_CR;
     else if ( ch1 == 10 ) ch2 = DUMPIT_LF;
     else if ( ch1 <  32 ) ch2 = DUMPIT_PERIOD;
     else if ( ch1 >  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; pass<passes; pass++ )
    {
     pass_result = 0;

     #ifdef MOD_GZIP_DEBUG1_VALIDATE1_VERBOSE1
     #ifdef MOD_GZIP_DEBUG1
     mod_gzip_printf( "%s: ",cn);
     #endif
     #endif

     filter_value = pass;

     #ifdef MOD_GZIP_DEBUG1_VALIDATE1_VERBOSE1
     #ifdef MOD_GZIP_DEBUG1
     mod_gzip_printf( "%s: pass         = %d", cn, pass );
     mod_gzip_printf( "%s: filter_value = %d", cn, filter_value );
     mod_gzip_printf( "%s: mgc->imap_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<passes; pass++ )' */
       
 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_printf( "%s: item_is_excluded = %d",cn,item_is_excluded);
 mod_gzip_printf( "%s: item_is_included = %d",cn,item_is_included);
 #endif

 if ( item_is_excluded )
   {
    #ifdef MOD_GZIP_DEBUG1
    mod_gzip_printf( "%s: The item is EXCLUDED...",cn);
    mod_gzip_printf( "%s: Exit > 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,
    "<html><body>"
    "mod_gzip is available...<br>\r\n"
    "mod_gzip_version = %s<br>\r\n"
    "mod_gzip_on = %s<br>\r\n"
    "</body></html>",
    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; i<MOD_GZIP_IMAP_MAXNAMES; i++ )
    {
     memset( &(cfg->imap[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_GZIP_DEBUG1
 if ( !nconf->temp_dir_set ) 
      { mod_gzip_strcpy(merged_config->temp_dir,pconf->temp_dir); ch1='='; }
 else { mod_gzip_strcpy(merged_config->temp_dir,nconf->temp_dir); ch1='!'; }
 mod_gzip_printf( "%s: pconf %c= nconf : merged_config->temp_dir           = [%s]", cn, ch1,mod_gzip_npp(merged_config->temp_dir));
 #else
 if ( !nconf->temp_dir_set ) 
      { mod_gzip_strcpy(merged_config->temp_dir,pconf->temp_dir); }
 else { mod_gzip_strcpy(merged_config->temp_dir,nconf->temp_dir); }
 #endif

 #ifdef MOD_GZIP_COMMAND_VERSION_USED
 #ifdef MOD_GZIP_DEBUG1
 if ( !nconf->command_version_set )
      { mod_gzip_strcpy(merged_config->command_version,pconf->command_version); ch1='='; }
 else { mod_gzip_strcpy(merged_config->command_version,nconf->command_version); ch1='!'; }
 mod_gzip_printf( "%s: pconf %c= nconf : merged_config->command_version    = [%s]", cn, ch1,mod_gzip_npp(merged_config->command_version));
 #else
 if ( !nconf->command_version_set )
      { mod_gzip_strcpy(merged_config->command_version,pconf->command_version); }
 else { mod_gzip_strcpy(merged_config->command_version,nconf->command_version); }
 #endif
 #endif

 total = 0; 

 for ( i=0; i<nconf->imap_total_entries; i++ )
    {
     memcpy(
     &(merged_config->imap[i]),
     &(nconf->imap[i]),
     mod_gzip_imap_size
     );

     total++; 

     if ( nconf->imap[i].type == MOD_GZIP_IMAP_ISMIME )
       {
        total_ismime++;
       }
     else if ( nconf->imap[i].type == MOD_GZIP_IMAP_ISFILE )
       {
        total_isfile++;
       }
     else if ( nconf->imap[i].type == MOD_GZIP_IMAP_ISURI )
       {
        total_isuri++;
       }
     else if ( nconf->imap[i].type == MOD_GZIP_IMAP_ISHANDLER )
       {
        total_ishandler++;
       }
     else if ( nconf->imap[i].type == MOD_GZIP_IMAP_ISREQHEADER )
       {
        total_isreqheader++;
       }
     else if ( nconf->imap[i].type == MOD_GZIP_IMAP_ISRSPHEADER )
       {
        total_isrspheader++;
       }
    }

 for ( i=0; i<pconf->imap_total_entries; i++ )
    {
     p1 = pconf->imap[i].name;
     l1 = mod_gzip_strlen( p1 );

     match = -1; 

     for ( ii=0; ii<nconf->imap_total_entries; ii++ )
        {
         p2 = nconf->imap[ii].name;
         l2 = nconf->imap[ii].namelen;

         if ( l1 == l2 ) 
           {
            if ( mod_gzip_strncmp( p1, p2, l1 ) == 0 )
              {
               match = ii; 

               break; 
              }
           }
        }

     if ( match != -1 )
       {
        /* Skip ahead... */
       }
     else 
       {
        if ( total < MOD_GZIP_IMAP_MAXNAMES ) 
          {
           memcpy(
           &(merged_config->imap[ total ]),
           &(pconf->imap[i]),
           mod_gzip_imap_size
           );

           total++; 

           if ( pconf->imap[i].type == MOD_GZIP_IMAP_ISMIME )
             {
              total_ismime++;
             }
           else if ( pconf->imap[i].type == MOD_GZIP_IMAP_ISFILE )
             {
              total_isfile++;
             }
           else if ( pconf->imap[i].type == MOD_GZIP_IMAP_ISURI )
             {
              total_isuri++;
             }
           else if ( pconf->imap[i].type == MOD_GZIP_IMAP_ISHANDLER )
             {
              total_ishandler++;
             }
           else if ( pconf->imap[i].type == MOD_GZIP_IMAP_ISREQHEADER )
             {
              total_isreqheader++;
             }
           else if ( pconf->imap[i].type == MOD_GZIP_IMAP_ISRSPHEADER )
             {
              total_isrspheader++;
             }
          }
       }
    }

 merged_config->imap_total_entries     = total;
 merged_config->imap_total_ismime      = total_ismime;
 merged_config->imap_total_isfile      = total_isfile;
 merged_config->imap_total_isuri       = total_isuri;
 merged_config->imap_total_ishandler   = total_ishandler;
 merged_config->imap_total_isreqheader = total_isreqheader;
 merged_config->imap_total_isrspheader = total_isrspheader;

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_printf( "%s: pconf += nconf : merged_config->imap_total_entries     = %ld", cn, (long) merged_config->imap_total_entries );
 mod_gzip_printf( "%s: pconf += nconf : merged_config->imap_total_ismime      = %ld", cn, (long) merged_config->imap_total_ismime );
 mod_gzip_printf( "%s: pconf += nconf : merged_config->imap_total_isfile      = %ld", cn, (long) merged_config->imap_total_isfile );
 mod_gzip_printf( "%s: pconf += nconf : merged_config->imap_total_isuri       = %ld", cn, (long) merged_config->imap_total_isuri );
 mod_gzip_printf( "%s: pconf += nconf : merged_config->imap_total_ishandler   = %ld", cn, (long) merged_config->imap_total_ishandler );
 mod_gzip_printf( "%s: pconf += nconf : merged_config->imap_total_isreqheader = %ld", cn, (long) merged_config->imap_total_isreqheader );
 mod_gzip_printf( "%s: pconf += nconf : merged_config->imap_total_isrspheader = %ld", cn, (long) merged_config->imap_total_isrspheader );
 #endif

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_printf( "%s: ",cn); 
 #endif

 return 0;
}

static const char *
mod_gzip_set_is_on(
cmd_parms *parms, void *cfg, const char *arg )
{
 mod_gzip_conf *mgc;

 #ifdef MOD_GZIP_DEBUG1
 server_rec *srv = parms->server;
 char cn[]="mod_gzip_set_is_on()";
 #endif

 #ifdef MOD_GZIP_DEBUG1

 mod_gzip_server_now = srv;

 mod_gzip_printf( " ");
 mod_gzip_printf( "%s: Entry", cn );
 mod_gzip_printf( "%s: arg=[%s]", cn, mod_gzip_npp(arg) );

 #endif

 mgc = ( mod_gzip_conf * ) cfg;

 if ( ( arg[0] == 'Y' )||( arg[0] == 'y' ) )
   {
    mgc->is_on = 1;
   }
 else
   {
    mgc->is_on = 0;
   }

 mgc->is_on_set = 1;

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_printf( "%s: mgc->loc             = [%s]", cn, mod_gzip_npp(mgc->loc));
 mod_gzip_printf( "%s: srv->is_virtual      = %ld",  cn, (long)srv->is_virtual );
 mod_gzip_printf( "%s: srv->server_hostname = [%s]", cn, mod_gzip_npp(srv->server_hostname));
 mod_gzip_printf( "%s: mgc->cmode           = %ld",  cn, (long) mgc->cmode );
 mod_gzip_printf( "%s: mgc->is_on           = %ld",  cn, (long) mgc->is_on );
 mod_gzip_printf( "%s: mgc->is_on_set       = %ld",  cn, (long) mgc->is_on_set );
 #endif

 return NULL;
}

static const char *
mod_gzip_set_add_header_count(
cmd_parms *parms, void *cfg, const char *arg )
{
 mod_gzip_conf *mgc;

 #ifdef MOD_GZIP_DEBUG1
 server_rec *srv = parms->server;
 char cn[]="mod_gzip_set_add_header_count()";
 #endif

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_server_now = srv;
 mod_gzip_printf( " ");
 mod_gzip_printf( "%s: Entry", cn );
 mod_gzip_printf( "%s: arg=[%s]", cn, mod_gzip_npp(arg) );
 #endif

 mgc = ( mod_gzip_conf * ) cfg;

 if ( ( arg[0] == 'Y' )||( arg[0] == 'y' ) )
   {
    mgc->add_header_count = 1;
   }
 else
   {
    mgc->add_header_count = 0;
   }

 mgc->add_header_count_set = 1;

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_printf( "%s: mgc->loc                  = [%s]",cn, mod_gzip_npp(mgc->loc));
 mod_gzip_printf( "%s: mgc->cmode                = %ld", cn, (long) mgc->cmode );
 mod_gzip_printf( "%s: srv->is_virtual           = %ld", cn, (long)srv->is_virtual );
 mod_gzip_printf( "%s: srv->server_hostname      = [%s]",cn, mod_gzip_npp(srv->server_hostname));
 mod_gzip_printf( "%s: mgc->add_header_count     = %ld", cn,
                (long) mgc->add_header_count );
 mod_gzip_printf( "%s: mgc->add_header_count_set = %ld", cn,
                (long) mgc->add_header_count_set );
 #endif

 return NULL;
}

static const char *
mod_gzip_set_keep_workfiles(
cmd_parms *parms, void *cfg, const char *arg )
{
 mod_gzip_conf *mgc;

 #ifdef MOD_GZIP_DEBUG1
 server_rec *srv = parms->server;
 char cn[]="mod_gzip_set_keep_workfiles()";
 #endif

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_server_now = srv;
 mod_gzip_printf( " ");
 mod_gzip_printf( "%s: Entry", cn );
 mod_gzip_printf( "%s: arg=[%s]", cn, mod_gzip_npp(arg) );
 #endif

 mgc = ( mod_gzip_conf * ) cfg;

 if ( ( arg[0] == 'Y' )||( arg[0] == 'y' ) )
   {
    mgc->keep_workfiles = 1;
   }
 else
   {
    mgc->keep_workfiles = 0;
   }

 mgc->keep_workfiles_set = 1;

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_printf( "%s: mgc->loc                = [%s]",cn, mod_gzip_npp(mgc->loc) );
 mod_gzip_printf( "%s: mgc->cmode              = %ld", cn, (long) mgc->cmode );
 mod_gzip_printf( "%s: srv->is_virtual         = %ld", cn, (long)srv->is_virtual );
 mod_gzip_printf( "%s: srv->server_hostname    = [%s]",cn, mod_gzip_npp(srv->server_hostname) );
 mod_gzip_printf( "%s: mgc->keep_workfiles     = %ld", cn,
                (long) mgc->keep_workfiles );
 mod_gzip_printf( "%s: mgc->keep_workfiles_set = %ld", cn,
                (long) mgc->keep_workfiles_set );
 #endif

 return NULL;
}

#ifdef MOD_GZIP_CAN_NEGOTIATE
static const char *
mod_gzip_set_can_negotiate(
cmd_parms *parms, void *cfg, const char *arg )
{
 mod_gzip_conf *mgc;

 #ifdef MOD_GZIP_DEBUG1
 server_rec *srv = parms->server;
 char cn[]="mod_gzip_set_can_negotiate()";
 #endif

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_server_now = srv;
 mod_gzip_printf( " ");
 mod_gzip_printf( "%s: Entry", cn );
 mod_gzip_printf( "%s: arg=[%s]", cn, mod_gzip_npp(arg) );
 #endif

 mgc = ( mod_gzip_conf * ) cfg;

 if ( ( arg[0] == 'Y' )||( arg[0] == 'y' ) )
   {
    mgc->can_negotiate = 1;
   }
 else
   {
    mgc->can_negotiate = 0;
   }

 mgc->can_negotiate_set = 1;

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_printf( "%s: mgc->loc                = [%s]",cn, mod_gzip_npp(mgc->loc) );
 mod_gzip_printf( "%s: mgc->cmode              = %ld", cn, (long) mgc->cmode );
 mod_gzip_printf( "%s: srv->is_virtual         = %ld", cn, (long)srv->is_virtual );
 mod_gzip_printf( "%s: srv->server_hostname    = [%s]",cn, mod_gzip_npp(srv->server_hostname) );
 mod_gzip_printf( "%s: mgc->can_negotiate      = %ld", cn,
                (long) mgc->can_negotiate );
 mod_gzip_printf( "%s: mgc->can_negotiate_set  = %ld", cn,
                (long) mgc->can_negotiate_set );
 #endif

 return NULL;
}
#endif

static const char *
mod_gzip_set_dechunk(
cmd_parms *parms, void *cfg, const char *arg )
{
 mod_gzip_conf *mgc;

 #ifdef MOD_GZIP_DEBUG1
 server_rec *srv = parms->server;
 char cn[]="mod_gzip_set_dechunk()";
 #endif

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_server_now = srv;
 mod_gzip_printf( " ");
 mod_gzip_printf( "%s: Entry", cn );
 mod_gzip_printf( "%s: arg=[%s]", cn, mod_gzip_npp(arg) );
 #endif

 mgc = ( mod_gzip_conf * ) cfg;

 if ( ( arg[0] == 'Y' )||( arg[0] == 'y' ) )
   {
    mgc->dechunk = 1;
   }
 else
   {
    mgc->dechunk = 0;
   }

 mgc->dechunk_set = 1;

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_printf( "%s: mgc->loc                = [%s]",cn, mod_gzip_npp(mgc->loc) );
 mod_gzip_printf( "%s: mgc->cmode              = %ld", cn, (long) mgc->cmode );
 mod_gzip_printf( "%s: srv->is_virtual         = %ld", cn, (long)srv->is_virtual );
 mod_gzip_printf( "%s: srv->server_hostname    = [%s]",cn, mod_gzip_npp(srv->server_hostname) );
 mod_gzip_printf( "%s: mgc->dechunk            = %ld", cn,
                (long) mgc->dechunk );
 mod_gzip_printf( "%s: mgc->dechunk_set        = %ld", cn,
                (long) mgc->dechunk_set );
 #endif

 return NULL;
}

static const char *
mod_gzip_set_min_http(
cmd_parms *parms, void *cfg, const char *arg )
{
 mod_gzip_conf *mgc;

 #ifdef MOD_GZIP_DEBUG1
 server_rec *srv = parms->server;
 char cn[]="mod_gzip_set_min_http()";
 #endif

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_server_now = srv;
 mod_gzip_printf( " ");
 mod_gzip_printf( "%s: Entry", cn );
 mod_gzip_printf( "%s: arg=[%s]", cn, mod_gzip_npp(arg) );
 #endif

 mgc = ( mod_gzip_conf * ) cfg;

 mgc->min_http     = (int) atoi( arg );
 mgc->min_http_set = 1;

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_printf( "%s: mgc->loc             = [%s]",cn, mod_gzip_npp(mgc->loc));
 mod_gzip_printf( "%s: mgc->cmode           = %ld", cn, (long) mgc->cmode );
 mod_gzip_printf( "%s: srv->is_virtual      = %ld", cn, (long)srv->is_virtual );
 mod_gzip_printf( "%s: srv->server_hostname = [%s]",cn, mod_gzip_npp(srv->server_hostname));
 mod_gzip_printf( "%s: mgc->min_http        = %ld", cn,
                (long) mgc->min_http );
 mod_gzip_printf( "%s: mgc->min_http        = %ld", cn,
                (long) mgc->min_http_set );
 #endif

 return NULL;
}

static const char *
mod_gzip_set_minimum_file_size(
cmd_parms *parms, void *cfg, const char *arg )
{
 mod_gzip_conf *mgc;

 #ifdef MOD_GZIP_DEBUG1
 server_rec *srv = parms->server;
 char cn[]="mod_gzip_set_minimum_file_size()";
 #endif

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_server_now = srv;
 mod_gzip_printf( " ");
 mod_gzip_printf( "%s: Entry", cn );
 mod_gzip_printf( "%s: arg=[%s]", cn, mod_gzip_npp(arg));
 #endif

 mgc = ( mod_gzip_conf * ) cfg;

 mgc->minimum_file_size     = (long) atol( arg );
 mgc->minimum_file_size_set = 1;

 if ( mgc->minimum_file_size < 300 )
   {
    mgc->minimum_file_size = 300;
   }

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_printf( "%s: mgc->loc                = [%s]",cn, mod_gzip_npp(mgc->loc));
 mod_gzip_printf( "%s: mgc->cmode              = %ld", cn, (long) mgc->cmode );
 mod_gzip_printf( "%s: srv->is_virtual         = %ld", cn, (long)srv->is_virtual );
 mod_gzip_printf( "%s: srv->server_hostname    = [%s]",cn, mod_gzip_npp(srv->server_hostname));
 mod_gzip_printf( "%s: mgc->minimum_file_size  = %ld", cn,
                (long) mgc->minimum_file_size );
 mod_gzip_printf( "%s: mgc->minimum_file_size  = %ld", cn,
                (long) mgc->minimum_file_size_set );
 #endif

 return NULL;
}

static const char *
mod_gzip_set_maximum_file_size(
cmd_parms *parms, void *cfg, const char *arg )
{
 mod_gzip_conf *mgc;

 #ifdef MOD_GZIP_DEBUG1
 server_rec *srv = parms->server;
 char cn[]="mod_gzip_set_maximum_file_size()";
 #endif

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_server_now = srv;
 mod_gzip_printf( " ");
 mod_gzip_printf( "%s: Entry", cn );
 mod_gzip_printf( "%s: arg=[%s]", cn, mod_gzip_npp(arg));
 #endif

 mgc = ( mod_gzip_conf * ) cfg;

 mgc->maximum_file_size     = (long) atol( arg );
 mgc->maximum_file_size_set = 1;

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_printf( "%s: mgc->loc                = [%s]",cn, mod_gzip_npp(mgc->loc));
 mod_gzip_printf( "%s: mgc->cmode              = %ld", cn, (long) mgc->cmode );
 mod_gzip_printf( "%s: srv->is_virtual         = %ld", cn, (long)srv->is_virtual );
 mod_gzip_printf( "%s: srv->server_hostname    = [%s]",cn, mod_gzip_npp(srv->server_hostname));
 mod_gzip_printf( "%s: mgc->maximum_file_size  = %ld", cn,
                (long) mgc->maximum_file_size );
 mod_gzip_printf( "%s: mgc->maximum_file_size  = %ld", cn,
                (long) mgc->maximum_file_size_set );
 #endif

 return NULL;
}

static const char *
mod_gzip_set_maximum_inmem_size(
cmd_parms *parms, void *cfg, const char *arg )
{
 mod_gzip_conf *mgc;

 #ifdef MOD_GZIP_DEBUG1
 server_rec *srv = parms->server;
 char cn[]="mod_gzip_set_maximum_inmem_size()";
 #endif

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_server_now = srv;
 mod_gzip_printf( " ");
 mod_gzip_printf( "%s: Entry", cn );
 mod_gzip_printf( "%s: arg=[%s]", cn, mod_gzip_npp(arg) );
 #endif

 mgc = ( mod_gzip_conf * ) cfg;

 mgc->maximum_inmem_size     = (long) atol(arg);
 mgc->maximum_inmem_size_set = 1;

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_printf( "%s: mgc->loc                = [%s]",cn, mod_gzip_npp(mgc->loc));
 mod_gzip_printf( "%s: mgc->cmode              = %ld", cn, (long) mgc->cmode );
 mod_gzip_printf( "%s: srv->is_virtual         = %ld", cn, (long)srv->is_virtual );
 mod_gzip_printf( "%s: srv->server_hostname    = [%s]",cn, mod_gzip_npp(srv->server_hostname));
 mod_gzip_printf( "%s: mgc->maximum_inmem_size = %ld", cn,
                (long) mgc->maximum_inmem_size );
 mod_gzip_printf( "%s: mgc->maximum_inmem_size = %ld", cn,
                (long) mgc->maximum_inmem_size_set );
 #endif

 return NULL;
}

static const char *
mod_gzip_set_deflate_compression_level(
cmd_parms *parms, void *cfg, const char *arg )
{
 mod_gzip_conf *mgc;

 int deflate_compression_level; /* 0-9 */

 #ifdef MOD_GZIP_DEBUG1
 server_rec *srv = parms->server;
 char cn[]="mod_gzip_set_deflate_compression_level()";
 #endif

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_server_now = srv;
 mod_gzip_printf( " ");
 mod_gzip_printf( "%s: Entry", cn );
 mod_gzip_printf( "%s: arg=[%s]", cn, mod_gzip_npp(arg) );
 #endif

 mgc = ( mod_gzip_conf * ) cfg;

 deflate_compression_level = (int) atoi( arg );

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_printf( "%s: deflate_compression_level = %ld", cn,
                (long) deflate_compression_level );
 #endif

 /* Sanity checking... */

 if ( ( deflate_compression_level < 0 ) ||
      ( deflate_compression_level > 9 ) )
   {
    /* Requested value is out of range... use normal default... */

    deflate_compression_level =
    MOD_GZIP_DEFLATE_DEFAULT_COMPRESSION_LEVEL;
   }

 mgc->deflate_compression_level     = (int) deflate_compression_level;
 mgc->deflate_compression_level_set = 1;

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_printf( "%s: mgc->loc              = [%s]",cn, mod_gzip_npp(mgc->loc) );
 mod_gzip_printf( "%s: mgc->cmode            = %ld", cn, (long) mgc->cmode );
 mod_gzip_printf( "%s: srv->is_virtual       = %ld", cn, (long)srv->is_virtual );
 mod_gzip_printf( "%s: srv->server_hostname  = [%s]",cn, mod_gzip_npp(srv->server_hostname) );
 mod_gzip_printf( "%s: mgc->deflate_compression_level     = %ld", cn,
                (long) mgc->deflate_compression_level );
 mod_gzip_printf( "%s: mgc->deflate_compression_level_set = %ld", cn,
                (long) mgc->deflate_compression_level_set );
 #endif

 return NULL;
}

static const char *
mod_gzip_set_temp_dir(
cmd_parms *parms, void *cfg, const char *arg )
{
 mod_gzip_conf *mgc;

 #ifdef MOD_GZIP_DEBUG1
 server_rec *srv = parms->server;
 char cn[]="mod_gzip_set_temp_dir()";
 #endif

 int arglen = 0;
 int rc     = 0;

 int errnu = 0;

 struct stat sbuf;

 #ifdef WIN32
 char dirsep[]="\\";
 #else
 char dirsep[]="/";
 #endif

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_server_now = srv;
 mod_gzip_printf( " ");
 mod_gzip_printf( "%s: Entry", cn );
 #endif

 if ( !arg )
   {
    #ifdef MOD_GZIP_DEBUG1
    mod_gzip_printf( "%s: ERROR: 'arg' is NULL...", cn );
    mod_gzip_printf( "%s: ERROR: No valid directory supplied.", cn );
    #endif

    return "mod_gzip_temp_dir: ERROR: No valid directory supplied.";
   }

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_printf( "%s: arg=[%s]", cn, mod_gzip_npp(arg) );
 #endif

 mgc = ( mod_gzip_conf * ) cfg;

 arglen = mod_gzip_strlen( (char *) arg );

 if ( arglen < 256 )
   {
    mod_gzip_strcpy( mgc->temp_dir, (char *) arg );
    mgc->temp_dir_set = 1;

    if ( arglen > 0 )
      {
       if (( arglen == 1 ) && ( *arg == 32 ))
         {
          #ifdef MOD_GZIP_DEBUG1
          mod_gzip_printf( "%s: Special ONE SPACE pickup seen.", cn );
          mod_gzip_printf( "%s: temp_dir set to NOTHING.", cn );
          #endif

          mod_gzip_strcpy( mgc->temp_dir, "" );
         }
       else /* See if the directory exists... */
         {
          rc = stat( mgc->temp_dir, &sbuf );
          errnu = errno;

          /* stat() returns '0' if OK, -1 + errno if ERROR */

          if ( rc != 0 )
            {
             #ifdef MOD_GZIP_DEBUG1
             mod_gzip_printf( "%s: stat(%s) call FAILED",cn,mgc->temp_dir);
             mod_gzip_printf( "%s: stat() return code rc = %d",cn,rc);
             mod_gzip_printf( "%s: errnu = %d",cn,errnu);
             mod_gzip_printf( "%s: Directory name is not valid.",cn);
             #endif

             return "mod_gzip_temp_dir: ERROR: Directory does not exist.";
            }
          else
            {
             #ifdef MOD_GZIP_DEBUG1
             mod_gzip_printf( "%s: stat(%s) call SUCCEEDED",cn,mgc->temp_dir);
             mod_gzip_printf( "%s: Directory name appears to be valid.",cn);
             mod_gzip_printf( "%s: Pre-adding slash separator to mgc->temp_dir...",cn);
             #endif

             /* Pre-add slash separator... */

             if ( ( *(mgc->temp_dir+(arglen-1)) != '\\' ) &&
                  ( *(mgc->temp_dir+(arglen-1)) != '/'  ) )
               {
                mod_gzip_strcat( mgc->temp_dir, dirsep );
               }
            }
         }
      }

    #ifdef MOD_GZIP_DEBUG1
    mod_gzip_printf( "%s: mgc->loc             = [%s]", cn, mod_gzip_npp(mgc->loc));
    mod_gzip_printf( "%s: srv->is_virtual      = %ld",  cn, (long)srv->is_virtual );
    mod_gzip_printf( "%s: srv->server_hostname = [%s]", cn, mod_gzip_npp(srv->server_hostname));
    mod_gzip_printf( "%s: mgc->cmode           = %ld",  cn, (long) mgc->cmode);
    mod_gzip_printf( "%s: mgc->temp_dir        = [%s]", cn, mod_gzip_npp(mgc->temp_dir));
    mod_gzip_printf( "%s: mgc->temp_dir_set    = %d",   cn, mgc->temp_dir_set);
    #endif

    return NULL;
   }
 else
   {
    return "mod_gzip_temp_dir pathname must be less than 256 characters.";
   }
}

#ifdef MOD_GZIP_COMMAND_VERSION_USED
static const char *
mod_gzip_set_command_version(
cmd_parms *parms, void *cfg, const char *arg )
{
 mod_gzip_conf *mgc;

 #ifdef MOD_GZIP_DEBUG1
 server_rec *srv = parms->server;
 char cn[]="mod_gzip_set_command_version()";
 #endif

 int arglen = 0;

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_server_now = srv;
 mod_gzip_printf( " ");
 mod_gzip_printf( "%s: Entry", cn );
 #endif

 if ( !arg )
   {
    #ifdef MOD_GZIP_DEBUG1
    mod_gzip_printf( "%s: ERROR: 'arg' is NULL...", cn );
    mod_gzip_printf( "%s: ERROR: No valid string supplied.", cn );
    #endif

    return "mod_gzip_command_version: ERROR: No valid string supplied.";
   }

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_printf( "%s: arg=[%s]", cn, mod_gzip_npp(arg) );
 #endif

 mgc = ( mod_gzip_conf * ) cfg;

 arglen = mod_gzip_strlen( (char *) arg );

 if ( arglen < MOD_GZIP_COMMAND_VERSION_MAXLEN )
   {
    mod_gzip_strcpy( mgc->command_version, (char *) arg );
    mgc->command_version_set = 1;

    #ifdef MOD_GZIP_DEBUG1
    mod_gzip_printf( "%s: mgc->loc                 = [%s]", cn, mod_gzip_npp(mgc->loc));
    mod_gzip_printf( "%s: srv->is_virtual          = %ld",  cn, (long)srv->is_virtual );
    mod_gzip_printf( "%s: srv->server_hostname     = [%s]", cn, mod_gzip_npp(srv->server_hostname));
    mod_gzip_printf( "%s: mgc->cmode               = %ld",  cn, (long) mgc->cmode);
    mod_gzip_printf( "%s: mgc->command_version     = [%s]", cn, mod_gzip_npp(mgc->command_version));
    mod_gzip_printf( "%s: mgc->command_version_set = %d",   cn, mgc->command_version_set);
    #endif

    return NULL;
   }
 else
   {
    return "mod_gzip_command_version string must be less than 128 characters.";
   }
}
#endif

static const char *
mod_gzip_set_item_include(
cmd_parms *parms, void *cfg, const char *a1, const char *a2 )
{
 mod_gzip_conf *mgc;
 char *arg;

 #ifdef MOD_GZIP_DEBUG1
 server_rec *srv = parms->server;
 char cn[]="mod_gzip_set_item_include()";
 #endif

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_server_now = srv;
 mod_gzip_printf( " ");
 mod_gzip_printf( "%s: Entry", cn );
 mod_gzip_printf( "%s: a1=[%s]", cn, mod_gzip_npp(a1) );
 mod_gzip_printf( "%s: a2=[%s]", cn, mod_gzip_npp(a2) );
 #endif

 arg = (char *) a1;

 mgc = ( mod_gzip_conf * ) cfg;

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_printf( "%s: mgc->loc             = [%s]", cn, mod_gzip_npp(mgc->loc));
 mod_gzip_printf( "%s: srv->is_virtual      = %ld",  cn, (long)srv->is_virtual );
 mod_gzip_printf( "%s: srv->server_hostname = [%s]", cn, mod_gzip_npp(srv->server_hostname));
 mod_gzip_printf( "%s: mgc->cmode           = %ld",  cn, (long) mgc->cmode );
 #endif

 return( mod_gzip_imap_add_item( parms, mgc, (char *) a1, (char *) a2, 1 ) );
}

static const char *
mod_gzip_set_item_exclude(
cmd_parms *parms, void *cfg, const char *a1, const char *a2 )
{
 mod_gzip_conf *mgc;
 char *arg;

 #ifdef MOD_GZIP_DEBUG1
 server_rec *srv = parms->server;
 char cn[]="mod_gzip_set_item_exclude()";
 #endif

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_server_now = srv;
 mod_gzip_printf( " ");
 mod_gzip_printf( "%s: Entry", cn );
 mod_gzip_printf( "%s: a1=[%s]", cn, mod_gzip_npp(a1));
 mod_gzip_printf( "%s: a2=[%s]", cn, mod_gzip_npp(a2));
 #endif

 arg = (char *) a1;

 mgc = ( mod_gzip_conf * ) cfg;

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_printf( "%s: mgc->loc             = [%s]", cn, mod_gzip_npp(mgc->loc));
 mod_gzip_printf( "%s: srv->is_virtual      = %ld",  cn, (long)srv->is_virtual );
 mod_gzip_printf( "%s: srv->server_hostname = [%s]", cn, mod_gzip_npp(srv->server_hostname));
 mod_gzip_printf( "%s: mgc->cmode           = %ld",  cn, (long) mgc->cmode );
 #endif

 return( mod_gzip_imap_add_item( parms, mgc, (char *) a1, (char *) a2, 0 ) );
}

/* Directory configuration routines... */

static void *mod_gzip_create_dconfig(
apr_pool_t *p,
char *dirspec
)
{
 mod_gzip_conf *cfg;
 char *dname = dirspec;

 cfg = (mod_gzip_conf *) apr_pcalloc(p, sizeof(mod_gzip_conf));

 cfg->cmode = MOD_GZIP_CONFIG_MODE_DIRECTORY;

 dname = (dname != NULL) ? dname : "";

 cfg->loc = (char *) apr_pstrcat(p, "DIR(", dname, ")", NULL);

 mod_gzip_set_defaults1( (mod_gzip_conf *) cfg );

 return (void *) cfg;
}

static void *mod_gzip_merge_dconfig(
apr_pool_t *p,
void *parent_conf,
void *newloc_conf
)
{
 mod_gzip_conf *merged_config = (mod_gzip_conf *) apr_pcalloc(p, sizeof(mod_gzip_conf));
 mod_gzip_conf *pconf         = (mod_gzip_conf *) parent_conf;
 mod_gzip_conf *nconf         = (mod_gzip_conf *) newloc_conf;

 mod_gzip_merge1(
 ( apr_pool_t    * ) p,
 ( mod_gzip_conf * ) merged_config,
 ( mod_gzip_conf * ) pconf,
 ( mod_gzip_conf * ) nconf
 );

 return (void *) merged_config;
}

/* Server configuration routines... */

static void *mod_gzip_create_sconfig(
apr_pool_t *p,
server_rec *s
)
{
 mod_gzip_conf *cfg;
 char *sname = s->server_hostname;

 #ifdef MOD_GZIP_DEBUG1
 mod_gzip_server_now = s;
 #endif

 cfg = (mod_gzip_conf *) apr_pcalloc(p, sizeof(mod_gzip_conf));

 cfg->cmode = MOD_GZIP_CONFIG_MODE_SERVER;

 sname = (sname != NULL) ? sname : "";

 cfg->loc = (char *) apr_pstrcat(p, "SVR(", sname, ")", NULL);

 mod_gzip_set_defaults1( (mod_gzip_conf *) cfg );

 return (void *) cfg;
}

static void *mod_gzip_merge_sconfig(
apr_pool_t *p,
void *parent_conf,
void *newloc_conf
)
{
 mod_gzip_conf *merged_config = (mod_gzip_conf *) apr_pcalloc(p, sizeof(mod_gzip_conf));
 mod_gzip_conf *pconf         = (mod_gzip_conf *) parent_conf;
 mod_gzip_conf *nconf         = (mod_gzip_conf *) newloc_conf;

 mod_gzip_merge1(
 ( apr_pool_t    * ) p,
 ( mod_gzip_conf * ) merged_config,
 ( mod_gzip_conf * ) pconf,
 ( mod_gzip_conf * ) nconf
 );

 return (void *) merged_config;
}

/* Command stubs... */

char mod_gzip_command_no_longer_supported[] =
"Configuration directive no longer supported.";

char mod_gzip_command_not_available_for_20[] =
"Configuration directive not available for Apache 2.0.x series";

static const char *
mod_gzip_obsolete_command(
cmd_parms *parms, void *cfg, const char *arg )
{
 return mod_gzip_command_no_longer_supported;
}

static const char *
mod_gzip_command_not_available_in_20(
cmd_parms *parms, void *cfg, const char *arg )
{
 return mod_gzip_command_not_available_for_20;
}

/* Command table... */

static const command_rec mod_gzip_cmds[] =
{
 AP_INIT_TAKE1("mod_gzip_on", mod_gzip_set_is_on, NULL, OR_OPTIONS, 
  "Yes=mod_gzip will handle requests. No=mod_gzip is disabled."),
 AP_INIT_TAKE1("mod_gzip_add_header_count", mod_gzip_set_add_header_count, NULL, OR_OPTIONS, 
  "Yes=Add header byte counts to Common Log Format output total(s)."),
 AP_INIT_TAKE1("mod_gzip_keep_workfiles", mod_gzip_set_keep_workfiles, NULL, OR_OPTIONS, 
  "Yes=Keep any work files used. No=Automatically delete any work files used."),
 AP_INIT_TAKE1("mod_gzip_dechunk", mod_gzip_set_dechunk, NULL, OR_OPTIONS, 
  "Yes=Allow removal of 'Transfer-encoding: chunked' when necessary."),
 AP_INIT_TAKE1("mod_gzip_min_http", mod_gzip_set_min_http, NULL, OR_OPTIONS, 
  "Minimum HTTP protocol value to support. 1000 = HTTP/1.0  1001 = HTTP/1.1"),
 AP_INIT_TAKE1("mod_gzip_minimum_file_size", mod_gzip_set_minimum_file_size, NULL, OR_OPTIONS, 
  "Minimum size ( bytes ) of a file eligible for compression"),
 AP_INIT_TAKE1("mod_gzip_maximum_file_size", mod_gzip_set_maximum_file_size, NULL, OR_OPTIONS, 
  "Maximum size ( bytes ) of a file eligible for compression"),
 AP_INIT_TAKE1("mod_gzip_maximum_inmem_size", mod_gzip_set_maximum_inmem_size, NULL, OR_OPTIONS, 
  "Maximum size ( bytes ) to use for in-memory compression."),
 AP_INIT_TAKE1("mod_gzip_compression_level", mod_gzip_set_deflate_compression_level, NULL, OR_OPTIONS,
  "Desired level of compression 1-9 ( 1=Fastest 9=Best compression )"),
 AP_INIT_TAKE1("mod_gzip_temp_dir", mod_gzip_set_temp_dir, NULL, OR_OPTIONS, 
  "The directory to use for work files and compression cache"),
 AP_INIT_TAKE2("mod_gzip_item_include", mod_gzip_set_item_include, NULL, OR_OPTIONS,
  "\r\nARG1=[mime,handler,file,uri,reqheader,rspheader] \r\nARG2=[Name of item to INCLUDE in list of things that should be compressed]"),
 AP_INIT_TAKE2("mod_gzip_item_exclude", mod_gzip_set_item_exclude, NULL, OR_OPTIONS,
  "\r\nARG1=[mime,handler,file,uri,reqheader,rspheader] \r\nARG2=[Name of item to EXCLUDE from list of things that should be compressed]"),
 AP_INIT_TAKE1("mod_gzip_add_vinfo", mod_gzip_obsolete_command, NULL, OR_OPTIONS, 
  mod_gzip_command_no_longer_supported ),
 AP_INIT_TAKE1("mod_gzip_do_static_files", mod_gzip_obsolete_command, NULL, OR_OPTIONS, 
  mod_gzip_command_no_longer_supported ),
 AP_INIT_TAKE1("mod_gzip_do_cgi", mod_gzip_obsolete_command, NULL, OR_OPTIONS, 
  mod_gzip_command_no_longer_supported ),
 AP_INIT_TAKE1("mod_gzip_verbose_debug", mod_gzip_obsolete_command, NULL, OR_OPTIONS, 
  mod_gzip_command_no_longer_supported ),
 AP_INIT_TAKE1("mod_gzip_post_on", mod_gzip_obsolete_command, NULL, OR_OPTIONS, 
  mod_gzip_command_no_longer_supported ),
 #ifdef MOD_GZIP_COMMAND_VERSION_USED
 AP_INIT_TAKE1("mod_gzip_command_version", mod_gzip_set_command_version, NULL, OR_OPTIONS, 
  "User defined pickup string to use for mod_gzip version command."),
 #endif
 #ifdef MOD_GZIP_CAN_NEGOTIATE
 AP_INIT_TAKE1("mod_gzip_can_negotiate", mod_gzip_set_can_negotiate, NULL, OR_OPTIONS, 
  "Yes=Negotiate/send static compressed versions of files  No=Do not negotiate."),
 #endif
 {NULL}
};

module AP_MODULE_DECLARE_DATA gzip_module = {

    STANDARD20_MODULE_STUFF,
    mod_gzip_create_dconfig, /* Create Directory configuration record */
    mod_gzip_merge_dconfig,  /* Merge  Directory configuration record */
    mod_gzip_create_sconfig, /* Create Server    configuration record */
    mod_gzip_merge_sconfig,  /* Merge  Server    configuration record */
    mod_gzip_cmds,           /* Module command table */
    mod_gzip_register_hooks  /* Module hook registration(s) */
};

/* END OF FILE */

