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
@@ -10,7 +10,7 @@
10
10
  #include <ngx_http.h>
11
11
 
12
12
 
13
- static void ngx_http_init_request(ngx_event_t *ev);
13
+ static void ngx_http_wait_request_handler(ngx_event_t *ev);
14
14
  static void ngx_http_process_request_line(ngx_event_t *rev);
15
15
  static void ngx_http_process_request_headers(ngx_event_t *rev);
16
16
  static ssize_t ngx_http_read_request_header(ngx_http_request_t *r);
@@ -21,21 +21,22 @@ static ngx_int_t ngx_http_process_header_line(ngx_http_request_t *r,
21
21
  ngx_table_elt_t *h, ngx_uint_t offset);
22
22
  static ngx_int_t ngx_http_process_unique_header_line(ngx_http_request_t *r,
23
23
  ngx_table_elt_t *h, ngx_uint_t offset);
24
+ static ngx_int_t ngx_http_process_multi_header_lines(ngx_http_request_t *r,
25
+ ngx_table_elt_t *h, ngx_uint_t offset);
24
26
  static ngx_int_t ngx_http_process_host(ngx_http_request_t *r,
25
27
  ngx_table_elt_t *h, ngx_uint_t offset);
26
28
  static ngx_int_t ngx_http_process_connection(ngx_http_request_t *r,
27
29
  ngx_table_elt_t *h, ngx_uint_t offset);
28
30
  static ngx_int_t ngx_http_process_user_agent(ngx_http_request_t *r,
29
31
  ngx_table_elt_t *h, ngx_uint_t offset);
30
- static ngx_int_t ngx_http_process_cookie(ngx_http_request_t *r,
31
- ngx_table_elt_t *h, ngx_uint_t offset);
32
32
 
33
- static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r);
34
- static void ngx_http_process_request(ngx_http_request_t *r);
35
- static ssize_t ngx_http_validate_host(ngx_http_request_t *r, u_char **host,
36
- size_t len, ngx_uint_t alloc);
37
- static ngx_int_t ngx_http_find_virtual_server(ngx_http_request_t *r,
38
- u_char *host, size_t len);
33
+ static ngx_int_t ngx_http_validate_host(ngx_str_t *host, ngx_pool_t *pool,
34
+ ngx_uint_t alloc);
35
+ static ngx_int_t ngx_http_set_virtual_server(ngx_http_request_t *r,
36
+ ngx_str_t *host);
37
+ static ngx_int_t ngx_http_find_virtual_server(ngx_connection_t *c,
38
+ ngx_http_virtual_names_t *virtual_names, ngx_str_t *host,
39
+ ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp);
39
40
 
40
41
  static void ngx_http_request_handler(ngx_event_t *ev);
41
42
  static void ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc);
@@ -51,9 +52,7 @@ static void ngx_http_set_lingering_close(ngx_http_request_t *r);
51
52
  static void ngx_http_lingering_close_handler(ngx_event_t *ev);
52
53
  static ngx_int_t ngx_http_post_action(ngx_http_request_t *r);
53
54
  static void ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error);
54
- static void ngx_http_free_request(ngx_http_request_t *r, ngx_int_t error);
55
55
  static void ngx_http_log_request(ngx_http_request_t *r);
56
- static void ngx_http_close_connection(ngx_connection_t *c);
57
56
 
58
57
  static u_char *ngx_http_log_error(ngx_log_t *log, u_char *buf, size_t len);
59
58
  static u_char *ngx_http_log_error_handler(ngx_http_request_t *r,
@@ -93,6 +92,14 @@ ngx_http_header_t ngx_http_headers_in[] = {
93
92
  offsetof(ngx_http_headers_in_t, if_unmodified_since),
94
93
  ngx_http_process_unique_header_line },
95
94
 
95
+ { ngx_string("If-Match"),
96
+ offsetof(ngx_http_headers_in_t, if_match),
97
+ ngx_http_process_unique_header_line },
98
+
99
+ { ngx_string("If-None-Match"),
100
+ offsetof(ngx_http_headers_in_t, if_none_match),
101
+ ngx_http_process_unique_header_line },
102
+
96
103
  { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent),
97
104
  ngx_http_process_user_agent },
98
105
 
@@ -122,6 +129,10 @@ ngx_http_header_t ngx_http_headers_in[] = {
122
129
  offsetof(ngx_http_headers_in_t, expect),
123
130
  ngx_http_process_unique_header_line },
124
131
 
132
+ { ngx_string("Upgrade"),
133
+ offsetof(ngx_http_headers_in_t, upgrade),
134
+ ngx_http_process_header_line },
135
+
125
136
  #if (NGX_HTTP_GZIP)
126
137
  { ngx_string("Accept-Encoding"),
127
138
  offsetof(ngx_http_headers_in_t, accept_encoding),
@@ -141,7 +152,7 @@ ngx_http_header_t ngx_http_headers_in[] = {
141
152
  #if (NGX_HTTP_X_FORWARDED_FOR)
142
153
  { ngx_string("X-Forwarded-For"),
143
154
  offsetof(ngx_http_headers_in_t, x_forwarded_for),
144
- ngx_http_process_header_line },
155
+ ngx_http_process_multi_header_lines },
145
156
  #endif
146
157
 
147
158
  #if (NGX_HTTP_REALIP)
@@ -173,7 +184,8 @@ ngx_http_header_t ngx_http_headers_in[] = {
173
184
  ngx_http_process_header_line },
174
185
  #endif
175
186
 
176
- { ngx_string("Cookie"), 0, ngx_http_process_cookie },
187
+ { ngx_string("Cookie"), offsetof(ngx_http_headers_in_t, cookies),
188
+ ngx_http_process_multi_header_lines },
177
189
 
178
190
  { ngx_null_string, 0, NULL }
179
191
  };
@@ -182,137 +194,30 @@ ngx_http_header_t ngx_http_headers_in[] = {
182
194
  void
183
195
  ngx_http_init_connection(ngx_connection_t *c)
184
196
  {
185
- ngx_event_t *rev;
186
- ngx_http_log_ctx_t *ctx;
187
-
188
- ctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t));
189
- if (ctx == NULL) {
190
- ngx_http_close_connection(c);
191
- return;
192
- }
193
-
194
- ctx->connection = c;
195
- ctx->request = NULL;
196
- ctx->current_request = NULL;
197
-
198
- c->log->connection = c->number;
199
- c->log->handler = ngx_http_log_error;
200
- c->log->data = ctx;
201
- c->log->action = "reading client request line";
202
-
203
- c->log_error = NGX_ERROR_INFO;
204
-
205
- rev = c->read;
206
- rev->handler = ngx_http_init_request;
207
- c->write->handler = ngx_http_empty_handler;
208
-
209
- #if (NGX_STAT_STUB)
210
- (void) ngx_atomic_fetch_add(ngx_stat_reading, 1);
211
- #endif
212
-
213
- if (rev->ready) {
214
- /* the deferred accept(), rtsig, aio, iocp */
215
-
216
- if (ngx_use_accept_mutex) {
217
- ngx_post_event(rev, &ngx_posted_events);
218
- return;
219
- }
220
-
221
- ngx_http_init_request(rev);
222
- return;
223
- }
224
-
225
- ngx_add_timer(rev, c->listening->post_accept_timeout);
226
-
227
- if (ngx_handle_read_event(rev, 0) != NGX_OK) {
228
- #if (NGX_STAT_STUB)
229
- (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
230
- #endif
231
- ngx_http_close_connection(c);
232
- return;
233
- }
234
- }
235
-
236
-
237
- static void
238
- ngx_http_init_request(ngx_event_t *rev)
239
- {
240
- ngx_time_t *tp;
241
- ngx_uint_t i;
242
- ngx_connection_t *c;
243
- ngx_http_request_t *r;
244
- struct sockaddr_in *sin;
245
- ngx_http_port_t *port;
246
- ngx_http_in_addr_t *addr;
247
- ngx_http_log_ctx_t *ctx;
248
- ngx_http_addr_conf_t *addr_conf;
249
- ngx_http_connection_t *hc;
250
- ngx_http_core_srv_conf_t *cscf;
251
- ngx_http_core_loc_conf_t *clcf;
252
- ngx_http_core_main_conf_t *cmcf;
197
+ ngx_uint_t i;
198
+ ngx_event_t *rev;
199
+ struct sockaddr_in *sin;
200
+ ngx_http_port_t *port;
201
+ ngx_http_in_addr_t *addr;
202
+ ngx_http_log_ctx_t *ctx;
203
+ ngx_http_connection_t *hc;
253
204
  #if (NGX_HAVE_INET6)
254
- struct sockaddr_in6 *sin6;
255
- ngx_http_in6_addr_t *addr6;
205
+ struct sockaddr_in6 *sin6;
206
+ ngx_http_in6_addr_t *addr6;
256
207
  #endif
257
208
 
258
- #if (NGX_STAT_STUB)
259
- (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);
260
- #endif
261
-
262
- c = rev->data;
263
-
264
- if (rev->timedout) {
265
- ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
266
-
209
+ hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t));
210
+ if (hc == NULL) {
267
211
  ngx_http_close_connection(c);
268
212
  return;
269
213
  }
