nginxtra 1.4.7.9 → 1.6.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (169) hide show
  1. checksums.yaml +4 -4
  2. data/bin/nginxtra +1 -1
  3. data/bin/nginxtra_rails +1 -1
  4. data/lib/nginxtra/version.rb +1 -1
  5. data/vendor/nginx/CHANGES +286 -19
  6. data/vendor/nginx/CHANGES.ru +296 -22
  7. data/vendor/nginx/auto/cc/clang +4 -3
  8. data/vendor/nginx/auto/cc/conf +23 -0
  9. data/vendor/nginx/auto/cc/msvc +1 -0
  10. data/vendor/nginx/auto/cc/name +1 -1
  11. data/vendor/nginx/auto/cc/owc +4 -4
  12. data/vendor/nginx/auto/cc/sunc +1 -1
  13. data/vendor/nginx/auto/endianness +2 -2
  14. data/vendor/nginx/auto/feature +1 -1
  15. data/vendor/nginx/auto/include +1 -1
  16. data/vendor/nginx/auto/lib/libatomic/make +3 -1
  17. data/vendor/nginx/auto/lib/openssl/conf +4 -0
  18. data/vendor/nginx/auto/lib/openssl/make +1 -1
  19. data/vendor/nginx/auto/lib/pcre/conf +5 -0
  20. data/vendor/nginx/auto/lib/pcre/make +11 -11
  21. data/vendor/nginx/auto/lib/pcre/makefile.bcc +4 -3
  22. data/vendor/nginx/auto/lib/pcre/makefile.msvc +2 -1
  23. data/vendor/nginx/auto/lib/pcre/makefile.owc +2 -1
  24. data/vendor/nginx/auto/lib/perl/make +1 -0
  25. data/vendor/nginx/auto/lib/test +1 -1
  26. data/vendor/nginx/auto/lib/zlib/make +22 -1
  27. data/vendor/nginx/auto/modules +8 -0
  28. data/vendor/nginx/auto/options +3 -0
  29. data/vendor/nginx/auto/os/darwin +1 -1
  30. data/vendor/nginx/auto/os/linux +32 -0
  31. data/vendor/nginx/auto/os/win32 +12 -1
  32. data/vendor/nginx/auto/sources +8 -2
  33. data/vendor/nginx/auto/types/sizeof +1 -1
  34. data/vendor/nginx/auto/types/typedef +1 -1
  35. data/vendor/nginx/auto/types/uintptr_t +1 -1
  36. data/vendor/nginx/auto/unix +13 -1
  37. data/vendor/nginx/conf/mime.types +11 -2
  38. data/vendor/nginx/conf/nginx.conf +3 -4
  39. data/vendor/nginx/contrib/README +6 -0
  40. data/vendor/nginx/contrib/vim/ftdetect/nginx.vim +4 -0
  41. data/vendor/nginx/contrib/vim/indent/nginx.vim +11 -0
  42. data/vendor/nginx/contrib/vim/syntax/nginx.vim +703 -0
  43. data/vendor/nginx/src/core/nginx.c +2 -7
  44. data/vendor/nginx/src/core/nginx.h +2 -2
  45. data/vendor/nginx/src/core/ngx_conf_file.c +8 -88
  46. data/vendor/nginx/src/core/ngx_conf_file.h +3 -3
  47. data/vendor/nginx/src/core/ngx_config.h +2 -2
  48. data/vendor/nginx/src/core/ngx_connection.c +100 -29
  49. data/vendor/nginx/src/core/ngx_connection.h +11 -0
  50. data/vendor/nginx/src/core/ngx_core.h +1 -0
  51. data/vendor/nginx/src/core/ngx_cycle.c +23 -99
  52. data/vendor/nginx/src/core/ngx_cycle.h +2 -0
  53. data/vendor/nginx/src/core/ngx_file.c +100 -8
  54. data/vendor/nginx/src/core/ngx_file.h +3 -0
  55. data/vendor/nginx/src/core/ngx_hash.c +6 -9
  56. data/vendor/nginx/src/core/ngx_inet.c +93 -5
  57. data/vendor/nginx/src/core/ngx_inet.h +4 -2
  58. data/vendor/nginx/src/core/ngx_list.c +1 -9
  59. data/vendor/nginx/src/core/ngx_log.c +132 -30
  60. data/vendor/nginx/src/core/ngx_log.h +5 -2
  61. data/vendor/nginx/src/core/ngx_open_file_cache.c +67 -1
  62. data/vendor/nginx/src/core/ngx_palloc.c +5 -2
  63. data/vendor/nginx/src/core/ngx_proxy_protocol.c +91 -0
  64. data/vendor/nginx/src/core/ngx_proxy_protocol.h +23 -0
  65. data/vendor/nginx/src/core/ngx_resolver.c +1080 -285
  66. data/vendor/nginx/src/core/ngx_resolver.h +33 -3
  67. data/vendor/nginx/src/core/ngx_slab.c +7 -2
  68. data/vendor/nginx/src/core/ngx_slab.h +2 -0
  69. data/vendor/nginx/src/core/ngx_string.c +78 -13
  70. data/vendor/nginx/src/core/ngx_string.h +2 -0
  71. data/vendor/nginx/src/event/modules/ngx_devpoll_module.c +2 -2
  72. data/vendor/nginx/src/event/modules/ngx_epoll_module.c +13 -5
  73. data/vendor/nginx/src/event/modules/ngx_select_module.c +1 -1
  74. data/vendor/nginx/src/event/modules/ngx_win32_select_module.c +2 -2
  75. data/vendor/nginx/src/event/ngx_event.c +0 -1
  76. data/vendor/nginx/src/event/ngx_event.h +7 -6
  77. data/vendor/nginx/src/event/ngx_event_accept.c +6 -4
  78. data/vendor/nginx/src/event/ngx_event_connect.c +2 -2
  79. data/vendor/nginx/src/event/ngx_event_openssl.c +304 -13
  80. data/vendor/nginx/src/event/ngx_event_openssl.h +20 -1
  81. data/vendor/nginx/src/event/ngx_event_openssl_stapling.c +35 -23
  82. data/vendor/nginx/src/event/ngx_event_pipe.c +15 -30
  83. data/vendor/nginx/src/http/modules/ngx_http_access_module.c +115 -35
  84. data/vendor/nginx/src/http/modules/ngx_http_auth_basic_module.c +1 -1
  85. data/vendor/nginx/src/http/modules/ngx_http_auth_request_module.c +444 -0
  86. data/vendor/nginx/src/http/modules/ngx_http_autoindex_module.c +2 -1
  87. data/vendor/nginx/src/http/modules/ngx_http_charset_filter_module.c +1 -1
  88. data/vendor/nginx/src/http/modules/ngx_http_dav_module.c +1 -3
  89. data/vendor/nginx/src/http/modules/ngx_http_fastcgi_module.c +251 -36
  90. data/vendor/nginx/src/http/modules/ngx_http_gunzip_filter_module.c +9 -5
  91. data/vendor/nginx/src/http/modules/ngx_http_gzip_filter_module.c +5 -3
  92. data/vendor/nginx/src/http/modules/ngx_http_gzip_static_module.c +1 -1
  93. data/vendor/nginx/src/http/modules/ngx_http_headers_filter_module.c +4 -0
  94. data/vendor/nginx/src/http/modules/ngx_http_image_filter_module.c +8 -2
  95. data/vendor/nginx/src/http/modules/ngx_http_limit_req_module.c +5 -1
  96. data/vendor/nginx/src/http/modules/ngx_http_map_module.c +3 -3
  97. data/vendor/nginx/src/http/modules/ngx_http_memcached_module.c +21 -10
  98. data/vendor/nginx/src/http/modules/ngx_http_mp4_module.c +669 -197
  99. data/vendor/nginx/src/http/modules/ngx_http_proxy_module.c +93 -60
  100. data/vendor/nginx/src/http/modules/ngx_http_range_filter_module.c +13 -6
  101. data/vendor/nginx/src/http/modules/ngx_http_realip_module.c +20 -1
  102. data/vendor/nginx/src/http/modules/ngx_http_referer_module.c +132 -74
  103. data/vendor/nginx/src/http/modules/ngx_http_scgi_module.c +18 -12
  104. data/vendor/nginx/src/http/modules/ngx_http_ssi_filter_module.c +22 -20
  105. data/vendor/nginx/src/http/modules/ngx_http_ssl_module.c +121 -3
  106. data/vendor/nginx/src/http/modules/ngx_http_ssl_module.h +5 -0
  107. data/vendor/nginx/src/http/modules/ngx_http_stub_status_module.c +3 -0
  108. data/vendor/nginx/src/http/modules/ngx_http_sub_filter_module.c +123 -91
  109. data/vendor/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c +29 -19
  110. data/vendor/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c +2 -5
  111. data/vendor/nginx/src/http/modules/ngx_http_uwsgi_module.c +215 -19
  112. data/vendor/nginx/src/http/modules/ngx_http_xslt_filter_module.c +32 -6
  113. data/vendor/nginx/src/http/modules/perl/nginx.xs +4 -7
  114. data/vendor/nginx/src/http/modules/perl/ngx_http_perl_module.c +2 -2
  115. data/vendor/nginx/src/http/ngx_http.c +17 -7
  116. data/vendor/nginx/src/http/ngx_http_cache.h +4 -2
  117. data/vendor/nginx/src/http/ngx_http_copy_filter_module.c +4 -2
  118. data/vendor/nginx/src/http/ngx_http_core_module.c +63 -50
  119. data/vendor/nginx/src/http/ngx_http_core_module.h +5 -0
  120. data/vendor/nginx/src/http/ngx_http_file_cache.c +115 -3
  121. data/vendor/nginx/src/http/ngx_http_header_filter_module.c +9 -6
  122. data/vendor/nginx/src/http/ngx_http_parse.c +88 -10
  123. data/vendor/nginx/src/http/ngx_http_postpone_filter_module.c +2 -4
  124. data/vendor/nginx/src/http/ngx_http_request.c +116 -8
  125. data/vendor/nginx/src/http/ngx_http_request.h +5 -1
  126. data/vendor/nginx/src/http/ngx_http_request_body.c +7 -7
  127. data/vendor/nginx/src/http/ngx_http_script.c +6 -5
  128. data/vendor/nginx/src/http/ngx_http_spdy.c +889 -271
  129. data/vendor/nginx/src/http/ngx_http_spdy.h +51 -28
  130. data/vendor/nginx/src/http/ngx_http_spdy_filter_module.c +382 -167
  131. data/vendor/nginx/src/http/ngx_http_spdy_module.c +65 -8
  132. data/vendor/nginx/src/http/ngx_http_spdy_module.h +5 -0
  133. data/vendor/nginx/src/http/ngx_http_special_response.c +1 -1
  134. data/vendor/nginx/src/http/ngx_http_upstream.c +290 -114
  135. data/vendor/nginx/src/http/ngx_http_upstream.h +9 -5
  136. data/vendor/nginx/src/http/ngx_http_upstream_round_robin.c +32 -24
  137. data/vendor/nginx/src/http/ngx_http_variables.c +40 -6
  138. data/vendor/nginx/src/http/ngx_http_write_filter_module.c +12 -5
  139. data/vendor/nginx/src/mail/ngx_mail.c +4 -2
  140. data/vendor/nginx/src/mail/ngx_mail.h +2 -0
  141. data/vendor/nginx/src/mail/ngx_mail_auth_http_module.c +0 -1
  142. data/vendor/nginx/src/mail/ngx_mail_core_module.c +2 -1
  143. data/vendor/nginx/src/mail/ngx_mail_handler.c +17 -4
  144. data/vendor/nginx/src/mail/ngx_mail_parse.c +32 -2
  145. data/vendor/nginx/src/mail/ngx_mail_proxy_module.c +54 -7
  146. data/vendor/nginx/src/mail/ngx_mail_smtp_handler.c +50 -78
  147. data/vendor/nginx/src/mail/ngx_mail_ssl_module.c +48 -11
  148. data/vendor/nginx/src/mail/ngx_mail_ssl_module.h +3 -0
  149. data/vendor/nginx/src/os/unix/ngx_channel.c +3 -1
  150. data/vendor/nginx/src/os/unix/ngx_darwin_config.h +1 -0
  151. data/vendor/nginx/src/os/unix/ngx_darwin_init.c +1 -1
  152. data/vendor/nginx/src/os/unix/ngx_darwin_sendfile_chain.c +14 -16
  153. data/vendor/nginx/src/os/unix/ngx_errno.h +3 -0
  154. data/vendor/nginx/src/os/unix/ngx_files.h +10 -16
  155. data/vendor/nginx/src/os/unix/ngx_freebsd_config.h +6 -0
  156. data/vendor/nginx/src/os/unix/ngx_freebsd_init.c +1 -1
  157. data/vendor/nginx/src/os/unix/ngx_freebsd_rfork_thread.c +1 -1
  158. data/vendor/nginx/src/os/unix/ngx_freebsd_rfork_thread.h +2 -2
  159. data/vendor/nginx/src/os/unix/ngx_freebsd_sendfile_chain.c +17 -19
  160. data/vendor/nginx/src/os/unix/ngx_linux_config.h +8 -2
  161. data/vendor/nginx/src/os/unix/ngx_linux_sendfile_chain.c +20 -22
  162. data/vendor/nginx/src/os/unix/ngx_posix_config.h +1 -0
  163. data/vendor/nginx/src/os/unix/ngx_process.c +5 -0
  164. data/vendor/nginx/src/os/unix/ngx_process_cycle.c +15 -3
  165. data/vendor/nginx/src/os/unix/ngx_readv_chain.c +2 -1
  166. data/vendor/nginx/src/os/unix/ngx_recv.c +4 -1
  167. data/vendor/nginx/src/os/unix/ngx_solaris_config.h +1 -0
  168. data/vendor/nginx/src/os/unix/ngx_solaris_sendfilev_chain.c +14 -16
  169. metadata +8 -2
