upstream nginx-0.7.31
[nginx.git] / nginx / src / http / modules / ngx_http_not_modified_filter_module.c
1
2 /*
3  * Copyright (C) Igor Sysoev
4  */
5
6
7 #include <ngx_config.h>
8 #include <ngx_core.h>
9 #include <ngx_http.h>
10
11
12
13 static ngx_int_t ngx_http_not_modified_filter_init(ngx_conf_t *cf);
14
15
16 static ngx_http_module_t  ngx_http_not_modified_filter_module_ctx = {
17     NULL,                                  /* preconfiguration */
18     ngx_http_not_modified_filter_init,     /* postconfiguration */
19
20     NULL,                                  /* create main configuration */
21     NULL,                                  /* init main configuration */
22
23     NULL,                                  /* create server configuration */
24     NULL,                                  /* merge server configuration */
25
26     NULL,                                  /* create location configuration */
27     NULL                                   /* merge location configuration */
28 };
29
30
31 ngx_module_t  ngx_http_not_modified_filter_module = {
32     NGX_MODULE_V1,
33     &ngx_http_not_modified_filter_module_ctx, /* module context */
34     NULL,                                  /* module directives */
35     NGX_HTTP_MODULE,                       /* module type */
36     NULL,                                  /* init master */
37     NULL,                                  /* init module */
38     NULL,                                  /* init process */
39     NULL,                                  /* init thread */
40     NULL,                                  /* exit thread */
41     NULL,                                  /* exit process */
42     NULL,                                  /* exit master */
43     NGX_MODULE_V1_PADDING
44 };
45
46
47 static ngx_http_output_header_filter_pt  ngx_http_next_header_filter;
48
49
50 static
51 ngx_int_t ngx_http_not_modified_header_filter(ngx_http_request_t *r)
52 {
53     time_t                     ims;
54     ngx_http_core_loc_conf_t  *clcf;
55
56     if (r->headers_out.status != NGX_HTTP_OK
57         || r != r->main
58         || r->headers_in.if_modified_since == NULL
59         || r->headers_out.last_modified_time == -1)
60     {
61         return ngx_http_next_header_filter(r);
62     }
63
64     ims = ngx_http_parse_time(r->headers_in.if_modified_since->value.data,
65                               r->headers_in.if_modified_since->value.len);
66
67     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
68                    "http ims:%d lm:%d", ims, r->headers_out.last_modified_time);
69
70     if (ims != r->headers_out.last_modified_time) {
71
72         clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
73
74         if (clcf->if_modified_since == 0
75             || ims < r->headers_out.last_modified_time)
76         {
77             return ngx_http_next_header_filter(r);
78         }
79     }
80
81     r->headers_out.status = NGX_HTTP_NOT_MODIFIED;
82     r->headers_out.content_type.len = 0;
83     ngx_http_clear_content_length(r);
84     ngx_http_clear_accept_ranges(r);
85
86     return ngx_http_next_header_filter(r);
87 }
88
89
90 static
91 ngx_int_t ngx_http_not_modified_filter_init(ngx_conf_t *cf)
92 {
93     ngx_http_next_header_filter = ngx_http_top_header_filter;
94     ngx_http_top_header_filter = ngx_http_not_modified_header_filter;
95
96     return NGX_OK;
97 }