270
214
 
271
- c->requests++;
272
-
273
- hc = c->data;
274
-
275
- if (hc == NULL) {
276
- hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t));
277
- if (hc == NULL) {
278
- ngx_http_close_connection(c);
279
- return;
280
- }
281
- }
282
-
283
- r = hc->request;
284
-
285
- if (r) {
286
- ngx_memzero(r, sizeof(ngx_http_request_t));
287
-
288
- r->pipeline = hc->pipeline;
289
-
290
- if (hc->nbusy) {
291
- r->header_in = hc->busy[0];
292
- }
293
-
294
- } else {
295
- r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t));
296
- if (r == NULL) {
297
- ngx_http_close_connection(c);
298
- return;
299
- }
300
-
301
- hc->request = r;
302
- }
303
-
304
- c->data = r;
305
- r->http_connection = hc;
306
-
307
- c->sent = 0;
308
- r->signature = NGX_HTTP_MODULE;
215
+ c->data = hc;
309
216
 
310
217
  /* find the server configuration for the address:port */
311
218
 
312
219
  port = c->listening->servers;
313
220
 
314
- r->connection = c;
315
-
316
221
  if (port->naddrs > 1) {
317
222
 
318
223
  /*
@@ -342,7 +247,7 @@ ngx_http_init_request(ngx_event_t *rev)
342
247
  }
343
248
  }
344
249
 
345
- addr_conf = &addr6[i].conf;
250
+ hc->addr_conf = &addr6[i].conf;
346
251
 
347
252
  break;
348
253
  #endif
@@ -360,7 +265,7 @@ ngx_http_init_request(ngx_event_t *rev)
360
265
  }
361
266
  }
362
267
 
363
- addr_conf = &addr[i].conf;
268
+ hc->addr_conf = &addr[i].conf;
364
269
 
365
270
  break;
366
271
  }
@@ -372,105 +277,275 @@ ngx_http_init_request(ngx_event_t *rev)
372
277
  #if (NGX_HAVE_INET6)
373
278
  case AF_INET6:
374
279
  addr6 = port->addrs;
375
- addr_conf = &addr6[0].conf;
280
+ hc->addr_conf = &addr6[0].conf;
376
281
  break;
377
282
  #endif
378
283
 
379
284
  default: /* AF_INET */
380
285
  addr = port->addrs;
381
- addr_conf = &addr[0].conf;
286
+ hc->addr_conf = &addr[0].conf;
382
287
  break;
383
288
  }
384
289
  }
385
290
 
386
- r->virtual_names = addr_conf->virtual_names;
387
-
388
291
  /* the default server configuration for the address:port */
389
- cscf = addr_conf->default_server;
292
+ hc->conf_ctx = hc->addr_conf->default_server->ctx;
390
293
 
391
- r->main_conf = cscf->ctx->main_conf;
392
- r->srv_conf = cscf->ctx->srv_conf;
393
- r->loc_conf = cscf->ctx->loc_conf;
294
+ ctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t));
295
+ if (ctx == NULL) {
296
+ ngx_http_close_connection(c);
297
+ return;
298
+ }
394
299
 
395
- rev->handler = ngx_http_process_request_line;
396
- r->read_event_handler = ngx_http_block_reading;
300
+ ctx->connection = c;
301
+ ctx->request = NULL;
302
+ ctx->current_request = NULL;
397
303
 
398
- #if (NGX_HTTP_SSL)
304
+ c->log->connection = c->number;
305
+ c->log->handler = ngx_http_log_error;
306
+ c->log->data = ctx;
307
+ c->log->action = "waiting for request";
308
+
309
+ c->log_error = NGX_ERROR_INFO;
399
310
 
311
+ rev = c->read;
312
+ rev->handler = ngx_http_wait_request_handler;
313
+ c->write->handler = ngx_http_empty_handler;
314
+
315
+ #if (NGX_HTTP_SPDY)
316
+ if (hc->addr_conf->spdy) {
317
+ rev->handler = ngx_http_spdy_init;
318
+ }
319
+ #endif
320
+
321
+ #if (NGX_HTTP_SSL)
400
322
  {
401
323
  ngx_http_ssl_srv_conf_t *sscf;
402
324
 
403
- sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
404
- if (sscf->enable || addr_conf->ssl) {
325
+ sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module);
405
326
 
406
- if (c->ssl == NULL) {
327
+ if (sscf->enable || hc->addr_conf->ssl) {
407
328
 
408
- c->log->action = "SSL handshaking";
329
+ c->log->action = "SSL handshaking";
409
330
 
410
- if (addr_conf->ssl && sscf->ssl.ctx == NULL) {
411
- ngx_log_error(NGX_LOG_ERR, c->log, 0,
412
- "no \"ssl_certificate\" is defined "
413
- "in server listening on SSL port");
414
- ngx_http_close_connection(c);
415
- return;
416
- }
331
+ if (hc->addr_conf->ssl && sscf->ssl.ctx == NULL) {
332
+ ngx_log_error(NGX_LOG_ERR, c->log, 0,
333
+ "no \"ssl_certificate\" is defined "
334
+ "in server listening on SSL port");
335
+ ngx_http_close_connection(c);
336
+ return;
337
+ }
417
338
 
418
- if (ngx_ssl_create_connection(&sscf->ssl, c, NGX_SSL_BUFFER)
419
- != NGX_OK)
420
- {
421
- ngx_http_close_connection(c);
422
- return;
423
- }
339
+ hc->ssl = 1;
340
+
341
+ rev->handler = ngx_http_ssl_handshake;
342
+ }
343
+ }
344
+ #endif
345
+
346
+ if (rev->ready) {
347
+ /* the deferred accept(), rtsig, aio, iocp */
424
348
 
425
- rev->handler = ngx_http_ssl_handshake;
349
+ if (ngx_use_accept_mutex) {
350
+ ngx_post_event(rev, &ngx_posted_events);
351
+ return;
426
352
  }
427
353
 
428
- r->main_filter_need_in_memory = 1;
354
+ rev->handler(rev);
355
+ return;
356
+ }
357
+
358
+ ngx_add_timer(rev, c->listening->post_accept_timeout);
359
+ ngx_reusable_connection(c, 1);
360
+
361
+ if (ngx_handle_read_event(rev, 0) != NGX_OK) {
362
+ ngx_http_close_connection(c);
363
+ return;
364
+ }
365
+ }
366
+
367
+
368
+ static void
369
+ ngx_http_wait_request_handler(ngx_event_t *rev)
370
+ {
371
+ size_t size;
372
+ ssize_t n;
373
+ ngx_buf_t *b;
374
+ ngx_connection_t *c;
375
+ ngx_http_connection_t *hc;
376
+ ngx_http_core_srv_conf_t *cscf;
377
+
378
+ c = rev->data;
379
+
380
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http wait request handler");
381
+
382
+ if (rev->timedout) {
383
+ ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
384
+ ngx_http_close_connection(c);
385
+ return;
386
+ }
387
+
388
+ if (c->close) {
389
+ ngx_http_close_connection(c);
390
+ return;
429
391
  }
392
+
393
+ hc = c->data;
394
+ cscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_core_module);
395
+
396
+ size = cscf->client_header_buffer_size;
397
+
398
+ b = c->buffer;
399
+
400
+ if (b == NULL) {
401
+ b = ngx_create_temp_buf(c->pool, size);
402
+ if (b == NULL) {
403
+ ngx_http_close_connection(c);
404
+ return;
405
+ }
406
+
407
+ c->buffer = b;
408
+
409
+ } else if (b->start == NULL) {
410
+
411
+ b->start = ngx_palloc(c->pool, size);
412
+ if (b->start == NULL) {
413
+ ngx_http_close_connection(c);
414
+ return;
415
+ }
416
+
417
+ b->pos = b->start;
418
+ b->last = b->start;
419
+ b->end = b->last + size;
430
420
  }
431
421
 
422
+ n = c->recv(c, b->last, size);
423
+
424
+ if (n == NGX_AGAIN) {
425
+
426
+ #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
427
+ if (c->listening->deferred_accept
428
+ #if (NGX_HTTP_SSL)
429
+ && c->ssl == NULL
430
+ #endif
431
+ )
432
+ {
433
+ ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
434
+ "client timed out in deferred accept");
435
+ ngx_http_close_connection(c);
436
+ return;
437
+ }
432
438
  #endif
433
439
 