@@ -22,16 +22,19 @@ static ngx_int_t ngx_http_spdy_module_init(ngx_cycle_t *cycle);
22
22
 
23
23
  static void *ngx_http_spdy_create_main_conf(ngx_conf_t *cf);
24
24
  static char *ngx_http_spdy_init_main_conf(ngx_conf_t *cf, void *conf);
25
-
26
25
  static void *ngx_http_spdy_create_srv_conf(ngx_conf_t *cf);
27
26
  static char *ngx_http_spdy_merge_srv_conf(ngx_conf_t *cf, void *parent,
28
27
  void *child);
28
+ static void *ngx_http_spdy_create_loc_conf(ngx_conf_t *cf);
29
+ static char *ngx_http_spdy_merge_loc_conf(ngx_conf_t *cf, void *parent,
30
+ void *child);
29
31
 
30
32
  static char *ngx_http_spdy_recv_buffer_size(ngx_conf_t *cf, void *post,
31
33
  void *data);
32
34
  static char *ngx_http_spdy_pool_size(ngx_conf_t *cf, void *post, void *data);
33
35
  static char *ngx_http_spdy_streams_index_mask(ngx_conf_t *cf, void *post,
34
36
  void *data);
37
+ static char *ngx_http_spdy_chunk_size(ngx_conf_t *cf, void *post, void *data);
35
38
 
36
39
 
