nginxtra 1.2.8.8 → 1.4.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. data/bin/nginxtra +1 -1
  2. data/bin/nginxtra_rails +1 -1
  3. data/lib/nginxtra/version.rb +1 -1
  4. data/vendor/nginx/CHANGES +202 -63
  5. data/vendor/nginx/CHANGES.ru +208 -66
  6. data/vendor/nginx/auto/lib/md5/conf +3 -3
  7. data/vendor/nginx/auto/lib/perl/conf +3 -1
  8. data/vendor/nginx/auto/lib/perl/make +21 -16
  9. data/vendor/nginx/auto/lib/sha1/conf +1 -1
  10. data/vendor/nginx/auto/modules +25 -4
  11. data/vendor/nginx/auto/options +7 -1
  12. data/vendor/nginx/auto/sources +15 -1
  13. data/vendor/nginx/auto/unix +14 -0
  14. data/vendor/nginx/src/core/nginx.h +2 -2
  15. data/vendor/nginx/src/core/ngx_array.c +1 -7
  16. data/vendor/nginx/src/core/ngx_array.h +2 -2
  17. data/vendor/nginx/src/core/ngx_connection.c +13 -7
  18. data/vendor/nginx/src/core/ngx_connection.h +1 -2
  19. data/vendor/nginx/src/core/ngx_core.h +1 -2
  20. data/vendor/nginx/src/core/ngx_crypt.c +37 -0
  21. data/vendor/nginx/src/core/ngx_cycle.h +1 -1
  22. data/vendor/nginx/src/core/ngx_inet.c +219 -48
  23. data/vendor/nginx/src/core/ngx_inet.h +1 -1
  24. data/vendor/nginx/src/event/modules/ngx_devpoll_module.c +7 -1
  25. data/vendor/nginx/src/event/modules/ngx_eventport_module.c +1 -1
  26. data/vendor/nginx/src/event/ngx_event.c +5 -1
  27. data/vendor/nginx/src/event/ngx_event.h +1 -0
  28. data/vendor/nginx/src/event/ngx_event_connect.c +1 -1
  29. data/vendor/nginx/src/event/ngx_event_openssl.c +135 -9
  30. data/vendor/nginx/src/event/ngx_event_openssl.h +9 -0
  31. data/vendor/nginx/src/event/ngx_event_openssl_stapling.c +1749 -0
  32. data/vendor/nginx/src/http/modules/ngx_http_addition_filter_module.c +1 -0
  33. data/vendor/nginx/src/http/modules/ngx_http_chunked_filter_module.c +1 -0
  34. data/vendor/nginx/src/http/modules/ngx_http_fastcgi_module.c +5 -0
  35. data/vendor/nginx/src/http/modules/ngx_http_flv_module.c +4 -0
  36. data/vendor/nginx/src/http/modules/ngx_http_geo_module.c +7 -8
  37. data/vendor/nginx/src/http/modules/ngx_http_geoip_module.c +10 -12
  38. data/vendor/nginx/src/http/modules/ngx_http_gunzip_filter_module.c +677 -0
  39. data/vendor/nginx/src/http/modules/ngx_http_gzip_filter_module.c +3 -0
  40. data/vendor/nginx/src/http/modules/ngx_http_gzip_static_module.c +36 -10
  41. data/vendor/nginx/src/http/modules/ngx_http_headers_filter_module.c +31 -13
  42. data/vendor/nginx/src/http/modules/ngx_http_image_filter_module.c +13 -0
  43. data/vendor/nginx/src/http/modules/ngx_http_limit_conn_module.c +18 -2
  44. data/vendor/nginx/src/http/modules/ngx_http_limit_req_module.c +19 -2
  45. data/vendor/nginx/src/http/modules/ngx_http_map_module.c +1 -1
  46. data/vendor/nginx/src/http/modules/ngx_http_memcached_module.c +60 -8
  47. data/vendor/nginx/src/http/modules/ngx_http_mp4_module.c +4 -8
  48. data/vendor/nginx/src/http/modules/ngx_http_not_modified_filter_module.c +126 -29
  49. data/vendor/nginx/src/http/modules/ngx_http_proxy_module.c +59 -301
  50. data/vendor/nginx/src/http/modules/ngx_http_range_filter_module.c +34 -6
  51. data/vendor/nginx/src/http/modules/ngx_http_realip_module.c +13 -12
  52. data/vendor/nginx/src/http/modules/ngx_http_scgi_module.c +30 -11
  53. data/vendor/nginx/src/http/modules/ngx_http_ssi_filter_module.c +1 -0
  54. data/vendor/nginx/src/http/modules/ngx_http_ssl_module.c +155 -4
  55. data/vendor/nginx/src/http/modules/ngx_http_ssl_module.h +6 -0
  56. data/vendor/nginx/src/http/modules/ngx_http_static_module.c +4 -0
  57. data/vendor/nginx/src/http/modules/ngx_http_stub_status_module.c +90 -3
  58. data/vendor/nginx/src/http/modules/ngx_http_sub_filter_module.c +1 -0
  59. data/vendor/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c +5 -0
  60. data/vendor/nginx/src/http/modules/ngx_http_upstream_least_conn_module.c +5 -0
  61. data/vendor/nginx/src/http/modules/ngx_http_uwsgi_module.c +14 -1
  62. data/vendor/nginx/src/http/modules/ngx_http_xslt_filter_module.c +1 -0
  63. data/vendor/nginx/src/http/modules/perl/Makefile.PL +4 -2
  64. data/vendor/nginx/src/http/modules/perl/nginx.pm +1 -1
  65. data/vendor/nginx/src/http/modules/perl/nginx.xs +36 -3
  66. data/vendor/nginx/src/http/ngx_http.c +24 -1
  67. data/vendor/nginx/src/http/ngx_http.h +26 -2
  68. data/vendor/nginx/src/http/ngx_http_core_module.c +136 -10
  69. data/vendor/nginx/src/http/ngx_http_core_module.h +37 -13
  70. data/vendor/nginx/src/http/ngx_http_header_filter_module.c +9 -2
  71. data/vendor/nginx/src/http/ngx_http_parse.c +404 -0
  72. data/vendor/nginx/src/http/ngx_http_request.c +840 -517
  73. data/vendor/nginx/src/http/ngx_http_request.h +37 -25
  74. data/vendor/nginx/src/http/ngx_http_request_body.c +585 -156
  75. data/vendor/nginx/src/http/ngx_http_spdy.c +2882 -0
  76. data/vendor/nginx/src/http/ngx_http_spdy.h +235 -0
  77. data/vendor/nginx/src/http/ngx_http_spdy_filter_module.c +999 -0
  78. data/vendor/nginx/src/http/ngx_http_spdy_module.c +351 -0
  79. data/vendor/nginx/src/http/ngx_http_spdy_module.h +36 -0
  80. data/vendor/nginx/src/http/ngx_http_special_response.c +3 -1
  81. data/vendor/nginx/src/http/ngx_http_upstream.c +415 -26
  82. data/vendor/nginx/src/http/ngx_http_upstream.h +11 -1
  83. data/vendor/nginx/src/http/ngx_http_upstream_round_robin.c +2 -45
  84. data/vendor/nginx/src/http/ngx_http_upstream_round_robin.h +0 -2
  85. data/vendor/nginx/src/http/ngx_http_variables.c +72 -12
  86. data/vendor/nginx/src/mail/ngx_mail.h +2 -2
  87. data/vendor/nginx/src/mail/ngx_mail_auth_http_module.c +35 -25
  88. data/vendor/nginx/src/mail/ngx_mail_core_module.c +5 -1
  89. metadata +9 -2
