Mod_Deflate: lighttpd-1.4.13.mod_deflate.patch

File lighttpd-1.4.13.mod_deflate.patch, 66.5 kB (added by qhy, 2 years ago)

mod_deflate patch for lighttpd 1.4.13

  • ./configure.in

    old new  
    538538AC_OUTPUT 
    539539 
    540540 
    541 do_build="mod_cgi mod_fastcgi mod_proxy mod_evhost mod_simple_vhost mod_access mod_alias mod_setenv mod_usertrack mod_auth mod_status mod_accesslog mod_rrdtool mod_secdownload mod_expire mod_compress mod_dirlisting mod_indexfiles mod_userdir mod_webdav mod_staticfile mod_scgi mod_flv_streaming
     541do_build="mod_cgi mod_fastcgi mod_proxy mod_evhost mod_simple_vhost mod_access mod_alias mod_setenv mod_usertrack mod_auth mod_status mod_accesslog mod_rrdtool mod_secdownload mod_expire mod_compress mod_dirlisting mod_indexfiles mod_userdir mod_webdav mod_staticfile mod_scgi mod_flv_streaming mod_deflate
    542542 
    543543plugins="mod_rewrite mod_redirect mod_ssi mod_trigger_b4_dl" 
    544544features="regex-conditionals" 
  • ./src/Makefile.am

    old new  
    234234mod_accesslog_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined 
    235235mod_accesslog_la_LIBADD = $(common_libadd) 
    236236 
     237lib_LTLIBRARIES += mod_deflate.la 
     238mod_deflate_la_SOURCES = mod_deflate.c  
     239mod_deflate_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined 
     240mod_deflate_la_LIBADD = $(Z_LIB) $(BZ_LIB) $(common_libadd) 
     241 
    237242 
    238243hdr = server.h buffer.h network.h log.h keyvalue.h \ 
    239244      response.h request.h fastcgi.h chunk.h \ 
  • ./src/Makefile.in

    old new  
    1616 
    1717 
    1818 
    19 SOURCES = $(liblightcomp_la_SOURCES) $(mod_access_la_SOURCES) $(mod_accesslog_la_SOURCES) $(mod_alias_la_SOURCES) $(mod_auth_la_SOURCES) $(mod_cgi_la_SOURCES) $(mod_cml_la_SOURCES) $(mod_compress_la_SOURCES) $(mod_dirlisting_la_SOURCES) $(mod_evasive_la_SOURCES) $(mod_evhost_la_SOURCES) $(mod_expire_la_SOURCES) $(mod_fastcgi_la_SOURCES) $(mod_flv_streaming_la_SOURCES) $(mod_indexfile_la_SOURCES) $(mod_magnet_la_SOURCES) $(mod_mysql_vhost_la_SOURCES) $(mod_proxy_la_SOURCES) $(mod_redirect_la_SOURCES) $(mod_rewrite_la_SOURCES) $(mod_rrdtool_la_SOURCES) $(mod_scgi_la_SOURCES) $(mod_secdownload_la_SOURCES) $(mod_setenv_la_SOURCES) $(mod_simple_vhost_la_SOURCES) $(mod_ssi_la_SOURCES) $(mod_staticfile_la_SOURCES) $(mod_status_la_SOURCES) $(mod_trigger_b4_dl_la_SOURCES) $(mod_userdir_la_SOURCES) $(mod_usertrack_la_SOURCES) $(mod_webdav_la_SOURCES) $(lemon_SOURCES) $(lighttpd_SOURCES) $(proc_open_SOURCES) $(spawn_fcgi_SOURCES) 
     19SOURCES = $(liblightcomp_la_SOURCES) $(mod_access_la_SOURCES) $(mod_accesslog_la_SOURCES) $(mod_alias_la_SOURCES) $(mod_auth_la_SOURCES) $(mod_cgi_la_SOURCES) $(mod_cml_la_SOURCES) $(mod_compress_la_SOURCES) $(mod_deflate_la_SOURCES) $(mod_dirlisting_la_SOURCES) $(mod_evasive_la_SOURCES) $(mod_evhost_la_SOURCES) $(mod_expire_la_SOURCES) $(mod_fastcgi_la_SOURCES) $(mod_flv_streaming_la_SOURCES) $(mod_indexfile_la_SOURCES) $(mod_magnet_la_SOURCES) $(mod_mysql_vhost_la_SOURCES) $(mod_proxy_la_SOURCES) $(mod_redirect_la_SOURCES) $(mod_rewrite_la_SOURCES) $(mod_rrdtool_la_SOURCES) $(mod_scgi_la_SOURCES) $(mod_secdownload_la_SOURCES) $(mod_setenv_la_SOURCES) $(mod_simple_vhost_la_SOURCES) $(mod_ssi_la_SOURCES) $(mod_staticfile_la_SOURCES) $(mod_status_la_SOURCES) $(mod_trigger_b4_dl_la_SOURCES) $(mod_userdir_la_SOURCES) $(mod_usertrack_la_SOURCES) $(mod_webdav_la_SOURCES) $(lemon_SOURCES) $(lighttpd_SOURCES) $(proc_open_SOURCES) $(spawn_fcgi_SOURCES) 
    2020 
    2121srcdir = @srcdir@ 
    2222top_srcdir = @top_srcdir@ 
     
    142142        $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) 
    143143am_mod_compress_la_OBJECTS = mod_compress.lo 
    144144mod_compress_la_OBJECTS = $(am_mod_compress_la_OBJECTS) 
     145mod_deflate_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ 
     146       $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) 
     147am_mod_deflate_la_OBJECTS = mod_deflate.lo 
     148mod_deflate_la_OBJECTS = $(am_mod_deflate_la_OBJECTS) 
    145149mod_dirlisting_la_DEPENDENCIES = $(am__DEPENDENCIES_2) \ 
    146150        $(am__DEPENDENCIES_1) 
    147151am_mod_dirlisting_la_OBJECTS = mod_dirlisting.lo 
     
    296300        $(mod_accesslog_la_SOURCES) $(mod_alias_la_SOURCES) \ 
    297301        $(mod_auth_la_SOURCES) $(mod_cgi_la_SOURCES) \ 
    298302        $(mod_cml_la_SOURCES) $(mod_compress_la_SOURCES) \ 
     303        $(mod_deflate_la_SOURCES) \ 
    299304        $(mod_dirlisting_la_SOURCES) $(mod_evasive_la_SOURCES) \ 
    300305        $(mod_evhost_la_SOURCES) $(mod_expire_la_SOURCES) \ 
    301306        $(mod_fastcgi_la_SOURCES) $(mod_flv_streaming_la_SOURCES) \ 
     
    508513        mod_ssi.la mod_secdownload.la mod_expire.la mod_evhost.la \ 
    509514        mod_simple_vhost.la mod_fastcgi.la mod_access.la \ 
    510515        mod_compress.la mod_auth.la mod_rewrite.la mod_redirect.la \ 
    511         mod_status.la mod_accesslog.la 
     516        mod_status.la mod_accesslog.la mod_deflate.la 
    512517@NO_RDYNAMIC_TRUE@liblightcomp_la_SOURCES = $(common_src) 
    513518@NO_RDYNAMIC_TRUE@liblightcomp_la_CFLAGS = $(AM_CFLAGS) 
    514519@NO_RDYNAMIC_TRUE@liblightcomp_la_LDFLAGS = -avoid-version -no-undefined 
     
    612617mod_accesslog_la_SOURCES = mod_accesslog.c 
    613618mod_accesslog_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined 
    614619mod_accesslog_la_LIBADD = $(common_libadd) 
     620mod_deflate_la_SOURCES = mod_deflate.c  
     621mod_deflate_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined 
     622mod_deflate_la_LIBADD = $(Z_LIB) $(BZ_LIB) $(common_libadd) 
    615623hdr = server.h buffer.h network.h log.h keyvalue.h \ 
    616624      response.h request.h fastcgi.h chunk.h \ 
    617625      settings.h http_chunk.h http_auth_digest.h \ 
     
    723731        $(LINK) -rpath $(libdir) $(mod_cml_la_LDFLAGS) $(mod_cml_la_OBJECTS) $(mod_cml_la_LIBADD) $(LIBS) 
    724732mod_compress.la: $(mod_compress_la_OBJECTS) $(mod_compress_la_DEPENDENCIES)  
    725733        $(LINK) -rpath $(libdir) $(mod_compress_la_LDFLAGS) $(mod_compress_la_OBJECTS) $(mod_compress_la_LIBADD) $(LIBS) 
     734mod_deflate.la: $(mod_deflate_la_OBJECTS) $(mod_deflate_la_DEPENDENCIES)  
     735        $(LINK) -rpath $(libdir) $(mod_deflate_la_LDFLAGS) $(mod_deflate_la_OBJECTS) $(mod_deflate_la_LIBADD) $(LIBS) 
    726736mod_dirlisting.la: $(mod_dirlisting_la_OBJECTS) $(mod_dirlisting_la_DEPENDENCIES)  
    727737        $(LINK) -rpath $(libdir) $(mod_dirlisting_la_LDFLAGS) $(mod_dirlisting_la_OBJECTS) $(mod_dirlisting_la_LIBADD) $(LIBS) 
    728738mod_evasive.la: $(mod_evasive_la_OBJECTS) $(mod_evasive_la_DEPENDENCIES)  
     
    935945@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_cml_la-mod_cml_funcs.Plo@am__quote@ 
    936946@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_cml_la-mod_cml_lua.Plo@am__quote@ 
    937947@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_compress.Plo@am__quote@ 
     948@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_deflate.Plo@am__quote@ 
    938949@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_dirlisting.Plo@am__quote@ 
    939950@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_evasive.Plo@am__quote@ 
    940951@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_evhost.Plo@am__quote@ 
  • ./src/base.h

    old new  
    148148 
    149149        http_method_t  http_method; 
    150150        http_version_t http_version; 
     151        int true_http_10_client; 
    151152 
    152153        buffer *request_line; 
    153154 
     
    354355 
    355356        int file_started; 
    356357        int file_finished; 
     358        int end_chunk; /* used for chunked transfer encoding. */ 
    357359 
    358         chunkqueue *write_queue;      /* a large queue for low-level write ( HTTP response ) [ file, mem ] */ 
     360        chunkqueue *write_queue;  /* a large queue for HTTP response content [ file, mem ] */ 
     361        chunkqueue *output_queue; /* a large queue for low-level write ( HTTP response ) [ file, mem ] */ 
    359362        chunkqueue *read_queue;       /* a small queue for low-level read ( HTTP request ) [ mem ] */ 
    360363        chunkqueue *request_content_queue; /* takes request-content into tempfile if necessary [ tempfile, mem ]*/ 
    361364 
     
    583586 
    584587        connections *conns; 
    585588        connections *joblist; 
     589        connections *joblist_prev; 
    586590        connections *fdwaitqueue; 
    587591 
    588592        stat_cache  *stat_cache; 
  • ./src/chunk.c

    old new  
    1616#include <errno.h> 
    1717#include <string.h> 
    1818 
     19#include "server.h" 
    1920#include "chunk.h" 
     21#include "log.h" 
    2022 
    2123chunkqueue *chunkqueue_init(void) { 
    2224        chunkqueue *cq; 
     
    241243        return 0; 
    242244} 
    243245 
     246int chunkqueue_append_chunkqueue(chunkqueue *cq, chunkqueue *src) { 
     247        if(src == NULL) return 0; 
     248        chunkqueue_append_chunk(cq, src->first); 
     249        cq->last = src->last; 
     250        src->first = NULL; 
     251        src->last = NULL; 
     252 
     253        return 0; 
     254} 
     255 
    244256buffer * chunkqueue_get_prepend_buffer(chunkqueue *cq) { 
    245257        chunk *c; 
    246258 
     
    400412 
    401413        return 0; 
    402414} 
     415 
     416/** 
     417 * the HTTP chunk-API 
     418 *  
     419 *  
     420 */ 
     421 
     422static int chunk_encode_append_len(chunkqueue *cq, size_t len) { 
     423        size_t i, olen = len, j; 
     424        buffer *b; 
     425         
     426        /*b = srv->tmp_chunk_len;*/ 
     427        /*b = buffer_init();*/ 
     428        b = chunkqueue_get_append_buffer(cq); 
     429         
     430        if (len == 0) { 
     431                buffer_copy_string(b, "0"); 
     432        } else { 
     433                for (i = 0; i < 8 && len; i++) { 
     434                        len >>= 4; 
     435                } 
     436                 
     437                /* i is the number of hex digits we have */ 
     438                buffer_prepare_copy(b, i + 1); 
     439                 
     440                for (j = i-1, len = olen; j+1 > 0; j--) { 
     441                        b->ptr[j] = (len & 0xf) + (((len & 0xf) <= 9) ? '0' : 'a' - 10); 
     442                        len >>= 4; 
     443                } 
     444                b->used = i; 
     445                b->ptr[b->used++] = '\0'; 
     446        } 
     447                 
     448        buffer_append_string(b, "\r\n"); 
     449        /* 
     450        chunkqueue_append_buffer(cq, b); 
     451        buffer_free(b); 
     452        */ 
     453         
     454        return 0; 
     455} 
     456 
     457 
     458int chunk_encode_append_file(chunkqueue *cq, buffer *fn, off_t offset, off_t len) { 
     459        if (!cq) return -1; 
     460        if (len == 0) return 0; 
     461         
     462        chunk_encode_append_len(cq, len); 
     463         
     464        chunkqueue_append_file(cq, fn, offset, len); 
     465         
     466        chunkqueue_append_mem(cq, "\r\n", 2 + 1); 
     467         
     468        return 0; 
     469} 
     470 
     471int chunk_encode_append_buffer(chunkqueue *cq, buffer *mem) { 
     472        if (!cq) return -1; 
     473        if (mem->used <= 1) return 0; 
     474         
     475        chunk_encode_append_len(cq, mem->used - 1); 
     476         
     477        chunkqueue_append_buffer(cq, mem); 
     478         
     479        chunkqueue_append_mem(cq, "\r\n", 2 + 1); 
     480         
     481        return 0; 
     482} 
     483 
     484int chunk_encode_append_mem(chunkqueue *cq, const char * mem, size_t len) { 
     485        if (!cq) return -1; 
     486        if (len <= 1) return 0; 
     487         
     488        chunk_encode_append_len(cq, len - 1); 
     489         
     490        chunkqueue_append_mem(cq, mem, len); 
     491         
     492        chunkqueue_append_mem(cq, "\r\n", 2 + 1); 
     493         
     494        return 0; 
     495} 
     496 
     497int chunk_encode_append_queue(chunkqueue *cq, chunkqueue *src) { 
     498        int len = chunkqueue_length(src); 
     499        if (!cq) return -1; 
     500        if (len == 0) return 0; 
     501         
     502        chunk_encode_append_len(cq, len); 
     503         
     504        chunkqueue_append_chunkqueue(cq, src); 
     505         
     506        chunkqueue_append_mem(cq, "\r\n", 2 + 1); 
     507         
     508        return 0; 
     509} 
     510 
     511int chunk_encode_end(chunkqueue *cq) { 
     512        chunk_encode_append_len(cq, 0); 
     513        chunkqueue_append_mem(cq, "\r\n", 2 + 1); 
     514        return 0; 
     515} 
     516 
  • ./src/chunk.h

    old new  
    5252int chunkqueue_append_mem(chunkqueue *c, const char *mem, size_t len); 
    5353int chunkqueue_append_buffer(chunkqueue *c, buffer *mem); 
    5454int chunkqueue_append_buffer_weak(chunkqueue *c, buffer *mem); 
     55int chunkqueue_append_chunkqueue(chunkqueue *cq, chunkqueue *src); 
    5556int chunkqueue_prepend_buffer(chunkqueue *c, buffer *mem); 
    5657 
    5758buffer * chunkqueue_get_append_buffer(chunkqueue *c); 
     
    6667void chunkqueue_reset(chunkqueue *c); 
    6768 
    6869int chunkqueue_is_empty(chunkqueue *c); 
     70 
     71int chunk_encode_append_mem(chunkqueue *cq, const char * mem, size_t len); 
     72int chunk_encode_append_buffer(chunkqueue *cq, buffer *mem); 
     73int chunk_encode_append_file(chunkqueue *cq, buffer *fn, off_t offset, off_t len); 
     74int chunk_encode_append_queue(chunkqueue *cq, chunkqueue *src); 
     75int chunk_encode_end(chunkqueue *cq); 
    6976 
    7077#endif 
  • ./src/connections.c

    old new  
    1818#include "response.h" 
    1919#include "network.h" 
    2020#include "http_chunk.h" 
     21#include "chunk.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; 
     
    402409                                con->file_finished = 1; 
    403410 
    404411                                chunkqueue_reset(con->write_queue); 
     412                                chunkqueue_reset(con->output_queue); 
    405413                        } 
    406414                        break; 
    407415                default: 
     
    512520                /* disable chunked encoding again as we have no body */ 
    513521                con->response.transfer_encoding &= ~HTTP_TRANSFER_ENCODING_CHUNKED; 
    514522                chunkqueue_reset(con->write_queue); 
     523                chunkqueue_reset(con->output_queue); 
    515524 
    516525                con->file_finished = 1; 
    517526                break; 
    518527        } 
    519528 
    520529 
     530        /* Allow filter plugins to change response headers before they are written. */ 
     531        switch(plugins_call_handle_response_start(srv, con)) { 
     532        case HANDLER_GO_ON: 
     533        case HANDLER_FINISHED: 
     534                /* response start is finished */ 
     535                break; 
     536        default: 
     537                /* something strange happend */ 
     538                log_error_write(srv, __FILE__, __LINE__, "s", "Filter plugin failed."); 
     539                connection_set_state(srv, con, CON_STATE_ERROR); 
     540                joblist_append(srv, con); 
     541                break; 
     542        } 
     543 
    521544        if (con->file_finished) { 
    522545                /* we have all the content and chunked encoding is not used, set a content-length */ 
    523546 
     
    568591                 * without the content 
    569592                 */ 
    570593                chunkqueue_reset(con->write_queue); 
     594                chunkqueue_reset(con->output_queue); 
    571595                con->response.transfer_encoding &= ~HTTP_TRANSFER_ENCODING_CHUNKED; 
    572596        } 
    573597 
     
    577601} 
    578602 
    579603static int connection_handle_write(server *srv, connection *con) { 
    580         switch(network_write_chunkqueue(srv, con, con->write_queue)) { 
     604        int finished = 0; 
     605        int len; 
     606 
     607        /* Allow filter plugins to modify response conent */ 
     608        switch(plugins_call_handle_response_filter(srv, con)) { 
     609        case HANDLER_GO_ON: 
     610                finished = con->file_finished; 
     611                /* response content not changed */ 
     612                break; 
     613        case HANDLER_COMEBACK: 
     614                /* response filter has more work */ 
     615                finished = 0; 
     616                break; 
     617        case HANDLER_FINISHED: 
     618                /* response filter is finished */ 
     619                finished = 1; 
     620                break; 
     621        default: 
     622                /* something strange happend */ 
     623                log_error_write(srv, __FILE__, __LINE__, "s", "Filter plugin failed."); 
     624                connection_set_state(srv, con, CON_STATE_ERROR); 
     625                joblist_append(srv, con); 
     626                finished = 1; 
     627                break; 
     628        } 
     629 
     630        /* move chunks from write_queue to output_queue. */ 
     631        if (con->request.http_method == HTTP_METHOD_HEAD) { 
     632                chunkqueue_reset(con->write_queue); 
     633        } else { 
     634                len = chunkqueue_length(con->write_queue); 
     635                if(con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { 
     636                        chunk_encode_append_queue(con->output_queue, con->write_queue); 
     637                        if(finished && !con->end_chunk) { 
     638                                con->end_chunk = 1; 
     639                                chunk_encode_end(con->output_queue); 
     640                        } 
     641                } else { 
     642                        chunkqueue_append_chunkqueue(con->output_queue, con->write_queue); 
     643                } 
     644                con->write_queue->bytes_out += len; 
     645        } 
     646        /* write chunks from output_queue to network */ 
     647        switch(network_write_chunkqueue(srv, con, con->output_queue)) { 
    581648        case 0: 
    582                 if (con->file_finished) { 
     649                if (finished) { 
    583650                        connection_set_state(srv, con, CON_STATE_RESPONSE_END); 
    584651                        joblist_append(srv, con); 
     652                } else { 
     653                        /* not finished yet -> WRITE */ 
     654                        con->is_writable = 1; 
    585655                } 
    586656                break; 
    587657        case -1: /* error on our side */ 
     
    651721 
    652722#undef CLEAN 
    653723        con->write_queue = chunkqueue_init(); 
     724        con->output_queue = chunkqueue_init(); 
    654725        con->read_queue = chunkqueue_init(); 
    655726        con->request_content_queue = chunkqueue_init(); 
    656727        chunkqueue_set_tempdirs(con->request_content_queue, srv->srvconf.upload_tempdirs); 
     
    679750                connection_reset(srv, con); 
    680751 
    681752                chunkqueue_free(con->write_queue); 
     753                chunkqueue_free(con->output_queue); 
    682754                chunkqueue_free(con->read_queue); 
    683755                chunkqueue_free(con->request_content_queue); 
    684756                array_free(con->request.headers); 
     
    733805        con->http_status = 0; 
    734806        con->file_finished = 0; 
    735807        con->file_started = 0; 
     808        con->end_chunk = 0; 
    736809        con->got_response = 0; 
     810        con->use_cache_file = 0; 
     811        con->write_cache_file = 0; 
    737812 
    738813        con->parsed_response = 0; 
    739814 
     
    803878        array_reset(con->environment); 
    804879 
    805880        chunkqueue_reset(con->write_queue); 
     881        chunkqueue_reset(con->output_queue); 
    806882        chunkqueue_reset(con->request_content_queue); 
    807883 
    808884        /* the plugins should cleanup themself */ 
     
    12031279        } 
    12041280 
    12051281        if (con->state == CON_STATE_WRITE && 
    1206             !chunkqueue_is_empty(con->write_queue) && 
    12071282            con->is_writable) { 
    12081283 
    12091284                if (-1 == connection_handle_write(srv, con)) { 
     
    16061681                        } 
    16071682 
    16081683                        /* only try to write if we have something in the queue */ 
    1609                         if (!chunkqueue_is_empty(con->write_queue)) { 
    16101684#if 0 
     1685                        if (!connection_queue_is_empty(con)) { 
    16111686                                log_error_write(srv, __FILE__, __LINE__, "dsd", 
    16121687                                                con->fd, 
    16131688                                                "packets to write:", 
    1614                                                 con->write_queue->used); 
    1615 #endif 
     1689                                                con->output_queue->used); 
    16161690                        } 
    1617                         if (!chunkqueue_is_empty(con->write_queue) && con->is_writable) { 
     1691#endif 
     1692                        if (con->is_writable) { 
    16181693                                if (-1 == connection_handle_write(srv, con)) { 
    16191694                                        log_error_write(srv, __FILE__, __LINE__, "ds", 
    16201695                                                        con->fd, 
     
    17241799                 * - if we have data to write 
    17251800                 * - if the socket is not writable yet 
    17261801                 */ 
    1727                 if (!chunkqueue_is_empty(con->write_queue) && 
    1728                     (con->is_writable == 0) && 
    1729                     (con->traffic_limit_reached == 0)) { 
     1802                if ((con->is_writable == 0) && 
     1803                    (con->traffic_limit_reached == 0) && 
     1804                               !connection_queue_is_empty(con)) { 
    17301805                        fdevent_event_add(srv->ev, &(con->fde_ndx), con->fd, FDEVENT_OUT); 
    17311806                } else { 
    17321807                        fdevent_event_del(srv->ev, &(con->fde_ndx), con->fd); 
  • ./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         } 
    6461 
    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         } 
    8474 
    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                         chunkqueue_append_mem(cq, "0\r\n\r\n", 5 + 1); 
    104                 } else { 
    105                         chunkqueue_append_mem(cq, "", 1); 
    106                 } 
    10788                return 0; 
    10889        } 
    10990 
    110         if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { 
    111                 http_chunk_append_len(srv, con, len - 1); 
    112         } 
    113  
    11491        chunkqueue_append_mem(cq, mem, len); 
    115  
    116         if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { 
    117                 chunkqueue_append_mem(cq, "\r\n", 2 + 1); 
    118         } 
    11992 
    12093        return 0; 
    12194} 
  • ./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

    old new  
     1/* bug fix on Robert Jakabosky from alphatrade.com's lighttp 1.4.10 mod_deflate path 
     2 * 
     3 * new module option: 
     4 * deflate.nocompress-url = "^/nocompressurl/" # pcre regex which don't compress 
     5 * 
     6 * Bug fix and new features: 
     7 * 1) fix loop bug when content-length is bigger than work-block-size*k 
     8 * 2) prevent compress on buggy http 1.0 client with Accept Encoding: gzip, deflate 
     9 * 3) fix bug with chunk transfer encoding (under mod_fastcgi+php environment) 
     10 *  
     11 * deflate.sync-flush = "enable" is buggy on chunk encoding transfer. Use it carefully, 
     12 */ 
     13#include <sys/types.h> 
     14#include <sys/stat.h> 
     15 
     16#include <fcntl.h> 
     17#include <unistd.h> 
     18#include <ctype.h> 
     19#include <stdlib.h> 
     20#include <string.h> 
     21#include <errno.h> 
     22#include <time.h> 
     23#include <assert.h> 
     24 
     25#if defined(HAVE_PCRE_H) 
     26#include <pcre.h> 
     27#endif 
     28 
     29#include "base.h" 
     30#include "log.h" 
     31#include "buffer.h" 
     32#include "response.h" 
     33#include "joblist.h" 
     34#include "stat_cache.h" 
     35 
     36#include "plugin.h" 
     37 
     38#include "crc32.h" 
     39#include "etag.h" 
     40#include "inet_ntop_cache.h" 
     41 
     42#if defined HAVE_ZLIB_H && defined HAVE_LIBZ 
     43# define USE_ZLIB 
     44# include <zlib.h> 
     45#else 
     46# define Z_DEFAULT_COMPRESSION 1 
     47#endif 
     48 
     49#if defined HAVE_BZLIB_H && defined HAVE_LIBBZ2 
     50# define USE_BZ2LIB 
     51/* we don't need stdio interface */ 
     52# define BZ_NO_STDIO 
     53# include <bzlib.h> 
     54#endif 
     55 
     56#include "sys-mmap.h" 
     57 
     58/* request: accept-encoding */ 
     59#define HTTP_ACCEPT_ENCODING_IDENTITY BV(0) 
     60#define HTTP_ACCEPT_ENCODING_GZIP     BV(1) 
     61#define HTTP_ACCEPT_ENCODING_DEFLATE  BV(2) 
     62#define HTTP_ACCEPT_ENCODING_COMPRESS BV(3) 
     63#define HTTP_ACCEPT_ENCODING_BZIP2    BV(4) 
     64 
     65#define KByte * 1024 
     66#define MByte * 1024 KByte 
     67#define GByte * 1024 MByte 
     68 
     69typedef struct { 
     70        unsigned short  debug; 
     71        unsigned short  enabled; 
     72        unsigned short  bzip2; 
     73        unsigned short  sync_flush; 
     74        unsigned short  output_buffer_size; 
     75        unsigned short  min_compress_size; 
     76        unsigned short  work_block_size; 
     77        short           mem_level; 
     78        short           compression_level; 
     79        short           window_size; 
     80        array           *mimetypes; 
     81        buffer          *nocompress_url; 
     82#if defined(HAVE_PCRE_H) 
     83        pcre    *nocompress_regex; 
     84#endif 
     85} plugin_config; 
     86 
     87typedef struct { 
     88        PLUGIN_DATA; 
     89        buffer *tmp_buf; 
     90         
     91        plugin_config **config_storage; 
     92        plugin_config conf;  
     93} plugin_data; 
     94 
     95typedef struct { 
     96        int bytes_in; 
     97        int bytes_out; 
     98        chunkqueue *in_queue; 
     99        buffer *output; 
     100        /* compression type & state */ 
     101        int compression_type; 
     102        int stream_open; 
     103#ifdef USE_ZLIB 
     104        unsigned long crc; 
     105        z_stream z; 
     106        unsigned short gzip_header; 
     107#endif 
     108#ifdef USE_BZ2LIB 
     109        bz_stream bz; 
     110#endif 
     111        plugin_data *plugin_data; 
     112} handler_ctx; 
     113 
     114static handler_ctx *handler_ctx_init() { 
     115        handler_ctx *hctx; 
     116 
     117        hctx = calloc(1, sizeof(*hctx)); 
     118        hctx->in_queue = chunkqueue_init(); 
     119 
     120        return hctx; 
     121} 
     122 
     123static void handler_ctx_free(handler_ctx *hctx) { 
     124        chunkqueue_free(hctx->in_queue); 
     125        free(hctx); 
     126} 
     127 
     128INIT_FUNC(mod_deflate_init) { 
     129        plugin_data *p; 
     130         
     131        p = calloc(1, sizeof(*p)); 
     132 
     133        p->tmp_buf = buffer_init(); 
     134         
     135        return p; 
     136} 
     137 
     138FREE_FUNC(mod_deflate_free) { 
     139        plugin_data *p = p_d; 
     140         
     141        UNUSED(srv); 
     142 
     143        if (!p) return HANDLER_GO_ON; 
     144         
     145        if (p->config_storage) { 
     146                size_t i; 
     147                for (i = 0; i < srv->config_context->used; i++) { 
     148                        plugin_config *s = p->config_storage[i]; 
     149 
     150                        if (!s) continue; 
     151                         
     152                        array_free(s->mimetypes); 
     153                        buffer_free(s->nocompress_url); 
     154#if defined(HAVE_PCRE_H) 
     155                        if (s->nocompress_regex) pcre_free(s->nocompress_regex); 
     156#endif 
     157                        free(s); 
     158                } 
     159                free(p->config_storage); 
     160        } 
     161 
     162        buffer_free(p->tmp_buf); 
     163         
     164        free(p); 
     165         
     166        return HANDLER_GO_ON; 
     167} 
     168 
     169SETDEFAULTS_FUNC(mod_deflate_setdefaults) { 
     170        plugin_data *p = p_d; 
     171        size_t i = 0; 
     172         
     173        config_values_t cv[] = {  
     174                { "deflate.output-buffer-size",    NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, 
     175                { "deflate.mimetypes",             NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, 
     176                { "deflate.compression-level",     NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, 
     177                { "deflate.mem-level",             NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, 
     178                { "deflate.window-size",           NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, 
     179                { "deflate.min-compress-size",     NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, 
     180                { "deflate.work-block-size",       NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, 
     181                { "deflate.enabled",               NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, 
     182                { "deflate.debug",                 NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, 
     183                { "deflate.bzip2",                 NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, 
     184                { "deflate.sync-flush",            NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, 
     185                { "deflate.nocompress-url",        NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, 
     186                { NULL,                            NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } 
     187        }; 
     188         
     189        p->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); 
     190         
     191        for (i = 0; i < srv->config_context->used; i++) { 
     192                plugin_config *s; 
     193#if defined(HAVE_PCRE_H) 
     194                const char *errptr; 
     195                int erroff; 
     196#endif 
     197                 
     198                s = calloc(1, sizeof(plugin_config)); 
     199                s->enabled = 1; 
     200                s->bzip2 = 1; 
     201                s->sync_flush = 0; 
     202                s->debug = 0; 
     203                s->output_buffer_size = 0; 
     204                s->mem_level = 9; 
     205                s->window_size = 15; 
     206                s->min_compress_size = 0; 
     207                s->work_block_size = 2048; 
     208                s->compression_level = Z_DEFAULT_COMPRESSION; 
     209                s->mimetypes = array_init(); 
     210                s->nocompress_url = buffer_init(); 
     211#if defined(HAVE_PCRE_H) 
     212                s->nocompress_regex = NULL; 
     213#endif 
     214 
     215                cv[0].destination = &(s->output_buffer_size); 
     216                cv[1].destination = s->mimetypes; 
     217                cv[2].destination = &(s->compression_level); 
     218                cv[3].destination = &(s->mem_level); 
     219                cv[4].destination = &(s->window_size); 
     220                cv[5].destination = &(s->min_compress_size); 
     221                cv[6].destination = &(s->work_block_size); 
     222                cv[7].destination = &(s->enabled); 
     223                cv[8].destination = &(s->debug); 
     224                cv[9].destination = &(s->bzip2); 
     225                cv[10].destination = &(s->sync_flush); 
     226                cv[11].destination = s->nocompress_url; 
     227                 
     228                p->config_storage[i] = s; 
     229         
     230                if (0 != config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv)) { 
     231                        return HANDLER_ERROR; 
     232                } 
     233 
     234#if defined(HAVE_PCRE_H)                 
     235                if (!buffer_is_empty(s->nocompress_url)) { 
     236                        if (NULL == (s->nocompress_regex = pcre_compile(s->nocompress_url->ptr, 
     237                                                                      0, &errptr, &erroff, NULL))) { 
     238                                 
     239                                log_error_write(srv, __FILE__, __LINE__, "sbss",  
     240                                                "compiling regex for nocompress-url failed:",  
     241                                                s->nocompress_url, "pos:", erroff); 
     242                                return HANDLER_ERROR; 
     243                        } 
     244                } 
     245#endif 
     246                if((s->compression_level < 1 || s->compression_level > 9) && 
     247                                s->compression_level != Z_DEFAULT_COMPRESSION) { 
     248                        log_error_write(srv, __FILE__, __LINE__, "sd",  
     249                                "compression-level must be between 1 and 9:", s->compression_level); 
     250                        return HANDLER_ERROR; 
     251                } 
     252 
     253                if(s->mem_level < 1 || s->mem_level > 9) { 
     254                        log_error_write(srv, __FILE__, __LINE__, "sd",  
     255                                "mem-level must be between 1 and 9:", s->mem_level); 
     256                        return HANDLER_ERROR; 
     257                } 
     258 
     259                if(s->window_size < 1 || s->window_size > 15) { 
     260                        log_error_write(srv, __FILE__, __LINE__, "sd",  
     261                                "window-size must be between 1 and 15:", s->window_size); 
     262                        return HANDLER_ERROR; 
     263                } 
     264                s->window_size = 0 - s->window_size; 
     265 
     266                if(s->sync_flush) { 
     267                        s->output_buffer_size = 0; 
     268                } 
     269        } 
     270         
     271        return HANDLER_GO_ON; 
     272         
     273} 
     274 
     275#ifdef USE_ZLIB 
     276/* Copied gzip_header from apache 2.2's mod_deflate.c */ 
     277/* RFC 1952 Section 2.3 defines the gzip header: 
     278 * 
     279 * +---+---+---+---+---+---+---+---+---+---+ 
     280 * |ID1|ID2|CM |FLG|     MTIME     |XFL|OS | 
     281 * +---+---+---+---+---+---+---+---+---+---+ 
     282 */ 
     283static const char gzip_header[10] = 
     284{ '\037', '\213', Z_DEFLATED, 0, 
     285  0, 0, 0, 0, /* mtime */ 
     286  0, 0x03 /* Unix OS_CODE */ 
     287}; 
     288static int stream_deflate_init(server *srv, connection *con, handler_ctx *hctx) { 
     289        plugin_data *p = hctx->plugin_data; 
     290        z_stream *z; 
     291 
     292        UNUSED(srv); 
     293        UNUSED(con); 
     294 
     295        z = &(hctx->z); 
     296        z->zalloc = Z_NULL; 
     297        z->zfree = Z_NULL; 
     298        z->opaque = Z_NULL; 
     299        z->total_in = 0; 
     300        z->total_out = 0; 
     301        z->next_out = NULL; 
     302        z->avail_out = 0; 
     303         
     304        if(p->conf.debug) { 
     305                log_error_write(srv, __FILE__, __LINE__, "sd",  
     306                        "output-buffer-size:", p->conf.output_buffer_size); 
     307                log_error_write(srv, __FILE__, __LINE__, "sd",  
     308                        "compression-level:", p->conf.compression_level); 
     309                log_error_write(srv, __FILE__, __LINE__, "sd",  
     310                        "mem-level:", p->conf.mem_level); 
     311                log_error_write(srv, __FILE__, __LINE__, "sd",  
     312                        "window-size:", p->conf.window_size); 
     313                log_error_write(srv, __FILE__, __LINE__, "sd",  
     314                        "min-compress-size:", p->conf.min_compress_size); 
     315                log_error_write(srv, __FILE__, __LINE__, "sd",  
     316                        "work-block-size:", p->conf.work_block_size); 
     317        } 
     318        if (Z_OK != deflateInit2(z,  
     319                                 p->conf.compression_level, 
     320                                 Z_DEFLATED,  
     321                                 p->conf.window_size,  /* supress zlib-header */ 
     322                                 p->conf.mem_level, 
     323                                 Z_DEFAULT_STRATEGY)) { 
     324                return -1; 
     325        } 
     326        hctx->stream_open = 1; 
     327                 
     328        return 0; 
     329} 
     330 
     331static int stream_deflate_compress(server *srv, connection *con, handler_ctx *hctx, unsigned char *start, off_t st_size) { 
     332        plugin_data *p = hctx->plugin_data; 
     333        z_stream *z; 
     334        int len; 
     335        int in = 0, out = 0; 
     336 
     337        UNUSED(srv); 
     338        z = &(hctx->z); 
     339 
     340        if(z->next_out == NULL) { 
     341                z->next_out = (unsigned char *)hctx->output->ptr; 
     342                z->avail_out = hctx->output->size; 
     343        } 
     344         
     345        if(hctx->compression_type == HTTP_ACCEPT_ENCODING_GZIP) { 
     346                if(hctx->gzip_header == 0) { 
     347                        hctx->gzip_header = 1; 
     348                        /* copy gzip header into output buffer */ 
     349                        buffer_copy_memory(hctx->output, gzip_header, sizeof(gzip_header)); 
     350                        if(p->conf.debug) { 
     351                                log_error_write(srv, __FILE__, __LINE__, "sd", 
     352                                                "gzip_header len=", sizeof(gzip_header)); 
     353                        } 
     354                        /* initialize crc32 */ 
     355                        hctx->crc = crc32(0L, Z_NULL, 0); 
     356                        z->next_out = (unsigned char *)(hctx->output->ptr + sizeof(gzip_header)); 
     357                        z->avail_out = hctx->output->size - sizeof(gzip_header); 
     358                } 
     359                hctx->crc = crc32(hctx->crc, start, st_size); 
     360        } 
     361 
     362        z->next_in = start; 
     363        z->avail_in = st_size; 
     364        hctx->bytes_in += st_size; 
     365                 
     366        /* compress data */ 
     367        in = z->avail_in; 
     368        do { 
     369                if (Z_OK != deflate(z, Z_NO_FLUSH)) { 
     370                        deflateEnd(z); 
     371                        hctx->stream_open = 0; 
     372                        return -1; 
     373                } 
     374 
     375                if(z->avail_out == 0 || z->avail_in > 0) { 
     376                        len = hctx->output->size - z->avail_out; 
     377                        hctx->bytes_out += len; 
     378                        out += len; 
     379                        chunkqueue_append_mem(con->write_queue, hctx->output->ptr, len+1); 
     380                        z->next_out = (unsigned char *)hctx->output->ptr; 
     381                        z->avail_out = hctx->output->size; 
     382                } 
     383        } while (z->avail_in > 0); 
     384 
     385        if(p->conf.debug) { 
     386                log_error_write(srv, __FILE__, __LINE__, "sdsd", 
     387                                "compress: in=", in, ", out=", out); 
     388      &nbs