37
40
  static ngx_conf_num_bounds_t ngx_http_spdy_headers_comp_bounds = {
@@ -44,6 +47,8 @@ static ngx_conf_post_t ngx_http_spdy_pool_size_post =
44
47
  { ngx_http_spdy_pool_size };
45
48
  static ngx_conf_post_t ngx_http_spdy_streams_index_mask_post =
46
49
  { ngx_http_spdy_streams_index_mask };
50
+ static ngx_conf_post_t ngx_http_spdy_chunk_size_post =
51
+ { ngx_http_spdy_chunk_size };
47
52
 
48
53
 
49
54
  static ngx_command_t ngx_http_spdy_commands[] = {
@@ -97,6 +102,13 @@ static ngx_command_t ngx_http_spdy_commands[] = {
97
102
  offsetof(ngx_http_spdy_srv_conf_t, headers_comp),
98
103
  &ngx_http_spdy_headers_comp_bounds },
99
104
 
105
+ { ngx_string("spdy_chunk_size"),
106
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
107
+ ngx_conf_set_size_slot,
108
+ NGX_HTTP_LOC_CONF_OFFSET,
109
+ offsetof(ngx_http_spdy_loc_conf_t, chunk_size),
110
+ &ngx_http_spdy_chunk_size_post },
111
+
100
112
  ngx_null_command
101
113
  };
102
114
 
@@ -111,8 +123,8 @@ static ngx_http_module_t ngx_http_spdy_module_ctx = {
111
123
  ngx_http_spdy_create_srv_conf, /* create server configuration */
112
124
  ngx_http_spdy_merge_srv_conf, /* merge server configuration */
113
125
 
114
- NULL, /* create location configuration */
115
- NULL /* merge location configuration */
126
+ ngx_http_spdy_create_loc_conf, /* create location configuration */
127
+ ngx_http_spdy_merge_loc_conf /* merge location configuration */
116
128
  };
117
129
 
118
130
 
@@ -168,11 +180,11 @@ ngx_http_spdy_variable(ngx_http_request_t *r,
168
180
  ngx_http_variable_value_t *v, uintptr_t data)
169
181
  {
170
182
  if (r->spdy_stream) {
171
- v->len = 1;
183
+ v->len = sizeof("3.1") - 1;
172
184
  v->valid = 1;
173
185
  v->no_cacheable = 0;
174
186
  v->not_found = 0;
175
- v->data = (u_char *) "2";
187
+ v->data = (u_char *) "3.1";
176
188
 
177
189
  return NGX_OK;
178
190
  }
@@ -239,9 +251,7 @@ ngx_http_spdy_init_main_conf(ngx_conf_t *cf, void *conf)
239
251
  {
240
252
  ngx_http_spdy_main_conf_t *smcf = conf;
241
253
 
242
- if (smcf->recv_buffer_size == NGX_CONF_UNSET_SIZE) {
243
- smcf->recv_buffer_size = 256 * 1024;
244
- }
254
+ ngx_conf_init_size_value(smcf->recv_buffer_size, 256 * 1024);
245
255
 
246
256
  return NGX_CONF_OK;
247
257
  }
@@ -296,6 +306,34 @@ ngx_http_spdy_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
296
306
  }
297
307
 
298
308
 
309
+ static void *
310
+ ngx_http_spdy_create_loc_conf(ngx_conf_t *cf)
311
+ {
312
+ ngx_http_spdy_loc_conf_t *slcf;
313
+
314
+ slcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_spdy_loc_conf_t));
315
+ if (slcf == NULL) {
316
+ return NULL;
317
+ }
318
+
319
+ slcf->chunk_size = NGX_CONF_UNSET_SIZE;
320
+
321
+ return slcf;
322
+ }
323
+
324
+
325
+ static char *
326
+ ngx_http_spdy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
327
+ {
328
+ ngx_http_spdy_loc_conf_t *prev = parent;
329
+ ngx_http_spdy_loc_conf_t *conf = child;
330
+
331
+ ngx_conf_merge_size_value(conf->chunk_size, prev->chunk_size, 8 * 1024);
332
+
333
+ return NGX_CONF_OK;
334
+ }
335
+
336
+
299
337
  static char *
300
338
  ngx_http_spdy_recv_buffer_size(ngx_conf_t *cf, void *post, void *data)
301
339
  {
@@ -349,3 +387,22 @@ ngx_http_spdy_streams_index_mask(ngx_conf_t *cf, void *post, void *data)
349
387
 
350
388
  return NGX_CONF_OK;
351
389
  }
390
+
391
+
392
+ static char *
393
+ ngx_http_spdy_chunk_size(ngx_conf_t *cf, void *post, void *data)
394
+ {
395
+ size_t *sp = data;
396
+
397
+ if (*sp == 0) {
398
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
399
+ "the spdy chunk size cannot be zero");
400
+ return NGX_CONF_ERROR;
401
+ }
402
+
403
+ if (*sp > NGX_SPDY_MAX_FRAME_SIZE) {
404
+ *sp = NGX_SPDY_MAX_FRAME_SIZE;
405
+ }
406
+
407
+ return NGX_CONF_OK;
408
+ }
@@ -30,6 +30,11 @@ typedef struct {
30
30
  } ngx_http_spdy_srv_conf_t;
31
31
 
32
32
 
33
+ typedef struct {
34
+ size_t chunk_size;
35
+ } ngx_http_spdy_loc_conf_t;
36
+
37
+
33
38
  extern ngx_module_t ngx_http_spdy_module;
34
39
 
35
40
 
@@ -370,7 +370,7 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
370
370
  ngx_http_core_loc_conf_t *clcf;
371
371
 
372
372
  ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
373
- "http special response: %d, \"%V?%V\"",
373
+ "http special response: %i, \"%V?%V\"",
374
374
  error, &r->uri, &r->args);
375
375
 
376
376
  r->err_status = error;
@@ -17,6 +17,8 @@ static ngx_int_t ngx_http_upstream_cache_send(ngx_http_request_t *r,
17
17
  ngx_http_upstream_t *u);
18
18
  static ngx_int_t ngx_http_upstream_cache_status(ngx_http_request_t *r,
19
19
  ngx_http_variable_value_t *v, uintptr_t data);
20
+ static ngx_int_t ngx_http_upstream_cache_last_modified(ngx_http_request_t *r,
21
+ ngx_http_variable_value_t *v, uintptr_t data);
20
22
  #endif
21
23
 
22
24
  static void ngx_http_upstream_init_request(ngx_http_request_t *r);
@@ -358,6 +360,10 @@ static ngx_http_variable_t ngx_http_upstream_vars[] = {
358
360
  ngx_http_upstream_cache_status, 0,
359
361
  NGX_HTTP_VAR_NOCACHEABLE, 0 },
360
362
 
363
+ { ngx_string("upstream_cache_last_modified"), NULL,
364
+ ngx_http_upstream_cache_last_modified, 0,
365
+ NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
366
+
361
367
  #endif
362
368
 
363
369
  { ngx_null_string, NULL, NULL, 0, 0, 0 }
@@ -369,6 +375,7 @@ static ngx_http_upstream_next_t ngx_http_upstream_next_errors[] = {
369
375
  { 502, NGX_HTTP_UPSTREAM_FT_HTTP_502 },
370
376
  { 503, NGX_HTTP_UPSTREAM_FT_HTTP_503 },
371
377
  { 504, NGX_HTTP_UPSTREAM_FT_HTTP_504 },
378
+ { 403, NGX_HTTP_UPSTREAM_FT_HTTP_403 },
372
379
  { 404, NGX_HTTP_UPSTREAM_FT_HTTP_404 },
373
380
  { 0, 0 }
374
381
  };
@@ -605,7 +612,7 @@ ngx_http_upstream_init_request(ngx_http_request_t *r)
605
612
  if (uscf->host.len == host->len
606
613
  && ((uscf->port == 0 && u->resolved->no_port)
607
614
  || uscf->port == u->resolved->port)
608
- && ngx_memcmp(uscf->host.data, host->data, host->len) == 0)
615
+ && ngx_strncasecmp(uscf->host.data, host->data, host->len) == 0)
609
616
  {
610
617
  goto found;
611
618
  }
