~ [ 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.6.26 ] ~ [ nginx-0.5.35 ] ~ [ nginx-0.5.20 ] ~ [ nginx-0.5.19 ] ~

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

~ [ 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.