Mercurial > hg > nginx-quic
annotate src/http/modules/ngx_http_addition_filter_module.c @ 4622:0dfdc3f732cb
Upstream: fixed ip_hash rebalancing with the "down" flag.
Due to weight being set to 0 for down peers, order of peers after sorting
wasn't the same as without the "down" flag (with down peers at the end),
resulting in client rebalancing for clients on other servers. The only
rebalancing which should happen after adding "down" to a server is one
for clients on the server.
The problem was introduced in r1377 (which fixed endless loop by setting
weight to 0 for down servers). The loop is no longer possible with new
smooth algorithm, so preserving original weight is safe.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 14 May 2012 09:58:07 +0000 |
parents | d620f497c50f |
children | 4a18bf1833a9 |
rev | line source |
---|---|
629 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
629 | 5 */ |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_http.h> | |
11 | |
12 | |
13 typedef struct { | |
2167 | 14 ngx_str_t before_body; |
15 ngx_str_t after_body; | |
16 | |
17 ngx_hash_t types; | |
18 ngx_array_t *types_keys; | |
629 | 19 } ngx_http_addition_conf_t; |
20 | |
21 | |
22 typedef struct { | |
2167 | 23 ngx_uint_t before_body_sent; |
629 | 24 } ngx_http_addition_ctx_t; |
25 | |
26 | |
27 static void *ngx_http_addition_create_conf(ngx_conf_t *cf); | |
28 static char *ngx_http_addition_merge_conf(ngx_conf_t *cf, void *parent, | |
29 void *child); | |
681 | 30 static ngx_int_t ngx_http_addition_filter_init(ngx_conf_t *cf); |
629 | 31 |
32 | |
33 static ngx_command_t ngx_http_addition_commands[] = { | |
34 | |
35 { ngx_string("add_before_body"), | |
36 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
37 ngx_conf_set_str_slot, | |
38 NGX_HTTP_LOC_CONF_OFFSET, | |
39 offsetof(ngx_http_addition_conf_t, before_body), | |
40 NULL }, | |
41 | |
42 { ngx_string("add_after_body"), | |
43 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
44 ngx_conf_set_str_slot, | |
45 NGX_HTTP_LOC_CONF_OFFSET, | |
46 offsetof(ngx_http_addition_conf_t, after_body), | |
47 NULL }, | |
48 | |
3146
29ba1de1ab0b
fix typo in addition_types directive name
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
49 { ngx_string("addition_types"), |
2167 | 50 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, |
51 ngx_http_types_slot, | |
52 NGX_HTTP_LOC_CONF_OFFSET, | |
53 offsetof(ngx_http_addition_conf_t, types_keys), | |
54 &ngx_http_html_default_types[0] }, | |
55 | |
629 | 56 ngx_null_command |
57 }; | |
58 | |
59 | |
60 static ngx_http_module_t ngx_http_addition_filter_module_ctx = { | |
61 NULL, /* preconfiguration */ | |
681 | 62 ngx_http_addition_filter_init, /* postconfiguration */ |
629 | 63 |
64 NULL, /* create main configuration */ | |
65 NULL, /* init main configuration */ | |
66 | |
67 NULL, /* create server configuration */ | |
68 NULL, /* merge server configuration */ | |
69 | |
70 ngx_http_addition_create_conf, /* create location configuration */ | |
71 ngx_http_addition_merge_conf /* merge location configuration */ | |
72 }; | |
73 | |
74 | |
75 ngx_module_t ngx_http_addition_filter_module = { | |
76 NGX_MODULE_V1, | |
77 &ngx_http_addition_filter_module_ctx, /* module context */ | |
78 ngx_http_addition_commands, /* module directives */ | |
79 NGX_HTTP_MODULE, /* module type */ | |
80 NULL, /* init master */ | |
681 | 81 NULL, /* init module */ |
629 | 82 NULL, /* init process */ |
83 NULL, /* init thread */ | |
84 NULL, /* exit thread */ | |
85 NULL, /* exit process */ | |
86 NULL, /* exit master */ | |
87 NGX_MODULE_V1_PADDING | |
88 }; | |
89 | |
90 | |
91 static ngx_http_output_header_filter_pt ngx_http_next_header_filter; | |
92 static ngx_http_output_body_filter_pt ngx_http_next_body_filter; | |
93 | |
94 | |
95 static ngx_int_t | |
96 ngx_http_addition_header_filter(ngx_http_request_t *r) | |
97 { | |
98 ngx_http_addition_ctx_t *ctx; | |
99 ngx_http_addition_conf_t *conf; | |
100 | |
2167 | 101 if (r->headers_out.status != NGX_HTTP_OK || r != r->main) { |
629 | 102 return ngx_http_next_header_filter(r); |
103 } | |
104 | |
631 | 105 conf = ngx_http_get_module_loc_conf(r, ngx_http_addition_filter_module); |
106 | |
107 if (conf->before_body.len == 0 && conf->after_body.len == 0) { | |
108 return ngx_http_next_header_filter(r); | |
109 } | |
110 | |
2167 | 111 if (ngx_http_test_content_type(r, &conf->types) == NULL) { |
629 | 112 return ngx_http_next_header_filter(r); |
113 } | |
114 | |
115 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_addition_ctx_t)); | |
116 if (ctx == NULL) { | |
117 return NGX_ERROR; | |
118 } | |
119 | |
120 ngx_http_set_ctx(r, ctx, ngx_http_addition_filter_module); | |
121 | |
122 ngx_http_clear_content_length(r); | |
123 ngx_http_clear_accept_ranges(r); | |
124 | |
125 return ngx_http_next_header_filter(r); | |
126 } | |
127 | |
128 | |
129 static ngx_int_t | |
130 ngx_http_addition_body_filter(ngx_http_request_t *r, ngx_chain_t *in) | |
131 { | |
132 ngx_int_t rc; | |
133 ngx_uint_t last; | |
134 ngx_chain_t *cl; | |
758
86bb73dc8d40
fix <!--#include virtual=... wait="yes" -->
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
135 ngx_http_request_t *sr; |
629 | 136 ngx_http_addition_ctx_t *ctx; |
137 ngx_http_addition_conf_t *conf; | |
138 | |
139 if (in == NULL || r->header_only) { | |
140 return ngx_http_next_body_filter(r, in); | |
141 } | |
142 | |
143 ctx = ngx_http_get_module_ctx(r, ngx_http_addition_filter_module); | |
144 | |
145 if (ctx == NULL) { | |
146 return ngx_http_next_body_filter(r, in); | |
147 } | |
148 | |
149 conf = ngx_http_get_module_loc_conf(r, ngx_http_addition_filter_module); | |
150 | |
151 if (!ctx->before_body_sent) { | |
152 ctx->before_body_sent = 1; | |
153 | |
154 if (conf->before_body.len) { | |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2167
diff
changeset
|
155 if (ngx_http_subrequest(r, &conf->before_body, NULL, &sr, NULL, 0) |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2167
diff
changeset
|
156 != NGX_OK) |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2167
diff
changeset
|
157 { |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2167
diff
changeset
|
158 return NGX_ERROR; |
629 | 159 } |
160 } | |
161 } | |
162 | |
846
c2cae54f2045
fix add_before_body without add_after_body
Igor Sysoev <igor@sysoev.ru>
parents:
777
diff
changeset
|
163 if (conf->after_body.len == 0) { |
c2cae54f2045
fix add_before_body without add_after_body
Igor Sysoev <igor@sysoev.ru>
parents:
777
diff
changeset
|
164 ngx_http_set_ctx(r, NULL, ngx_http_addition_filter_module); |
c2cae54f2045
fix add_before_body without add_after_body
Igor Sysoev <igor@sysoev.ru>
parents:
777
diff
changeset
|
165 return ngx_http_next_body_filter(r, in); |
c2cae54f2045
fix add_before_body without add_after_body
Igor Sysoev <igor@sysoev.ru>
parents:
777
diff
changeset
|
166 } |
c2cae54f2045
fix add_before_body without add_after_body
Igor Sysoev <igor@sysoev.ru>
parents:
777
diff
changeset
|
167 |
629 | 168 last = 0; |
169 | |
170 for (cl = in; cl; cl = cl->next) { | |
171 if (cl->buf->last_buf) { | |
172 cl->buf->last_buf = 0; | |
631 | 173 cl->buf->sync = 1; |
629 | 174 last = 1; |
175 } | |
176 } | |
177 | |
178 rc = ngx_http_next_body_filter(r, in); | |
179 | |
631 | 180 if (rc == NGX_ERROR || !last || conf->after_body.len == 0) { |
629 | 181 return rc; |
182 } | |
183 | |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2167
diff
changeset
|
184 if (ngx_http_subrequest(r, &conf->after_body, NULL, &sr, NULL, 0) |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2167
diff
changeset
|
185 != NGX_OK) |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2167
diff
changeset
|
186 { |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2167
diff
changeset
|
187 return NGX_ERROR; |
629 | 188 } |
189 | |
631 | 190 ngx_http_set_ctx(r, NULL, ngx_http_addition_filter_module); |
629 | 191 |
192 return ngx_http_send_special(r, NGX_HTTP_LAST); | |
193 } | |
194 | |
195 | |
196 static ngx_int_t | |
681 | 197 ngx_http_addition_filter_init(ngx_conf_t *cf) |
629 | 198 { |
199 ngx_http_next_header_filter = ngx_http_top_header_filter; | |
200 ngx_http_top_header_filter = ngx_http_addition_header_filter; | |
201 | |
202 ngx_http_next_body_filter = ngx_http_top_body_filter; | |
203 ngx_http_top_body_filter = ngx_http_addition_body_filter; | |
204 | |
205 return NGX_OK; | |
206 } | |
207 | |
208 | |
209 static void * | |
210 ngx_http_addition_create_conf(ngx_conf_t *cf) | |
211 { | |
212 ngx_http_addition_conf_t *conf; | |
213 | |
214 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_addition_conf_t)); | |
215 if (conf == NULL) { | |
2912
c7d57b539248
return NULL instead of NGX_CONF_ERROR on a create conf failure
Igor Sysoev <igor@sysoev.ru>
parents:
2377
diff
changeset
|
216 return NULL; |
629 | 217 } |
218 | |
219 /* | |
220 * set by ngx_pcalloc(): | |
221 * | |
2167 | 222 * conf->before_body = { 0, NULL }; |
223 * conf->after_body = { 0, NULL }; | |
224 * conf->types = { NULL }; | |
225 * conf->types_keys = NULL; | |
629 | 226 */ |
227 | |
228 return conf; | |
229 } | |
230 | |
231 | |
232 static char * | |
233 ngx_http_addition_merge_conf(ngx_conf_t *cf, void *parent, void *child) | |
234 { | |
235 ngx_http_addition_conf_t *prev = parent; | |
236 ngx_http_addition_conf_t *conf = child; | |
237 | |
238 ngx_conf_merge_str_value(conf->before_body, prev->before_body, ""); | |
239 ngx_conf_merge_str_value(conf->after_body, prev->after_body, ""); | |
240 | |
3372
6b8e5c882e47
support "*" in gzip_types, ssi_types, etc
Igor Sysoev <igor@sysoev.ru>
parents:
3146
diff
changeset
|
241 if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types, |
6b8e5c882e47
support "*" in gzip_types, ssi_types, etc
Igor Sysoev <igor@sysoev.ru>
parents:
3146
diff
changeset
|
242 &prev->types_keys, &prev->types, |
2167 | 243 ngx_http_html_default_types) |
244 != NGX_OK) | |
245 { | |
246 return NGX_CONF_ERROR; | |
247 } | |
248 | |
629 | 249 return NGX_CONF_OK; |
250 } |