@@ -637,7 +644,6 @@ ngx_http_upstream_init_request(ngx_http_request_t *r)
637
644
  }
638
645
 
639
646
  ctx->name = *host;
640
- ctx->type = NGX_RESOLVE_A;
641
647
  ctx->handler = ngx_http_upstream_resolve_handler;
642
648
  ctx->data = r;
643
649
  ctx->timeout = clcf->resolver_timeout;
@@ -709,7 +715,7 @@ ngx_http_upstream_cache(ngx_http_request_t *r, ngx_http_upstream_t *u)
709
715
  if (r->cache->header_start + 256 >= u->conf->buffer_size) {
710
716
  ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
711
717
  "%V_buffer_size %uz is not enough for cache key, "
712
- "it should increased at least to %uz",
718
+ "it should be increased to at least %uz",
713
719
  &u->conf->module, u->conf->buffer_size,
714
720
  ngx_align(r->cache->header_start + 256, 1024));
715
721
 
@@ -911,16 +917,18 @@ ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx)
911
917
 
912
918
  #if (NGX_DEBUG)
913
919
  {
914
- in_addr_t addr;
920
+ u_char text[NGX_SOCKADDR_STRLEN];
921
+ ngx_str_t addr;
915
922
  ngx_uint_t i;
916
923
 
924
+ addr.data = text;
925
+
917
926
  for (i = 0; i < ctx->naddrs; i++) {
918
- addr = ntohl(ur->addrs[i]);
927
+ addr.len = ngx_sock_ntop(ur->addrs[i].sockaddr, ur->addrs[i].socklen,
928
+ text, NGX_SOCKADDR_STRLEN, 0);
919
929
 
920
- ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
921
- "name was resolved to %ud.%ud.%ud.%ud",
922
- (addr >> 24) & 0xff, (addr >> 16) & 0xff,
923
- (addr >> 8) & 0xff, addr & 0xff);
930
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
931
+ "name was resolved to %V", &addr);
924
932
  }
925
933
  }
926
934
  #endif
@@ -1067,6 +1075,55 @@ ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
1067
1075
  return;
1068
1076
  }
1069
1077
 
1078
+ #endif
1079
+
1080
+ #if (NGX_HAVE_EPOLLRDHUP)
1081
+
1082
+ if ((ngx_event_flags & NGX_USE_EPOLL_EVENT) && ev->pending_eof) {
1083
+ socklen_t len;
1084
+
1085
+ ev->eof = 1;
1086
+ c->error = 1;
1087
+
1088
+ err = 0;
1089
+ len = sizeof(ngx_err_t);
1090
+
1091
+ /*
1092
+ * BSDs and Linux return 0 and set a pending error in err
1093
+ * Solaris returns -1 and sets errno
1094
+ */
1095
+
1096
+ if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len)
1097
+ == -1)
1098
+ {
1099
+ err = ngx_socket_errno;
1100
+ }
1101
+
1102
+ if (err) {
1103
+ ev->error = 1;
1104
+ }
1105
+
1106
+ if (!u->cacheable && u->peer.connection) {
1107
+ ngx_log_error(NGX_LOG_INFO, ev->log, err,
1108
+ "epoll_wait() reported that client prematurely closed "
1109
+ "connection, so upstream connection is closed too");
1110
+ ngx_http_upstream_finalize_request(r, u,
1111
+ NGX_HTTP_CLIENT_CLOSED_REQUEST);
1112
+ return;
1113
+ }
1114
+
1115
+ ngx_log_error(NGX_LOG_INFO, ev->log, err,
1116
+ "epoll_wait() reported that client prematurely closed "
1117
+ "connection");
1118
+
1119
+ if (u->peer.connection == NULL) {
1120
+ ngx_http_upstream_finalize_request(r, u,
1121
+ NGX_HTTP_CLIENT_CLOSED_REQUEST);
1122
+ }
1123
+
1124
+ return;
1125
+ }
1126
+
1070
1127
  #endif
1071
1128
 
1072
1129
  n = recv(c->fd, buf, 1, MSG_PEEK);
@@ -1180,7 +1237,7 @@ ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u)
1180
1237
  return;
1181
1238
  }
1182
1239
 
1183
- /* rc == NGX_OK || rc == NGX_AGAIN */
1240
+ /* rc == NGX_OK || rc == NGX_AGAIN || rc == NGX_DONE */
1184
1241
 
1185
1242
  c = u->peer.connection;
1186
1243
 
@@ -1281,6 +1338,11 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
1281
1338
  {
1282
1339
  ngx_int_t rc;
1283
1340
 
1341
+ if (ngx_http_upstream_test_connect(c) != NGX_OK) {
1342
+ ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
1343
+ return;
1344
+ }
1345
+
1284
1346
  if (ngx_ssl_create_connection(u->conf->ssl, c,
1285
1347
  NGX_SSL_BUFFER|NGX_SSL_CLIENT)
1286
1348
  != NGX_OK)
@@ -1332,13 +1394,19 @@ ngx_http_upstream_ssl_handshake(ngx_connection_t *c)
1332
1394
  c->write->handler = ngx_http_upstream_handler;
1333
1395
  c->read->handler = ngx_http_upstream_handler;
1334
1396
 
1397
+ c = r->connection;
1398
+
1335
1399
  ngx_http_upstream_send_request(r, u);
1336
1400
 
1401
+ ngx_http_run_posted_requests(c);
1337
1402
  return;
1338
1403
  }
1339
1404
 
1405
+ c = r->connection;
1406
+
1340
1407
  ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
1341
1408
 
1409
+ ngx_http_run_posted_requests(c);
1342
1410
  }
1343
1411
 
1344
1412
  #endif
@@ -1471,22 +1539,10 @@ ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u)
1471
1539
 
1472
1540
  ngx_add_timer(c->read, u->conf->read_timeout);
1473
1541
 
1474
- #if 1
1475
1542
  if (c->read->ready) {
1476
-
1477
- /* post aio operation */
1478
-
1479
- /*
1480
- * TODO comment
1481
- * although we can post aio operation just in the end
1482
- * of ngx_http_upstream_connect() CHECK IT !!!
1483
- * it's better to do here because we postpone header buffer allocation
1484
- */
1485
-
1486
1543
  ngx_http_upstream_process_header(r, u);
1487
1544
  return;
1488
1545
  }
1489
- #endif
1490
1546
 
1491
1547
  u->write_event_handler = ngx_http_upstream_dummy_handler;
1492
1548
 
@@ -1660,11 +1716,7 @@ ngx_http_upstream_process_header(ngx_http_request_t *r, ngx_http_upstream_t *u)
1660
1716
 
1661
1717
  /* rc == NGX_OK */
1662
1718
 
