]> granicus.if.org Git - apache/commitdiff
Update inflate_out_filter to support gzip compression flags.
authorNick Kew <niq@apache.org>
Fri, 25 Jun 2004 03:44:29 +0000 (03:44 +0000)
committerNick Kew <niq@apache.org>
Fri, 25 Jun 2004 03:44:29 +0000 (03:44 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@104034 13f79535-47bb-0310-9956-ffa450edef68

modules/filters/mod_deflate.c

index c2af498b58a5c21d450b9e701c39d88aa3727ef8..f19f01270214f1d410ab9f04e8ed1cf9bed29906 100644 (file)
  */
 
 /*
- * Portions of this software are based upon public domain software
- * (zlib functions gz_open and gzwrite)
+ * Portions of this software are based upon zlib code by Jean-loup Gailly
+ * (zlib functions gz_open and gzwrite, check_header)
  */
 
+/* zlib flags */
+#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
+#define HEAD_CRC     0x02 /* bit 1 set: header CRC present */
+#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
+#define COMMENT      0x10 /* bit 4 set: file comment present */
+#define RESERVED     0xE0 /* bits 5..7: reserved */
+
+
+
 #include "httpd.h"
 #include "http_config.h"
 #include "http_log.h"
@@ -871,7 +881,8 @@ static apr_status_t deflate_in_filter(ap_filter_t *f,
 static apr_status_t inflate_out_filter(ap_filter_t *f,
                                       apr_bucket_brigade *bb)
 {
-    /* have we read the zlib header in yet? assume we have in a previous pass */
+    int zlib_method ;
+    int zlib_flags ;
     int deflate_init = 1; 
     apr_bucket *bkt;
     request_rec *r = f->r;
@@ -960,6 +971,8 @@ static apr_status_t inflate_out_filter(ap_filter_t *f,
             apr_bucket *tmp_heap;
             zRC = inflate(&(ctx->stream), Z_SYNC_FLUSH);
             if (zRC != Z_OK) {
+                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+                    "Inflate error %d on flush", zRC) ;
                 inflateEnd(&ctx->stream);
                 return APR_EGENERAL;
             }
@@ -989,8 +1002,17 @@ static apr_status_t inflate_out_filter(ap_filter_t *f,
                 return APR_EGENERAL ;
             } 
             else  {
+                zlib_method = data[2] ;
+                zlib_flags = data[3] ;
+                if ( zlib_method != Z_DEFLATED ) {
+                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+                        "inflate: data not deflated!") ;
+                    ap_remove_output_filter(f) ;
+                    return ap_pass_brigade(f->next, bb) ;
+                }
                 if (data[0] != deflate_magic[0] ||
-                    data[1] != deflate_magic[1]) {
+                    data[1] != deflate_magic[1] ||
+                    (zlib_flags & RESERVED) != 0 ) {
                         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                                       "deflate: bad header");
                     return APR_EGENERAL ;
@@ -998,6 +1020,29 @@ static apr_status_t inflate_out_filter(ap_filter_t *f,
                 data += 10 ;
                 len -= 10 ;
            }
+           if ( zlib_flags & EXTRA_FIELD) {
+               unsigned int bytes =
+                        (unsigned int)(data[0]) ;
+               bytes += ((unsigned int)(data[1])) << 8 ;
+               bytes += 2 ;
+               if ( len < bytes ) {
+                   ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+                              "inflate: extra field too big (not supported)") ;
+                   return APR_EGENERAL ;
+               }
+               data += bytes ;
+               len -= bytes ;
+           }
+           if ( zlib_flags & ORIG_NAME) {
+               while ( len-- && *data++ ) ;
+           }
+           if ( zlib_flags & COMMENT) {
+               while ( len-- && *data++ ) ;
+           }
+           if ( zlib_flags & HEAD_CRC) {
+                len -= 2 ;
+                data += 2 ;
+           }
         }
 
         /* pass through zlib inflate. */