Mercurial > hg > nginx
diff src/http/modules/ngx_http_gzip_static_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 | src/http/modules/ngx_http_static_module.c@25c93614e6b9 |
children | 0b5b94805d26 |
line wrap: on
line diff
copy from src/http/modules/ngx_http_static_module.c copy to src/http/modules/ngx_http_gzip_static_module.c --- a/src/http/modules/ngx_http_static_module.c +++ b/src/http/modules/ngx_http_gzip_static_module.c @@ -9,13 +9,34 @@ #include <ngx_http.h> -static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r); -static ngx_int_t ngx_http_static_init(ngx_conf_t *cf); +typedef struct { + ngx_flag_t enable; +} ngx_http_gzip_static_conf_t; + + +static ngx_int_t ngx_http_gzip_static_handler(ngx_http_request_t *r); +static void *ngx_http_gzip_static_create_conf(ngx_conf_t *cf); +static char *ngx_http_gzip_static_merge_conf(ngx_conf_t *cf, void *parent, + void *child); +static ngx_int_t ngx_http_gzip_static_init(ngx_conf_t *cf); -ngx_http_module_t ngx_http_static_module_ctx = { +static ngx_command_t ngx_http_gzip_static_commands[] = { + + { ngx_string("gzip_static"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_gzip_static_conf_t, enable), + NULL }, + + ngx_null_command +}; + + +ngx_http_module_t ngx_http_gzip_static_module_ctx = { NULL, /* preconfiguration */ - ngx_http_static_init, /* postconfiguration */ + ngx_http_gzip_static_init, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -23,15 +44,15 @@ ngx_http_module_t ngx_http_static_modul NULL, /* create server configuration */ NULL, /* merge server configuration */ - NULL, /* create location configuration */ - NULL /* merge location configuration */ + ngx_http_gzip_static_create_conf, /* create location configuration */ + ngx_http_gzip_static_merge_conf /* merge location configuration */ }; -ngx_module_t ngx_http_static_module = { +ngx_module_t ngx_http_gzip_static_module = { NGX_MODULE_V1, - &ngx_http_static_module_ctx, /* module context */ - NULL, /* module directives */ + &ngx_http_gzip_static_module_ctx, /* module context */ + ngx_http_gzip_static_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ NULL, /* init module */ @@ -45,18 +66,20 @@ ngx_module_t ngx_http_static_module = { static ngx_int_t -ngx_http_static_handler(ngx_http_request_t *r) +ngx_http_gzip_static_handler(ngx_http_request_t *r) { - u_char *last, *location; - size_t root; - ngx_str_t path; - ngx_int_t rc; - ngx_uint_t level; - ngx_log_t *log; - ngx_buf_t *b; - ngx_chain_t out; - ngx_open_file_info_t of; - ngx_http_core_loc_conf_t *clcf; + u_char *p; + size_t root; + ngx_str_t path; + ngx_int_t rc; + ngx_uint_t level; + ngx_log_t *log; + ngx_buf_t *b; + ngx_chain_t out; + ngx_table_elt_t *h; + ngx_open_file_info_t of; + ngx_http_core_loc_conf_t *clcf; + ngx_http_gzip_static_conf_t *gzcf; if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) { return NGX_HTTP_NOT_ALLOWED; @@ -71,25 +94,25 @@ ngx_http_static_handler(ngx_http_request return NGX_DECLINED; } - rc = ngx_http_discard_request_body(r); + gzcf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_static_module); - if (rc != NGX_OK) { - return rc; + if (!gzcf->enable || ngx_http_gzip_ok(r) != NGX_OK) { + return NGX_DECLINED; } log = r->connection->log; - /* - * ngx_http_map_uri_to_path() allocates memory for terminating '\0' - * so we do not need to reserve memory for '/' for possible redirect - */ - - last = ngx_http_map_uri_to_path(r, &path, &root, 0); - if (last == NULL) { + p = ngx_http_map_uri_to_path(r, &path, &root, sizeof(".gz") - 1); + if (p == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } - path.len = last - path.data; + *p++ = '.'; + *p++ = 'g'; + *p++ = 'z'; + *p = '\0'; + + path.len = p - path.data; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, "http filename: \"%s\"", path.data); @@ -115,27 +138,23 @@ ngx_http_static_handler(ngx_http_request case NGX_ENOTDIR: case NGX_ENAMETOOLONG: - level = NGX_LOG_ERR; - rc = NGX_HTTP_NOT_FOUND; - break; + return NGX_DECLINED; case NGX_EACCES: level = NGX_LOG_ERR; - rc = NGX_HTTP_FORBIDDEN; + rc = NGX_DECLINED; break; default: level = NGX_LOG_CRIT; - rc = NGX_HTTP_INTERNAL_SERVER_ERROR; + rc = NGX_DECLINED; break; } - if (rc != NGX_HTTP_NOT_FOUND || clcf->log_not_found) { - ngx_log_error(level, log, of.err, - ngx_open_file_n " \"%s\" failed", path.data); - } + ngx_log_error(level, log, of.err, + ngx_open_file_n " \"%s\" failed", path.data); return rc; } @@ -143,37 +162,8 @@ ngx_http_static_handler(ngx_http_request ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, "http static fd: %d", of.fd); if (of.is_dir) { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "http dir"); - - r->headers_out.location = ngx_palloc(r->pool, sizeof(ngx_table_elt_t)); - if (r->headers_out.location == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - if (!clcf->alias && clcf->root_lengths == NULL) { - location = path.data + clcf->root.len; - - } else { - location = ngx_palloc(r->pool, r->uri.len + 1); - if (location == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - last = ngx_copy(location, r->uri.data, r->uri.len); - } - - *last = '/'; - - /* - * we do not need to set the r->headers_out.location->hash and - * r->headers_out.location->key fields - */ - - r->headers_out.location->value.len = r->uri.len + 1; - r->headers_out.location->value.data = location; - - return NGX_HTTP_MOVED_PERMANENTLY; + return NGX_DECLINED; } #if !(NGX_WIN32) /* the not regular files are probably Unix specific */ @@ -187,6 +177,12 @@ ngx_http_static_handler(ngx_http_request #endif + rc = ngx_http_discard_request_body(r); + + if (rc != NGX_OK) { + return rc; + } + log->action = "sending response to client"; r->headers_out.status = NGX_HTTP_OK; @@ -197,11 +193,31 @@ ngx_http_static_handler(ngx_http_request return NGX_HTTP_INTERNAL_SERVER_ERROR; } - if (r != r->main && of.size == 0) { - return ngx_http_send_header(r); + h = ngx_list_push(&r->headers_out.headers); + if (h == NULL) { + return NGX_ERROR; } - r->allow_ranges = 1; + h->hash = 1; + h->key.len = sizeof("Content-Encoding") - 1; + h->key.data = (u_char *) "Content-Encoding"; + h->value.len = sizeof("gzip") - 1; + h->value.data = (u_char *) "gzip"; + + r->headers_out.content_encoding = h; + + if (clcf->gzip_vary) { + h = ngx_list_push(&r->headers_out.headers); + if (h == NULL) { + return NGX_ERROR; + } + + h->hash = 1; + h->key.len = sizeof("Vary") - 1; + h->key.data = (u_char *) "Vary"; + h->value.len = sizeof("Accept-Encoding") - 1; + h->value.data = (u_char *) "Accept-Encoding"; + } /* we need to allocate all before the header would be sent */ @@ -224,8 +240,8 @@ ngx_http_static_handler(ngx_http_request b->file_pos = 0; b->file_last = of.size; - b->in_file = b->file_last ? 1: 0; - b->last_buf = (r == r->main) ? 1: 0; + b->in_file = b->file_last ? 1 : 0; + b->last_buf = 1; b->last_in_chain = 1; b->file->fd = of.fd; @@ -239,8 +255,36 @@ ngx_http_static_handler(ngx_http_request } +static void * +ngx_http_gzip_static_create_conf(ngx_conf_t *cf) +{ + ngx_http_gzip_static_conf_t *conf; + + conf = ngx_palloc(cf->pool, sizeof(ngx_http_gzip_static_conf_t)); + if (conf == NULL) { + return NGX_CONF_ERROR; + } + + conf->enable = NGX_CONF_UNSET; + + return conf; +} + + +static char * +ngx_http_gzip_static_merge_conf(ngx_conf_t *cf, void *parent, void *child) +{ + ngx_http_gzip_static_conf_t *prev = parent; + ngx_http_gzip_static_conf_t *conf = child; + + ngx_conf_merge_value(conf->enable, prev->enable, 0); + + return NGX_CONF_OK; +} + + static ngx_int_t -ngx_http_static_init(ngx_conf_t *cf) +ngx_http_gzip_static_init(ngx_conf_t *cf) { ngx_http_handler_pt *h; ngx_http_core_main_conf_t *cmcf; @@ -252,7 +296,7 @@ ngx_http_static_init(ngx_conf_t *cf) return NGX_ERROR; } - *h = ngx_http_static_handler; + *h = ngx_http_gzip_static_handler; return NGX_OK; }