1663
- if (u->headers_in.status_n > NGX_HTTP_SPECIAL_RESPONSE) {
1664
-
1665
- if (r->subrequest_in_memory) {
1666
- u->buffer.last = u->buffer.pos;
1667
- }
1719
+ if (u->headers_in.status_n >= NGX_HTTP_SPECIAL_RESPONSE) {
1668
1720
 
1669
1721
  if (ngx_http_upstream_test_next(r, u) == NGX_OK) {
1670
1722
  return;
@@ -1693,15 +1745,14 @@ ngx_http_upstream_process_header(ngx_http_request_t *r, ngx_http_upstream_t *u)
1693
1745
  }
1694
1746
 
1695
1747
  if (u->input_filter_init(u->input_filter_ctx) == NGX_ERROR) {
1696
- ngx_http_upstream_finalize_request(r, u,
1697
- NGX_HTTP_INTERNAL_SERVER_ERROR);
1748
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
1698
1749
  return;
1699
1750
  }
1700
1751
 
1701
1752
  n = u->buffer.last - u->buffer.pos;
1702
1753
 
1703
1754
  if (n) {
1704
- u->buffer.last -= n;
1755
+ u->buffer.last = u->buffer.pos;
1705
1756
 
1706
1757
  u->state->response_length += n;
1707
1758
 
@@ -1709,11 +1760,11 @@ ngx_http_upstream_process_header(ngx_http_request_t *r, ngx_http_upstream_t *u)
1709
1760
  ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
1710
1761
  return;
1711
1762
  }
1763
+ }
1712
1764
 
1713
- if (u->length == 0) {
1714
- ngx_http_upstream_finalize_request(r, u, 0);
1715
- return;
1716
- }
1765
+ if (u->length == 0) {
1766
+ ngx_http_upstream_finalize_request(r, u, 0);
1767
+ return;
1717
1768
  }
1718
1769
 
1719
1770
  u->read_event_handler = ngx_http_upstream_process_body_in_memory;
@@ -1762,6 +1813,56 @@ ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u)
1762
1813
  #endif
1763
1814
  }
1764
1815
 
1816
+ #if (NGX_HTTP_CACHE)
1817
+
1818
+ if (status == NGX_HTTP_NOT_MODIFIED
1819
+ && u->cache_status == NGX_HTTP_CACHE_EXPIRED
1820
+ && u->conf->cache_revalidate)
1821
+ {
1822
+ time_t now, valid;
1823
+ ngx_int_t rc;
1824
+
1825
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1826
+ "http upstream not modified");
1827
+
1828
+ now = ngx_time();
1829
+ valid = r->cache->valid_sec;
1830
+
1831
+ rc = u->reinit_request(r);
1832
+
1833
+ if (rc != NGX_OK) {
1834
+ ngx_http_upstream_finalize_request(r, u, rc);
1835
+ return NGX_OK;
1836
+ }
1837
+
1838
+ u->cache_status = NGX_HTTP_CACHE_REVALIDATED;
1839
+ rc = ngx_http_upstream_cache_send(r, u);
1840
+
1841
+ if (valid == 0) {
1842
+ valid = r->cache->valid_sec;
1843
+ }
1844
+
1845
+ if (valid == 0) {
1846
+ valid = ngx_http_file_cache_valid(u->conf->cache_valid,
1847
+ u->headers_in.status_n);
1848
+ if (valid) {
1849
+ valid = now + valid;
1850
+ }
1851
+ }
1852
+
1853
+ if (valid) {
1854
+ r->cache->valid_sec = valid;
1855
+ r->cache->date = now;
1856
+
1857
+ ngx_http_file_cache_update_header(r);
1858
+ }
1859
+
1860
+ ngx_http_upstream_finalize_request(r, u, rc);
1861
+ return NGX_OK;
1862
+ }
1863
+
1864
+ #endif
1865
+
1765
1866
  return NGX_DECLINED;
1766
1867
  }
1767
1868
 
@@ -1876,7 +1977,7 @@ ngx_http_upstream_test_connect(ngx_connection_t *c)
1876
1977
  if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len)
1877
1978
  == -1)
1878
1979
  {
1879
- err = ngx_errno;
1980
+ err = ngx_socket_errno;
1880
1981
  }
1881
1982
 
1882
1983
  if (err) {
@@ -1893,7 +1994,7 @@ ngx_http_upstream_test_connect(ngx_connection_t *c)
1893
1994
  static ngx_int_t
1894
1995
  ngx_http_upstream_process_headers(ngx_http_request_t *r, ngx_http_upstream_t *u)
1895
1996
  {
1896
- ngx_str_t *uri, args;
1997
+ ngx_str_t uri, args;
1897
1998
  ngx_uint_t i, flags;
1898
1999
  ngx_list_part_t *part;
1899
2000
  ngx_table_elt_t *h;
@@ -1934,11 +2035,11 @@ ngx_http_upstream_process_headers(ngx_http_request_t *r, ngx_http_upstream_t *u)
1934
2035
  }
1935
2036
  }
1936
2037
 
1937
- uri = &u->headers_in.x_accel_redirect->value;
2038
+ uri = u->headers_in.x_accel_redirect->value;
1938
2039
  ngx_str_null(&args);
1939
2040
  flags = NGX_HTTP_LOG_UNSAFE;
1940
2041
 
1941
- if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) {
2042
+ if (ngx_http_parse_unsafe_uri(r, &uri, &args, &flags) != NGX_OK) {
1942
2043
  ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
1943
2044
  return NGX_DONE;
1944
2045
  }
@@ -1947,7 +2048,7 @@ ngx_http_upstream_process_headers(ngx_http_request_t *r, ngx_http_upstream_t *u)
1947
2048
  r->method = NGX_HTTP_GET;
1948
2049
  }
1949
2050
 
1950
- ngx_http_internal_redirect(r, uri, &args);
2051
+ ngx_http_internal_redirect(r, &uri, &args);
1951
2052
  ngx_http_finalize_request(r, NGX_DONE);
1952
2053
  return NGX_DONE;
1953
2054
  }
@@ -2006,7 +2107,7 @@ ngx_http_upstream_process_headers(ngx_http_request_t *r, ngx_http_upstream_t *u)
2006
2107
 
2007
2108
  r->headers_out.content_length_n = u->headers_in.content_length_n;
2008
2109
 
2009
- u->length = u->headers_in.content_length_n;
2110
+ u->length = -1;
2010
2111
 
2011
2112
  return NGX_OK;
2012
2113
  }
@@ -2030,7 +2131,7 @@ ngx_http_upstream_process_body_in_memory(ngx_http_request_t *r,
2030
2131
 
2031
2132
  if (rev->timedout) {
2032
2133
  ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
2033
- ngx_http_upstream_finalize_request(r, u, NGX_ETIMEDOUT);
2134
+ ngx_http_upstream_finalize_request(r, u, NGX_HTTP_GATEWAY_TIME_OUT);
2034
2135
  return;
2035
2136
  }
2036
2137
 
@@ -2106,6 +2207,8 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
2106
2207
  return;
2107
2208
  }
2108
2209
 
2210
+ u->header_sent = 1;
2211
+
2109
2212
  if (u->upgrade) {
2110
2213
  ngx_http_upstream_upgrade(r, u);
2111
2214
  return;
@@ -2132,8 +2235,6 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
2132
2235
  }
2133
2236
  }
2134
2237
 
2135
- u->header_sent = 1;
2136
-
2137
2238
  if (r->request_body && r->request_body->temp_file) {
2138
2239
  ngx_pool_run_cleanup_file(r->pool, r->request_body->temp_file->file.fd);
2139
2240
  r->request_body->temp_file->file.fd = NGX_INVALID_FILE;
@@ -2156,7 +2257,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
2156
2257
  r->limit_rate = 0;
2157
2258
 
2158
2259
  if (u->input_filter_init(u->input_filter_ctx) == NGX_ERROR) {
2159
- ngx_http_upstream_finalize_request(r, u, 0);
2260
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2160
2261
  return;
2161
2262
  }
2162
2263
 
@@ -2170,7 +2271,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
2170
2271
  {
2171
2272
  ngx_connection_error(c, ngx_socket_errno,
2172
2273
  "setsockopt(TCP_NODELAY) failed");
2173
- ngx_http_upstream_finalize_request(r, u, 0);
2274
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2174
2275
  return;
2175
2276
  }
2176
2277
 
@@ -2185,7 +2286,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
2185
2286
  u->state->response_length += n;
2186
2287
 
2187
2288
  if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) {
2188
- ngx_http_upstream_finalize_request(r, u, 0);
2289
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2189
2290
  return;
2190
2291
  }