@@ -0,0 +1,351 @@
1
+
2
+ /*
3
+ * Copyright (C) Nginx, Inc.
4
+ * Copyright (C) Valentin V. Bartenev
5
+ */
6
+
7
+
8
+ #include <ngx_config.h>
9
+ #include <ngx_core.h>
10
+ #include <ngx_http.h>
11
+ #include <ngx_http_spdy_module.h>
12
+
13
+
14
+ static ngx_int_t ngx_http_spdy_add_variables(ngx_conf_t *cf);
15
+
16
+ static ngx_int_t ngx_http_spdy_variable(ngx_http_request_t *r,
17
+ ngx_http_variable_value_t *v, uintptr_t data);
18
+ static ngx_int_t ngx_http_spdy_request_priority_variable(ngx_http_request_t *r,
19
+ ngx_http_variable_value_t *v, uintptr_t data);
20
+
21
+ static ngx_int_t ngx_http_spdy_module_init(ngx_cycle_t *cycle);
22
+
23
+ static void *ngx_http_spdy_create_main_conf(ngx_conf_t *cf);
24
+ static char *ngx_http_spdy_init_main_conf(ngx_conf_t *cf, void *conf);
25
+
26
+ static void *ngx_http_spdy_create_srv_conf(ngx_conf_t *cf);
27
+ static char *ngx_http_spdy_merge_srv_conf(ngx_conf_t *cf, void *parent,
28
+ void *child);
29
+
30
+ static char *ngx_http_spdy_recv_buffer_size(ngx_conf_t *cf, void *post,
31
+ void *data);
32
+ static char *ngx_http_spdy_pool_size(ngx_conf_t *cf, void *post, void *data);
33
+ static char *ngx_http_spdy_streams_index_mask(ngx_conf_t *cf, void *post,
34
+ void *data);
35
+
36
+
37
+ static ngx_conf_num_bounds_t ngx_http_spdy_headers_comp_bounds = {
38
+ ngx_conf_check_num_bounds, 0, 9
39
+ };
40
+
41
+ static ngx_conf_post_t ngx_http_spdy_recv_buffer_size_post =
42
+ { ngx_http_spdy_recv_buffer_size };
43
+ static ngx_conf_post_t ngx_http_spdy_pool_size_post =
44
+ { ngx_http_spdy_pool_size };
45
+ static ngx_conf_post_t ngx_http_spdy_streams_index_mask_post =
46
+ { ngx_http_spdy_streams_index_mask };
47
+
48
+
49
+ static ngx_command_t ngx_http_spdy_commands[] = {
50
+
51
+ { ngx_string("spdy_recv_buffer_size"),
52
+ NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
53
+ ngx_conf_set_size_slot,
54
+ NGX_HTTP_MAIN_CONF_OFFSET,
55
+ offsetof(ngx_http_spdy_main_conf_t, recv_buffer_size),
56
+ &ngx_http_spdy_recv_buffer_size_post },
57
+
58
+ { ngx_string("spdy_pool_size"),
59
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
60
+ ngx_conf_set_size_slot,
61
+ NGX_HTTP_SRV_CONF_OFFSET,
62
+ offsetof(ngx_http_spdy_srv_conf_t, pool_size),
63
+ &ngx_http_spdy_pool_size_post },
64
+
65
+ { ngx_string("spdy_max_concurrent_streams"),
66
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
67
+ ngx_conf_set_num_slot,
68
+ NGX_HTTP_SRV_CONF_OFFSET,
69
+ offsetof(ngx_http_spdy_srv_conf_t, concurrent_streams),
70
+ NULL },
71
+
72
+ { ngx_string("spdy_streams_index_size"),
73
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
74
+ ngx_conf_set_num_slot,
75
+ NGX_HTTP_SRV_CONF_OFFSET,
76
+ offsetof(ngx_http_spdy_srv_conf_t, streams_index_mask),
77
+ &ngx_http_spdy_streams_index_mask_post },
78
+
79
+ { ngx_string("spdy_recv_timeout"),
80
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
81
+ ngx_conf_set_msec_slot,
82
+ NGX_HTTP_SRV_CONF_OFFSET,
83
+ offsetof(ngx_http_spdy_srv_conf_t, recv_timeout),
84
+ NULL },
85
+
86
+ { ngx_string("spdy_keepalive_timeout"),
87
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
88
+ ngx_conf_set_msec_slot,
89
+ NGX_HTTP_SRV_CONF_OFFSET,
90
+ offsetof(ngx_http_spdy_srv_conf_t, keepalive_timeout),
91
+ NULL },
92
+
93
+ { ngx_string("spdy_headers_comp"),
94
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
95
+ ngx_conf_set_num_slot,
96
+ NGX_HTTP_SRV_CONF_OFFSET,
97
+ offsetof(ngx_http_spdy_srv_conf_t, headers_comp),
98
+ &ngx_http_spdy_headers_comp_bounds },
99
+
100
+ ngx_null_command
101
+ };
102
+
103
+
104
+ static ngx_http_module_t ngx_http_spdy_module_ctx = {
105
+ ngx_http_spdy_add_variables, /* preconfiguration */
106
+ NULL, /* postconfiguration */
107
+
108
+ ngx_http_spdy_create_main_conf, /* create main configuration */
109
+ ngx_http_spdy_init_main_conf, /* init main configuration */
110
+
111
+ ngx_http_spdy_create_srv_conf, /* create server configuration */
112
+ ngx_http_spdy_merge_srv_conf, /* merge server configuration */
113
+
114
+ NULL, /* create location configuration */
115
+ NULL /* merge location configuration */
116
+ };
117
+
118
+
119
+ ngx_module_t ngx_http_spdy_module = {
120
+ NGX_MODULE_V1,
121
+ &ngx_http_spdy_module_ctx, /* module context */
122
+ ngx_http_spdy_commands, /* module directives */
123
+ NGX_HTTP_MODULE, /* module type */
124
+ NULL, /* init master */
125
+ ngx_http_spdy_module_init, /* init module */
126
+ NULL, /* init process */
127
+ NULL, /* init thread */
128
+ NULL, /* exit thread */
129
+ NULL, /* exit process */
130
+ NULL, /* exit master */
131
+ NGX_MODULE_V1_PADDING
132
+ };
133
+
134
+
135
+ static ngx_http_variable_t ngx_http_spdy_vars[] = {
136
+
137
+ { ngx_string("spdy"), NULL,
138
+ ngx_http_spdy_variable, 0, 0, 0 },
139
+
140
+ { ngx_string("spdy_request_priority"), NULL,
141
+ ngx_http_spdy_request_priority_variable, 0, 0, 0 },
142
+
143
+ { ngx_null_string, NULL, NULL, 0, 0, 0 }
144
+ };
145
+
146
+
147
+ static ngx_int_t
148
+ ngx_http_spdy_add_variables(ngx_conf_t *cf)
149
+ {
150
+ ngx_http_variable_t *var, *v;
151
+
152
+ for (v = ngx_http_spdy_vars; v->name.len; v++) {
153
+ var = ngx_http_add_variable(cf, &v->name, v->flags);
154
+ if (var == NULL) {
155
+ return NGX_ERROR;
156
+ }
157
+
158
+ var->get_handler = v->get_handler;
159
+ var->data = v->data;
160
+ }
161
+
162
+ return NGX_OK;
163
+ }
164
+
165
+
166
+ static ngx_int_t
167
+ ngx_http_spdy_variable(ngx_http_request_t *r,
168
+ ngx_http_variable_value_t *v, uintptr_t data)
169
+ {
170
+ if (r->spdy_stream) {
171
+ v->len = 1;
172
+ v->valid = 1;
173
+ v->no_cacheable = 0;
174
+ v->not_found = 0;
175
+ v->data = (u_char *) "2";
176
+
177
+ return NGX_OK;
178
+ }
179
+
180
+ *v = ngx_http_variable_null_value;
181
+
182
+ return NGX_OK;
183
+ }
184
+
185
+
186
+ static ngx_int_t
187
+ ngx_http_spdy_request_priority_variable(ngx_http_request_t *r,
188
+ ngx_http_variable_value_t *v, uintptr_t data)
189
+ {
190
+ if (r->spdy_stream) {
191
+ v->len = 1;
192
+ v->valid = 1;
193
+ v->no_cacheable = 0;
194
+ v->not_found = 0;
195
+
196
+ v->data = ngx_pnalloc(r->pool, 1);
197
+ if (v->data == NULL) {
198
+ return NGX_ERROR;
199
+ }
200
+
201
+ v->data[0] = '0' + (u_char) r->spdy_stream->priority;
202
+
203
+ return NGX_OK;
204
+ }
205
+
206
+ *v = ngx_http_variable_null_value;
207
+
208
+ return NGX_OK;
209
+ }
210
+
211
+
212
+ static ngx_int_t
213
+ ngx_http_spdy_module_init(ngx_cycle_t *cycle)
214
+ {
215
+ ngx_http_spdy_request_headers_init();
216
+
217
+ return NGX_OK;
218
+ }
219
+
220
+
221
+ static void *
222
+ ngx_http_spdy_create_main_conf(ngx_conf_t *cf)
223
+ {
224
+ ngx_http_spdy_main_conf_t *smcf;
225
+
226
+ smcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_spdy_main_conf_t));
227
+ if (smcf == NULL) {
228
+ return NULL;
229
+ }
230
+
231
+ smcf->recv_buffer_size = NGX_CONF_UNSET_SIZE;
232
+
233
+ return smcf;
234
+ }
235
+
236
+
237
+ static char *
238
+ ngx_http_spdy_init_main_conf(ngx_conf_t *cf, void *conf)
239
+ {
240
+ ngx_http_spdy_main_conf_t *smcf = conf;
241
+
242
+ if (smcf->recv_buffer_size == NGX_CONF_UNSET_SIZE) {
243
+ smcf->recv_buffer_size = 256 * 1024;
244
+ }
245
+
246
+ return NGX_CONF_OK;
247
+ }
248
+
249
+
250
+ static void *
251
+ ngx_http_spdy_create_srv_conf(ngx_conf_t *cf)
252
+ {
253
+ ngx_http_spdy_srv_conf_t *sscf;
254
+
255
+ sscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_spdy_srv_conf_t));
256
+ if (sscf == NULL) {
257
+ return NULL;
258
+ }
259
+
260
+ sscf->pool_size = NGX_CONF_UNSET_SIZE;
261
+
262
+ sscf->concurrent_streams = NGX_CONF_UNSET_UINT;
263
+ sscf->streams_index_mask = NGX_CONF_UNSET_UINT;
264
+
265
+ sscf->recv_timeout = NGX_CONF_UNSET_MSEC;
266
+ sscf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
267
+
268
+ sscf->headers_comp = NGX_CONF_UNSET;
269
+
270
+ return sscf;
271
+ }
272
+
273
+
274
+ static char *
275
+ ngx_http_spdy_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
276
+ {
277
+ ngx_http_spdy_srv_conf_t *prev = parent;
278
+ ngx_http_spdy_srv_conf_t *conf = child;
279
+
280
+ ngx_conf_merge_size_value(conf->pool_size, prev->pool_size, 4096);
281
+
282
+ ngx_conf_merge_uint_value(conf->concurrent_streams,
283
+ prev->concurrent_streams, 100);
284
+
285
+ ngx_conf_merge_uint_value(conf->streams_index_mask,
286
+ prev->streams_index_mask, 32 - 1);
287
+
288
+ ngx_conf_merge_msec_value(conf->recv_timeout,
289
+ prev->recv_timeout, 30000);
290
+ ngx_conf_merge_msec_value(conf->keepalive_timeout,
291
+ prev->keepalive_timeout, 180000);
292
+
293
+ ngx_conf_merge_value(conf->headers_comp, prev->headers_comp, 0);
294
+
295
+ return NGX_CONF_OK;
296
+ }
297
+
298
+
299
+ static char *
300
+ ngx_http_spdy_recv_buffer_size(ngx_conf_t *cf, void *post, void *data)
301
+ {
302
+ size_t *sp = data;
303
+
304
+ if (*sp <= 2 * NGX_SPDY_STATE_BUFFER_SIZE) {
305
+ return "value is too small";
306
+ }
307
+
308
+ return NGX_CONF_OK;
309
+ }
310
+
311
+
312
+ static char *
313
+ ngx_http_spdy_pool_size(ngx_conf_t *cf, void *post, void *data)
314
+ {
315
+ size_t *sp = data;
316
+
317
+ if (*sp < NGX_MIN_POOL_SIZE) {
318
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
319
+ "the pool size must be no less than %uz",
320
+ NGX_MIN_POOL_SIZE);
321
+ return NGX_CONF_ERROR;
322
+ }
323
+
324
+ if (*sp % NGX_POOL_ALIGNMENT) {
325
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
326
+ "the pool size must be a multiple of %uz",
327
+ NGX_POOL_ALIGNMENT);
328
+ return NGX_CONF_ERROR;
329
+ }
330
+
331
+ return NGX_CONF_OK;
332
+ }
333
+
334
+
335
+ static char *
336
+ ngx_http_spdy_streams_index_mask(ngx_conf_t *cf, void *post, void *data)
337
+ {
338
+ ngx_uint_t *np = data;
339
+
340
+ ngx_uint_t mask;
341
+
342
+ mask = *np - 1;
343
+
344
+ if (*np == 0 || (*np & mask)) {
345
+ return "must be a power of two";
346
+ }
347
+
348
+ *np = mask;
349
+
350
+ return NGX_CONF_OK;
351
+ }
@@ -0,0 +1,36 @@
1
+
2
+ /*
3
+ * Copyright (C) Nginx, Inc.
4
+ * Copyright (C) Valentin V. Bartenev
5
+ */
6
+
7
+
8
+ #ifndef _NGX_HTTP_SPDY_MODULE_H_INCLUDED_
9
+ #define _NGX_HTTP_SPDY_MODULE_H_INCLUDED_
10
+
11
+
12
+ #include <ngx_config.h>
13
+ #include <ngx_core.h>
14
+ #include <ngx_http.h>
15
+
16
+
17
+ typedef struct {
18
+ size_t recv_buffer_size;
19
+ u_char *recv_buffer;
20
+ } ngx_http_spdy_main_conf_t;
21
+
22
+
23
+ typedef struct {
24
+ size_t pool_size;
25
+ ngx_uint_t concurrent_streams;
26
+ ngx_uint_t streams_index_mask;
27
+ ngx_msec_t recv_timeout;
28
+ ngx_msec_t keepalive_timeout;
29
+ ngx_int_t headers_comp;
30
+ } ngx_http_spdy_srv_conf_t;
31
+
32
+
33
+ extern ngx_module_t ngx_http_spdy_module;
34
+
35
+
36
+ #endif /* _NGX_HTTP_SPDY_MODULE_H_INCLUDED_ */
@@ -421,7 +421,7 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
421
421
  r->expect_tested = 1;
