Changeset 1503

Show
Ignore:
Timestamp:
01/06/2007 06:59:03 AM (20 months ago)
Author:
jakabosky
Message:

fixed bugs in mod_chunked, Mostly just code cleanup.
Added mod_deflate, ported from patch for lighttpd 1.4.13
Content-Length header is removed from backend response and re-generated
since mod_deflate will change the length.

Location:
trunk
Files:
1 added
8 modified

Legend:

Unmodified
Added
Removed
  • trunk/configure.in

    r1502 r1503  
    569569 
    570570 
    571 do_build="mod_proxy_core mod_proxy_backend_http mod_proxy_backend_fastcgi mod_proxy_backend_scgi 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_chunked mod_flv_streaming"  
     571do_build="mod_proxy_core mod_proxy_backend_http mod_proxy_backend_fastcgi mod_proxy_backend_scgi 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_deflate mod_chunked mod_flv_streaming"  
    572572 
    573573plugins="mod_rewrite mod_redirect mod_ssi mod_trigger_b4_dl" 
  • trunk/src/Makefile.am

    r1502 r1503  
    141141mod_staticfile_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined 
    142142mod_staticfile_la_LIBADD = $(common_libadd) 
     143 
     144lib_LTLIBRARIES += mod_deflate.la 
     145mod_deflate_la_SOURCES = mod_deflate.c  
     146mod_deflate_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined 
     147mod_deflate_la_LIBADD = $(Z_LIB) $(BZ_LIB) $(common_libadd) 
    143148 
    144149lib_LTLIBRARIES += mod_chunked.la 
  • trunk/src/filter.c

    r1502 r1503  
    127127} 
    128128 
     129void filter_chain_remove_filter(filter_chain *chain, filter *fl) { 
     130        if (!chain || !fl) return; 
     131 
     132        if (chain->first == fl) { 
     133                chain->first = fl->next; 
     134        } 
     135        if (chain->last == fl) { 
     136                chain->last = fl->prev; 
     137        } 
     138        filter_free(fl); 
     139} 
     140 
    129141int filter_chain_copy_output(filter_chain *chain, chunkqueue *out) { 
    130142        int total; 
  • trunk/src/filter.h

    r1502 r1503  
    3636filter *filter_chain_create_filter(filter_chain *chain, int id); 
    3737filter *filter_chain_get_filter(filter_chain *chain, int id); 
     38void filter_chain_remove_filter(filter_chain *chain, filter *fl); 
    3839 
    3940int filter_chain_copy_output(filter_chain *chain, chunkqueue *out); 
  • trunk/src/mod_chunked.c

    r1502 r1503  
    4040 
    4141typedef struct { 
    42         unsigned short is_chunked; 
    4342        unsigned short debug; 
     43        filter *fl; 
    4444} handler_ctx; 
    4545 
     
    4848 
    4949        hctx = calloc(1, sizeof(*hctx)); 
    50         hctx->is_chunked = 0; 
    5150        hctx->debug = 0; 
     51        hctx->fl = NULL; 
    5252 
    5353        return hctx; 
     
    179179        plugin_data *p = p_d; 
    180180        handler_ctx *hctx; 
    181         int need_length = 0; 
     181        filter *fl; 
     182        chunkqueue *in; 
     183        int use_chunked = 0; 
    182184 
    183185        mod_chunked_patch_connection(srv, con, p); 
    184186 
    185         hctx = handler_ctx_init(); 
    186         hctx->is_chunked = 0; 
    187         hctx->debug = p->conf.debug; 
    188         con->plugin_ctx[p->id] = hctx; 
    189  
    190         if (!con->send->is_closed && 
    191                         NULL == array_get_element(con->response.headers, "Content-Length")) { 
     187        /* get filter. */ 
     188        fl = filter_chain_get_filter(con->send_filters, p->id); 
     189        if (!fl) { 
     190                if (p->conf.debug > 0) TRACE("%s", "add chunked filter to filter chain"); 
     191                fl = filter_chain_create_filter(con->send_filters, p->id); 
     192        } 
     193        /* get our input and output chunkqueues. */ 
     194        if (!fl || !fl->prev) { 
     195                filter_chain_remove_filter(con->send_filters, fl); 
     196                return HANDLER_GO_ON; 
     197        } 
     198        in = fl->prev->cq; 
     199 
     200        /* check if response needs chunked encoding. */ 
     201        if(in->is_closed) { 
     202                if (p->conf.debug > 0) TRACE("%s", "response content finished disable chunked encoding"); 
     203                con->response.content_length = chunkqueue_length(in); 
     204                use_chunked = 0; 
     205        } else { 
    192206                /* we don't know the size of the content yet 
    193207                 * - either enable chunking 
     
    195209 
    196210                if (con->request.http_version == HTTP_VERSION_1_1 && p->conf.encoding) { 
    197                         /* enable chunk-encoding */ 
    198                         con->response.transfer_encoding |= HTTP_TRANSFER_ENCODING_CHUNKED; 
     211                        use_chunked = 1; 
    199212                } else { 
    200                         con->response.transfer_encoding &= ~HTTP_TRANSFER_ENCODING_CHUNKED; 
     213                        if (p->conf.debug > 0) 
     214                                TRACE("%s", "content length unknown and can't use chunked encoding.  disable keep-alive"); 
    201215                        con->keep_alive = 0; 
    202                 } 
    203         } 
    204  
    205         /* check if Content-Length header is needed. */ 
    206         if ((con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) == 0 && 
    207             NULL == array_get_element(con->response.headers, "Content-Length")) { 
    208                 need_length = 1; 
    209         } 
    210         if (con->send->is_closed) { 
    211                 /* we have all the content and chunked encoding is not used, set a content-length */ 
    212  
    213                 if (need_length) { 
    214                         buffer_copy_off_t(srv->tmp_buf, chunkqueue_length(con->send)); 
    215  
    216                         response_header_overwrite(srv, con, CONST_STR_LEN("Content-Length"), CONST_BUF_LEN(srv->tmp_buf)); 
    217                 } 
    218         } else if (need_length) { 
    219                 /* we don't know the size of the content yet and chunked encoding is disabled. 
    220                  * - disable keep-alive  */ 
    221                 con->keep_alive = 0; 
    222         } 
    223  
    224         /* check if another module requested chunk-encoding. */ 
    225         hctx->is_chunked = (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED); 
    226         if (hctx->debug > 0) TRACE("is_chunked=%d", hctx->is_chunked); 
     216                        use_chunked = 0; 
     217                } 
     218        } 
     219 
     220        if (!use_chunked) { 
     221                /* chunked encoding disabled.  remove filter */ 
     222                con->response.transfer_encoding &= ~HTTP_TRANSFER_ENCODING_CHUNKED; 
     223                filter_chain_remove_filter(con->send_filters, fl); 
     224                return HANDLER_GO_ON; 
     225        } 
     226 
     227        /* enable chunked encoding */ 
     228        con->response.transfer_encoding |= HTTP_TRANSFER_ENCODING_CHUNKED; 
     229        hctx = handler_ctx_init(); 
     230        hctx->debug = p->conf.debug; 
     231        con->plugin_ctx[p->id] = hctx; 
     232        hctx->fl = fl; 
     233 
     234        if (hctx->debug > 0) 
     235                TRACE("%s", "chunked encoding enabled"); 
    227236 
    228237        return HANDLER_GO_ON; 
     
    268277        plugin_data *p = p_d; 
    269278        handler_ctx *hctx = con->plugin_ctx[p->id]; 
    270         filter *fl; 
    271279        chunkqueue *in; 
    272280        chunkqueue *out; 
     
    276284        UNUSED(srv); 
    277285 
     286        /* check if chunk-encoding is enabled. */ 
    278287        if (!hctx) return HANDLER_GO_ON; 
    279288 
    280         /* check if chunk-encoding is enabled. */ 
    281         if (0 == hctx->is_chunked) return HANDLER_GO_ON; 
    282  
    283         /* get filter. */ 
    284         fl = filter_chain_get_filter(con->send_filters, p->id); 
    285         if (!fl) { 
    286                 if (hctx->debug > 0) TRACE("%s", "add chunked filter to filter chain"); 
    287                 fl = filter_chain_create_filter(con->send_filters, p->id); 
    288         } 
    289289        /* get our input and output chunkqueues. */ 
    290         if (!fl || !fl->prev) return HANDLER_GO_ON; 
    291         in = fl->prev->cq; 
    292         out = fl->cq; 
     290        if (!hctx->fl || !hctx->fl->prev) return HANDLER_GO_ON; 
     291        in = hctx->fl->prev->cq; 
     292        out = hctx->fl->cq; 
    293293 
    294294        /* no more data to encode. */ 
  • trunk/src/mod_proxy_core.c

    r1502 r1503  
    574574                                return PARSE_ERROR; 
    575575                        } 
     576                        con->response.content_length = sess->content_length; 
     577                        /* don't save this header, other modules might change the content length. */ 
     578                        continue; 
    576579                } else if (0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("X-Sendfile")) || 
    577580                           0 == buffer_caseless_compare(CONST_BUF_LEN(header->key), CONST_STR_LEN("X-LIGHTTPD-Sendfile"))) { 
  • trunk/src/plugin.c

    r1502 r1503  
    124124PLUGIN_STATIC(mod_evhost); 
    125125PLUGIN_STATIC(mod_expire); 
     126PLUGIN_STATIC(mod_deflate); 
    126127PLUGIN_STATIC(mod_chunked); 
    127128PLUGIN_STATIC(mod_indexfile); 
     
    160161PLUGIN_STATIC(mod_evhost), 
    161162PLUGIN_STATIC(mod_expire), 
     163PLUGIN_STATIC(mod_deflate), 
    162164PLUGIN_STATIC(mod_chunked), 
    163165PLUGIN_STATIC(mod_indexfile), 
  • trunk/src/response.c

    r1496 r1503  
    3232        int have_date = 0; 
    3333        int have_server = 0; 
     34        int allow_keep_alive = 0; 
    3435 
    3536        b = chunkqueue_get_prepend_buffer(raw); 
     
    4445        buffer_append_string(b, get_http_status_name(con->http_status)); 
    4546 
     47        if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { 
     48                BUFFER_APPEND_STRING_CONST(b, "\r\nTransfer-Encoding: chunked"); 
     49                allow_keep_alive = 1; 
     50        } else if (con->response.content_length >= 0) { 
     51                BUFFER_APPEND_STRING_CONST(b, "\r\nContent-Length: "); 
     52                buffer_append_off_t(b, con->response.content_length); 
     53                allow_keep_alive = 1; 
     54        } 
     55 
     56        /* keep-alive needs Content-Length or chunked encoding. */ 
     57        if (!allow_keep_alive) con->keep_alive = 0; 
     58 
    4659        if (con->request.http_version != HTTP_VERSION_1_1 || con->keep_alive == 0) { 
    4760                BUFFER_APPEND_STRING_CONST(b, "\r\nConnection: "); 
    4861                buffer_append_string(b, con->keep_alive ? "keep-alive" : "close"); 
    49         } 
    50  
    51         if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { 
    52                 BUFFER_APPEND_STRING_CONST(b, "\r\nTransfer-Encoding: chunked"); 
    5362        } 
    5463