2191
2292
 
@@ -2196,7 +2297,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
2196
2297
  u->buffer.last = u->buffer.start;
2197
2298
 
2198
2299
  if (ngx_http_send_special(r, NGX_HTTP_FLUSH) == NGX_ERROR) {
2199
- ngx_http_upstream_finalize_request(r, u, 0);
2300
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2200
2301
  return;
2201
2302
  }
2202
2303
 
@@ -2220,7 +2321,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
2220
2321
  switch (ngx_http_test_predicates(r, u->conf->no_cache)) {
2221
2322
 
2222
2323
  case NGX_ERROR:
2223
- ngx_http_upstream_finalize_request(r, u, 0);
2324
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2224
2325
  return;
2225
2326
 
2226
2327
  case NGX_DECLINED:
@@ -2236,7 +2337,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
2236
2337
  r->cache->file_cache = u->conf->cache->data;
2237
2338
 
2238
2339
  if (ngx_http_file_cache_create(r) != NGX_OK) {
2239
- ngx_http_upstream_finalize_request(r, u, 0);
2340
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2240
2341
  return;
2241
2342
  }
2242
2343
  }
@@ -2297,7 +2398,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
2297
2398
 
2298
2399
  p->temp_file = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t));
2299
2400
  if (p->temp_file == NULL) {
2300
- ngx_http_upstream_finalize_request(r, u, 0);
2401
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2301
2402
  return;
2302
2403
  }
2303
2404
 
@@ -2320,7 +2421,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
2320
2421
 
2321
2422
  p->preread_bufs = ngx_alloc_chain_link(r->pool);
2322
2423
  if (p->preread_bufs == NULL) {
2323
- ngx_http_upstream_finalize_request(r, u, 0);
2424
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2324
2425
  return;
2325
2426
  }
2326
2427
 
@@ -2334,7 +2435,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
2334
2435
 
2335
2436
  p->buf_to_file = ngx_calloc_buf(r->pool);
2336
2437
  if (p->buf_to_file == NULL) {
2337
- ngx_http_upstream_finalize_request(r, u, 0);
2438
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2338
2439
  return;
2339
2440
  }
2340
2441
 
@@ -2382,7 +2483,7 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
2382
2483
  if (u->input_filter_init
2383
2484
  && u->input_filter_init(p->input_ctx) != NGX_OK)
2384
2485
  {
2385
- ngx_http_upstream_finalize_request(r, u, 0);
2486
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2386
2487
  return;
2387
2488
  }
2388
2489
 
@@ -2424,7 +2525,7 @@ ngx_http_upstream_upgrade(ngx_http_request_t *r, ngx_http_upstream_t *u)
2424
2525
  {
2425
2526
  ngx_connection_error(c, ngx_socket_errno,
2426
2527
  "setsockopt(TCP_NODELAY) failed");
2427
- ngx_http_upstream_finalize_request(r, u, 0);
2528
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2428
2529
  return;
2429
2530
  }
2430
2531
 
@@ -2440,7 +2541,7 @@ ngx_http_upstream_upgrade(ngx_http_request_t *r, ngx_http_upstream_t *u)
2440
2541
  {
2441
2542
  ngx_connection_error(u->peer.connection, ngx_socket_errno,
2442
2543
  "setsockopt(TCP_NODELAY) failed");
2443
- ngx_http_upstream_finalize_request(r, u, 0);
2544
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2444
2545
  return;
2445
2546
  }
2446
2547
 
@@ -2449,7 +2550,7 @@ ngx_http_upstream_upgrade(ngx_http_request_t *r, ngx_http_upstream_t *u)
2449
2550
  }
2450
2551
 
2451
2552
  if (ngx_http_send_special(r, NGX_HTTP_FLUSH) == NGX_ERROR) {
2452
- ngx_http_upstream_finalize_request(r, u, 0);
2553
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2453
2554
  return;
2454
2555
  }
2455
2556
 
@@ -2524,7 +2625,7 @@ ngx_http_upstream_process_upgraded(ngx_http_request_t *r,
2524
2625
 
2525
2626
  if (upstream->read->timedout || upstream->write->timedout) {
2526
2627
  ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
2527
- ngx_http_upstream_finalize_request(r, u, 0);
2628
+ ngx_http_upstream_finalize_request(r, u, NGX_HTTP_GATEWAY_TIME_OUT);
2528
2629
  return;
2529
2630
  }
2530
2631
 
@@ -2547,7 +2648,7 @@ ngx_http_upstream_process_upgraded(ngx_http_request_t *r,
2547
2648
  if (b->start == NULL) {
2548
2649
  b->start = ngx_palloc(r->pool, u->conf->buffer_size);
2549
2650
  if (b->start == NULL) {
2550
- ngx_http_upstream_finalize_request(r, u, 0);
2651
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2551
2652
  return;
2552
2653
  }
2553
2654
 
@@ -2570,7 +2671,7 @@ ngx_http_upstream_process_upgraded(ngx_http_request_t *r,
2570
2671
  n = dst->send(dst, b->pos, size);
2571
2672
 
2572
2673
  if (n == NGX_ERROR) {
2573
- ngx_http_upstream_finalize_request(r, u, 0);
2674
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2574
2675
  return;
2575
2676
  }
2576
2677
 
@@ -2625,7 +2726,7 @@ ngx_http_upstream_process_upgraded(ngx_http_request_t *r,
2625
2726
  if (ngx_handle_write_event(upstream->write, u->conf->send_lowat)
2626
2727
  != NGX_OK)
2627
2728
  {
2628
- ngx_http_upstream_finalize_request(r, u, 0);
2729
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2629
2730
  return;
2630
2731
  }
2631
2732
 
@@ -2637,7 +2738,7 @@ ngx_http_upstream_process_upgraded(ngx_http_request_t *r,
2637
2738
  }
2638
2739
 
2639
2740
  if (ngx_handle_read_event(upstream->read, 0) != NGX_OK) {
2640
- ngx_http_upstream_finalize_request(r, u, 0);
2741
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2641
2742
  return;
2642
2743
  }
2643
2744
 
@@ -2651,12 +2752,12 @@ ngx_http_upstream_process_upgraded(ngx_http_request_t *r,
2651
2752
  if (ngx_handle_write_event(downstream->write, clcf->send_lowat)
2652
2753
  != NGX_OK)
2653
2754
  {
2654
- ngx_http_upstream_finalize_request(r, u, 0);
2755
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2655
2756
  return;
2656
2757
  }
2657
2758
 
2658
2759
  if (ngx_handle_read_event(downstream->read, 0) != NGX_OK) {
2659
- ngx_http_upstream_finalize_request(r, u, 0);
2760
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2660
2761
  return;
2661
2762
  }
2662
2763
 
@@ -2711,7 +2812,7 @@ ngx_http_upstream_process_non_buffered_upstream(ngx_http_request_t *r,
2711
2812
 
2712
2813
  if (c->read->timedout) {
2713
2814
  ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
2714
- ngx_http_upstream_finalize_request(r, u, 0);
2815
+ ngx_http_upstream_finalize_request(r, u, NGX_HTTP_GATEWAY_TIME_OUT);
2715
2816
  return;
2716
2817
  }
2717
2818
 
@@ -2747,7 +2848,7 @@ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
2747
2848
  rc = ngx_http_output_filter(r, u->out_bufs);
2748
2849
 
2749
2850
  if (rc == NGX_ERROR) {
2750
- ngx_http_upstream_finalize_request(r, u, 0);
2851
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2751
2852
  return;
2752
2853
  }
2753
2854
 
@@ -2758,13 +2859,27 @@ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
2758
2859
  if (u->busy_bufs == NULL) {
2759
2860
 
2760
2861
  if (u->length == 0
2761
- || upstream->read->eof
2762
- || upstream->read->error)
2862
+ || (upstream->read->eof && u->length == -1))
2763
2863
  {
2764
2864
  ngx_http_upstream_finalize_request(r, u, 0);
2765
2865
  return;
2766
2866
  }
2767
2867
 
2868
+ if (upstream->read->eof) {
2869
+ ngx_log_error(NGX_LOG_ERR, upstream->log, 0,
2870
+ "upstream prematurely closed connection");
2871
+
2872
+ ngx_http_upstream_finalize_request(r, u,
2873
+ NGX_HTTP_BAD_GATEWAY);
2874
+ return;
2875
+ }
2876
+
2877
+ if (upstream->read->error) {
2878
+ ngx_http_upstream_finalize_request(r, u,
2879
+ NGX_HTTP_BAD_GATEWAY);
2880
+ return;
2881
+ }
2882
+
2768
2883
  b->pos = b->start;
2769
2884
  b->last = b->start;
2770
2885
  }
@@ -2784,7 +2899,7 @@ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
2784
2899
  u->state->response_length += n;
2785
2900
 
2786
2901
  if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) {
2787
- ngx_http_upstream_finalize_request(r, u, 0);
2902
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2788
2903
  return;
2789
2904
  }
2790
2905
  }
@@ -2803,7 +2918,7 @@ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
2803
2918
  if (ngx_handle_write_event(downstream->write, clcf->send_lowat)
2804
2919
  != NGX_OK)
2805
2920
  {
2806
- ngx_http_upstream_finalize_request(r, u, 0);
2921
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2807
2922
  return;
2808
2923
  }
2809
2924
  }
@@ -2816,7 +2931,7 @@ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
2816
2931
  }
2817
2932
 
2818
2933
  if (ngx_handle_read_event(upstream->read, 0) != NGX_OK) {
2819
- ngx_http_upstream_finalize_request(r, u, 0);
2934
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2820
2935
  return;
2821
2936
  }
2822
2937
 
@@ -2907,14 +3022,14 @@ ngx_http_upstream_process_downstream(ngx_http_request_t *r)
2907
3022
  ngx_add_timer(wev, p->send_timeout);
2908
3023
 
2909
3024
  if (ngx_handle_write_event(wev, p->send_lowat) != NGX_OK) {
2910
- ngx_http_upstream_finalize_request(r, u, 0);
3025
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2911
3026
  }
2912
3027
 
2913
3028
  return;
2914
3029
  }
2915
3030
 
2916
3031
  if (ngx_event_pipe(p, wev->write) == NGX_ABORT) {
2917
- ngx_http_upstream_finalize_request(r, u, 0);
3032
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2918
3033
  return;
2919
3034
  }
2920
3035
 
@@ -2932,14 +3047,14 @@ ngx_http_upstream_process_downstream(ngx_http_request_t *r)
2932
3047
  "http downstream delayed");