434
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
435
- c->log->file = clcf->error_log->file;
436
- if (!(c->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
437
- c->log->log_level = clcf->error_log->log_level;
440
+ if (!rev->timer_set) {
441
+ ngx_add_timer(rev, c->listening->post_accept_timeout);
442
+ ngx_reusable_connection(c, 1);
443
+ }
444
+
445
+ if (ngx_handle_read_event(rev, 0) != NGX_OK) {
446
+ ngx_http_close_connection(c);
447
+ return;
448
+ }
449
+
450
+ /*
451
+ * We are trying to not hold c->buffer's memory for an idle connection.
452
+ */
453
+
454
+ if (ngx_pfree(c->pool, b->start) == NGX_OK) {
455
+ b->start = NULL;
456
+ }
457
+
458
+ return;
459
+ }
460
+
461
+ if (n == NGX_ERROR) {
462
+ ngx_http_close_connection(c);
463
+ return;
464
+ }
465
+
466
+ if (n == 0) {
467
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
468
+ "client closed connection");
469
+ ngx_http_close_connection(c);
470
+ return;
471
+ }
472
+
473
+ b->last += n;
474
+
475
+ c->log->action = "reading client request line";
476
+
477
+ ngx_reusable_connection(c, 0);
478
+
479
+ c->data = ngx_http_create_request(c);
480
+ if (c->data == NULL) {
481
+ ngx_http_close_connection(c);
482
+ return;
483
+ }
484
+
485
+ rev->handler = ngx_http_process_request_line;
486
+ ngx_http_process_request_line(rev);
487
+ }
488
+
489
+
490
+ ngx_http_request_t *
491
+ ngx_http_create_request(ngx_connection_t *c)
492
+ {
493
+ ngx_pool_t *pool;
494
+ ngx_time_t *tp;
495
+ ngx_http_request_t *r;
496
+ ngx_http_log_ctx_t *ctx;
497
+ ngx_http_connection_t *hc;
498
+ ngx_http_core_srv_conf_t *cscf;
499
+ ngx_http_core_loc_conf_t *clcf;
500
+ ngx_http_core_main_conf_t *cmcf;
501
+
502
+ c->requests++;
503
+
504
+ hc = c->data;
505
+
506
+ cscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_core_module);
507
+
508
+ pool = ngx_create_pool(cscf->request_pool_size, c->log);
509
+ if (pool == NULL) {
510
+ return NULL;
511
+ }
512
+
513
+ r = ngx_pcalloc(pool, sizeof(ngx_http_request_t));
514
+ if (r == NULL) {
515
+ ngx_destroy_pool(pool);
516
+ return NULL;
438
517
  }
439
518
 
440
- if (c->buffer == NULL) {
441
- c->buffer = ngx_create_temp_buf(c->pool,
442
- cscf->client_header_buffer_size);
443
- if (c->buffer == NULL) {
444
- ngx_http_close_connection(c);
445
- return;
446
- }
447
- }
519
+ r->pool = pool;
520
+
521
+ r->http_connection = hc;
522
+ r->signature = NGX_HTTP_MODULE;
523
+ r->connection = c;
524
+
525
+ r->main_conf = hc->conf_ctx->main_conf;
526
+ r->srv_conf = hc->conf_ctx->srv_conf;
527
+ r->loc_conf = hc->conf_ctx->loc_conf;
528
+
529
+ r->read_event_handler = ngx_http_block_reading;
448
530
 
449
- if (r->header_in == NULL) {
450
- r->header_in = c->buffer;
451
- }
531
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
452
532
 
453
- r->pool = ngx_create_pool(cscf->request_pool_size, c->log);
454
- if (r->pool == NULL) {
455
- ngx_http_close_connection(c);
456
- return;
457
- }
533
+ ngx_http_set_connection_log(r->connection, clcf->error_log);
458
534
 
535
+ r->header_in = hc->nbusy ? hc->busy[0] : c->buffer;
459
536
 
460
537
  if (ngx_list_init(&r->headers_out.headers, r->pool, 20,
461
538
  sizeof(ngx_table_elt_t))
462
539
  != NGX_OK)
463
540
  {
464
541
  ngx_destroy_pool(r->pool);
465
- ngx_http_close_connection(c);
466
- return;
542
+ return NULL;
467
543
  }
468
544
 
469
545
  r->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
470
546
  if (r->ctx == NULL) {
471
547
  ngx_destroy_pool(r->pool);
472
- ngx_http_close_connection(c);
473
- return;
548
+ return NULL;
474
549
  }
475
550
 
476
551
  cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
@@ -479,12 +554,14 @@ ngx_http_init_request(ngx_event_t *rev)
479
554
  * sizeof(ngx_http_variable_value_t));
480
555
  if (r->variables == NULL) {
481
556
  ngx_destroy_pool(r->pool);
482
- ngx_http_close_connection(c);
483
- return;
557
+ return NULL;
484
558
  }
485
559
 
486
- c->single_connection = 1;
487
- c->destroyed = 0;
560
+ #if (NGX_HTTP_SSL)
561
+ if (c->ssl) {
562
+ r->main_filter_need_in_memory = 1;
563
+ }
564
+ #endif
488
565
 
489
566
  r->main = r;
490
567
  r->count = 1;
@@ -516,7 +593,7 @@ ngx_http_init_request(ngx_event_t *rev)
516
593
  (void) ngx_atomic_fetch_add(ngx_stat_requests, 1);
517
594
  #endif
518
595
 
519
- rev->handler(rev);
596
+ return r;
520
597
  }
521
598
 
522
599
 
@@ -525,37 +602,63 @@ ngx_http_init_request(ngx_event_t *rev)
525
602
  static void
526
603
  ngx_http_ssl_handshake(ngx_event_t *rev)
527
604
  {
528
- u_char buf[1];
529
- ssize_t n;
530
- ngx_int_t rc;
531
- ngx_connection_t *c;
532
- ngx_http_request_t *r;
605
+ u_char buf[1];
606
+ ssize_t n;
607
+ ngx_err_t err;
608
+ ngx_int_t rc;
609
+ ngx_connection_t *c;
610
+ ngx_http_connection_t *hc;
611
+ ngx_http_ssl_srv_conf_t *sscf;
533
612
 
534
613
  c = rev->data;
535
- r = c->data;
536
614
 
537
615
  ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0,
538
616
  "http check ssl handshake");
539
617
 
540
618
  if (rev->timedout) {
541
619
  ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
542
- c->timedout = 1;
543
- ngx_http_close_request(r, NGX_HTTP_REQUEST_TIME_OUT);
620
+ ngx_http_close_connection(c);
621
+ return;
622
+ }
623
+
624
+ if (c->close) {
625
+ ngx_http_close_connection(c);
544
626
  return;
545
627
  }
546
628
 
547
629
  n = recv(c->fd, (char *) buf, 1, MSG_PEEK);
548
630
 
549
- if (n == -1 && ngx_socket_errno == NGX_EAGAIN) {
631
+ err = ngx_socket_errno;
550
632
 
551
- if (!rev->timer_set) {
552
- ngx_add_timer(rev, c->listening->post_accept_timeout);
553
- }
633
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, "http recv(): %d", n);
554
634
 
555
- if (ngx_handle_read_event(rev, 0) != NGX_OK) {
556
- ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
635
+ if (n == -1) {
636
+ if (err == NGX_EAGAIN) {
637
+
638
+ #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
639
+ if (c->listening->deferred_accept) {
640
+ ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
641
+ "client timed out in deferred accept");
642
+ ngx_http_close_connection(c);
643
+ return;
644
+ }
645
+ #endif
646
+
647
+ if (!rev->timer_set) {
648
+ ngx_add_timer(rev, c->listening->post_accept_timeout);
649
+ ngx_reusable_connection(c, 1);
650
+ }
651
+
652
+ if (ngx_handle_read_event(rev, 0) != NGX_OK) {
653
+ ngx_http_close_connection(c);
654
+ }
655
+
656
+ return;
557
657
  }
558
658
 
659
+ ngx_connection_error(c, err, "recv() failed");
660
+ ngx_http_close_connection(c);
661
+
559
662
  return;
560
663
  }
561
664
 
@@ -564,6 +667,17 @@ ngx_http_ssl_handshake(ngx_event_t *rev)
564
667
  ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0,
565
668
  "https ssl handshake: 0x%02Xd", buf[0]);
566
669
 
670
+ hc = c->data;
671
+ sscf = ngx_http_get_module_srv_conf(hc->conf_ctx,
672
+ ngx_http_ssl_module);
673
+
674
+ if (ngx_ssl_create_connection(&sscf->ssl, c, NGX_SSL_BUFFER)
675
+ != NGX_OK)
676
+ {
677
+ ngx_http_close_connection(c);
678
+ return;
679
+ }
680
+
567
681
  rc = ngx_ssl_handshake(c);
568
682
 
569
683
  if (rc == NGX_AGAIN) {
@@ -572,6 +686,8 @@ ngx_http_ssl_handshake(ngx_event_t *rev)
572
686
  ngx_add_timer(rev, c->listening->post_accept_timeout);
573
687
  }
574
688
 
689
+ ngx_reusable_connection(c, 0);
690
+
575
691
  c->ssl->handler = ngx_http_ssl_handshake_handler;
576
692
  return;
577
693
  }
@@ -579,27 +695,26 @@ ngx_http_ssl_handshake(ngx_event_t *rev)
579
695
  ngx_http_ssl_handshake_handler(c);
580
696
 
581
697
  return;
698
+ }
582
699
 
583
- } else {
584
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0,
585
- "plain http");
700
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, "plain http");
586
701
 
