upstream nginx-0.7.34
[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     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
65
66     if (clcf->if_modified_since == NGX_HTTP_IMS_OFF) {
67         return ngx_http_next_header_filter(r);
68     }
69
70     ims = ngx_http_parse_time(r->headers_in.if_modified_since->value.data,
71                               r->headers_in.if_modified_since->value.len);
72
73     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
74                    "http ims:%d lm:%d", ims, r->headers_out.last_modified_time);
75
76     if (ims != r->headers_out.last_modified_time) {
77
78         if (clcf->if_modified_since == NGX_HTTP_IMS_EXACT
79             || ims < r->headers_out.last_modified_time)
80         {
81             return ngx_http_next_header_filter(r);
82         }
83     }
84
85     r->headers_out.status = NGX_HTTP_NOT_MODIFIED;
86     r->headers_out.content_type.len = 0;
87     ngx_http_clear_content_length(r);
88     ngx_http_clear_accept_ranges(r);
89
90     return ngx_http_next_header_filter(r);
91 }
92
93
94 static
95 ngx_int_t ngx_http_not_modified_filter_init(ngx_conf_t *cf)
96 {
97     ngx_http_next_header_filter = ngx_http_top_header_filter;
98     ngx_http_top_header_filter = ngx_http_not_modified_header_filter;
99
100     return NGX_OK;
101 }