422
422
 
423
423
  if (ngx_http_discard_request_body(r) != NGX_OK) {
424
- error = NGX_HTTP_INTERNAL_SERVER_ERROR;
424
+ r->keepalive = 0;
425
425
  }
426
426
 
427
427
  if (clcf->msie_refresh
@@ -657,6 +657,7 @@ ngx_http_send_special_response(ngx_http_request_t *r,
657
657
 
658
658
  ngx_http_clear_accept_ranges(r);
659
659
  ngx_http_clear_last_modified(r);
660
+ ngx_http_clear_etag(r);
660
661
 
661
662
  rc = ngx_http_send_header(r);
662
663
 
@@ -755,6 +756,7 @@ ngx_http_send_refresh(ngx_http_request_t *r)
755
756
 
756
757
  ngx_http_clear_accept_ranges(r);
757
758
  ngx_http_clear_last_modified(r);
759
+ ngx_http_clear_etag(r);
758
760
 
759
761
  rc = ngx_http_send_header(r);
760
762
 
@@ -46,6 +46,16 @@ static void ngx_http_upstream_process_body_in_memory(ngx_http_request_t *r,
46
46
  ngx_http_upstream_t *u);
47
47
  static void ngx_http_upstream_send_response(ngx_http_request_t *r,
48
48
  ngx_http_upstream_t *u);
49
+ static void ngx_http_upstream_upgrade(ngx_http_request_t *r,
50
+ ngx_http_upstream_t *u);
51
+ static void ngx_http_upstream_upgraded_read_downstream(ngx_http_request_t *r);
52
+ static void ngx_http_upstream_upgraded_write_downstream(ngx_http_request_t *r);
53
+ static void ngx_http_upstream_upgraded_read_upstream(ngx_http_request_t *r,
54
+ ngx_http_upstream_t *u);
55
+ static void ngx_http_upstream_upgraded_write_upstream(ngx_http_request_t *r,
56
+ ngx_http_upstream_t *u);
57
+ static void ngx_http_upstream_process_upgraded(ngx_http_request_t *r,
58
+ ngx_uint_t from_upstream, ngx_uint_t do_write);
49
59
  static void
50
60
  ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r);
51
61
  static void
@@ -134,6 +144,9 @@ static char *ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy);
134
144
  static char *ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd,