587
- r->plain_http = 1;
588
- }
589
- }
702
+ c->log->action = "waiting for request";
590
703
 
591
- c->log->action = "reading client request line";
704
+ rev->handler = ngx_http_wait_request_handler;
705
+ ngx_http_wait_request_handler(rev);
592
706
 
593
- rev->handler = ngx_http_process_request_line;
594
- ngx_http_process_request_line(rev);
707
+ return;
708
+ }
709
+
710
+ ngx_log_error(NGX_LOG_INFO, c->log, 0, "client closed connection");
711
+ ngx_http_close_connection(c);
595
712
  }
596
713
 
597
714
 
598
715
  static void
599
716
  ngx_http_ssl_handshake_handler(ngx_connection_t *c)
600
717
  {
601
- ngx_http_request_t *r;
602
-
603
718
  if (c->ssl->handshaked) {
604
719
 
605
720
  /*
@@ -612,21 +727,38 @@ ngx_http_ssl_handshake_handler(ngx_connection_t *c)
612
727
 
613
728
  c->ssl->no_wait_shutdown = 1;
614
729
 
615
- c->log->action = "reading client request line";
730
+ #if (NGX_HTTP_SPDY && defined TLSEXT_TYPE_next_proto_neg)
731
+ {
732
+ unsigned int len;
733
+ const unsigned char *data;
734
+ static const ngx_str_t spdy = ngx_string(NGX_SPDY_NPN_NEGOTIATED);
735
+
736
+ SSL_get0_next_proto_negotiated(c->ssl->connection, &data, &len);
737
+
738
+ if (len == spdy.len && ngx_strncmp(data, spdy.data, spdy.len) == 0) {
739
+ ngx_http_spdy_init(c->read);
740
+ return;
741
+ }
742
+ }
743
+ #endif
616
744
 
617
- c->read->handler = ngx_http_process_request_line;
745
+ c->log->action = "waiting for request";
746
+
747
+ c->read->handler = ngx_http_wait_request_handler;
618
748
  /* STUB: epoll edge */ c->write->handler = ngx_http_empty_handler;
619
749
 
620
- ngx_http_process_request_line(c->read);
750
+ ngx_reusable_connection(c, 1);
751
+
752
+ ngx_http_wait_request_handler(c->read);
621
753
 
622
754
  return;
623
755
  }
624
756
 
625
- r = c->data;
626
-
627
- ngx_http_close_request(r, NGX_HTTP_BAD_REQUEST);
757
+ if (c->read->timedout) {
758
+ ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
759
+ }
628
760
 
629
- return;
761
+ ngx_http_close_connection(c);
630
762
  }
631
763
 
632
764
  #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
@@ -634,12 +766,13 @@ ngx_http_ssl_handshake_handler(ngx_connection_t *c)
634
766
  int
635
767
  ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
636
768
  {
637
- size_t len;
638
- u_char *host;
639
- const char *servername;
640
- ngx_connection_t *c;
641
- ngx_http_request_t *r;
642
- ngx_http_ssl_srv_conf_t *sscf;
769
+ ngx_str_t host;
770
+ const char *servername;
771
+ ngx_connection_t *c;
772
+ ngx_http_connection_t *hc;
773
+ ngx_http_ssl_srv_conf_t *sscf;
774
+ ngx_http_core_loc_conf_t *clcf;
775
+ ngx_http_core_srv_conf_t *cscf;
643
776
 
644
777
  servername = SSL_get_servername(ssl_conn, TLSEXT_NAMETYPE_host_name);
645
778
 
@@ -652,27 +785,41 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
652
785
  ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
653
786
  "SSL server name: \"%s\"", servername);
654
787
 
655
- len = ngx_strlen(servername);
788
+ host.len = ngx_strlen(servername);
656
789
 
657
- if (len == 0) {
790
+ if (host.len == 0) {
658
791
  return SSL_TLSEXT_ERR_NOACK;
659
792
  }
660
793
 
661
- r = c->data;
794
+ host.data = (u_char *) servername;
662
795
 
663
- host = (u_char *) servername;
796
+ if (ngx_http_validate_host(&host, c->pool, 1) != NGX_OK) {
797
+ return SSL_TLSEXT_ERR_NOACK;
798
+ }
664
799
 
665
- len = ngx_http_validate_host(r, &host, len, 1);
800
+ hc = c->data;
666
801
 
667
- if (len <= 0) {
802
+ if (ngx_http_find_virtual_server(c, hc->addr_conf->virtual_names, &host,
803
+ NULL, &cscf)
804
+ != NGX_OK)
805
+ {
668
806
  return SSL_TLSEXT_ERR_NOACK;
669
807
  }
670
808
 
671
- if (ngx_http_find_virtual_server(r, host, len) != NGX_OK) {
809
+ hc->ssl_servername = ngx_palloc(c->pool, sizeof(ngx_str_t));
810
+ if (hc->ssl_servername == NULL) {
672
811
  return SSL_TLSEXT_ERR_NOACK;
673
812
  }
674
813
 
675
- sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
814
+ *hc->ssl_servername = host;
815
+
816
+ hc->conf_ctx = cscf->ctx;
817
+
818
+ clcf = ngx_http_get_module_loc_conf(hc->conf_ctx, ngx_http_core_module);
819
+
820
+ ngx_http_set_connection_log(c, clcf->error_log);
821
+
822
+ sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module);
676
823
 
677
824
  if (sscf->ssl.ctx) {
678
825
  SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx);
@@ -707,12 +854,11 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
707
854
  static void
708
855
  ngx_http_process_request_line(ngx_event_t *rev)
709
856
  {
710
- u_char *host;
711
- ssize_t n;
712
- ngx_int_t rc, rv;
713
- ngx_connection_t *c;
714
- ngx_http_request_t *r;
715
- ngx_http_core_srv_conf_t *cscf;
857
+ ssize_t n;
858
+ ngx_int_t rc, rv;
859
+ ngx_str_t host;
860
+ ngx_connection_t *c;
861
+ ngx_http_request_t *r;
716
862
 
717
863
  c = rev->data;
718
864
  r = c->data;
@@ -749,224 +895,223 @@ ngx_http_process_request_line(ngx_event_t *rev)
749
895
  r->request_line.data = r->request_start;
750
896
  r->request_length = r->header_in->pos - r->request_start;
751
897
 
898
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
899
+ "http request line: \"%V\"", &r->request_line);
752
900
 
753
- if (r->args_start) {
754
- r->uri.len = r->args_start - 1 - r->uri_start;
755
- } else {
756
- r->uri.len = r->uri_end - r->uri_start;
757
- }
901
+ r->method_name.len = r->method_end - r->request_start + 1;
902
+ r->method_name.data = r->request_line.data;
758
903
 
904
+ if (r->http_protocol.data) {
905
+ r->http_protocol.len = r->request_end - r->http_protocol.data;
906
+ }
759
907
 
760
- if (r->complex_uri || r->quoted_uri) {
908
+ if (ngx_http_process_request_uri(r) != NGX_OK) {
909
+ return;
910
+ }
761
911
 
762
- r->uri.data = ngx_pnalloc(r->pool, r->uri.len + 1);
763
- if (r->uri.data == NULL) {
764
- ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
765
- return;
766
- }
912
+ if (r->host_start && r->host_end) {
767
913
 
768
- cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
914
+ host.len = r->host_end - r->host_start;
915
+ host.data = r->host_start;
769
916
 
770
- rc = ngx_http_parse_complex_uri(r, cscf->merge_slashes);
917
+ rc = ngx_http_validate_host(&host, r->pool, 0);
771
918
 
772
- if (rc == NGX_HTTP_PARSE_INVALID_REQUEST) {
919
+ if (rc == NGX_DECLINED) {
773
920
  ngx_log_error(NGX_LOG_INFO, c->log, 0,
774
- "client sent invalid request");
921
+ "client sent invalid host in request line");
775
922
  ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
776
923
  return;
777
924
  }
778
925
 
779
- } else {
780
- r->uri.data = r->uri_start;
781
- }
782
-
783
-
784
- r->unparsed_uri.len = r->uri_end - r->uri_start;
785
- r->unparsed_uri.data = r->uri_start;
786
-
787
- r->valid_unparsed_uri = r->space_in_uri ? 0 : 1;
788
-
789
- r->method_name.len = r->method_end - r->request_start + 1;
790
- r->method_name.data = r->request_line.data;
926
+ if (rc == NGX_ERROR) {
927
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
928
+ return;
929
+ }
791
930
 
931
+ if (ngx_http_set_virtual_server(r, &host) == NGX_ERROR) {
932
+ return;
933
+ }
792
934
 
793
- if (r->http_protocol.data) {
794
- r->http_protocol.len = r->request_end - r->http_protocol.data;
935
+ r->headers_in.server = host;
795
936
  }
796
937
 
938
+ if (r->http_version < NGX_HTTP_VERSION_10) {
797
939
 
798
- if (r->uri_ext) {
799
- if (r->args_start) {
800
- r->exten.len = r->args_start - 1 - r->uri_ext;
801
- } else {
802
- r->exten.len = r->uri_end - r->uri_ext;
940
+ if (r->headers_in.server.len == 0
941
+ && ngx_http_set_virtual_server(r, &r->headers_in.server)
942
+ == NGX_ERROR)
943
+ {
944
+ return;
803
945
  }
804
946
 
805
- r->exten.data = r->uri_ext;
947
+ ngx_http_process_request(r);
948
+ return;
806
949
  }
807
950
 
808
951
 
809
- if (r->args_start && r->uri_end > r->args_start) {
810
- r->args.len = r->uri_end - r->args_start;
811
- r->args.data = r->args_start;
812
- }
813
-
814
- #if (NGX_WIN32)
952
+ if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
953
+ sizeof(ngx_table_elt_t))
954
+ != NGX_OK)
815
955
  {
816
- u_char *p, *last;
956
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
957
+ return;
958
+ }
817
959
 
818
- p = r->uri.data;
819
- last = r->uri.data + r->uri.len;
960
+ c->log->action = "reading client request headers";
820
961
 
821
- while (p < last) {
962
+ rev->handler = ngx_http_process_request_headers;
963
+ ngx_http_process_request_headers(rev);
822
964
 
823
- if (*p++ == ':') {
965
+ return;
966
+ }
824
967
 
825
- /*
826
- * this check covers "::$data", "::$index_allocation" and
827
- * ":$i30:$index_allocation"
828
- */
968
+ if (rc != NGX_AGAIN) {
829
969
 
830
- if (p < last && *p == '$') {
831
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
832
- "client sent unsafe win32 URI");
833
- ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
834
- return;
835
- }
836
- }
837
- }
970
+ /* there was error while a request line parsing */
838
971
 
839
- p = r->uri.data + r->uri.len - 1;
972
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
973
+ ngx_http_client_errors[rc - NGX_HTTP_CLIENT_ERROR]);
974
+ ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
975
+ return;
976
+ }
840
977
 
