comparison src/http/ngx_http_core_module.c @ 1790:775edc46ee66

ngx_http_gzip_static_module and gzip_disable
author Igor Sysoev <igor@sysoev.ru>
date Thu, 27 Dec 2007 14:21:59 +0000
parents bfb66d7c2b42
children 3e1c695258d3
comparison
equal deleted inserted replaced
1789:a35032212cf2 1790:775edc46ee66
69 void *conf); 69 void *conf);
70 static char *ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd, 70 static char *ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd,
71 void *conf); 71 void *conf);
72 static char *ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, 72 static char *ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd,
73 void *conf); 73 void *conf);
74 #if (NGX_HTTP_GZIP)
75 static char *ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd,
76 void *conf);
77 #endif
74 78
75 static char *ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data); 79 static char *ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data);
76 static char *ngx_http_core_pool_size(ngx_conf_t *cf, void *post, void *data); 80 static char *ngx_http_core_pool_size(ngx_conf_t *cf, void *post, void *data);
77 81
78 static ngx_conf_post_t ngx_http_core_lowat_post = 82 static ngx_conf_post_t ngx_http_core_lowat_post =
96 { ngx_string("clean"), NGX_HTTP_REQUEST_BODY_FILE_CLEAN }, 100 { ngx_string("clean"), NGX_HTTP_REQUEST_BODY_FILE_CLEAN },
97 { ngx_null_string, 0 } 101 { ngx_null_string, 0 }
98 }; 102 };
99 103
100 104
105 #if (NGX_HTTP_GZIP)
106
107 static ngx_conf_enum_t ngx_http_gzip_http_version[] = {
108 { ngx_string("1.0"), NGX_HTTP_VERSION_10 },
109 { ngx_string("1.1"), NGX_HTTP_VERSION_11 },
110 { ngx_null_string, 0 }
111 };
112
113
114 static ngx_conf_bitmask_t ngx_http_gzip_proxied_mask[] = {
115 { ngx_string("off"), NGX_HTTP_GZIP_PROXIED_OFF },
116 { ngx_string("expired"), NGX_HTTP_GZIP_PROXIED_EXPIRED },
117 { ngx_string("no-cache"), NGX_HTTP_GZIP_PROXIED_NO_CACHE },
118 { ngx_string("no-store"), NGX_HTTP_GZIP_PROXIED_NO_STORE },
119 { ngx_string("private"), NGX_HTTP_GZIP_PROXIED_PRIVATE },
120 { ngx_string("no_last_modified"), NGX_HTTP_GZIP_PROXIED_NO_LM },
121 { ngx_string("no_etag"), NGX_HTTP_GZIP_PROXIED_NO_ETAG },
122 { ngx_string("auth"), NGX_HTTP_GZIP_PROXIED_AUTH },
123 { ngx_string("any"), NGX_HTTP_GZIP_PROXIED_ANY },
124 { ngx_null_string, 0 }
125 };
126
127
128 static ngx_str_t ngx_http_gzip_no_cache = ngx_string("no-cache");
129 static ngx_str_t ngx_http_gzip_no_store = ngx_string("no-store");
130 static ngx_str_t ngx_http_gzip_private = ngx_string("private");
131
132 #endif
133
134
101 static ngx_command_t ngx_http_core_commands[] = { 135 static ngx_command_t ngx_http_core_commands[] = {
102 136
103 { ngx_string("variables_hash_max_size"), 137 { ngx_string("variables_hash_max_size"),
104 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, 138 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
105 ngx_conf_set_num_slot, 139 ngx_conf_set_num_slot,
523 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, 557 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
524 ngx_conf_set_msec_slot, 558 ngx_conf_set_msec_slot,
525 NGX_HTTP_LOC_CONF_OFFSET, 559 NGX_HTTP_LOC_CONF_OFFSET,
526 offsetof(ngx_http_core_loc_conf_t, resolver_timeout), 560 offsetof(ngx_http_core_loc_conf_t, resolver_timeout),
527 NULL }, 561 NULL },
562
563 #if (NGX_HTTP_GZIP)
564
565 { ngx_string("gzip_vary"),
566 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
567 ngx_conf_set_flag_slot,
568 NGX_HTTP_LOC_CONF_OFFSET,
569 offsetof(ngx_http_core_loc_conf_t, gzip_vary),
570 NULL },
571
572 { ngx_string("gzip_http_version"),
573 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
574 ngx_conf_set_enum_slot,
575 NGX_HTTP_LOC_CONF_OFFSET,
576 offsetof(ngx_http_core_loc_conf_t, gzip_http_version),
577 &ngx_http_gzip_http_version },
578
579 { ngx_string("gzip_proxied"),
580 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
581 ngx_conf_set_bitmask_slot,
582 NGX_HTTP_LOC_CONF_OFFSET,
583 offsetof(ngx_http_core_loc_conf_t, gzip_proxied),
584 &ngx_http_gzip_proxied_mask },
585
586 { ngx_string("gzip_disable"),
587 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
588 ngx_http_gzip_disable,
589 NGX_HTTP_LOC_CONF_OFFSET,
590 0,
591 NULL },
592
593 #endif
528 594
529 ngx_null_command 595 ngx_null_command
530 }; 596 };
531 597
532 598
616 if (r->unparsed_uri.len) { 682 if (r->unparsed_uri.len) {
617 r->valid_unparsed_uri = 1; 683 r->valid_unparsed_uri = 1;
618 } 684 }
619 685
620 r->valid_location = 1; 686 r->valid_location = 1;
687 r->gzip = 0;
621 688
622 r->write_event_handler = ngx_http_core_run_phases; 689 r->write_event_handler = ngx_http_core_run_phases;
623 ngx_http_core_run_phases(r); 690 ngx_http_core_run_phases(r);
624 } 691 }
625 692
1400 r->headers_in.passwd.len = auth.len - len - 1; 1467 r->headers_in.passwd.len = auth.len - len - 1;
1401 r->headers_in.passwd.data = &auth.data[len + 1]; 1468 r->headers_in.passwd.data = &auth.data[len + 1];
1402 1469
1403 return NGX_OK; 1470 return NGX_OK;
1404 } 1471 }
1472
1473
1474 #if (NGX_HTTP_GZIP)
1475
1476 ngx_int_t
1477 ngx_http_gzip_ok(ngx_http_request_t *r)
1478 {
1479 time_t date, expires;
1480 ngx_uint_t p;
1481 ngx_array_t *cc;
1482 ngx_table_elt_t *e, *d;
1483 ngx_http_core_loc_conf_t *clcf;
1484
1485 if (r->gzip == 1) {
1486 return NGX_OK;
1487 }
1488
1489 if (r->gzip == 2) {
1490 return NGX_DECLINED;
1491 }
1492
1493 r->gzip = 2;
1494
1495 if (r != r->main
1496 || r->headers_in.accept_encoding == NULL
1497 || ngx_strcasestrn(r->headers_in.accept_encoding->value.data,
1498 "gzip", 4 - 1)
1499 == NULL
1500
1501 /*
1502 * if the URL (without the "http://" prefix) is longer than 253 bytes,
1503 * then MSIE 4.x can not handle the compressed stream - it waits
1504 * too long, hangs up or crashes
1505 */
1506
1507 || (r->headers_in.msie4 && r->unparsed_uri.len > 200))
1508 {
1509 return NGX_DECLINED;
1510 }
1511
1512 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1513
1514 if (r->http_version < clcf->gzip_http_version) {
1515 return NGX_DECLINED;
1516 }
1517
1518 if (r->headers_in.via == NULL) {
1519 goto ok;
1520 }
1521
1522 p = clcf->gzip_proxied;
1523
1524 if (p & NGX_HTTP_GZIP_PROXIED_OFF) {
1525 return NGX_DECLINED;
1526 }
1527
1528 if (p & NGX_HTTP_GZIP_PROXIED_ANY) {
1529 goto ok;
1530 }
1531
1532 if (r->headers_in.authorization && (p & NGX_HTTP_GZIP_PROXIED_AUTH)) {
1533 goto ok;
1534 }
1535
1536 e = r->headers_out.expires;
1537
1538 if (e) {
1539
1540 if (!(p & NGX_HTTP_GZIP_PROXIED_EXPIRED)) {
1541 return NGX_DECLINED;
1542 }
1543
1544 expires = ngx_http_parse_time(e->value.data, e->value.len);
1545 if (expires == NGX_ERROR) {
1546 return NGX_DECLINED;
1547 }
1548
1549 d = r->headers_out.date;
1550
1551 if (d) {
1552 date = ngx_http_parse_time(d->value.data, d->value.len);
1553 if (date == NGX_ERROR) {
1554 return NGX_DECLINED;
1555 }
1556
1557 } else {
1558 date = ngx_time();
1559 }
1560
1561 if (expires < date) {
1562 goto ok;
1563 }
1564
1565 return NGX_DECLINED;
1566 }
1567
1568 cc = &r->headers_out.cache_control;
1569
1570 if (cc->elts) {
1571
1572 if ((p & NGX_HTTP_GZIP_PROXIED_NO_CACHE)
1573 && ngx_http_parse_multi_header_lines(cc, &ngx_http_gzip_no_cache,
1574 NULL)
1575 >= 0)
1576 {
1577 goto ok;
1578 }
1579
1580 if ((p & NGX_HTTP_GZIP_PROXIED_NO_STORE)
1581 && ngx_http_parse_multi_header_lines(cc, &ngx_http_gzip_no_store,
1582 NULL)
1583 >= 0)
1584 {
1585 goto ok;
1586 }
1587
1588 if ((p & NGX_HTTP_GZIP_PROXIED_PRIVATE)
1589 && ngx_http_parse_multi_header_lines(cc, &ngx_http_gzip_private,
1590 NULL)
1591 >= 0)
1592 {
1593 goto ok;
1594 }
1595
1596 return NGX_DECLINED;
1597 }
1598
1599 if ((p & NGX_HTTP_GZIP_PROXIED_NO_LM) && r->headers_out.last_modified) {
1600 return NGX_DECLINED;
1601 }
1602
1603 if ((p & NGX_HTTP_GZIP_PROXIED_NO_ETAG) && r->headers_out.etag) {
1604 return NGX_DECLINED;
1605 }
1606
1607 ok:
1608
1609 #if (NGX_PCRE)
1610
1611 if (clcf->gzip_disable && r->headers_in.user_agent) {
1612
1613 if (ngx_regex_exec_array(clcf->gzip_disable,
1614 &r->headers_in.user_agent->value,
1615 r->connection->log)
1616 != NGX_DECLINED)
1617 {
1618 return NGX_DECLINED;
1619 }
1620 }
1621
1622 #endif
1623
1624 r->gzip = 1;
1625
1626 return NGX_OK;
1627 }
1628
1629 #endif
1405 1630
1406 1631
1407 ngx_int_t 1632 ngx_int_t
1408 ngx_http_subrequest(ngx_http_request_t *r, 1633 ngx_http_subrequest(ngx_http_request_t *r,
1409 ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **psr, 1634 ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **psr,
2402 * lcf->client_body_path = NULL; 2627 * lcf->client_body_path = NULL;
2403 * lcf->regex = NULL; 2628 * lcf->regex = NULL;
2404 * lcf->exact_match = 0; 2629 * lcf->exact_match = 0;
2405 * lcf->auto_redirect = 0; 2630 * lcf->auto_redirect = 0;
2406 * lcf->alias = 0; 2631 * lcf->alias = 0;
2632 * lcf->gzip_proxied = 0;
2407 */ 2633 */
2408 2634
2409 lcf->client_max_body_size = NGX_CONF_UNSET; 2635 lcf->client_max_body_size = NGX_CONF_UNSET;
2410 lcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE; 2636 lcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE;
2411 lcf->client_body_timeout = NGX_CONF_UNSET_MSEC; 2637 lcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
2432 lcf->log_not_found = NGX_CONF_UNSET; 2658 lcf->log_not_found = NGX_CONF_UNSET;
2433 lcf->recursive_error_pages = NGX_CONF_UNSET; 2659 lcf->recursive_error_pages = NGX_CONF_UNSET;
2434 lcf->server_tokens = NGX_CONF_UNSET; 2660 lcf->server_tokens = NGX_CONF_UNSET;
2435 lcf->types_hash_max_size = NGX_CONF_UNSET_UINT; 2661 lcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
2436 lcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT; 2662 lcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;
2663
2437 lcf->open_file_cache = NGX_CONF_UNSET_PTR; 2664 lcf->open_file_cache = NGX_CONF_UNSET_PTR;
2438 lcf->open_file_cache_valid = NGX_CONF_UNSET; 2665 lcf->open_file_cache_valid = NGX_CONF_UNSET;
2439 lcf->open_file_cache_min_uses = NGX_CONF_UNSET_UINT; 2666 lcf->open_file_cache_min_uses = NGX_CONF_UNSET_UINT;
2440 lcf->open_file_cache_errors = NGX_CONF_UNSET; 2667 lcf->open_file_cache_errors = NGX_CONF_UNSET;
2441 lcf->open_file_cache_events = NGX_CONF_UNSET; 2668 lcf->open_file_cache_events = NGX_CONF_UNSET;
2669
2670 #if (NGX_HTTP_GZIP)
2671 lcf->gzip_vary = NGX_CONF_UNSET;
2672 lcf->gzip_http_version = NGX_CONF_UNSET_UINT;
2673 lcf->gzip_disable = NGX_CONF_UNSET_PTR;
2674 #endif
2442 2675
2443 return lcf; 2676 return lcf;
2444 } 2677 }
2445 2678
2446 2679
2648 ngx_conf_merge_sec_value(conf->open_file_cache_errors, 2881 ngx_conf_merge_sec_value(conf->open_file_cache_errors,
2649 prev->open_file_cache_errors, 0); 2882 prev->open_file_cache_errors, 0);
2650 2883
2651 ngx_conf_merge_sec_value(conf->open_file_cache_events, 2884 ngx_conf_merge_sec_value(conf->open_file_cache_events,
2652 prev->open_file_cache_events, 0); 2885 prev->open_file_cache_events, 0);
2886 #if (NGX_HTTP_GZIP)
2887
2888 ngx_conf_merge_value(conf->gzip_vary, prev->gzip_vary, 0);
2889 ngx_conf_merge_uint_value(conf->gzip_http_version, prev->gzip_http_version,
2890 NGX_HTTP_VERSION_11);
2891 ngx_conf_merge_bitmask_value(conf->gzip_proxied, prev->gzip_proxied,
2892 (NGX_CONF_BITMASK_SET|NGX_HTTP_GZIP_PROXIED_OFF));
2893
2894 ngx_conf_merge_ptr_value(conf->gzip_disable, prev->gzip_disable, NULL);
2895
2896 #endif
2653 2897
2654 return NGX_CONF_OK; 2898 return NGX_CONF_OK;
2655 } 2899 }
2656 2900
2657 2901
3436 3680
3437 return NGX_CONF_OK; 3681 return NGX_CONF_OK;
3438 } 3682 }
3439 3683
3440 3684
3685 #if (NGX_HTTP_GZIP)
3686
3687 static char *
3688 ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
3689 {
3690 #if (NGX_PCRE)
3691 ngx_http_core_loc_conf_t *clcf = conf;
3692
3693 ngx_str_t err, *value;
3694 ngx_uint_t i;
3695 ngx_regex_elt_t *re;
3696 u_char errstr[NGX_MAX_CONF_ERRSTR];
3697
3698 if (clcf->gzip_disable == NGX_CONF_UNSET_PTR) {
3699 clcf->gzip_disable = ngx_array_create(cf->pool, 2,
3700 sizeof(ngx_regex_elt_t));
3701 if (clcf->gzip_disable == NULL) {
3702 return NGX_CONF_ERROR;
3703 }
3704 }
3705
3706 value = cf->args->elts;
3707
3708 err.len = NGX_MAX_CONF_ERRSTR;
3709 err.data = errstr;
3710
3711 for (i = 1; i < cf->args->nelts; i++) {
3712
3713 re = ngx_array_push(clcf->gzip_disable);
3714 if (re == NULL) {
3715 return NGX_CONF_ERROR;
3716 }
3717
3718 re->regex = ngx_regex_compile(&value[i], NGX_REGEX_CASELESS, cf->pool,
3719 &err);
3720
3721 if (re->regex == NULL) {
3722 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
3723 return NGX_CONF_ERROR;
3724 }
3725
3726 re->name = value[i].data;
3727 }
3728
3729 return NGX_CONF_OK;
3730
3731 #else
3732 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
3733 "\"gzip_disable\" requires PCRE library");
3734
3735 return NGX_CONF_ERROR;
3736 #endif
3737 }
3738
3739 #endif
3740
3741
3441 static char * 3742 static char *
3442 ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data) 3743 ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data)
3443 { 3744 {
3444 #if (NGX_FREEBSD) 3745 #if (NGX_FREEBSD)
3445 ssize_t *np = data; 3746 ssize_t *np = data;