135
145
  void *conf);
136
146
 
147
+ static ngx_addr_t *ngx_http_upstream_get_local(ngx_http_request_t *r,
148
+ ngx_http_upstream_local_t *local);
149
+
137
150
  static void *ngx_http_upstream_create_main_conf(ngx_conf_t *cf);
138
151
  static char *ngx_http_upstream_init_main_conf(ngx_conf_t *cf, void *conf);
139
152
 
@@ -427,6 +440,13 @@ ngx_http_upstream_init(ngx_http_request_t *r)
427
440
  ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
428
441
  "http init upstream, client timer: %d", c->read->timer_set);
429
442
 
443
+ #if (NGX_HTTP_SPDY)
444
+ if (r->spdy_stream) {
445
+ ngx_http_upstream_init_request(r);
446
+ return;
447
+ }
448
+ #endif
449
+
430
450
  if (c->read->timer_set) {
431
451
  ngx_del_timer(c->read);
432
452
  }
@@ -507,7 +527,7 @@ ngx_http_upstream_init_request(ngx_http_request_t *r)
507
527
  return;
508
528
  }
509
529
 
510
- u->peer.local = u->conf->local;
530
+ u->peer.local = ngx_http_upstream_get_local(r, u->conf->local);
511
531
 
512
532
  clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
