comparison src/http/modules/ngx_http_addition_filter_module.c @ 178:87699398f955 NGINX_0_3_36

nginx 0.3.36 *) Feature: the ngx_http_addition_filter_module. *) Feature: the "proxy_pass" and "fastcgi_pass" directives may be used inside the "if" block. *) Feature: the "proxy_ignore_client_abort" and "fastcgi_ignore_client_abort" directives. *) Feature: the "$request_completion" variable. *) Feature: the ngx_http_perl_module supports the $r->request_method and $r->remote_addr. *) Feature: the ngx_http_ssi_module supports the "elif" command. *) Bugfix: the "\/" string in the expression of the "if" command of the ngx_http_ssi_module was treated incorrectly. *) Bugfix: in the regular expressions in the "if" command of the ngx_http_ssi_module. *) Bugfix: if the relative path was specified in the "client_body_temp_path", "proxy_temp_path", "fastcgi_temp_path", and "perl_modules" directives, then the directory was used relatively to a current path but not to a server prefix.
author Igor Sysoev <http://sysoev.ru>
date Wed, 05 Apr 2006 00:00:00 +0400
parents
children 4cd3e70c4d60
comparison
equal deleted inserted replaced
177:4a3ddd758222 178:87699398f955
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 unsigned before_body_sent:1;
20 unsigned after_body_sent:1;
21 } ngx_http_addition_ctx_t;
22
23
24 static ngx_int_t ngx_http_addition_filter_init(ngx_cycle_t *cycle);
25 static void *ngx_http_addition_create_conf(ngx_conf_t *cf);
26 static char *ngx_http_addition_merge_conf(ngx_conf_t *cf, void *parent,
27 void *child);
28
29
30 static ngx_command_t ngx_http_addition_commands[] = {
31
32 { ngx_string("add_before_body"),
33 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
34 ngx_conf_set_str_slot,
35 NGX_HTTP_LOC_CONF_OFFSET,
36 offsetof(ngx_http_addition_conf_t, before_body),
37 NULL },
38
39 { ngx_string("add_after_body"),
40 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
41 ngx_conf_set_str_slot,
42 NGX_HTTP_LOC_CONF_OFFSET,
43 offsetof(ngx_http_addition_conf_t, after_body),
44 NULL },
45
46 ngx_null_command
47 };
48
49
50 static ngx_http_module_t ngx_http_addition_filter_module_ctx = {
51 NULL, /* preconfiguration */
52 NULL, /* postconfiguration */
53
54 NULL, /* create main configuration */
55 NULL, /* init main configuration */
56
57 NULL, /* create server configuration */
58 NULL, /* merge server configuration */
59
60 ngx_http_addition_create_conf, /* create location configuration */
61 ngx_http_addition_merge_conf /* merge location configuration */
62 };
63
64
65 ngx_module_t ngx_http_addition_filter_module = {
66 NGX_MODULE_V1,
67 &ngx_http_addition_filter_module_ctx, /* module context */
68 ngx_http_addition_commands, /* module directives */
69 NGX_HTTP_MODULE, /* module type */
70 NULL, /* init master */
71 ngx_http_addition_filter_init, /* init module */
72 NULL, /* init process */
73 NULL, /* init thread */
74 NULL, /* exit thread */
75 NULL, /* exit process */
76 NULL, /* exit master */
77 NGX_MODULE_V1_PADDING
78 };
79
80
81 static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
82 static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
83
84
85 static ngx_int_t
86 ngx_http_addition_header_filter(ngx_http_request_t *r)
87 {
88 ngx_http_addition_ctx_t *ctx;
89 ngx_http_addition_conf_t *conf;
90
91 if (r->headers_out.status != NGX_HTTP_OK || r != r->main) {
92 return ngx_http_next_header_filter(r);
93 }
94
95 if (ngx_strncasecmp(r->headers_out.content_type.data, "text/html",
96 sizeof("text/html") - 1)
97 != 0)
98 {
99 return ngx_http_next_header_filter(r);
100 }
101
102 conf = ngx_http_get_module_loc_conf(r, ngx_http_addition_filter_module);
103
104 if (conf->before_body.len == 0 && conf->after_body.len == 0) {
105 return ngx_http_next_header_filter(r);
106 }
107
108 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_addition_ctx_t));
109 if (ctx == NULL) {
110 return NGX_ERROR;
111 }
112
113 ngx_http_set_ctx(r, ctx, ngx_http_addition_filter_module);
114
115 ngx_http_clear_content_length(r);
116 ngx_http_clear_accept_ranges(r);
117
118 return ngx_http_next_header_filter(r);
119 }
120
121
122 static ngx_int_t
123 ngx_http_addition_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
124 {
125 ngx_int_t rc;
126 ngx_uint_t last;
127 ngx_chain_t *cl;
128 ngx_http_addition_ctx_t *ctx;
129 ngx_http_addition_conf_t *conf;
130
131 if (in == NULL || r->header_only) {
132 return ngx_http_next_body_filter(r, in);
133 }
134
135 ctx = ngx_http_get_module_ctx(r, ngx_http_addition_filter_module);
136
137 if (ctx == NULL) {
138 return ngx_http_next_body_filter(r, in);
139 }
140
141 conf = ngx_http_get_module_loc_conf(r, ngx_http_addition_filter_module);
142
143 if (!ctx->before_body_sent) {
144 ctx->before_body_sent = 1;
145
146 if (conf->before_body.len) {
147 if (ngx_http_subrequest(r, &conf->before_body, NULL, 0) != NGX_OK) {
148 return NGX_ERROR;
149 }
150 }
151 }
152
153 last = 0;
154
155 for (cl = in; cl; cl = cl->next) {
156 if (cl->buf->last_buf) {
157 cl->buf->last_buf = 0;
158 last = 1;
159 }
160 }
161
162 rc = ngx_http_next_body_filter(r, in);
163
164 if (rc == NGX_ERROR
165 || !last
166 || ctx->after_body_sent
167 || conf->after_body.len == 0)
168 {
169 return rc;
170 }
171
172 if (ngx_http_subrequest(r, &conf->after_body, NULL, 0) != NGX_OK) {
173 return NGX_ERROR;
174 }
175
176 ctx->after_body_sent = 1;
177
178 return ngx_http_send_special(r, NGX_HTTP_LAST);
179 }
180
181
182 static ngx_int_t
183 ngx_http_addition_filter_init(ngx_cycle_t *cycle)
184 {
185 ngx_http_next_header_filter = ngx_http_top_header_filter;
186 ngx_http_top_header_filter = ngx_http_addition_header_filter;
187
188 ngx_http_next_body_filter = ngx_http_top_body_filter;
189 ngx_http_top_body_filter = ngx_http_addition_body_filter;
190
191 return NGX_OK;
192 }
193
194
195 static void *
196 ngx_http_addition_create_conf(ngx_conf_t *cf)
197 {
198 ngx_http_addition_conf_t *conf;
199
200 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_addition_conf_t));
201 if (conf == NULL) {
202 return NGX_CONF_ERROR;
203 }
204
205 /*
206 * set by ngx_pcalloc():
207 *
208 * conf->before_body.len = 0;
209 * conf->before_body.date = NULL;
210 * conf->after_body.len = 0;
211 * conf->after_body.date = NULL;
212 */
213
214 return conf;
215 }
216
217
218 static char *
219 ngx_http_addition_merge_conf(ngx_conf_t *cf, void *parent, void *child)
220 {
221 ngx_http_addition_conf_t *prev = parent;
222 ngx_http_addition_conf_t *conf = child;
223
224 ngx_conf_merge_str_value(conf->before_body, prev->before_body, "");
225 ngx_conf_merge_str_value(conf->after_body, prev->after_body, "");
226
227 return NGX_CONF_OK;
228 }