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) |
|---|
-
./configure.in
old new 538 538 AC_OUTPUT 539 539 540 540 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 "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 mod_deflate" 542 542 543 543 plugins="mod_rewrite mod_redirect mod_ssi mod_trigger_b4_dl" 544 544 features="regex-conditionals" -
./src/Makefile.am
old new 234 234 mod_accesslog_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined 235 235 mod_accesslog_la_LIBADD = $(common_libadd) 236 236 237 lib_LTLIBRARIES += mod_deflate.la 238 mod_deflate_la_SOURCES = mod_deflate.c 239 mod_deflate_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined 240 mod_deflate_la_LIBADD = $(Z_LIB) $(BZ_LIB) $(common_libadd) 241 237 242 238 243 hdr = server.h buffer.h network.h log.h keyvalue.h \ 239 244 response.h request.h fastcgi.h chunk.h \ -
./src/Makefile.in
old new 16 16 17 17 18 18 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_d irlisting_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)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_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) 20 20 21 21 srcdir = @srcdir@ 22 22 top_srcdir = @top_srcdir@ … … 142 142 $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) 143 143 am_mod_compress_la_OBJECTS = mod_compress.lo 144 144 mod_compress_la_OBJECTS = $(am_mod_compress_la_OBJECTS) 145 mod_deflate_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ 146 $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) 147 am_mod_deflate_la_OBJECTS = mod_deflate.lo 148 mod_deflate_la_OBJECTS = $(am_mod_deflate_la_OBJECTS) 145 149 mod_dirlisting_la_DEPENDENCIES = $(am__DEPENDENCIES_2) \ 146 150 $(am__DEPENDENCIES_1) 147 151 am_mod_dirlisting_la_OBJECTS = mod_dirlisting.lo … … 296 300 $(mod_accesslog_la_SOURCES) $(mod_alias_la_SOURCES) \ 297 301 $(mod_auth_la_SOURCES) $(mod_cgi_la_SOURCES) \ 298 302 $(mod_cml_la_SOURCES) $(mod_compress_la_SOURCES) \ 303 $(mod_deflate_la_SOURCES) \ 299 304 $(mod_dirlisting_la_SOURCES) $(mod_evasive_la_SOURCES) \ 300 305 $(mod_evhost_la_SOURCES) $(mod_expire_la_SOURCES) \ 301 306 $(mod_fastcgi_la_SOURCES) $(mod_flv_streaming_la_SOURCES) \ … … 508 513 mod_ssi.la mod_secdownload.la mod_expire.la mod_evhost.la \ 509 514 mod_simple_vhost.la mod_fastcgi.la mod_access.la \ 510 515 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 512 517 @NO_RDYNAMIC_TRUE@liblightcomp_la_SOURCES = $(common_src) 513 518 @NO_RDYNAMIC_TRUE@liblightcomp_la_CFLAGS = $(AM_CFLAGS) 514 519 @NO_RDYNAMIC_TRUE@liblightcomp_la_LDFLAGS = -avoid-version -no-undefined … … 612 617 mod_accesslog_la_SOURCES = mod_accesslog.c 613 618 mod_accesslog_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined 614 619 mod_accesslog_la_LIBADD = $(common_libadd) 620 mod_deflate_la_SOURCES = mod_deflate.c 621 mod_deflate_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined 622 mod_deflate_la_LIBADD = $(Z_LIB) $(BZ_LIB) $(common_libadd) 615 623 hdr = server.h buffer.h network.h log.h keyvalue.h \ 616 624 response.h request.h fastcgi.h chunk.h \ 617 625 settings.h http_chunk.h http_auth_digest.h \ … … 723 731 $(LINK) -rpath $(libdir) $(mod_cml_la_LDFLAGS) $(mod_cml_la_OBJECTS) $(mod_cml_la_LIBADD) $(LIBS) 724 732 mod_compress.la: $(mod_compress_la_OBJECTS) $(mod_compress_la_DEPENDENCIES) 725 733 $(LINK) -rpath $(libdir) $(mod_compress_la_LDFLAGS) $(mod_compress_la_OBJECTS) $(mod_compress_la_LIBADD) $(LIBS) 734 mod_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) 726 736 mod_dirlisting.la: $(mod_dirlisting_la_OBJECTS) $(mod_dirlisting_la_DEPENDENCIES) 727 737 $(LINK) -rpath $(libdir) $(mod_dirlisting_la_LDFLAGS) $(mod_dirlisting_la_OBJECTS) $(mod_dirlisting_la_LIBADD) $(LIBS) 728 738 mod_evasive.la: $(mod_evasive_la_OBJECTS) $(mod_evasive_la_DEPENDENCIES) … … 935 945 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_cml_la-mod_cml_funcs.Plo@am__quote@ 936 946 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_cml_la-mod_cml_lua.Plo@am__quote@ 937 947 @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@ 938 949 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_dirlisting.Plo@am__quote@ 939 950 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_evasive.Plo@am__quote@ 940 951 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mod_evhost.Plo@am__quote@ -
./src/base.h
old new 148 148 149 149 http_method_t http_method; 150 150 http_version_t http_version; 151 int true_http_10_client; 151 152 152 153 buffer *request_line; 153 154 … … 354 355 355 356 int file_started; 356 357 int file_finished; 358 int end_chunk; /* used for chunked transfer encoding. */ 357 359 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 ] */ 359 362 chunkqueue *read_queue; /* a small queue for low-level read ( HTTP request ) [ mem ] */ 360 363 chunkqueue *request_content_queue; /* takes request-content into tempfile if necessary [ tempfile, mem ]*/ 361 364 … … 583 586 584 587 connections *conns; 585 588 connections *joblist; 589 connections *joblist_prev; 586 590 connections *fdwaitqueue; 587 591 588 592 stat_cache *stat_cache; -
./src/chunk.c
old new 16 16 #include <errno.h> 17 17 #include <string.h> 18 18 19 #include "server.h" 19 20 #include "chunk.h" 21 #include "log.h" 20 22 21 23 chunkqueue *chunkqueue_init(void) { 22 24 chunkqueue *cq; … … 241 243 return 0; 242 244 } 243 245 246 int 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 244 256 buffer * chunkqueue_get_prepend_buffer(chunkqueue *cq) { 245 257 chunk *c; 246 258 … … 400 412 401 413 return 0; 402 414 } 415 416 /** 417 * the HTTP chunk-API 418 * 419 * 420 */ 421 422 static 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 458 int 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 471 int 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 484 int 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 497 int 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 511 int 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 52 52 int chunkqueue_append_mem(chunkqueue *c, const char *mem, size_t len); 53 53 int chunkqueue_append_buffer(chunkqueue *c, buffer *mem); 54 54 int chunkqueue_append_buffer_weak(chunkqueue *c, buffer *mem); 55 int chunkqueue_append_chunkqueue(chunkqueue *cq, chunkqueue *src); 55 56 int chunkqueue_prepend_buffer(chunkqueue *c, buffer *mem); 56 57 57 58 buffer * chunkqueue_get_append_buffer(chunkqueue *c); … … 66 67 void chunkqueue_reset(chunkqueue *c); 67 68 68 69 int chunkqueue_is_empty(chunkqueue *c); 70 71 int chunk_encode_append_mem(chunkqueue *cq, const char * mem, size_t len); 72 int chunk_encode_append_buffer(chunkqueue *cq, buffer *mem); 73 int chunk_encode_append_file(chunkqueue *cq, buffer *fn, off_t offset, off_t len); 74 int chunk_encode_append_queue(chunkqueue *cq, chunkqueue *src); 75 int chunk_encode_end(chunkqueue *cq); 69 76 70 77 #endif -
./src/connections.c
old new 18 18 #include "response.h" 19 19 #include "network.h" 20 20 #include "http_chunk.h" 21 #include "chunk.h" 21 22 #include "stat_cache.h" 22 23 #include "joblist.h" 23 24 … … 146 147 return 0; 147 148 } 148 149 150 int 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 149 156 #if 0 150 157 static void dump_packet(const unsigned char *data, size_t len) { 151 158 size_t i, j; … … 402 409 con->file_finished = 1; 403 410 404 411 chunkqueue_reset(con->write_queue); 412 chunkqueue_reset(con->output_queue); 405 413 } 406 414 break; 407 415 default: … … 512 520 /* disable chunked encoding again as we have no body */ 513 521 con->response.transfer_encoding &= ~HTTP_TRANSFER_ENCODING_CHUNKED; 514 522 chunkqueue_reset(con->write_queue); 523 chunkqueue_reset(con->output_queue); 515 524 516 525 con->file_finished = 1; 517 526 break; 518 527 } 519 528 520 529 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 521 544 if (con->file_finished) { 522 545 /* we have all the content and chunked encoding is not used, set a content-length */ 523 546 … … 568 591 * without the content 569 592 */ 570 593 chunkqueue_reset(con->write_queue); 594 chunkqueue_reset(con->output_queue); 571 595 con->response.transfer_encoding &= ~HTTP_TRANSFER_ENCODING_CHUNKED; 572 596 } 573 597 … … 577 601 } 578 602 579 603 static 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)) { 581 648 case 0: 582 if ( con->file_finished) {649 if (finished) { 583 650 connection_set_state(srv, con, CON_STATE_RESPONSE_END); 584 651 joblist_append(srv, con); 652 } else { 653 /* not finished yet -> WRITE */ 654 con->is_writable = 1; 585 655 } 586 656 break; 587 657 case -1: /* error on our side */ … … 651 721 652 722 #undef CLEAN 653 723 con->write_queue = chunkqueue_init(); 724 con->output_queue = chunkqueue_init(); 654 725 con->read_queue = chunkqueue_init(); 655 726 con->request_content_queue = chunkqueue_init(); 656 727 chunkqueue_set_tempdirs(con->request_content_queue, srv->srvconf.upload_tempdirs); … … 679 750 connection_reset(srv, con); 680 751 681 752 chunkqueue_free(con->write_queue); 753 chunkqueue_free(con->output_queue); 682 754 chunkqueue_free(con->read_queue); 683 755 chunkqueue_free(con->request_content_queue); 684 756 array_free(con->request.headers); … … 733 805 con->http_status = 0; 734 806 con->file_finished = 0; 735 807 con->file_started = 0; 808 con->end_chunk = 0; 736 809 con->got_response = 0; 810 con->use_cache_file = 0; 811 con->write_cache_file = 0; 737 812 738 813 con->parsed_response = 0; 739 814 … … 803 878 array_reset(con->environment); 804 879 805 880 chunkqueue_reset(con->write_queue); 881 chunkqueue_reset(con->output_queue); 806 882 chunkqueue_reset(con->request_content_queue); 807 883 808 884 /* the plugins should cleanup themself */ … … 1203 1279 } 1204 1280 1205 1281 if (con->state == CON_STATE_WRITE && 1206 !chunkqueue_is_empty(con->write_queue) &&1207 1282 con->is_writable) { 1208 1283 1209 1284 if (-1 == connection_handle_write(srv, con)) { … … 1606 1681 } 1607 1682 1608 1683 /* only try to write if we have something in the queue */ 1609 if (!chunkqueue_is_empty(con->write_queue)) {1610 1684 #if 0 1685 if (!connection_queue_is_empty(con)) { 1611 1686 log_error_write(srv, __FILE__, __LINE__, "dsd", 1612 1687 con->fd, 1613 1688 "packets to write:", 1614 con->write_queue->used); 1615 #endif 1689 con->output_queue->used); 1616 1690 } 1617 if (!chunkqueue_is_empty(con->write_queue) && con->is_writable) { 1691 #endif 1692 if (con->is_writable) { 1618 1693 if (-1 == connection_handle_write(srv, con)) { 1619 1694 log_error_write(srv, __FILE__, __LINE__, "ds", 1620 1695 con->fd, … … 1724 1799 * - if we have data to write 1725 1800 * - if the socket is not writable yet 1726 1801 */ 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)) { 1730 1805 fdevent_event_add(srv->ev, &(con->fde_ndx), con->fd, FDEVENT_OUT); 1731 1806 } else { 1732 1807 fdevent_event_del(srv->ev, &(con->fde_ndx), con->fd); -
./src/http_chunk.c
old new 58 58 59 59 cq = con->write_queue; 60 60 61 if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {62 http_chunk_append_len(srv, con, len);63 }64 61 65 62 chunkqueue_append_file(cq, fn, offset, len); 66 63 67 if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED && len > 0) {68 chunkqueue_append_mem(cq, "\r\n", 2 + 1);69 }70 71 64 return 0; 72 65 } 73 66 … … 78 71 79 72 cq = con->write_queue; 80 73 81 if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {82 http_chunk_append_len(srv, con, mem->used - 1);83 }84 74 85 75 chunkqueue_append_buffer(cq, mem); 86 76 87 if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED && mem->used > 0) {88 chunkqueue_append_mem(cq, "\r\n", 2 + 1);89 }90 91 77 return 0; 92 78 } 93 79 … … 99 85 cq = con->write_queue; 100 86 101 87 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 }107 88 return 0; 108 89 } 109 90 110 if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {111 http_chunk_append_len(srv, con, len - 1);112 }113 114 91 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 }119 92 120 93 return 0; 121 94 } -
./src/joblist.c
old new 7 7 8 8 int joblist_append(server *srv, connection *con) { 9 9 if (con->in_joblist) return 0; 10 con->in_joblist = 1; 10 11 11 12 if (srv->joblist->size == 0) { 12 13 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 69 typedef 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 87 typedef struct { 88 PLUGIN_DATA; 89 buffer *tmp_buf; 90 91 plugin_config **config_storage; 92 plugin_config conf; 93 } plugin_data; 94 95 typedef 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 114 static 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 123 static void handler_ctx_free(handler_ctx *hctx) { 124 chunkqueue_free(hctx->in_queue); 125 free(hctx); 126 } 127 128 INIT_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 138 FREE_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 169 SETDEFAULTS_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 */ 283 static const char gzip_header[10] = 284 { '\037', '\213', Z_DEFLATED, 0, 285 0, 0, 0, 0, /* mtime */ 286 0, 0x03 /* Unix OS_CODE */ 287 }; 288 static 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 331 static 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