513
533
 
@@ -1005,6 +1025,12 @@ ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
1005
1025
  return;
1006
1026
  }
1007
1027
 
1028
+ #if (NGX_HTTP_SPDY)
1029
+ if (r->spdy_stream) {
1030
+ return;
1031
+ }
1032
+ #endif
1033
+
1008
1034
  #if (NGX_HAVE_KQUEUE)
1009
1035
 
1010
1036
  if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
@@ -1111,8 +1137,6 @@ ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u)
1111
1137
 
1112
1138
  r->connection->log->action = "connecting to upstream";
1113
1139
 
1114
- r->connection->single_connection = 0;
1115
-
1116
1140
  if (u->state && u->state->response_sec) {
1117
1141
  tp = ngx_timeofday();
1118
1142
  u->state->response_sec = tp->sec - u->state->response_sec;
@@ -1330,6 +1354,7 @@ ngx_http_upstream_reinit(ngx_http_request_t *r, ngx_http_upstream_t *u)
1330
1354
  }
1331
1355
 
1332
1356
  u->keepalive = 0;
1357
+ u->upgrade = 0;
1333
1358
 
1334
1359
  ngx_memzero(&u->headers_in, sizeof(ngx_http_upstream_headers_in_t));
1335
1360
  u->headers_in.content_length_n = -1;
@@ -2081,6 +2106,11 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
2081
2106
  return;
2082
2107
  }
2083
2108
 
2109
+ if (u->upgrade) {
2110
+ ngx_http_upstream_upgrade(r, u);
2111
+ return;
2112
+ }
2113
+
2084
2114
  c = r->connection;
2085
2115
 
2086
2116
  if (r->header_only) {
@@ -2363,6 +2393,284 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
2363
2393
  }
2364
2394
 
2365
2395
 