2933
3048
 
2934
3049
  if (ngx_handle_write_event(wev, p->send_lowat) != NGX_OK) {
2935
- ngx_http_upstream_finalize_request(r, u, 0);
3050
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2936
3051
  }
2937
3052
 
2938
3053
  return;
2939
3054
  }
2940
3055
 
2941
3056
  if (ngx_event_pipe(p, 1) == NGX_ABORT) {
2942
- ngx_http_upstream_finalize_request(r, u, 0);
3057
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2943
3058
  return;
2944
3059
  }
2945
3060
  }
@@ -2967,7 +3082,7 @@ ngx_http_upstream_process_upstream(ngx_http_request_t *r,
2967
3082
 
2968
3083
  } else {
2969
3084
  if (ngx_event_pipe(u->pipe, 0) == NGX_ABORT) {
2970
- ngx_http_upstream_finalize_request(r, u, 0);
3085
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
2971
3086
  return;
2972
3087
  }
2973
3088
  }
@@ -2992,11 +3107,12 @@ ngx_http_upstream_process_request(ngx_http_request_t *r)
2992
3107
 
2993
3108
  if (p->upstream_eof || p->upstream_done) {
2994
3109
 
2995
- tf = u->pipe->temp_file;
3110
+ tf = p->temp_file;
2996
3111
 
2997
3112
  if (u->headers_in.status_n == NGX_HTTP_OK
3113
+ && (p->upstream_done || p->length == -1)
2998
3114
  && (u->headers_in.content_length_n == -1
2999
- || (u->headers_in.content_length_n == tf->offset)))
3115
+ || u->headers_in.content_length_n == tf->offset))
3000
3116
  {
3001
3117
  ngx_http_upstream_store(r, u);
3002
3118
  u->store = 0;
@@ -3009,15 +3125,16 @@ ngx_http_upstream_process_request(ngx_http_request_t *r)
3009
3125
  if (u->cacheable) {
3010
3126
 
3011
3127
  if (p->upstream_done) {
3012
- ngx_http_file_cache_update(r, u->pipe->temp_file);
3128
+ ngx_http_file_cache_update(r, p->temp_file);
3013
3129
 
3014
3130
  } else if (p->upstream_eof) {
3015
3131
 
3016
- tf = u->pipe->temp_file;
3132
+ tf = p->temp_file;
3017
3133
 
3018
- if (u->headers_in.content_length_n == -1
3019
- || u->headers_in.content_length_n
3020
- == tf->offset - (off_t) r->cache->body_start)
3134
+ if (p->length == -1
3135
+ && (u->headers_in.content_length_n == -1
3136
+ || u->headers_in.content_length_n
3137
+ == tf->offset - (off_t) r->cache->body_start))
3021
3138
  {
3022
3139
  ngx_http_file_cache_update(r, tf);
3023
3140
 
@@ -3026,7 +3143,7 @@ ngx_http_upstream_process_request(ngx_http_request_t *r)
3026
3143
  }
3027
3144
 
3028
3145
  } else if (p->upstream_error) {
3029
- ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
3146
+ ngx_http_file_cache_free(r->cache, p->temp_file);
3030
3147
  }
3031
3148
  }
3032
3149
 
@@ -3035,10 +3152,20 @@ ngx_http_upstream_process_request(ngx_http_request_t *r)
3035
3152
  if (p->upstream_done || p->upstream_eof || p->upstream_error) {
3036
3153
  ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
3037
3154
  "http upstream exit: %p", p->out);
3038
- #if 0
3039
- ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock);
3040
- #endif
3041
- ngx_http_upstream_finalize_request(r, u, 0);
3155
+
3156
+ if (p->upstream_done
3157
+ || (p->upstream_eof && p->length == -1))
3158
+ {
3159
+ ngx_http_upstream_finalize_request(r, u, 0);
3160
+ return;
3161
+ }
3162
+
3163
+ if (p->upstream_eof) {
3164
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
3165
+ "upstream prematurely closed connection");
3166
+ }
3167
+
3168
+ ngx_http_upstream_finalize_request(r, u, NGX_HTTP_BAD_GATEWAY);
3042
3169
  return;
3043
3170
  }
3044
3171
  }
@@ -3048,7 +3175,7 @@ ngx_http_upstream_process_request(ngx_http_request_t *r)
3048
3175
  "http upstream downstream error");
3049
3176
 
3050
3177
  if (!u->cacheable && !u->store && u->peer.connection) {
3051
- ngx_http_upstream_finalize_request(r, u, 0);
3178
+ ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
3052
3179
  }
3053
3180
  }
3054
3181
  }
@@ -3148,14 +3275,13 @@ ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u,
3148
3275
  ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
