Release-1.4.10-patches: lighttpd-1.4.10-mod_deflate.diff

File lighttpd-1.4.10-mod_deflate.diff, 55.1 kB (added by jakabosky, 3 years ago)

dynamic compression

  • src/Makefile.am

    diff -Naur lighttpd-1.4.10.orig/src/Makefile.am lighttpd-1.4.10/src/Makefile.am
    old new  
    2828mod_ssi_expr.c: mod_ssi_exprparser.h 
    2929 
    3030common_src=buffer.c log.c \ 
    31       keyvalue.c chunk.c \ 
     31      keyvalue.c chunk.c chunk_encode.c \ 
    3232      http_chunk.c stream.c fdevent.c \ 
    3333      stat_cache.c plugin.c joblist.c etag.c array.c \ 
    3434      data_string.c data_count.c data_array.c \ 
     
    222222mod_accesslog_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined 
    223223mod_accesslog_la_LIBADD = $(common_libadd) 
    224224 
     225lib_LTLIBRARIES += mod_deflate.la 
     226mod_deflate_la_SOURCES = mod_deflate.c  
     227mod_deflate_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined 
     228mod_deflate_la_LIBADD = $(Z_LIB) $(BZ_LIB) $(common_libadd) 
     229 
    225230 
    226231hdr = server.h buffer.h network.h log.h keyvalue.h \ 
    227       response.h request.h fastcgi.h chunk.h \ 
     232      response.h request.h fastcgi.h chunk.h chunk_encode.h \ 
    228233      settings.h http_chunk.h http_auth_digest.h \ 
    229234      md5.h http_auth.h stream.h \ 
    230235      fdevent.h connections.h base.h stat_cache.h \ 
  • lighttpd-1.4.10

    diff -Naur lighttpd-1.4.10.orig/src/base.h lighttpd-1.4.10/src/base.h
    old new  
    345345         
    346346        int file_started; 
    347347        int file_finished; 
     348        int end_chunk; /* used for chunked transfer encoding. */ 
    348349         
    349         chunkqueue *write_queue;      /* a large queue for low-level write ( HTTP response ) [ file, mem ] */ 
     350        chunkqueue *write_queue;  /* a large queue for HTTP response content [ file, mem ] */ 
     351        chunkqueue *output_queue; /* a large queue for low-level write ( HTTP response ) [ file, mem ] */ 
    350352        chunkqueue *read_queue;       /* a small queue for low-level read ( HTTP request ) [ mem ] */ 
    351353        chunkqueue *request_content_queue; /* takes request-content into tempfile if necessary [ tempfile, mem ]*/ 
    352354         
     
    570572         
    571573        connections *conns; 
    572574        connections *joblist; 
     575        connections *joblist_prev; 
    573576        connections *fdwaitqueue; 
    574577         
    575578        stat_cache  *stat_cache; 
  • lighttpd-1.4.10

    diff -Naur lighttpd-1.4.10.orig/src/chunk.c lighttpd-1.4.10/src/chunk.c
    old new  
    224224        return 0; 
    225225} 
    226226 
     227int chunkqueue_append_chunkqueue(chunkqueue *cq, chunkqueue *src) { 
     228        if(src == NULL) return 0; 
     229        chunkqueue_append_chunk(cq, src->first); 
     230        cq->last = src->last; 
     231        src->first = NULL; 
     232        src->last = NULL; 
     233 
     234        return 0; 
     235} 
     236 
    227237buffer * chunkqueue_get_prepend_buffer(chunkqueue *cq) { 
    228238        chunk *c; 
    229239         
  • lighttpd-1.4.10

    diff -Naur lighttpd-1.4.10.orig/src/chunk.h lighttpd-1.4.10/src/chunk.h
    old new  
    5151int chunkqueue_append_file(chunkqueue *c, buffer *fn, off_t offset, off_t len); 
    5252int chunkqueue_append_mem(chunkqueue *c, const char *mem, size_t len); 
    5353int chunkqueue_append_buffer(chunkqueue *c, buffer *mem); 
     54int chunkqueue_append_chunkqueue(chunkqueue *cq, chunkqueue *src); 
    5455int chunkqueue_prepend_buffer(chunkqueue *c, buffer *mem); 
    5556 
    5657buffer * chunkqueue_get_append_buffer(chunkqueue *c); 
  • src/chunk_encode.c

    diff -Naur lighttpd-1.4.10.orig/src/chunk_encode.c lighttpd-1.4.10/src/chunk_encode.c
    old new  
     1/** 
     2 * the HTTP chunk-API 
     3 *  
     4 *  
     5 */ 
     6 
     7#include <sys/types.h> 
     8#include <sys/stat.h> 
     9 
     10#include <stdlib.h> 
     11#include <fcntl.h> 
     12#include <unistd.h> 
     13 
     14#include <stdio.h> 
     15#include <errno.h> 
     16#include <string.h> 
     17 
     18#include "server.h" 
     19#include "chunk.h" 
     20#include "chunk_encode.h" 
     21#include "log.h" 
     22 
     23static int chunk_encode_append_len(chunkqueue *cq, size_t len) { 
     24        size_t i, olen = len, j; 
     25        buffer *b; 
     26         
     27        /*b = srv->tmp_chunk_len;*/ 
     28        /*b = buffer_init();*/ 
     29        b = chunkqueue_get_append_buffer(cq); 
     30         
     31        if (len == 0) { 
     32                buffer_copy_string(b, "0"); 
     33        } else { 
     34                for (i = 0; i < 8 && len; i++) { 
     35                        len >>= 4; 
     36                } 
     37                 
     38                /* i is the number of hex digits we have */ 
     39                buffer_prepare_copy(b, i + 1); 
     40                 
     41                for (j = i-1, len = olen; j+1 > 0; j--) { 
     42                        b->ptr[j] = (len & 0xf) + (((len & 0xf) <= 9) ? '0' : 'a' - 10); 
     43                        len >>= 4; 
     44                } 
     45                b->used = i; 
     46                b->ptr[b->used++] = '\0'; 
     47        } 
     48                 
     49        buffer_append_string(b, "\r\n"); 
     50        /* 
     51        chunkqueue_append_buffer(cq, b); 
     52        buffer_free(b); 
     53        */ 
     54         
     55        return 0; 
     56} 
     57 
     58 
     59int chunk_encode_append_file(chunkqueue *cq, buffer *fn, off_t offset, off_t len) { 
     60        if (!cq) return -1; 
     61        if (len == 0) return 0; 
     62         
     63        chunk_encode_append_len(cq, len); 
     64         
     65        chunkqueue_append_file(cq, fn, offset, len); 
     66         
     67        chunkqueue_append_mem(cq, "\r\n", 2 + 1); 
     68         
     69        return 0; 
     70} 
     71 
     72int chunk_encode_append_buffer(chunkqueue *cq, buffer *mem) { 
     73        if (!cq) return -1; 
     74        if (mem->used <= 1) return 0; 
     75         
     76        chunk_encode_append_len(cq, mem->used - 1); 
     77         
     78        chunkqueue_append_buffer(cq, mem); 
     79         
     80        chunkqueue_append_mem(cq, "\r\n", 2 + 1); 
     81         
     82        return 0; 
     83} 
     84 
     85int chunk_encode_append_mem(chunkqueue *cq, const char * mem, size_t len) { 
     86        if (!cq) return -1; 
     87        if (len <= 1) return 0; 
     88         
     89        chunk_encode_append_len(cq, len - 1); 
     90         
     91        chunkqueue_append_mem(cq, mem, len); 
     92         
     93        chunkqueue_append_mem(cq, "\r\n", 2 + 1); 
     94         
     95        return 0; 
     96} 
     97 
     98int chunk_encode_append_queue(chunkqueue *cq, chunkqueue *src) { 
     99        int len = chunkqueue_length(src); 
     100        if (!cq) return -1; 
     101        if (len == 0) return 0; 
     102         
     103        chunk_encode_append_len(cq, len); 
     104         
     105        chunkqueue_append_chunkqueue(cq, src); 
     106         
     107        chunkqueue_append_mem(cq, "\r\n", 2 + 1); 
     108         
     109        return 0; 
     110} 
     111 
     112int chunk_encode_end(chunkqueue *cq) { 
     113        chunk_encode_append_len(cq, 0); 
     114        chunkqueue_append_mem(cq, "\r\n", 2 + 1); 
     115        return 0; 
     116} 
     117 
  • src/chunk_encode.h

    diff -Naur lighttpd-1.4.10.orig/src/chunk_encode.h lighttpd-1.4.10/src/chunk_encode.h
    old new  
     1#ifndef _CHUNK_ENCODE_H_ 
     2#define _CHUNK_ENCODE_H_ 
     3 
     4#include "server.h" 
     5#include <sys/types.h> 
     6 
     7int chunk_encode_append_mem(chunkqueue *cq, const char * mem, size_t len); 
     8int chunk_encode_append_buffer(chunkqueue *cq, buffer *mem); 
     9int chunk_encode_append_file(chunkqueue *cq, buffer *fn, off_t offset, off_t len); 
     10int chunk_encode_append_queue(chunkqueue *cq, chunkqueue *src); 
     11int chunk_encode_end(chunkqueue *cq); 
     12 
     13#endif 
  • src/connections.c

    diff -Naur lighttpd-1.4.10.orig/src/connections.c lighttpd-1.4.10/src/connections.c
    old new  
    1818#include "response.h" 
    1919#include "network.h" 
    2020#include "http_chunk.h" 
     21#include "chunk_encode.h" 
    2122#include "stat_cache.h" 
    2223#include "joblist.h" 
    2324 
     
    146147        return 0; 
    147148} 
    148149 
     150int connection_queue_is_empty(connection *con) { 
     151        if(!chunkqueue_is_empty(con->write_queue)) return 0; 
     152        if(!chunkqueue_is_empty(con->output_queue)) return 0; 
     153        return 1; 
     154} 
     155 
    149156#if 0 
    150157static void dump_packet(const unsigned char *data, size_t len) { 
    151158        size_t i, j; 
     
    365372                                con->file_finished = 1; 
    366373 
    367374                                chunkqueue_reset(con->write_queue); 
     375                                chunkqueue_reset(con->output_queue); 
    368376                        } 
    369377                        break; 
    370378                default: 
     
    472480                /* disable chunked encoding again as we have no body */ 
    473481                con->response.transfer_encoding &= ~HTTP_TRANSFER_ENCODING_CHUNKED; 
    474482                chunkqueue_reset(con->write_queue); 
     483                chunkqueue_reset(con->output_queue); 
    475484                 
    476485                con->file_finished = 1; 
    477486                break; 
    478487        } 
    479488         
    480489 
     490        /* Allow filter plugins to change response headers before they are written. */ 
     491        switch(plugins_call_handle_response_start(srv, con)) { 
     492        case HANDLER_GO_ON: 
     493        case HANDLER_FINISHED: 
     494                /* response start is finished */ 
     495                break; 
     496        default: 
     497                /* something strange happend */ 
     498                log_error_write(srv, __FILE__, __LINE__, "s", "Filter plugin failed."); 
     499                connection_set_state(srv, con, CON_STATE_ERROR); 
     500                joblist_append(srv, con); 
     501                break; 
     502        } 
     503 
    481504        if (con->file_finished) { 
    482505                /* we have all the content and chunked encoding is not used, set a content-length */  
    483506                 
     
    517540         
    518541        if (con->request.http_method == HTTP_METHOD_HEAD) { 
    519542                chunkqueue_reset(con->write_queue); 
     543                chunkqueue_reset(con->output_queue); 
    520544        } 
    521545 
    522546        http_response_write_header(srv, con); 
     
    525549} 
    526550 
    527551static int connection_handle_write(server *srv, connection *con) { 
    528         switch(network_write_chunkqueue(srv, con, con->write_queue)) { 
     552        int finished = 0; 
     553        int len; 
     554 
     555        /* Allow filter plugins to modify response conent */ 
     556        switch(plugins_call_handle_response_filter(srv, con)) { 
     557        case HANDLER_GO_ON: 
     558                finished = con->file_finished; 
     559                /* response content not changed */ 
     560                break; 
     561        case HANDLER_COMEBACK: 
     562                /* response filter has more work */ 
     563                finished = 0; 
     564                break; 
     565        case HANDLER_FINISHED: 
     566                /* response filter is finished */ 
     567                finished = 1; 
     568                break; 
     569        default: 
     570                /* something strange happend */ 
     571                log_error_write(srv, __FILE__, __LINE__, "s", "Filter plugin failed."); 
     572                connection_set_state(srv, con, CON_STATE_ERROR); 
     573                joblist_append(srv, con); 
     574                finished = 1; 
     575                break; 
     576        } 
     577 
     578        /* move chunks from write_queue to output_queue. */ 
     579        len = chunkqueue_length(con->write_queue); 
     580        if(con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { 
     581                chunk_encode_append_queue(con->output_queue, con->write_queue); 
     582                if(finished && !con->end_chunk) { 
     583                        con->end_chunk = 1; 
     584                        chunk_encode_end(con->output_queue); 
     585                } 
     586        } else { 
     587                chunkqueue_append_chunkqueue(con->output_queue, con->write_queue); 
     588        } 
     589        con->write_queue->bytes_out += len; 
     590        /* write chunks from output_queue to network */ 
     591        switch(network_write_chunkqueue(srv, con, con->output_queue)) { 
    529592        case 0: 
    530                 if (con->file_finished) { 
     593                if (finished) { 
    531594                        connection_set_state(srv, con, CON_STATE_RESPONSE_END); 
    532595                        joblist_append(srv, con); 
     596                } else { 
     597                        /* not finished yet -> WRITE */ 
     598                        con->is_writable = 1; 
    533599                } 
    534600                break; 
    535601        case -1: /* error on our side */ 
     
    599665         
    600666#undef CLEAN 
    601667        con->write_queue = chunkqueue_init(); 
     668        con->output_queue = chunkqueue_init(); 
    602669        con->read_queue = chunkqueue_init(); 
    603670        con->request_content_queue = chunkqueue_init(); 
    604671        chunkqueue_set_tempdirs(con->request_content_queue, srv->srvconf.upload_tempdirs); 
     
    627694                connection_reset(srv, con); 
    628695                 
    629696                chunkqueue_free(con->write_queue); 
     697                chunkqueue_free(con->output_queue); 
    630698                chunkqueue_free(con->read_queue); 
    631699                chunkqueue_free(con->request_content_queue); 
    632700                array_free(con->request.headers); 
     
    681749        con->http_status = 0; 
    682750        con->file_finished = 0; 
    683751        con->file_started = 0; 
     752        con->end_chunk = 0; 
    684753        con->got_response = 0; 
    685754         
    686755        con->parsed_response = 0; 
     
    751820        array_reset(con->environment); 
    752821         
    753822        chunkqueue_reset(con->write_queue); 
     823        chunkqueue_reset(con->output_queue); 
    754824        chunkqueue_reset(con->request_content_queue); 
    755825 
    756826        /* the plugins should cleanup themself */        
     
    11781248        } 
    11791249         
    11801250        if (con->state == CON_STATE_WRITE && 
    1181             !chunkqueue_is_empty(con->write_queue) && 
    11821251            con->is_writable) { 
    11831252                 
    11841253                if (-1 == connection_handle_write(srv, con)) { 
     
    15731642                        } 
    15741643                         
    15751644                        /* only try to write if we have something in the queue */ 
    1576                         if (!chunkqueue_is_empty(con->write_queue)) { 
    15771645#if 0 
     1646                        if (!connection_queue_is_empty(con)) { 
    15781647                                log_error_write(srv, __FILE__, __LINE__, "dsd", 
    15791648                                                con->fd, 
    15801649                                                "packets to write:", 
    1581                                                 con->write_queue->used); 
    1582 #endif 
     1650                                                con->output_queue->used); 
    15831651                        } 
    1584                         if (!chunkqueue_is_empty(con->write_queue) && con->is_writable) { 
     1652#endif 
     1653                        if (con->is_writable) { 
    15851654                                if (-1 == connection_handle_write(srv, con)) { 
    15861655                                        log_error_write(srv, __FILE__, __LINE__, "ds", 
    15871656                                                        con->fd, 
     
    16911760                 * - if we have data to write 
    16921761                 * - if the socket is not writable yet  
    16931762                 */ 
    1694                 if (!chunkqueue_is_empty(con->write_queue) &&  
    1695                     (con->is_writable == 0) && 
    1696                     (con->traffic_limit_reached == 0)) { 
     1763                if ((con->is_writable == 0) && 
     1764                    (con->traffic_limit_reached == 0) && 
     1765                                !connection_queue_is_empty(con)) { 
    16971766                        fdevent_event_add(srv->ev, &(con->fde_ndx), con->fd, FDEVENT_OUT); 
    16981767                } else { 
    16991768                        fdevent_event_del(srv->ev, &(con->fde_ndx), con->fd); 
  • src/http_chunk.c

    diff -Naur lighttpd-1.4.10.orig/src/http_chunk.c lighttpd-1.4.10/src/http_chunk.c
    old new  
    5858         
    5959        cq = con->write_queue; 
    6060         
    61         if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { 
    62                 http_chunk_append_len(srv, con, len); 
    63         } 
    64          
     61 
    6562        chunkqueue_append_file(cq, fn, offset, len); 
    6663         
    67         if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED && len > 0) { 
    68                 chunkqueue_append_mem(cq, "\r\n", 2 + 1); 
    69         } 
    70          
    7164        return 0; 
    7265} 
    7366 
     
    7871         
    7972        cq = con->write_queue; 
    8073         
    81         if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { 
    82                 http_chunk_append_len(srv, con, mem->used - 1); 
    83         } 
    84          
     74 
    8575        chunkqueue_append_buffer(cq, mem); 
    8676         
    87         if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED && mem->used > 0) { 
    88                 chunkqueue_append_mem(cq, "\r\n", 2 + 1); 
    89         } 
    90          
    9177        return 0; 
    9278} 
    9379 
     
    9985        cq = con->write_queue; 
    10086         
    10187        if (len == 0) { 
    102                 if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { 
    103                         http_chunk_append_len(srv, con, 0); 
    104                         chunkqueue_append_mem(cq, "\r\n", 2 + 1); 
    105                 } else { 
    106                         chunkqueue_append_mem(cq, "", 1); 
    107                 } 
    10888                return 0; 
    10989        } 
    11090         
    111         if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { 
    112                 http_chunk_append_len(srv, con, len - 1); 
    113         } 
    114          
    11591        chunkqueue_append_mem(cq, mem, len); 
    11692         
    117         if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { 
    118                 chunkqueue_append_mem(cq, "\r\n", 2 + 1); 
    119         } 
    120          
    12193        return 0; 
    12294} 
    12395 
  • lighttpd-1.4.10

    diff -Naur lighttpd-1.4.10.orig/src/joblist.c lighttpd-1.4.10/src/joblist.c
    old new  
    77 
    88int joblist_append(server *srv, connection *con) { 
    99        if (con->in_joblist) return 0; 
     10        con->in_joblist = 1; 
    1011         
    1112        if (srv->joblist->size == 0) { 
    1213                srv->joblist->size  = 16; 
  • src/mod_deflate.c

    diff -Naur lighttpd-1.4.10.orig/src/mod_deflate.c lighttpd-1.4.10/src/mod_deflate.c
    old new  
     1#include <sys/types.h> 
     2#include <sys/stat.h> 
     3 
     4#include <fcntl.h> 
     5#include <unistd.h> 
     6#include <ctype.h> 
     7#include <stdlib.h> 
     8#include <string.h> 
     9#include <errno.h> 
     10#include <time.h> 
     11#include <assert.h> 
     12 
     13#include "base.h" 
     14#include "log.h" 
     15#include "buffer.h" 
     16#include "response.h" 
     17#include "joblist.h" 
     18#include "stat_cache.h" 
     19 
     20#include "plugin.h" 
     21 
     22#include "crc32.h" 
     23#include "etag.h" 
     24 
     25#if defined HAVE_ZLIB_H && defined HAVE_LIBZ 
     26# define USE_ZLIB 
     27# include <zlib.h> 
     28#else 
     29# define Z_DEFAULT_COMPRESSION 1 
     30#endif 
     31 
     32#if defined HAVE_BZLIB_H && defined HAVE_LIBBZ2 
     33# define USE_BZ2LIB 
     34/* we don't need stdio interface */ 
     35# define BZ_NO_STDIO 
     36# include <bzlib.h> 
     37#endif 
     38 
     39#include "sys-mmap.h" 
     40 
     41/* request: accept-encoding */ 
     42#define HTTP_ACCEPT_ENCODING_IDENTITY BV(0) 
     43#define HTTP_ACCEPT_ENCODING_GZIP     BV(1) 
     44#define HTTP_ACCEPT_ENCODING_DEFLATE  BV(2) 
     45#define HTTP_ACCEPT_ENCODING_COMPRESS BV(3) 
     46#define HTTP_ACCEPT_ENCODING_BZIP2    BV(4) 
     47 
     48#define KByte * 1024 
     49#define MByte * 1024 KByte 
     50#define GByte * 1024 MByte 
     51 
     52typedef struct { 
     53        unsigned short  debug; 
     54        unsigned short  enabled; 
     55        unsigned short  bzip2; 
     56        unsigned short  sync_flush; 
     57        unsigned short  output_buffer_size; 
     58        unsigned short  min_compress_size; 
     59        unsigned short  work_block_size; 
     60        short           mem_level; 
     61        short           compression_level; 
     62        short           window_size; 
     63        array           *mimetypes; 
     64} plugin_config; 
     65 
     66typedef struct { 
     67        PLUGIN_DATA; 
     68        buffer *tmp_buf; 
     69         
     70        plugin_config **config_storage; 
     71        plugin_config conf;  
     72} plugin_data; 
     73 
     74typedef struct { 
     75        int bytes_in; 
     76        int bytes_out; 
     77        chunkqueue *in_queue; 
     78        buffer *output; 
     79        /* compression type & state */ 
     80        int compression_type; 
     81        int stream_open; 
     82#ifdef USE_ZLIB 
     83        unsigned long crc; 
     84        z_stream z; 
     85        unsigned short gzip_header; 
     86#endif 
     87#ifdef USE_BZ2LIB 
     88        bz_stream bz; 
     89#endif 
     90        plugin_data *plugin_data; 
     91} handler_ctx; 
     92 
     93static handler_ctx *handler_ctx_init() { 
     94        handler_ctx *hctx; 
     95 
     96        hctx = calloc(1, sizeof(*hctx)); 
     97        hctx->in_queue = chunkqueue_init(); 
     98 
     99        return hctx; 
     100} 
     101 
     102static void handler_ctx_free(handler_ctx *hctx) { 
     103        chunkqueue_free(hctx->in_queue); 
     104        free(hctx); 
     105} 
     106 
     107INIT_FUNC(mod_deflate_init) { 
     108        plugin_data *p; 
     109         
     110        p = calloc(1, sizeof(*p)); 
     111 
     112        p->tmp_buf = buffer_init(); 
     113         
     114        return p; 
     115} 
     116 
     117FREE_FUNC(mod_deflate_free) { 
     118        plugin_data *p = p_d; 
     119         
     120        UNUSED(srv); 
     121 
     122        if (!p) return HANDLER_GO_ON; 
     123         
     124        if (p->config_storage) { 
     125                size_t i; 
     126                for (i = 0; i < srv->config_context->used; i++) { 
     127                        plugin_config *s = p->config_storage[i]; 
     128 
     129                        if (!s) continue; 
     130                         
     131                        array_free(s->mimetypes); 
     132                         
     133                        free(s); 
     134                } 
     135                free(p->config_storage); 
     136        } 
     137 
     138        buffer_free(p->tmp_buf); 
     139         
     140        free(p); 
     141         
     142        return HANDLER_GO_ON; 
     143} 
     144 
     145SETDEFAULTS_FUNC(mod_deflate_setdefaults) { 
     146        plugin_data *p = p_d; 
     147        size_t i = 0; 
     148         
     149        config_values_t cv[] = {  
     150                { "deflate.output-buffer-size",    NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, 
     151                { "deflate.mimetypes",             NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, 
     152                { "deflate.compression-level",     NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, 
     153                { "deflate.mem-level",             NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, 
     154                { "deflate.window-size",           NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, 
     155                { "deflate.min-compress-size",     NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, 
     156                { "deflate.work-block-size",       NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, 
     157                { "deflate.enabled",               NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, 
     158                { "deflate.debug",                 NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, 
     159                { "deflate.bzip2",                 NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, 
     160                { "deflate.sync-flush",            NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, 
     161                { NULL,                            NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } 
     162        }; 
     163         
     164        p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); 
     165         
     166        for (i = 0; i < srv->config_context->used; i++) { 
     167                plugin_config *s; 
     168                 
     169                s = calloc(1, sizeof(plugin_config)); 
     170                s->enabled = 1; 
     171                s->bzip2 = 1; 
     172                s->sync_flush = 0; 
     173                s->debug = 0; 
     174                s->output_buffer_size = 0; 
     175                s->mem_level = 9; 
     176                s->window_size = 15; 
     177                s->min_compress_size = 0; 
     178                s->work_block_size = 2048; 
     179                s->compression_level = Z_DEFAULT_COMPRESSION; 
     180                s->mimetypes = array_init(); 
     181 
     182                cv[0].destination = &(s->output_buffer_size); 
     183                cv[1].destination = s->mimetypes; 
     184                cv[2].destination = &(s->compression_level); 
     185                cv[3].destination = &(s->mem_level); 
     186                cv[4].destination = &(s->window_size); 
     187                cv[5].destination = &(s->min_compress_size); 
     188                cv[6].destination = &(s->work_block_size); 
     189                cv[7].destination = &(s->enabled); 
     190                cv[8].destination = &(s->debug); 
     191                cv[9].destination = &(s->bzip2); 
     192                cv[10].destination = &(s->sync_flush); 
     193                 
     194                p->config_storage[i] = s; 
     195         
     196                if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { 
     197                        return HANDLER_ERROR; 
     198                } 
     199 
     200                if((s->compression_level < 1 || s->compression_level > 9) && 
     201                                s->compression_level != Z_DEFAULT_COMPRESSION) { 
     202                        log_error_write(srv, __FILE__, __LINE__, "sd",  
     203                                "compression-level must be between 1 and 9:", s->compression_level); 
     204<