2396
+ static void
2397
+ ngx_http_upstream_upgrade(ngx_http_request_t *r, ngx_http_upstream_t *u)
2398
+ {
2399
+ int tcp_nodelay;
2400
+ ngx_connection_t *c;
2401
+ ngx_http_core_loc_conf_t *clcf;
2402
+
2403
+ c = r->connection;
2404
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
2405
+
2406
+ /* TODO: prevent upgrade if not requested or not possible */
2407
+
2408
+ r->keepalive = 0;
2409
+ c->log->action = "proxying upgraded connection";
2410
+
2411
+ u->read_event_handler = ngx_http_upstream_upgraded_read_upstream;
2412
+ u->write_event_handler = ngx_http_upstream_upgraded_write_upstream;
2413
+ r->read_event_handler = ngx_http_upstream_upgraded_read_downstream;
2414
+ r->write_event_handler = ngx_http_upstream_upgraded_write_downstream;
2415
+
2416
+ if (clcf->tcp_nodelay) {
2417
+ tcp_nodelay = 1;
2418
+
2419
+ if (c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) {
2420
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
2421
+
2422
+ if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
2423
+ (const void *) &tcp_nodelay, sizeof(int)) == -1)
2424
+ {
2425
+ ngx_connection_error(c, ngx_socket_errno,
2426
+ "setsockopt(TCP_NODELAY) failed");
2427
+ ngx_http_upstream_finalize_request(r, u, 0);
2428
+ return;
2429
+ }
2430
+
2431
+ c->tcp_nodelay = NGX_TCP_NODELAY_SET;
2432
+ }
2433
+
2434
+ if (u->peer.connection->tcp_nodelay == NGX_TCP_NODELAY_UNSET) {
2435
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, u->peer.connection->log, 0,
2436
+ "tcp_nodelay");
2437
+
2438
+ if (setsockopt(u->peer.connection->fd, IPPROTO_TCP, TCP_NODELAY,
2439
+ (const void *) &tcp_nodelay, sizeof(int)) == -1)
2440
+ {
2441
+ ngx_connection_error(u->peer.connection, ngx_socket_errno,
2442
+ "setsockopt(TCP_NODELAY) failed");
2443
+ ngx_http_upstream_finalize_request(r, u, 0);
2444
+ return;
2445
+ }
2446
+
2447
+ u->peer.connection->tcp_nodelay = NGX_TCP_NODELAY_SET;
2448
+ }
2449
+ }
2450
+
2451
+ if (ngx_http_send_special(r, NGX_HTTP_FLUSH) == NGX_ERROR) {
2452
+ ngx_http_upstream_finalize_request(r, u, 0);
2453
+ return;
2454
+ }
2455
+
2456
+ if (u->peer.connection->read->ready
2457
+ || u->buffer.pos != u->buffer.last)
2458
+ {
2459
+ ngx_http_upstream_process_upgraded(r, 1, 1);
2460
+ }
2461
+
2462
+ if (c->read->ready
2463
+ || r->header_in->pos != r->header_in->last)
2464
+ {
2465
+ ngx_http_upstream_process_upgraded(r, 0, 1);
2466
+ }
2467
+ }
2468
+
2469
+
2470
+ static void
2471
+ ngx_http_upstream_upgraded_read_downstream(ngx_http_request_t *r)
2472
+ {
2473
+ ngx_http_upstream_process_upgraded(r, 0, 0);
2474
+ }
2475
+
2476
+
2477
+ static void
2478
+ ngx_http_upstream_upgraded_write_downstream(ngx_http_request_t *r)
2479
+ {
2480
+ ngx_http_upstream_process_upgraded(r, 1, 1);
2481
+ }
2482
+
2483
+
2484
+ static void
2485
+ ngx_http_upstream_upgraded_read_upstream(ngx_http_request_t *r,
2486
+ ngx_http_upstream_t *u)
2487
+ {
2488
+ ngx_http_upstream_process_upgraded(r, 1, 0);
2489
+ }
2490
+
2491
+
2492
+ static void
2493
+ ngx_http_upstream_upgraded_write_upstream(ngx_http_request_t *r,
2494
+ ngx_http_upstream_t *u)
2495
+ {
2496
+ ngx_http_upstream_process_upgraded(r, 0, 1);
2497
+ }
2498
+
2499
+
2500
+ static void
2501
+ ngx_http_upstream_process_upgraded(ngx_http_request_t *r,
2502
+ ngx_uint_t from_upstream, ngx_uint_t do_write)
2503
+ {
2504
+ size_t size;
2505
+ ssize_t n;
2506
+ ngx_buf_t *b;
2507
+ ngx_connection_t *c, *downstream, *upstream, *dst, *src;
2508
+ ngx_http_upstream_t *u;
2509
+ ngx_http_core_loc_conf_t *clcf;
2510
+
2511
+ c = r->connection;
2512
+ u = r->upstream;
2513
+
2514
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
2515
+ "http upstream process upgraded, fu:%ui", from_upstream);
2516
+
2517
+ downstream = c;
2518
+ upstream = u->peer.connection;
2519
+
2520
+ if (downstream->write->timedout) {
2521
+ c->timedout = 1;
2522
+ ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out");
2523
+ ngx_http_upstream_finalize_request(r, u, NGX_HTTP_REQUEST_TIME_OUT);
2524
+ return;
2525
+ }
2526
+
2527
+ if (upstream->read->timedout || upstream->write->timedout) {
2528
+ ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
2529
+ ngx_http_upstream_finalize_request(r, u, 0);
2530
+ return;
2531
+ }
2532
+
2533
+ if (from_upstream) {
2534
+ src = upstream;
2535
+ dst = downstream;
2536
+ b = &u->buffer;
2537
+
2538
+ } else {
2539
+ src = downstream;
2540
+ dst = upstream;
2541
+ b = &u->from_client;
2542
+
2543
+ if (r->header_in->last > r->header_in->pos) {
2544
+ b = r->header_in;
2545
+ b->end = b->last;
2546
+ do_write = 1;
2547
+ }
2548
+
2549
+ if (b->start == NULL) {
2550
+ b->start = ngx_palloc(r->pool, u->conf->buffer_size);
2551
+ if (b->start == NULL) {
2552
+ ngx_http_upstream_finalize_request(r, u, 0);
2553
+ return;
2554
+ }
2555
+
2556
+ b->pos = b->start;
2557
+ b->last = b->start;
2558
+ b->end = b->start + u->conf->buffer_size;
2559
+ b->temporary = 1;
2560
+ b->tag = u->output.tag;
2561
+ }
2562
+ }
2563
+
2564
+ for ( ;; ) {
2565
+
2566
+ if (do_write) {
2567
+
2568
+ size = b->last - b->pos;
2569
+
2570
+ if (size && dst->write->ready) {
2571
+
2572
+ n = dst->send(dst, b->pos, size);
2573
+
2574
+ if (n == NGX_ERROR) {
2575
+ ngx_http_upstream_finalize_request(r, u, 0);
2576
+ return;
2577
+ }
2578
+
2579
+ if (n > 0) {
2580
+ b->pos += n;
2581
+
2582
+ if (b->pos == b->last) {
2583
+ b->pos = b->start;
2584
+ b->last = b->start;
2585
+ }
2586
+ }
2587
+ }
2588
+ }
2589
+
2590
+ size = b->end - b->last;
2591
+
2592
+ if (size && src->read->ready) {
2593
+
2594
+ n = src->recv(src, b->last, size);
2595
+
2596
+ if (n == NGX_AGAIN || n == 0) {
2597
+ break;
2598
+ }
2599
+
2600
+ if (n > 0) {
2601
+ do_write = 1;
2602
+ b->last += n;
2603
+
2604
+ continue;
2605
+ }
2606
+
2607
+ if (n == NGX_ERROR) {
2608
+ src->read->eof = 1;
2609
+ }
2610
+ }
2611
+
2612
+ break;
2613
+ }
2614
+
2615
+ if ((upstream->read->eof && u->buffer.pos == u->buffer.last)
2616
+ || (downstream->read->eof && u->from_client.pos == u->from_client.last)
2617
+ || (downstream->read->eof && upstream->read->eof))
2618
+ {
2619
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
2620
+ "http upstream upgraded done");
2621
+ ngx_http_upstream_finalize_request(r, u, 0);
2622
+ return;
2623
+ }
2624
+
2625
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
2626
+
2627
+ if (ngx_handle_write_event(upstream->write, u->conf->send_lowat)
2628
+ != NGX_OK)
2629
+ {
2630
+ ngx_http_upstream_finalize_request(r, u, 0);
2631
+ return;
2632
+ }
2633
+
2634
+ if (upstream->write->active && !upstream->write->ready) {
2635
+ ngx_add_timer(upstream->write, u->conf->send_timeout);
2636
+
2637
+ } else if (upstream->write->timer_set) {
2638
+ ngx_del_timer(upstream->write);
2639
+ }
2640
+
2641
+ if (ngx_handle_read_event(upstream->read, 0) != NGX_OK) {
2642
+ ngx_http_upstream_finalize_request(r, u, 0);
2643
+ return;
2644
+ }
2645
+
2646
+ if (upstream->read->active && !upstream->read->ready) {
2647
+ ngx_add_timer(upstream->read, u->conf->read_timeout);
2648
+
2649
+ } else if (upstream->read->timer_set) {
2650
+ ngx_del_timer(upstream->read);
2651
+ }
2652
+
2653
+ if (ngx_handle_write_event(downstream->write, clcf->send_lowat)
2654
+ != NGX_OK)
2655
+ {
2656
+ ngx_http_upstream_finalize_request(r, u, 0);
2657
+ return;
2658
+ }
2659
+
2660
+ if (ngx_handle_read_event(downstream->read, 0) != NGX_OK) {
2661
+ ngx_http_upstream_finalize_request(r, u, 0);
2662
+ return;
2663
+ }
2664
+
2665
+ if (downstream->write->active && !downstream->write->ready) {
2666
+ ngx_add_timer(downstream->write, clcf->send_timeout);
2667
+
2668
+ } else if (downstream->write->timer_set) {
2669
+ ngx_del_timer(downstream->write);
2670
+ }
2671
+ }
2672
+
2673
+
2366
2674
  static void