841
- while (p > r->uri.data) {
978
+ /* NGX_AGAIN: a request line parsing is still incomplete */
842
979
 
843
- if (*p == ' ') {
844
- p--;
845
- continue;
846
- }
980
+ if (r->header_in->pos == r->header_in->end) {
847
981
 
848
- if (*p == '.') {
849
- p--;
850
- continue;
851
- }
982
+ rv = ngx_http_alloc_large_header_buffer(r, 1);
852
983
 
853
- break;
984
+ if (rv == NGX_ERROR) {
985
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
986
+ return;
854
987
  }
855
988
 
856
- if (p != r->uri.data + r->uri.len - 1) {
857
- r->uri.len = p + 1 - r->uri.data;
858
- ngx_http_set_exten(r);
859
- }
989
+ if (rv == NGX_DECLINED) {
990
+ r->request_line.len = r->header_in->end - r->request_start;
991
+ r->request_line.data = r->request_start;
860
992
 
993
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
994
+ "client sent too long URI");
995
+ ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE);
996
+ return;
861
997
  }
862
- #endif
998
+ }
999
+ }
1000
+ }
863
1001
 
864
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
865
- "http request line: \"%V\"", &r->request_line);
866
1002
 
867
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
868
- "http uri: \"%V\"", &r->uri);
1003
+ ngx_int_t
1004
+ ngx_http_process_request_uri(ngx_http_request_t *r)
1005
+ {
1006
+ ngx_http_core_srv_conf_t *cscf;
869
1007
 
870
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
871
- "http args: \"%V\"", &r->args);
1008
+ if (r->args_start) {
1009
+ r->uri.len = r->args_start - 1 - r->uri_start;
1010
+ } else {
1011
+ r->uri.len = r->uri_end - r->uri_start;
1012
+ }
872
1013
 
873
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
874
- "http exten: \"%V\"", &r->exten);
1014
+ if (r->complex_uri || r->quoted_uri) {
875
1015
 
876
- if (r->host_start && r->host_end) {
1016
+ r->uri.data = ngx_pnalloc(r->pool, r->uri.len + 1);
1017
+ if (r->uri.data == NULL) {
1018
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1019
+ return NGX_ERROR;
1020
+ }
877
1021
 
878
- host = r->host_start;
879
- n = ngx_http_validate_host(r, &host,
880
- r->host_end - r->host_start, 0);
1022
+ cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
881
1023
 
882
- if (n == 0) {
883
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
884
- "client sent invalid host in request line");
885
- ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
886
- return;
887
- }
1024
+ if (ngx_http_parse_complex_uri(r, cscf->merge_slashes) != NGX_OK) {
1025
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1026
+ "client sent invalid request");
1027
+ ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
1028
+ return NGX_ERROR;
1029
+ }
888
1030
 
889
- if (n < 0) {
890
- ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
891
- return;
892
- }
1031
+ } else {
1032
+ r->uri.data = r->uri_start;
1033
+ }
893
1034
 
894
- r->headers_in.server.len = n;
895
- r->headers_in.server.data = host;
896
- }
1035
+ r->unparsed_uri.len = r->uri_end - r->uri_start;
1036
+ r->unparsed_uri.data = r->uri_start;
897
1037
 
898
- if (r->http_version < NGX_HTTP_VERSION_10) {
1038
+ r->valid_unparsed_uri = r->space_in_uri ? 0 : 1;
899
1039
 
900
- if (ngx_http_find_virtual_server(r, r->headers_in.server.data,
901
- r->headers_in.server.len)
902
- == NGX_ERROR)
903
- {
904
- ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
905
- return;
906
- }
1040
+ if (r->uri_ext) {
1041
+ if (r->args_start) {
1042
+ r->exten.len = r->args_start - 1 - r->uri_ext;
1043
+ } else {
1044
+ r->exten.len = r->uri_end - r->uri_ext;
1045
+ }
907
1046
 
908
- ngx_http_process_request(r);
909
- return;
910
- }
1047
+ r->exten.data = r->uri_ext;
1048
+ }
911
1049
 
1050
+ if (r->args_start && r->uri_end > r->args_start) {
1051
+ r->args.len = r->uri_end - r->args_start;
1052
+ r->args.data = r->args_start;
1053
+ }
912
1054
 
913
- if (ngx_list_init(&r->headers_in.headers, r->pool, 20,
914
- sizeof(ngx_table_elt_t))
915
- != NGX_OK)
916
- {
917
- ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
918
- return;
919
- }
1055
+ #if (NGX_WIN32)
1056
+ {
1057
+ u_char *p, *last;
920
1058
 
1059
+ p = r->uri.data;
1060
+ last = r->uri.data + r->uri.len;
921
1061
 
922
- if (ngx_array_init(&r->headers_in.cookies, r->pool, 2,
923
- sizeof(ngx_table_elt_t *))
924
- != NGX_OK)
925
- {
926
- ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
927
- return;
928
- }
1062
+ while (p < last) {
929
1063
 
930
- c->log->action = "reading client request headers";
1064
+ if (*p++ == ':') {
931
1065
 
932
- rev->handler = ngx_http_process_request_headers;
933
- ngx_http_process_request_headers(rev);
1066
+ /*
1067
+ * this check covers "::$data", "::$index_allocation" and
1068
+ * ":$i30:$index_allocation"
1069
+ */
934
1070
 
935
- return;
1071
+ if (p < last && *p == '$') {
1072
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1073
+ "client sent unsafe win32 URI");
1074
+ ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
1075
+ return NGX_ERROR;
1076
+ }
936
1077
  }
1078
+ }
937
1079
 
938
- if (rc != NGX_AGAIN) {
1080
+ p = r->uri.data + r->uri.len - 1;
939
1081
 
940
- /* there was error while a request line parsing */
1082
+ while (p > r->uri.data) {
941
1083
 
942
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
943
- ngx_http_client_errors[rc - NGX_HTTP_CLIENT_ERROR]);
944
- ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
945
- return;
1084
+ if (*p == ' ') {
1085
+ p--;
1086
+ continue;
946
1087
  }
947
1088
 
948
- /* NGX_AGAIN: a request line parsing is still incomplete */
1089
+ if (*p == '.') {
1090
+ p--;
1091
+ continue;
1092
+ }
949
1093
 
950
- if (r->header_in->pos == r->header_in->end) {
1094
+ break;
1095
+ }
951
1096
 
952
- rv = ngx_http_alloc_large_header_buffer(r, 1);
1097
+ if (p != r->uri.data + r->uri.len - 1) {
1098
+ r->uri.len = p + 1 - r->uri.data;
1099
+ ngx_http_set_exten(r);
1100
+ }
953
1101
 
954
- if (rv == NGX_ERROR) {
955
- ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
956
- return;
957
- }
1102
+ }
1103
+ #endif
958
1104
 
959
- if (rv == NGX_DECLINED) {
960
- r->request_line.len = r->header_in->end - r->request_start;
961
- r->request_line.data = r->request_start;
1105
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1106
+ "http uri: \"%V\"", &r->uri);
962
1107
 
