~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Nginx/http/modules/ngx_http_addition_filter_module.c

Version: ~ [ nginx-0.8.20 ] ~ [ nginx-0.7.62 ] ~ [ nginx-0.6.39 ] ~

  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 typedef struct {
 13     ngx_str_t     before_body;
 14     ngx_str_t     after_body;
 15 
 16     ngx_hash_t    types;
 17     ngx_array_t  *types_keys;
 18 } ngx_http_addition_conf_t;
 19 
 20 
 21 typedef struct {
 22     ngx_uint_t    before_body_sent;
 23 } ngx_http_addition_ctx_t;
 24 
 25 
 26 static void *ngx_http_addition_create_conf(ngx_conf_t *cf);
 27 static char *ngx_http_addition_merge_conf(ngx_conf_t *cf, void *parent,
 28     void *child);
 29 static ngx_int_t ngx_http_addition_filter_init(ngx_conf_t *cf);
 30 
 31 
 32 static ngx_command_t  ngx_http_addition_commands[] = {
 33 
 34     { ngx_string("add_before_body"),
 35       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
 36       ngx_conf_set_str_slot,
 37       NGX_HTTP_LOC_CONF_OFFSET,
 38       offsetof(ngx_http_addition_conf_t, before_body),
 39       NULL },
 40 
 41     { ngx_string("add_after_body"),
 42       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
 43       ngx_conf_set_str_slot,
 44       NGX_HTTP_LOC_CONF_OFFSET,
 45       offsetof(ngx_http_addition_conf_t, after_body),
 46       NULL },
 47 
 48     { ngx_string("addition_types"),
 49       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
 50       ngx_http_types_slot,
 51       NGX_HTTP_LOC_CONF_OFFSET,
 52       offsetof(ngx_http_addition_conf_t, types_keys),
 53       &ngx_http_html_default_types[0] },
 54 
 55       ngx_null_command
 56 };
 57 
 58 
 59 static ngx_http_module_t  ngx_http_addition_filter_module_ctx = {
 60     NULL,                                  /* preconfiguration */
 61     ngx_http_addition_filter_init,         /* postconfiguration */
 62 
 63     NULL,                                  /* create main configuration */
 64     NULL,                                  /* init main configuration */
 65 
 66     NULL,                                  /* create server configuration */
 67     NULL,                                  /* merge server configuration */
 68 
 69     ngx_http_addition_create_conf,         /* create location configuration */
 70     ngx_http_addition_merge_conf           /* merge location configuration */
 71 };
 72 
 73 
 74 ngx_module_t  ngx_http_addition_filter_module = {
 75     NGX_MODULE_V1,
 76     &ngx_http_addition_filter_module_ctx,  /* module context */
 77     ngx_http_addition_commands,            /* module directives */
 78     NGX_HTTP_MODULE,                       /* module type */
 79     NULL,                                  /* init master */
 80     NULL,                                  /* init module */
 81     NULL,                                  /* init process */
 82     NULL,                                  /* init thread */
 83     NULL,                                  /* exit thread */
 84     NULL,                                  /* exit process */
 85     NULL,                                  /* exit master */
 86     NGX_MODULE_V1_PADDING
 87 };
 88 
 89 
 90 static ngx_http_output_header_filter_pt  ngx_http_next_header_filter;
 91 static ngx_http_output_body_filter_pt    ngx_http_next_body_filter;
 92 
 93 
 94 static ngx_int_t
 95 ngx_http_addition_header_filter(ngx_http_request_t *r)
 96 {
 97     ngx_http_addition_ctx_t   *ctx;
 98     ngx_http_addition_conf_t  *conf;
 99 
100     if (r->headers_out.status != NGX_HTTP_OK || r != r->main) {
101         return ngx_http_next_header_filter(r);
102     }
103 
104     conf = ngx_http_get_module_loc_conf(r, ngx_http_addition_filter_module);
105 
106     if (conf->before_body.len == 0 && conf->after_body.len == 0) {
107         return ngx_http_next_header_filter(r);
108     }
109 
110     if (ngx_http_test_content_type(r, &conf->types) == NULL) {
111         return ngx_http_next_header_filter(r);
112     }
113 
114     ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_addition_ctx_t));
115     if (ctx == NULL) {
116         return NGX_ERROR;
117     }
118 
119     ngx_http_set_ctx(r, ctx, ngx_http_addition_filter_module);
120 
121     ngx_http_clear_content_length(r);
122     ngx_http_clear_accept_ranges(r);
123 
124     return ngx_http_next_header_filter(r);
125 }
126 
127 
128 static ngx_int_t
129 ngx_http_addition_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
130 {
131     ngx_int_t                  rc;
132     ngx_uint_t                 last;
133     ngx_chain_t               *cl;
134     ngx_http_request_t        *sr;
135     ngx_http_addition_ctx_t   *ctx;
136     ngx_http_addition_conf_t  *conf;
137 
138     if (in == NULL || r->header_only) {
139         return ngx_http_next_body_filter(r, in);
140     }
141 
142     ctx = ngx_http_get_module_ctx(r, ngx_http_addition_filter_module);
143 
144     if (ctx == NULL) {
145         return ngx_http_next_body_filter(r, in);
146     }
147 
148     conf = ngx_http_get_module_loc_conf(r, ngx_http_addition_filter_module);
149 
150     if (!ctx->before_body_sent) {
151         ctx->before_body_sent = 1;
152 
153         if (conf->before_body.len) {
154             if (ngx_http_subrequest(r, &conf->before_body, NULL, &sr, NULL, 0)
155                 != NGX_OK)
156             {
157                 return NGX_ERROR;
158             }
159         }
160     }
161 
162     if (conf->after_body.len == 0) {
163         ngx_http_set_ctx(r, NULL, ngx_http_addition_filter_module);
164         return ngx_http_next_body_filter(r, in);
165     }
166 
167     last = 0;
168 
169     for (cl = in; cl; cl = cl->next) {
170         if (cl->buf->last_buf) {
171             cl->buf->last_buf = 0;
172             cl->buf->sync = 1;
173             last = 1;
174         }
175     }
176 
177     rc = ngx_http_next_body_filter(r, in);
178 
179     if (rc == NGX_ERROR || !last || conf->after_body.len == 0) {
180         return rc;
181     }
182 
183     if (ngx_http_subrequest(r, &conf->after_body, NULL, &sr, NULL, 0)
184         != NGX_OK)
185     {
186         return NGX_ERROR;
187     }
188 
189     ngx_http_set_ctx(r, NULL, ngx_http_addition_filter_module);
190 
191     return ngx_http_send_special(r, NGX_HTTP_LAST);
192 }
193 
194 
195 static ngx_int_t
196 ngx_http_addition_filter_init(ngx_conf_t *cf)
197 {
198     ngx_http_next_header_filter = ngx_http_top_header_filter;
199     ngx_http_top_header_filter = ngx_http_addition_header_filter;
200 
201     ngx_http_next_body_filter = ngx_http_top_body_filter;
202     ngx_http_top_body_filter = ngx_http_addition_body_filter;
203 
204     return NGX_OK;
205 }
206 
207 
208 static void *
209 ngx_http_addition_create_conf(ngx_conf_t *cf)
210 {
211     ngx_http_addition_conf_t  *conf;
212 
213     conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_addition_conf_t));
214     if (conf == NULL) {
215         return NULL;
216     }
217 
218     /*
219      * set by ngx_pcalloc():
220      *
221      *     conf->before_body = { 0, NULL };
222      *     conf->after_body = { 0, NULL };
223      *     conf->types = { NULL };
224      *     conf->types_keys = NULL;
225      */
226 
227     return conf;
228 }
229 
230 
231 static char *
232 ngx_http_addition_merge_conf(ngx_conf_t *cf, void *parent, void *child)
233 {
234     ngx_http_addition_conf_t *prev = parent;
235     ngx_http_addition_conf_t *conf = child;
236 
237     ngx_conf_merge_str_value(conf->before_body, prev->before_body, "");
238     ngx_conf_merge_str_value(conf->after_body, prev->after_body, "");
239 
240     if (ngx_http_merge_types(cf, conf->types_keys, &conf->types,
241                              prev->types_keys, &prev->types,
242                              ngx_http_html_default_types)
243         != NGX_OK)
244     {
245         return NGX_CONF_ERROR;
246     }
247 
248     return NGX_CONF_OK;
249 }
250 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.