2367
2675
  ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r)
2368
2676
  {
@@ -2968,19 +3276,10 @@ ngx_http_upstream_cleanup(void *data)
2968
3276
  {
2969
3277
  ngx_http_request_t *r = data;
2970
3278
 
2971
- ngx_http_upstream_t *u;
2972
-
2973
3279
  ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2974
3280
  "cleanup http upstream request: \"%V\"", &r->uri);
2975
3281
 
2976
- u = r->upstream;
2977
-
2978
- if (u->resolved && u->resolved->ctx) {
2979
- ngx_resolve_name_done(u->resolved->ctx);
2980
- u->resolved->ctx = NULL;
2981
- }
2982
-
2983
- ngx_http_upstream_finalize_request(r, u, NGX_DONE);
3282
+ ngx_http_upstream_finalize_request(r, r->upstream, NGX_DONE);
2984
3283
  }
2985
3284
 
2986
3285
 
@@ -3008,7 +3307,7 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r,
3008
3307
  u->state->response_sec = tp->sec - u->state->response_sec;
3009
3308
  u->state->response_msec = tp->msec - u->state->response_msec;
3010
3309
 
3011
- if (u->pipe) {
3310
+ if (u->pipe && u->pipe->read_length) {
3012
3311
  u->state->response_length = u->pipe->read_length;
3013
3312
  }
3014
3313
  }
@@ -4130,6 +4429,7 @@ ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
4130
4429
  value = cf->args->elts;
4131
4430
  u.host = value[1];
4132
4431
  u.no_resolve = 1;
4432
+ u.no_port = 1;
4133
4433
 
4134
4434
  uscf = ngx_http_upstream_add(cf, &u, NGX_HTTP_UPSTREAM_CREATE
4135
4435
  |NGX_HTTP_UPSTREAM_WEIGHT
@@ -4400,14 +4700,14 @@ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
4400
4700
  return NULL;
4401
4701
  }
4402
4702
 
4403
- if ((uscfp[i]->flags & NGX_HTTP_UPSTREAM_CREATE) && u->port) {
4703
+ if ((uscfp[i]->flags & NGX_HTTP_UPSTREAM_CREATE) && !u->no_port) {
4404
4704
  ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
4405
4705
  "upstream \"%V\" may not have port %d",
4406
4706
  &u->host, u->port);
4407
4707
  return NULL;
4408
4708
  }