963
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
964
- "client sent too long URI");
965
- ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE);
966
- return;
967
- }
968
- }
969
- }
1108
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1109
+ "http args: \"%V\"", &r->args);
1110
+
1111
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1112
+ "http exten: \"%V\"", &r->exten);
1113
+
1114
+ return NGX_OK;
970
1115
  }
971
1116
 
972
1117
 
@@ -998,7 +1143,6 @@ ngx_http_process_request_headers(ngx_event_t *rev)
998
1143
  }
999
1144
 
1000
1145
  cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
1001
- cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
1002
1146
 
1003
1147
  rc = NGX_AGAIN;
1004
1148
 
@@ -1052,6 +1196,9 @@ ngx_http_process_request_headers(ngx_event_t *rev)
1052
1196
  }
1053
1197
  }
1054
1198
 
1199
+ /* the host header could change the server configuration context */
1200
+ cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
1201
+
1055
1202
  rc = ngx_http_parse_header_line(r, r->header_in,
1056
1203
  cscf->underscores_in_headers);
1057
1204
 
@@ -1401,24 +1548,25 @@ static ngx_int_t
1401
1548
  ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h,
1402
1549
  ngx_uint_t offset)
1403
1550
  {
1404
- u_char *host;
1405
- ssize_t len;
1551
+ ngx_int_t rc;
1552
+ ngx_str_t host;
1406
1553
 
1407
1554
  if (r->headers_in.host == NULL) {
1408
1555
  r->headers_in.host = h;
1409
1556
  }
1410
1557
 
1411
- host = h->value.data;
1412
- len = ngx_http_validate_host(r, &host, h->value.len, 0);
1558
+ host = h->value;
1559
+
1560
+ rc = ngx_http_validate_host(&host, r->pool, 0);
1413
1561
 
1414
- if (len == 0) {
1562
+ if (rc == NGX_DECLINED) {
1415
1563
  ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1416
1564
  "client sent invalid host header");
1417
1565
  ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
1418
1566
  return NGX_ERROR;
1419
1567
  }
1420
1568
 
1421
- if (len < 0) {
1569
+ if (rc == NGX_ERROR) {
1422
1570
  ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1423
1571
  return NGX_ERROR;
1424
1572
  }
@@ -1427,8 +1575,11 @@ ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h,
1427
1575
  return NGX_OK;
1428
1576
  }
1429
1577
 
1430
- r->headers_in.server.len = len;
1431
- r->headers_in.server.data = host;
1578
+ if (ngx_http_set_virtual_server(r, &host) == NGX_ERROR) {
1579
+ return NGX_ERROR;
1580
+ }
1581
+
1582
+ r->headers_in.server = host;
1432
1583
 
1433
1584
  return NGX_OK;
1434
1585
  }
@@ -1523,31 +1674,41 @@ ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h,
1523
1674
 
1524
1675
 
1525
1676
  static ngx_int_t
1526
- ngx_http_process_cookie(ngx_http_request_t *r, ngx_table_elt_t *h,
1677
+ ngx_http_process_multi_header_lines(ngx_http_request_t *r, ngx_table_elt_t *h,
1527
1678
  ngx_uint_t offset)
1528
1679
  {
1529
- ngx_table_elt_t **cookie;
1680
+ ngx_array_t *headers;
1681
+ ngx_table_elt_t **ph;
1530
1682
 
1531
- cookie = ngx_array_push(&r->headers_in.cookies);
1532
- if (cookie) {
1533
- *cookie = h;
1534
- return NGX_OK;
1683
+ headers = (ngx_array_t *) ((char *) &r->headers_in + offset);
1684
+
1685
+ if (headers->elts == NULL) {
1686
+ if (ngx_array_init(headers, r->pool, 1, sizeof(ngx_table_elt_t *))
1687
+ != NGX_OK)
1688
+ {
1689
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1690
+ return NGX_ERROR;
1691
+ }
1535
1692
  }
1536
1693
 
1537
- ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1694
+ ph = ngx_array_push(headers);
1695
+ if (ph == NULL) {
1696
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1697
+ return NGX_ERROR;
1698
+ }
1538
1699
 
1539
- return NGX_ERROR;
1700
+ *ph = h;
1701
+ return NGX_OK;
1540
1702
  }
1541
1703
 
1542
1704
 
1543
- static ngx_int_t
1705
+ ngx_int_t
1544
1706
  ngx_http_process_request_header(ngx_http_request_t *r)
1545
1707
  {
1546
- if (ngx_http_find_virtual_server(r, r->headers_in.server.data,
1547
- r->headers_in.server.len)
1548
- == NGX_ERROR)
1708
+ if (r->headers_in.server.len == 0
1709
+ && ngx_http_set_virtual_server(r, &r->headers_in.server)
1710
+ == NGX_ERROR)
1549
1711
  {
1550
- ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1551
1712
  return NGX_ERROR;
1552
1713
  }
1553
1714
 
@@ -1566,19 +1727,11 @@ ngx_http_process_request_header(ngx_http_request_t *r)
1566
1727
  if (r->headers_in.content_length_n == NGX_ERROR) {
1567
1728
  ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1568
1729
  "client sent invalid \"Content-Length\" header");
1569
- ngx_http_finalize_request(r, NGX_HTTP_LENGTH_REQUIRED);
1730
+ ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
1570
1731
  return NGX_ERROR;
1571
1732
  }
1572
1733
  }
1573
1734
 
1574
- if (r->method & NGX_HTTP_PUT && r->headers_in.content_length_n == -1) {
1575
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1576
- "client sent %V method without \"Content-Length\" header",
1577
- &r->method_name);
1578
- ngx_http_finalize_request(r, NGX_HTTP_LENGTH_REQUIRED);
1579
- return NGX_ERROR;
1580
- }
1581
-
1582
1735
  if (r->method & NGX_HTTP_TRACE) {
1583
1736
  ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1584
1737
  "client sent TRACE method");
@@ -1586,14 +1739,25 @@ ngx_http_process_request_header(ngx_http_request_t *r)
1586
1739
  return NGX_ERROR;
1587
1740
  }
1588
1741
 
1589
- if (r->headers_in.transfer_encoding
1590
- && ngx_strcasestrn(r->headers_in.transfer_encoding->value.data,
1591
- "chunked", 7 - 1))
1592
- {
1593
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1594
- "client sent \"Transfer-Encoding: chunked\" header");
1595
- ngx_http_finalize_request(r, NGX_HTTP_LENGTH_REQUIRED);
1596
- return NGX_ERROR;
1742
+ if (r->headers_in.transfer_encoding) {
1743
+ if (r->headers_in.transfer_encoding->value.len == 7
1744
+ && ngx_strncasecmp(r->headers_in.transfer_encoding->value.data,
1745
+ (u_char *) "chunked", 7) == 0)
1746
+ {
1747
+ r->headers_in.content_length = NULL;
1748
+ r->headers_in.content_length_n = -1;
1749
+ r->headers_in.chunked = 1;
1750
+
1751
+ } else if (r->headers_in.transfer_encoding->value.len != 8
1752
+ || ngx_strncasecmp(r->headers_in.transfer_encoding->value.data,
1753
+ (u_char *) "identity", 8) != 0)
1754
+ {
1755
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
1756
+ "client sent unknown \"Transfer-Encoding\": \"%V\"",
1757
+ &r->headers_in.transfer_encoding->value);
1758
+ ngx_http_finalize_request(r, NGX_HTTP_NOT_IMPLEMENTED);
1759
+ return NGX_ERROR;
1760
+ }
1597
1761
  }
1598
1762
 
1599
1763
  if (r->headers_in.connection_type == NGX_HTTP_CONNECTION_KEEP_ALIVE) {
@@ -1608,27 +1772,27 @@ ngx_http_process_request_header(ngx_http_request_t *r)
1608
1772
  }
1609
1773
 
1610
1774
 
1611
- static void
1775
+ void
1612
1776
  ngx_http_process_request(ngx_http_request_t *r)
1613
1777
  {
1614
1778
  ngx_connection_t *c;
1615
1779
 
1616
1780
  c = r->connection;
1617
1781
 
1618
- if (r->plain_http) {
1619
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
1620
- "client sent plain HTTP request to HTTPS port");
1621
- ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS);
1622
- return;
1623
- }
1624
-
1625
1782
  #if (NGX_HTTP_SSL)
1626
1783
 