3149
3276
  "http next upstream, %xi", ft_type);
3150
3277
 
3151
- #if 0
3152
- ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock);
3153
- #endif
3154
-
3155
3278
  if (u->peer.sockaddr) {
3156
3279
 
3157
- if (ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_404) {
3280
+ if (ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_403
3281
+ || ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_404)
3282
+ {
3158
3283
  state = NGX_PEER_NEXT;
3284
+
3159
3285
  } else {
3160
3286
  state = NGX_PEER_FAILED;
3161
3287
  }
@@ -3187,6 +3313,10 @@ ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u,
3187
3313
  status = NGX_HTTP_INTERNAL_SERVER_ERROR;
3188
3314
  break;
3189
3315
 
3316
+ case NGX_HTTP_UPSTREAM_FT_HTTP_403:
3317
+ status = NGX_HTTP_FORBIDDEN;
3318
+ break;
3319
+
3190
3320
  case NGX_HTTP_UPSTREAM_FT_HTTP_404:
3191
3321
  status = NGX_HTTP_NOT_FOUND;
3192
3322
  break;
@@ -3258,13 +3388,6 @@ ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u,
3258
3388
  u->peer.connection = NULL;
3259
3389
  }
3260
3390
 
3261
- #if 0
3262
- if (u->conf->busy_lock && !u->busy_locked) {
3263
- ngx_http_upstream_busy_lock(p);
3264
- return;
3265
- }
3266
- #endif
3267
-
3268
3391
  ngx_http_upstream_connect(r, u);
3269
3392
  }
3270
3393
 
@@ -3285,6 +3408,7 @@ static void
3285
3408
  ngx_http_upstream_finalize_request(ngx_http_request_t *r,
3286
3409
  ngx_http_upstream_t *u, ngx_int_t rc)
3287
3410
  {
3411
+ ngx_uint_t flush;
3288
3412
  ngx_time_t *tp;
3289
3413
 
3290
3414
  ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -3391,11 +3515,10 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r,
3391
3515
 
3392
3516
  #endif
3393
3517
 
3394
- if (u->header_sent
3395
- && rc != NGX_HTTP_REQUEST_TIME_OUT
3396
- && (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE))
3518
+ if (r->subrequest_in_memory
3519
+ && u->headers_in.status_n >= NGX_HTTP_SPECIAL_RESPONSE)
3397
3520
  {
3398
- rc = 0;
3521
+ u->buffer.last = u->buffer.pos;
3399
3522
  }
3400
3523
 
3401
3524
  if (rc == NGX_DECLINED) {
@@ -3404,14 +3527,32 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r,
3404
3527
 
3405
3528
  r->connection->log->action = "sending to client";
3406
3529
 
3407
- if (rc == 0
3408
- && !r->header_only
3409
- #if (NGX_HTTP_CACHE)
3410
- && !r->cached
3411
- #endif
3412
- )
3530
+ if (!u->header_sent
3531
+ || rc == NGX_HTTP_REQUEST_TIME_OUT
3532
+ || rc == NGX_HTTP_CLIENT_CLOSED_REQUEST)
3413
3533
  {
3534
+ ngx_http_finalize_request(r, rc);
3535
+ return;
3536
+ }
3537
+
3538
+ flush = 0;
3539
+
3540
+ if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
3541
+ rc = NGX_ERROR;
3542
+ flush = 1;
3543
+ }
3544
+
3545
+ if (r->header_only) {
3546
+ ngx_http_finalize_request(r, rc);
3547
+ return;
3548
+ }
3549
+
3550
+ if (rc == 0) {
3414
3551
  rc = ngx_http_send_special(r, NGX_HTTP_LAST);
3552
+
3553
+ } else if (flush) {
3554
+ r->keepalive = 0;
3555
+ rc = ngx_http_send_special(r, NGX_HTTP_FLUSH);
3415
3556
  }
3416
3557
 
3417
3558
  ngx_http_finalize_request(r, rc);
@@ -3513,7 +3654,7 @@ ngx_http_upstream_process_cache_control(ngx_http_request_t *r,
3513
3654
  return NGX_OK;
3514
3655
  }
3515
3656
 
3516
- if (r->cache->valid_sec != 0) {
3657
+ if (r->cache->valid_sec != 0 && u->headers_in.x_accel_expires != NULL) {
3517
3658
  return NGX_OK;
3518
3659
  }
3519
3660
 
@@ -4042,7 +4183,12 @@ ngx_http_upstream_copy_allow_ranges(ngx_http_request_t *r,
4042
4183
  if (r->cached) {
4043
4184
  r->allow_ranges = 1;
4044
4185
  return NGX_OK;
4186
+ }
4045
4187
 
4188
+ if (r->upstream->cacheable) {
4189
+ r->allow_ranges = 1;
4190
+ r->single_range = 1;
4191
+ return NGX_OK;
4046
4192
  }
4047
4193
 
4048
4194
  #endif
@@ -4274,7 +4420,7 @@ ngx_http_upstream_response_time_variable(ngx_http_request_t *r,
4274
4420
  ms = (ngx_msec_int_t)
4275
4421
  (state[i].response_sec * 1000 + state[i].response_msec);
4276
4422
  ms = ngx_max(ms, 0);
4277
- p = ngx_sprintf(p, "%d.%03d", ms / 1000, ms % 1000);
4423
+ p = ngx_sprintf(p, "%T.%03M", (time_t) ms / 1000, ms % 1000);
4278
4424
 
4279
4425
  } else {
4280
4426
  *p++ = '-';
@@ -4406,6 +4552,36 @@ ngx_http_upstream_cache_status(ngx_http_request_t *r,
4406
4552
  return NGX_OK;
4407
4553
  }
4408
4554
 
4555
+
4556
+ static ngx_int_t
4557
+ ngx_http_upstream_cache_last_modified(ngx_http_request_t *r,
4558
+ ngx_http_variable_value_t *v, uintptr_t data)
4559
+ {
4560
+ u_char *p;
4561
+
4562
+ if (r->upstream == NULL
4563
+ || !r->upstream->conf->cache_revalidate
4564
+ || r->upstream->cache_status != NGX_HTTP_CACHE_EXPIRED
4565
+ || r->cache->last_modified == -1)
4566
+ {
4567
+ v->not_found = 1;
4568
+ return NGX_OK;
4569
+ }
4570
+
4571
+ p = ngx_pnalloc(r->pool, sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1);
4572
+ if (p == NULL) {
4573
+ return NGX_ERROR;
4574
+ }
4575
+
4576
+ v->len = ngx_http_time(p, r->cache->last_modified) - p;
4577
+ v->valid = 1;
4578
+ v->no_cacheable = 0;
4579
+ v->not_found = 0;
4580
+ v->data = p;
4581
+
4582
+ return NGX_OK;
4583
+ }
4584
+
4409
4585
  #endif
4410
4586
 
4411
4587
 
@@ -4615,7 +4791,7 @@ ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4615
4791
  continue;
4616
4792
  }
4617
4793
 
4618
- if (ngx_strncmp(value[i].data, "backup", 6) == 0) {
4794
+ if (ngx_strcmp(value[i].data, "backup") == 0) {
4619
4795
 
4620
4796
  if (!(uscf->flags & NGX_HTTP_UPSTREAM_BACKUP)) {
4621
4797
  goto invalid;
@@ -4626,7 +4802,7 @@ ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4626
4802
  continue;
4627
4803
  }
4628
4804
 
4629
- if (ngx_strncmp(value[i].data, "down", 4) == 0) {
4805
+ if (ngx_strcmp(value[i].data, "down") == 0) {
4630
4806
 
4631
4807
  if (!(uscf->flags & NGX_HTTP_UPSTREAM_DOWN)) {
4632
4808
  goto invalid;