4409
4709
 
4410
- if ((flags & NGX_HTTP_UPSTREAM_CREATE) && uscfp[i]->port) {
4710
+ if ((flags & NGX_HTTP_UPSTREAM_CREATE) && !uscfp[i]->no_port) {
4411
4711
  ngx_log_error(NGX_LOG_WARN, cf->log, 0,
4412
4712
  "upstream \"%V\" may not have port %d in %s:%ui",
4413
4713
  &u->host, uscfp[i]->port,
@@ -4415,7 +4715,9 @@ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
4415
4715
  return NULL;
4416
4716
  }
4417
4717
 
4418
- if (uscfp[i]->port != u->port) {
4718
+ if (uscfp[i]->port && u->port
4719
+ && uscfp[i]->port != u->port)
4720
+ {
4419
4721
  continue;
4420
4722
  }
4421
4723
 
@@ -4443,6 +4745,7 @@ ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
4443
4745
  uscf->line = cf->conf_file->line;
4444
4746
  uscf->port = u->port;
4445
4747
  uscf->default_port = u->default_port;
4748
+ uscf->no_port = u->no_port;
4446
4749
 
4447
4750
  if (u->naddrs == 1) {
4448
4751
  uscf->servers = ngx_array_create(cf->pool, 1,
@@ -4479,24 +4782,63 @@ ngx_http_upstream_bind_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
4479
4782
  {
4480
4783
  char *p = conf;
4481
4784
 
4482
- ngx_int_t rc;
4483
- ngx_str_t *value;
4484
- ngx_addr_t **paddr;
4785
+ ngx_int_t rc;
4786
+ ngx_str_t *value;
4787
+ ngx_http_complex_value_t cv;
4788
+ ngx_http_upstream_local_t **plocal, *local;
4789
+ ngx_http_compile_complex_value_t ccv;
4485
4790
 
4486
- paddr = (ngx_addr_t **) (p + cmd->offset);
4791
+ plocal = (ngx_http_upstream_local_t **) (p + cmd->offset);
4487
4792
 
4488
- *paddr = ngx_palloc(cf->pool, sizeof(ngx_addr_t));
4489
- if (*paddr == NULL) {
4490
- return NGX_CONF_ERROR;
4793
+ if (*plocal != NGX_CONF_UNSET_PTR) {
4794
+ return "is duplicate";
4491
4795
  }
4492
4796
 
4493
4797
  value = cf->args->elts;
4494
4798
 
4495
- rc = ngx_parse_addr(cf->pool, *paddr, value[1].data, value[1].len);
4799
+ if (ngx_strcmp(value[1].data, "off") == 0) {
4800
+ *plocal = NULL;
4801
+ return NGX_CONF_OK;
4802
+ }
4803
+
4804
+ ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
4805
+
4806
+ ccv.cf = cf;
4807
+ ccv.value = &value[1];
4808
+ ccv.complex_value = &cv;
4809
+
4810
+ if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
4811
+ return NGX_CONF_ERROR;
4812
+ }
4813
+
4814
+ local = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_local_t));
4815
+ if (local == NULL) {
4816
+ return NGX_CONF_ERROR;
4817
+ }
4818
+
4819
+ *plocal = local;
4820
+
4821
+ if (cv.lengths) {
4822
+ local->value = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
4823
+ if (local->value == NULL) {
4824
+ return NGX_CONF_ERROR;
4825
+ }
4826
+
4827
+ *local->value = cv;
4828
+
4829
+ return NGX_CONF_OK;
4830
+ }
4831
+
4832
+ local->addr = ngx_palloc(cf->pool, sizeof(ngx_addr_t));
4833
+ if (local->addr == NULL) {
4834
+ return NGX_CONF_ERROR;
4835
+ }
4836
+
4837
+ rc = ngx_parse_addr(cf->pool, local->addr, value[1].data, value[1].len);
4496
4838
 
4497
4839
  switch (rc) {
4498
4840
  case NGX_OK:
4499
- (*paddr)->name = value[1];
4841
+ local->addr->name = value[1];
4500
4842
  return NGX_CONF_OK;
4501
4843
 
4502
4844
  case NGX_DECLINED:
@@ -4510,6 +4852,53 @@ ngx_http_upstream_bind_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
4510
4852
  }
4511
4853
 
4512
4854
 
4855
+ static ngx_addr_t *
4856
+ ngx_http_upstream_get_local(ngx_http_request_t *r,
4857
+ ngx_http_upstream_local_t *local)
4858
+ {
4859
+ ngx_int_t rc;
4860
+ ngx_str_t val;
4861
+ ngx_addr_t *addr;
4862
+
4863
+ if (local == NULL) {
4864
+ return NULL;
4865
+ }
4866
+
4867
+ if (local->value == NULL) {
4868
+ return local->addr;
4869
+ }
4870
+
4871
+ if (ngx_http_complex_value(r, local->value, &val) != NGX_OK) {
4872
+ return NULL;
4873
+ }
4874
+
4875
+ if (val.len == 0) {
4876
+ return NULL;
4877
+ }
4878
+
4879
+ addr = ngx_palloc(r->pool, sizeof(ngx_addr_t));
4880
+ if (addr == NULL) {
4881
+ return NULL;
4882
+ }
4883
+
4884
+ rc = ngx_parse_addr(r->pool, addr, val.data, val.len);
4885
+
4886
+ switch (rc) {
4887
+ case NGX_OK:
4888
+ addr->name = val;
4889
+ return addr;
4890
+
4891
+ case NGX_DECLINED:
4892
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
4893
+ "invalid local address \"%V\"", &val);
4894
+ /* fall through */
4895
+
4896
+ default:
4897
+ return NULL;
4898
+ }
4899
+ }
4900
+
4901
+
4513
4902
  char *
4514
4903
  ngx_http_upstream_param_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
4515
4904
  void *conf)