1627
- if (c->ssl) {
1784
+ if (r->http_connection->ssl) {
1628
1785
  long rc;
1629
1786
  X509 *cert;
1630
1787
  ngx_http_ssl_srv_conf_t *sscf;
1631
1788
 
1789
+ if (c->ssl == NULL) {
1790
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
1791
+ "client sent plain HTTP request to HTTPS port");
1792
+ ngx_http_finalize_request(r, NGX_HTTP_TO_HTTPS);
1793
+ return;
1794
+ }
1795
+
1632
1796
  sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
1633
1797
 
1634
1798
  if (sscf->verify) {
@@ -1690,9 +1854,8 @@ ngx_http_process_request(ngx_http_request_t *r)
1690
1854
  }
1691
1855
 
1692
1856
 
1693
- static ssize_t
1694
- ngx_http_validate_host(ngx_http_request_t *r, u_char **host, size_t len,
1695
- ngx_uint_t alloc)
1857
+ static ngx_int_t
1858
+ ngx_http_validate_host(ngx_str_t *host, ngx_pool_t *pool, ngx_uint_t alloc)
1696
1859
  {
1697
1860
  u_char *h, ch;
1698
1861
  size_t i, dot_pos, host_len;
@@ -1703,21 +1866,21 @@ ngx_http_validate_host(ngx_http_request_t *r, u_char **host, size_t len,
1703
1866
  sw_rest
1704
1867
  } state;
1705
1868
 
1706
- dot_pos = len;
1707
- host_len = len;
1869
+ dot_pos = host->len;
1870
+ host_len = host->len;
1708
1871
 
1709
- h = *host;
1872
+ h = host->data;
1710
1873
 
1711
1874
  state = sw_usual;
1712
1875
 
1713
- for (i = 0; i < len; i++) {
1876
+ for (i = 0; i < host->len; i++) {
1714
1877
  ch = h[i];
1715
1878
 
1716
1879
  switch (ch) {
1717
1880
 
1718
1881
  case '.':
1719
1882
  if (dot_pos == i - 1) {
1720
- return 0;
1883
+ return NGX_DECLINED;
1721
1884
  }
1722
1885
  dot_pos = i;
1723
1886
  break;
@@ -1743,12 +1906,12 @@ ngx_http_validate_host(ngx_http_request_t *r, u_char **host, size_t len,
1743
1906
  break;
1744
1907
 
1745
1908
  case '\0':
1746
- return 0;
1909
+ return NGX_DECLINED;
1747
1910
 
1748
1911
  default:
1749
1912
 
1750
1913
  if (ngx_path_separator(ch)) {
1751
- return 0;
1914
+ return NGX_DECLINED;
1752
1915
  }
1753
1916
 
1754
1917
  if (ch >= 'A' && ch <= 'Z') {
@@ -1763,83 +1926,187 @@ ngx_http_validate_host(ngx_http_request_t *r, u_char **host, size_t len,
1763
1926
  host_len--;
1764
1927
  }
1765
1928
 
1929
+ if (host_len == 0) {
1930
+ return NGX_DECLINED;
1931
+ }
1932
+
1766
1933
  if (alloc) {
1767
- *host = ngx_pnalloc(r->pool, host_len);
1768
- if (*host == NULL) {
1769
- return -1;
1934
+ host->data = ngx_pnalloc(pool, host_len);
1935
+ if (host->data == NULL) {
1936
+ return NGX_ERROR;
1770
1937
  }
1771
1938
 
1772
- ngx_strlow(*host, h, host_len);
1939
+ ngx_strlow(host->data, h, host_len);
1773
1940
  }
1774
1941
 
1775
- return host_len;
1942
+ host->len = host_len;
1943
+
1944
+ return NGX_OK;
1776
1945
  }
1777
1946
 
1778
1947
 
1779
1948
  static ngx_int_t
1780
- ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
1949
+ ngx_http_set_virtual_server(ngx_http_request_t *r, ngx_str_t *host)
1781
1950
  {
1951
+ ngx_int_t rc;
1952
+ ngx_http_connection_t *hc;
1782
1953
  ngx_http_core_loc_conf_t *clcf;
1783
1954
  ngx_http_core_srv_conf_t *cscf;
1784
1955
 
1785
- if (r->virtual_names == NULL) {
1956
+ hc = r->http_connection;
1957
+
1958
+ #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1959
+
1960
+ if (hc->ssl_servername) {
1961
+ if (hc->ssl_servername->len == host->len
1962
+ && ngx_strncmp(hc->ssl_servername->data,
1963
+ host->data, host->len) == 0)
1964
+ {
1965
+ #if (NGX_PCRE)
1966
+ if (hc->ssl_servername_regex
1967
+ && ngx_http_regex_exec(r, hc->ssl_servername_regex,
1968
+ hc->ssl_servername) != NGX_OK)
1969
+ {
1970
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1971
+ return NGX_ERROR;
1972
+ }
1973
+ #endif
1974
+ return NGX_OK;
1975
+ }
1976
+ }
1977
+
1978
+ #endif
1979
+
1980
+ rc = ngx_http_find_virtual_server(r->connection,
1981
+ hc->addr_conf->virtual_names,
1982
+ host, r, &cscf);
1983
+
1984
+ if (rc == NGX_ERROR) {
1985
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1986
+ return NGX_ERROR;
1987
+ }
1988
+
1989
+ #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1990
+
1991
+ if (hc->ssl_servername) {
1992
+ ngx_http_ssl_srv_conf_t *sscf;
1993
+
1994
+ if (rc == NGX_DECLINED) {
1995
+ cscf = hc->addr_conf->default_server;
1996
+ rc = NGX_OK;
1997
+ }
1998
+
1999
+ sscf = ngx_http_get_module_srv_conf(cscf->ctx, ngx_http_ssl_module);
2000
+
2001
+ if (sscf->verify) {
2002
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
2003
+ "client attempted to request the server name "
2004
+ "different from that one was negotiated");
2005
+ ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
2006
+ return NGX_ERROR;
2007
+ }
2008
+ }
2009
+
2010
+ #endif
2011
+
2012
+ if (rc == NGX_DECLINED) {
2013
+ return NGX_OK;
2014
+ }
2015
+
2016
+ r->srv_conf = cscf->ctx->srv_conf;
2017
+ r->loc_conf = cscf->ctx->loc_conf;
2018
+
2019
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
2020
+
2021
+ ngx_http_set_connection_log(r->connection, clcf->error_log);
2022
+
2023
+ return NGX_OK;
2024
+ }
2025
+
2026
+
2027
+ static ngx_int_t
2028
+ ngx_http_find_virtual_server(ngx_connection_t *c,
2029
+ ngx_http_virtual_names_t *virtual_names, ngx_str_t *host,
2030
+ ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp)
2031
+ {
2032
+ ngx_http_core_srv_conf_t *cscf;
2033
+
2034
+ if (virtual_names == NULL) {
1786
2035
  return NGX_DECLINED;
1787
2036
  }
1788
2037
 
1789
- cscf = ngx_hash_find_combined(&r->virtual_names->names,
1790
- ngx_hash_key(host, len), host, len);
2038
+ cscf = ngx_hash_find_combined(&virtual_names->names,
2039
+ ngx_hash_key(host->data, host->len),
2040
+ host->data, host->len);
1791
2041
 
1792
2042
  if (cscf) {
1793
- goto found;
2043
+ *cscfp = cscf;
2044
+ return NGX_OK;
1794
2045
  }
1795
2046
 
1796
2047
  #if (NGX_PCRE)
1797
2048
 
1798
- if (len && r->virtual_names->nregex) {
2049
+ if (host->len && virtual_names->nregex) {
1799
2050
  ngx_int_t n;
1800
2051
  ngx_uint_t i;
1801
- ngx_str_t name;
1802
2052
  ngx_http_server_name_t *sn;
1803
2053
 
1804
- name.len = len;
1805
- name.data = host;
2054
+ sn = virtual_names->regex;
2055
+
2056
+ #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1806
2057
 
1807
- sn = r->virtual_names->regex;
2058
+ if (r == NULL) {
2059
+ ngx_http_connection_t *hc;
1808
2060
 
1809
- for (i = 0; i < r->virtual_names->nregex; i++) {
2061
+ for (i = 0; i < virtual_names->nregex; i++) {
1810
2062
 
1811
- n = ngx_http_regex_exec(r, sn[i].regex, &name);
2063
+ n = ngx_regex_exec(sn[i].regex->regex, host, NULL, 0);
1812
2064
 
1813
- if (n == NGX_OK) {
1814
- cscf = sn[i].server;
1815
- goto found;
1816
- }
2065
+ if (n == NGX_REGEX_NO_MATCHED) {
2066
+ continue;
2067
+ }
1817
2068
 
1818
- if (n == NGX_DECLINED) {
1819
- continue;
2069
+ if (n >= 0) {
2070
+ hc = c->data;
2071
+ hc->ssl_servername_regex = sn[i].regex;
2072
+
2073
+ *cscfp = sn[i].server;
2074
+ return NGX_OK;
2075
+ }
2076
+
2077
+ ngx_log_error(NGX_LOG_ALERT, c->log, 0,
2078
+ ngx_regex_exec_n " failed: %i "
2079
+ "on \"%V\" using \"%V\"",
2080
+ n, host, &sn[i].regex->name);
2081
+
2082
+ return NGX_ERROR;
1820
2083
  }
1821
2084
 
1822
- return NGX_ERROR;
2085
+ return NGX_DECLINED;
1823
2086
  }
1824
- }
1825
2087
 
1826
- #endif
2088
+ #endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1827
2089
 
1828
- return NGX_DECLINED;
2090
+ for (i = 0; i < virtual_names->nregex; i++) {
1829
2091
 
1830
- found:
2092
+ n = ngx_http_regex_exec(r, sn[i].regex, host);
1831
2093
 
1832
- r->srv_conf = cscf->ctx->srv_conf;
1833
- r->loc_conf = cscf->ctx->loc_conf;
2094
+ if (n == NGX_DECLINED) {
2095
+ continue;
2096
+ }
1834
2097
 
1835
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1836
- r->connection->log->file = clcf->error_log->file;
2098
+ if (n == NGX_OK) {
2099
+ *cscfp = sn[i].server;
2100
+ return NGX_OK;
2101
+ }
1837
2102
 
1838
- if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
1839
- r->connection->log->log_level = clcf->error_log->log_level;
2103
+ return NGX_ERROR;
2104
+ }
1840
2105
  }
1841
2106
 
1842
- return NGX_OK;
2107
+ #endif /* NGX_PCRE */
2108
+
2109
+ return NGX_DECLINED;
1843
2110
  }
1844
2111
 
1845
2112
 
@@ -2182,6 +2449,13 @@ ngx_http_finalize_connection(ngx_http_request_t *r)
2182
2449
  {
2183
2450
  ngx_http_core_loc_conf_t *clcf;
2184
2451
 
2452
+ #if (NGX_HTTP_SPDY)
2453
+ if (r->spdy_stream) {
2454
+ ngx_http_close_request(r, 0);
2455
+ return;
2456
+ }
2457
+ #endif
2458
+
2185
2459
  clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
2186
2460
 
2187
2461
  if (r->main->count != 1) {
@@ -2236,6 +2510,12 @@ ngx_http_set_write_handler(ngx_http_request_t *r)
2236
2510
  ngx_http_test_reading;
2237
2511
  r->write_event_handler = ngx_http_writer;
2238
2512
 
2513
+ #if (NGX_HTTP_SPDY)
2514
+ if (r->spdy_stream) {
2515
+ return NGX_OK;
2516
+ }
2517
+ #endif
2518
+
2239
2519
  wev = r->connection->write;
2240
2520
 
2241
2521
  if (wev->ready && wev->delayed) {
@@ -2383,6 +2663,19 @@ ngx_http_test_reading(ngx_http_request_t *r)
2383
2663
 
2384
2664
  ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http test reading");
2385
2665
 
2666
+ #if (NGX_HTTP_SPDY)
2667
+
2668
+ if (r->spdy_stream) {
2669
+ if (c->error) {
2670
+ err = 0;
2671
+ goto closed;
2672
+ }
2673
+
2674
+ return;
2675
+ }
2676
+
2677
+ #endif
2678
+
2386
2679
  #if (NGX_HAVE_KQUEUE)
2387
2680
 
2388
2681
  if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
@@ -2484,7 +2777,7 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
2484
2777
  /*
2485
2778
  * If the large header buffers were allocated while the previous
2486
2779
  * request processing then we do not use c->buffer for
2487
- * the pipelined request (see ngx_http_init_request()).
2780
+ * the pipelined request (see ngx_http_create_request()).
2488
2781
  *
2489
2782
  * Now we would move the large header buffers to the free list.
2490
2783
  */
@@ -2513,14 +2806,13 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
2513
2806
  }
2514
2807
  }
2515
2808
 
2809
+ /* guard against recursive call from ngx_http_finalize_connection() */
2516
2810
  r->keepalive = 0;
2517
2811
 
2518
2812
  ngx_http_free_request(r, 0);
2519
2813
 
2520
2814
  c->data = hc;
2521
2815
 
2522
- ngx_add_timer(rev, clcf->keepalive_timeout);
2523
-
2524
2816
  if (ngx_handle_read_event(rev, 0) != NGX_OK) {
2525
2817
  ngx_http_close_connection(c);
2526
2818
  return;
@@ -2533,32 +2825,37 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
2533
2825
 
2534
2826
  ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "pipelined request");
2535
2827
 
2536
- #if (NGX_STAT_STUB)
2537
- (void) ngx_atomic_fetch_add(ngx_stat_reading, 1);
2538
- #endif
2539
-
2540
- hc->pipeline = 1;
2541
2828
  c->log->action = "reading client pipelined request line";
2542
2829
 
2543
- rev->handler = ngx_http_init_request;
2830
+ r = ngx_http_create_request(c);
2831
+ if (r == NULL) {
2832
+ ngx_http_close_connection(c);
2833
+ return;
2834
+ }
2835
+
2836
+ r->pipeline = 1;
2837
+
2838
+ c->data = r;
2839
+
2840
+ c->sent = 0;
2841
+ c->destroyed = 0;
2842
+
2843
+ if (rev->timer_set) {
2844
+ ngx_del_timer(rev);
2845
+ }
2846
+
2847
+ rev->handler = ngx_http_process_request_line;
2544
2848
  ngx_post_event(rev, &ngx_posted_events);
2545
2849
  return;
2546
2850
  }
2547
2851
 
2548
- hc->pipeline = 0;
2549
-
2550
2852
  /*
2551
- * To keep a memory footprint as small as possible for an idle
2552
- * keepalive connection we try to free the ngx_http_request_t and
2553
- * c->buffer's memory if they were allocated outside the c->pool.
2554
- * The large header buffers are always allocated outside the c->pool and
2555
- * are freed too.
2853
+ * To keep a memory footprint as small as possible for an idle keepalive
2854
+ * connection we try to free c->buffer's memory if it was allocated outside
2855
+ * the c->pool. The large header buffers are always allocated outside the
2856
+ * c->pool and are freed too.
2556
2857
  */
2557
2858
 
2558
- if (ngx_pfree(c->pool, r) == NGX_OK) {
2559
- hc->request = NULL;
2560
- }
2561
-
2562
2859
  b = c->buffer;
2563
2860
 
2564
2861
  if (ngx_pfree(c->pool, b->start) == NGX_OK) {
@@ -2664,6 +2961,8 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
2664
2961
  c->idle = 1;
2665
2962
  ngx_reusable_connection(c, 1);
2666
2963
 
2964
+ ngx_add_timer(rev, clcf->keepalive_timeout);
2965
+
2667
2966
  if (rev->ready) {
2668
2967
  ngx_post_event(rev, &ngx_posted_events);
2669
2968
  }
@@ -2779,17 +3078,25 @@ ngx_http_keepalive_handler(ngx_event_t *rev)
2779
3078
 
2780
3079
  b->last += n;
2781
3080
 
2782
- #if (NGX_STAT_STUB)
2783
- (void) ngx_atomic_fetch_add(ngx_stat_reading, 1);
2784
- #endif
2785
-
2786
3081
  c->log->handler = ngx_http_log_error;
2787
3082
  c->log->action = "reading client request line";
2788
3083
 
2789
3084
  c->idle = 0;
2790
3085
  ngx_reusable_connection(c, 0);
2791
3086
 
2792
- ngx_http_init_request(rev);
3087
+ c->data = ngx_http_create_request(c);
3088
+ if (c->data == NULL) {
3089
+ ngx_http_close_connection(c);
3090
+ return;
3091
+ }
3092
+
3093
+ c->sent = 0;
3094
+ c->destroyed = 0;
3095
+
3096
+ ngx_del_timer(rev);
3097
+
3098
+ rev->handler = ngx_http_process_request_line;
3099
+ ngx_http_process_request_line(rev);
2793
3100
  }
2794
3101
 
2795
3102
 
@@ -3004,15 +3311,23 @@ ngx_http_close_request(ngx_http_request_t *r, ngx_int_t rc)
3004
3311
  return;
3005
3312
  }
3006
3313
 
3314
+ #if (NGX_HTTP_SPDY)
3315
+ if (r->spdy_stream) {
3316
+ ngx_http_spdy_close_stream(r->spdy_stream, rc);
3317
+ return;
3318
+ }
3319
+ #endif
3320
+
3007
3321
  ngx_http_free_request(r, rc);
3008
3322
  ngx_http_close_connection(c);
3009
3323
  }
3010
3324
 
3011
3325
 
3012
- static void
3326
+ void
3013
3327
  ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc)
3014
3328
  {
3015
3329
  ngx_log_t *log;
3330
+ ngx_pool_t *pool;
3016
3331
  struct linger linger;
3017
3332
  ngx_http_cleanup_t *cln;
3018
3333
  ngx_http_log_ctx_t *ctx;
@@ -3079,7 +3394,15 @@ ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc)
3079
3394
 
3080
3395
  r->connection->destroyed = 1;
3081
3396
 
3082
- ngx_destroy_pool(r->pool);
3397
+ /*
3398
+ * Setting r->pool to NULL will increase probability to catch double close
3399
+ * of request since the request object is allocated from its own pool.
3400
+ */
3401
+
3402
+ pool = r->pool;
3403
+ r->pool = NULL;
3404
+
3405
+ ngx_destroy_pool(pool);
3083
3406
  }
3084
3407
 
3085
3408
 
@@ -3101,7 +3424,7 @@ ngx_http_log_request(ngx_http_request_t *r)
3101
3424
  }
3102
3425
 
3103
3426
 
3104
- static void
3427
+ void
3105
3428
  ngx_http_close_connection(ngx_connection_t *c)
3106
3429
  {
3107
3430
  ngx_pool_t *pool;