nginxtra 1.0.15.0 → 1.2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/bin/nginxtra +1 -1
- data/lib/nginxtra/action.rb +10 -0
- data/lib/nginxtra/actions/compile.rb +16 -2
- data/lib/nginxtra/actions/start.rb +18 -2
- data/lib/nginxtra/actions/status.rb +1 -10
- data/lib/nginxtra/actions/stop.rb +18 -0
- data/lib/nginxtra/cli.rb +12 -3
- data/lib/nginxtra/config.rb +10 -0
- data/src/nginx/CHANGES +311 -90
- data/src/nginx/CHANGES.ru +315 -88
- data/src/nginx/auto/lib/pcre/conf +22 -5
- data/src/nginx/auto/lib/pcre/make +1 -1
- data/src/nginx/auto/modules +14 -3
- data/src/nginx/auto/options +17 -3
- data/src/nginx/auto/os/freebsd +8 -0
- data/src/nginx/auto/os/linux +5 -4
- data/src/nginx/auto/os/solaris +2 -1
- data/src/nginx/auto/sources +10 -2
- data/src/nginx/auto/summary +2 -0
- data/src/nginx/auto/types/sizeof +2 -1
- data/src/nginx/auto/types/typedef +1 -1
- data/src/nginx/auto/types/uintptr_t +7 -4
- data/src/nginx/auto/unix +82 -21
- data/src/nginx/conf/fastcgi.conf +1 -0
- data/src/nginx/conf/fastcgi_params +1 -0
- data/src/nginx/conf/scgi_params +1 -0
- data/src/nginx/conf/uwsgi_params +1 -0
- data/src/nginx/man/nginx.8 +49 -49
- data/src/nginx/src/core/nginx.c +10 -12
- data/src/nginx/src/core/nginx.h +2 -2
- data/src/nginx/src/core/ngx_buf.c +9 -7
- data/src/nginx/src/core/ngx_buf.h +2 -2
- data/src/nginx/src/core/ngx_conf_file.c +4 -11
- data/src/nginx/src/core/ngx_conf_file.h +1 -1
- data/src/nginx/src/core/ngx_connection.c +52 -1
- data/src/nginx/src/core/ngx_connection.h +6 -0
- data/src/nginx/src/core/ngx_core.h +5 -0
- data/src/nginx/src/core/ngx_cycle.c +1 -1
- data/src/nginx/src/core/ngx_cycle.h +2 -2
- data/src/nginx/src/core/ngx_file.c +1 -1
- data/src/nginx/src/core/ngx_inet.c +11 -8
- data/src/nginx/src/core/ngx_murmurhash.h +1 -1
- data/src/nginx/src/core/ngx_open_file_cache.c +343 -38
- data/src/nginx/src/core/ngx_open_file_cache.h +10 -0
- data/src/nginx/src/core/ngx_output_chain.c +2 -1
- data/src/nginx/src/core/ngx_parse.h +0 -3
- data/src/nginx/src/core/ngx_rbtree.c +1 -2
- data/src/nginx/src/core/ngx_regex.c +263 -5
- data/src/nginx/src/core/ngx_regex.h +6 -2
- data/src/nginx/src/core/ngx_resolver.c +88 -21
- data/src/nginx/src/core/ngx_resolver.h +7 -8
- data/src/nginx/src/core/ngx_shmtx.c +69 -44
- data/src/nginx/src/core/ngx_shmtx.h +12 -1
- data/src/nginx/src/core/ngx_slab.c +3 -3
- data/src/nginx/src/core/ngx_slab.h +1 -1
- data/src/nginx/src/core/ngx_string.c +19 -16
- data/src/nginx/src/core/ngx_times.c +2 -2
- data/src/nginx/src/event/modules/ngx_epoll_module.c +2 -2
- data/src/nginx/src/event/modules/ngx_eventport_module.c +1 -1
- data/src/nginx/src/event/modules/ngx_kqueue_module.c +1 -1
- data/src/nginx/src/event/ngx_event.c +25 -17
- data/src/nginx/src/event/ngx_event_openssl.c +3 -1
- data/src/nginx/src/event/ngx_event_pipe.c +108 -85
- data/src/nginx/src/event/ngx_event_pipe.h +1 -2
- data/src/nginx/src/event/ngx_event_timer.c +2 -3
- data/src/nginx/src/http/modules/ngx_http_access_module.c +9 -4
- data/src/nginx/src/http/modules/ngx_http_browser_module.c +5 -3
- data/src/nginx/src/http/modules/ngx_http_chunked_filter_module.c +1 -1
- data/src/nginx/src/http/modules/ngx_http_degradation_module.c +1 -1
- data/src/nginx/src/http/modules/ngx_http_fastcgi_module.c +144 -22
- data/src/nginx/src/http/modules/ngx_http_flv_module.c +8 -0
- data/src/nginx/src/http/modules/ngx_http_geo_module.c +3 -3
- data/src/nginx/src/http/modules/ngx_http_gzip_filter_module.c +20 -6
- data/src/nginx/src/http/modules/ngx_http_gzip_static_module.c +8 -0
- data/src/nginx/src/http/modules/ngx_http_headers_filter_module.c +23 -27
- data/src/nginx/src/http/modules/ngx_http_image_filter_module.c +1 -3
- data/src/nginx/src/http/modules/ngx_http_index_module.c +24 -0
- data/src/nginx/src/http/modules/ngx_http_limit_conn_module.c +747 -0
- data/src/nginx/src/http/modules/ngx_http_limit_req_module.c +289 -133
- data/src/nginx/src/http/modules/ngx_http_log_module.c +34 -6
- data/src/nginx/src/http/modules/ngx_http_memcached_module.c +19 -3
- data/src/nginx/src/http/modules/ngx_http_mp4_module.c +8 -0
- data/src/nginx/src/http/modules/ngx_http_proxy_module.c +1446 -239
- data/src/nginx/src/http/modules/ngx_http_realip_module.c +4 -10
- data/src/nginx/src/http/modules/ngx_http_scgi_module.c +90 -21
- data/src/nginx/src/http/modules/ngx_http_split_clients_module.c +8 -11
- data/src/nginx/src/http/modules/ngx_http_ssi_filter_module.c +16 -6
- data/src/nginx/src/http/modules/ngx_http_static_module.c +8 -0
- data/src/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c +2 -2
- data/src/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c +570 -0
- data/src/nginx/src/http/modules/ngx_http_userid_filter_module.c +1 -5
- data/src/nginx/src/http/modules/ngx_http_uwsgi_module.c +77 -26
- data/src/nginx/src/http/modules/ngx_http_xslt_filter_module.c +171 -37
- data/src/nginx/src/http/modules/perl/nginx.pm +2 -1
- data/src/nginx/src/http/modules/perl/nginx.xs +4 -0
- data/src/nginx/src/http/ngx_http.c +8 -1
- data/src/nginx/src/http/ngx_http.h +1 -0
- data/src/nginx/src/http/ngx_http_busy_lock.c +2 -2
- data/src/nginx/src/http/ngx_http_cache.h +12 -1
- data/src/nginx/src/http/ngx_http_copy_filter_module.c +4 -3
- data/src/nginx/src/http/ngx_http_core_module.c +303 -37
- data/src/nginx/src/http/ngx_http_core_module.h +15 -0
- data/src/nginx/src/http/ngx_http_file_cache.c +226 -52
- data/src/nginx/src/http/ngx_http_parse.c +69 -3
- data/src/nginx/src/http/ngx_http_postpone_filter_module.c +4 -4
- data/src/nginx/src/http/ngx_http_request.c +61 -27
- data/src/nginx/src/http/ngx_http_request.h +3 -3
- data/src/nginx/src/http/ngx_http_request_body.c +1 -1
- data/src/nginx/src/http/ngx_http_script.c +6 -0
- data/src/nginx/src/http/ngx_http_upstream.c +200 -47
- data/src/nginx/src/http/ngx_http_upstream.h +20 -1
- data/src/nginx/src/http/ngx_http_upstream_round_robin.c +22 -6
- data/src/nginx/src/http/ngx_http_upstream_round_robin.h +1 -0
- data/src/nginx/src/http/ngx_http_variables.c +123 -4
- data/src/nginx/src/mail/ngx_mail.c +13 -0
- data/src/nginx/src/mail/ngx_mail.h +12 -0
- data/src/nginx/src/mail/ngx_mail_core_module.c +100 -15
- data/src/nginx/src/os/unix/ngx_daemon.c +2 -1
- data/src/nginx/src/os/unix/ngx_darwin.h +3 -0
- data/src/nginx/src/os/unix/ngx_darwin_config.h +1 -0
- data/src/nginx/src/os/unix/ngx_darwin_init.c +30 -0
- data/src/nginx/src/os/unix/ngx_darwin_sendfile_chain.c +11 -5
- data/src/nginx/src/os/unix/ngx_errno.h +5 -0
- data/src/nginx/src/os/unix/ngx_files.h +50 -1
- data/src/nginx/src/os/unix/ngx_freebsd.h +2 -1
- data/src/nginx/src/os/unix/ngx_freebsd_config.h +2 -0
- data/src/nginx/src/os/unix/ngx_freebsd_init.c +4 -3
- data/src/nginx/src/os/unix/ngx_freebsd_rfork_thread.c +2 -2
- data/src/nginx/src/os/unix/ngx_freebsd_sendfile_chain.c +12 -6
- data/src/nginx/src/os/unix/ngx_gcc_atomic_sparc64.h +1 -1
- data/src/nginx/src/os/unix/ngx_linux_config.h +1 -0
- data/src/nginx/src/os/unix/ngx_linux_sendfile_chain.c +6 -4
- data/src/nginx/src/os/unix/ngx_os.h +0 -1
- data/src/nginx/src/os/unix/ngx_posix_config.h +3 -0
- data/src/nginx/src/os/unix/ngx_process.c +50 -11
- data/src/nginx/src/os/unix/ngx_process.h +1 -0
- data/src/nginx/src/os/unix/ngx_process_cycle.c +6 -15
- data/src/nginx/src/os/unix/ngx_readv_chain.c +8 -0
- data/src/nginx/src/os/unix/ngx_setaffinity.c +69 -0
- data/src/nginx/src/os/unix/ngx_setaffinity.h +23 -0
- data/src/nginx/src/os/unix/ngx_setproctitle.c +1 -1
- data/src/nginx/src/os/unix/ngx_solaris_config.h +2 -0
- data/src/nginx/src/os/unix/ngx_solaris_sendfilev_chain.c +11 -3
- data/src/nginx/src/os/unix/ngx_writev_chain.c +7 -3
- metadata +7 -4
- data/src/nginx/src/http/modules/ngx_http_limit_zone_module.c +0 -553
@@ -16,13 +16,7 @@
|
|
16
16
|
|
17
17
|
|
18
18
|
typedef struct {
|
19
|
-
|
20
|
-
in_addr_t addr;
|
21
|
-
} ngx_http_realip_from_t;
|
22
|
-
|
23
|
-
|
24
|
-
typedef struct {
|
25
|
-
ngx_array_t *from; /* array of ngx_http_realip_from_t */
|
19
|
+
ngx_array_t *from; /* array of ngx_in_cidr_t */
|
26
20
|
ngx_uint_t type;
|
27
21
|
ngx_uint_t hash;
|
28
22
|
ngx_str_t header;
|
@@ -114,9 +108,9 @@ ngx_http_realip_handler(ngx_http_request_t *r)
|
|
114
108
|
ngx_list_part_t *part;
|
115
109
|
ngx_table_elt_t *header;
|
116
110
|
struct sockaddr_in *sin;
|
111
|
+
ngx_in_cidr_t *from;
|
117
112
|
ngx_connection_t *c;
|
118
113
|
ngx_http_realip_ctx_t *ctx;
|
119
|
-
ngx_http_realip_from_t *from;
|
120
114
|
ngx_http_realip_loc_conf_t *rlcf;
|
121
115
|
|
122
116
|
ctx = ngx_http_get_module_ctx(r, ngx_http_realip_module);
|
@@ -317,7 +311,7 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|
317
311
|
ngx_int_t rc;
|
318
312
|
ngx_str_t *value;
|
319
313
|
ngx_cidr_t cidr;
|
320
|
-
|
314
|
+
ngx_in_cidr_t *from;
|
321
315
|
|
322
316
|
value = cf->args->elts;
|
323
317
|
|
@@ -332,7 +326,7 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|
332
326
|
|
333
327
|
if (rlcf->from == NULL) {
|
334
328
|
rlcf->from = ngx_array_create(cf->pool, 2,
|
335
|
-
sizeof(
|
329
|
+
sizeof(ngx_in_cidr_t));
|
336
330
|
if (rlcf->from == NULL) {
|
337
331
|
return NGX_CONF_ERROR;
|
338
332
|
}
|
@@ -247,6 +247,20 @@ static ngx_command_t ngx_http_scgi_commands[] = {
|
|
247
247
|
offsetof(ngx_http_scgi_loc_conf_t, upstream.cache_methods),
|
248
248
|
&ngx_http_upstream_cache_method_mask },
|
249
249
|
|
250
|
+
{ ngx_string("scgi_cache_lock"),
|
251
|
+
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
|
252
|
+
ngx_conf_set_flag_slot,
|
253
|
+
NGX_HTTP_LOC_CONF_OFFSET,
|
254
|
+
offsetof(ngx_http_scgi_loc_conf_t, upstream.cache_lock),
|
255
|
+
NULL },
|
256
|
+
|
257
|
+
{ ngx_string("scgi_cache_lock_timeout"),
|
258
|
+
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
259
|
+
ngx_conf_set_msec_slot,
|
260
|
+
NGX_HTTP_LOC_CONF_OFFSET,
|
261
|
+
offsetof(ngx_http_scgi_loc_conf_t, upstream.cache_lock_timeout),
|
262
|
+
NULL },
|
263
|
+
|
250
264
|
#endif
|
251
265
|
|
252
266
|
{ ngx_string("scgi_temp_path"),
|
@@ -278,8 +292,8 @@ static ngx_command_t ngx_http_scgi_commands[] = {
|
|
278
292
|
&ngx_http_scgi_next_upstream_masks },
|
279
293
|
|
280
294
|
{ ngx_string("scgi_param"),
|
281
|
-
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|
|
282
|
-
|
295
|
+
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE23,
|
296
|
+
ngx_http_upstream_param_set_slot,
|
283
297
|
NGX_HTTP_LOC_CONF_OFFSET,
|
284
298
|
offsetof(ngx_http_scgi_loc_conf_t, params_source),
|
285
299
|
NULL },
|
@@ -519,10 +533,10 @@ static ngx_int_t
|
|
519
533
|
ngx_http_scgi_create_request(ngx_http_request_t *r)
|
520
534
|
{
|
521
535
|
u_char ch, *key, *val, *lowcase_key;
|
522
|
-
size_t len, allocated;
|
536
|
+
size_t len, key_len, val_len, allocated;
|
523
537
|
ngx_buf_t *b;
|
524
538
|
ngx_str_t *content_length;
|
525
|
-
ngx_uint_t i, n, hash, header_params;
|
539
|
+
ngx_uint_t i, n, hash, skip_empty, header_params;
|
526
540
|
ngx_chain_t *cl, *body;
|
527
541
|
ngx_list_part_t *part;
|
528
542
|
ngx_table_elt_t *header, **ignored;
|
@@ -554,15 +568,21 @@ ngx_http_scgi_create_request(ngx_http_request_t *r)
|
|
554
568
|
while (*(uintptr_t *) le.ip) {
|
555
569
|
|
556
570
|
lcode = *(ngx_http_script_len_code_pt *) le.ip;
|
557
|
-
|
571
|
+
key_len = lcode(&le);
|
558
572
|
|
559
|
-
|
573
|
+
lcode = *(ngx_http_script_len_code_pt *) le.ip;
|
574
|
+
skip_empty = lcode(&le);
|
575
|
+
|
576
|
+
for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) {
|
560
577
|
lcode = *(ngx_http_script_len_code_pt *) le.ip;
|
561
|
-
len += lcode(&le);
|
562
578
|
}
|
563
|
-
len++;
|
564
|
-
|
565
579
|
le.ip += sizeof(uintptr_t);
|
580
|
+
|
581
|
+
if (skip_empty && val_len == 0) {
|
582
|
+
continue;
|
583
|
+
}
|
584
|
+
|
585
|
+
len += key_len + val_len + 1;
|
566
586
|
}
|
567
587
|
}
|
568
588
|
|
@@ -665,7 +685,34 @@ ngx_http_scgi_create_request(ngx_http_request_t *r)
|
|
665
685
|
e.request = r;
|
666
686
|
e.flushed = 1;
|
667
687
|
|
668
|
-
|
688
|
+
le.ip = scf->params_len->elts;
|
689
|
+
|
690
|
+
while (*(uintptr_t *) le.ip) {
|
691
|
+
|
692
|
+
lcode = *(ngx_http_script_len_code_pt *) le.ip;
|
693
|
+
lcode(&le); /* key length */
|
694
|
+
|
695
|
+
lcode = *(ngx_http_script_len_code_pt *) le.ip;
|
696
|
+
skip_empty = lcode(&le);
|
697
|
+
|
698
|
+
for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) {
|
699
|
+
lcode = *(ngx_http_script_len_code_pt *) le.ip;
|
700
|
+
}
|
701
|
+
le.ip += sizeof(uintptr_t);
|
702
|
+
|
703
|
+
if (skip_empty && val_len == 0) {
|
704
|
+
e.skip = 1;
|
705
|
+
|
706
|
+
while (*(uintptr_t *) e.ip) {
|
707
|
+
code = *(ngx_http_script_code_pt *) e.ip;
|
708
|
+
code((ngx_http_script_engine_t *) &e);
|
709
|
+
}
|
710
|
+
e.ip += sizeof(uintptr_t);
|
711
|
+
|
712
|
+
e.skip = 0;
|
713
|
+
|
714
|
+
continue;
|
715
|
+
}
|
669
716
|
|
670
717
|
#if (NGX_DEBUG)
|
671
718
|
key = e.pos;
|
@@ -1032,6 +1079,8 @@ ngx_http_scgi_create_loc_conf(ngx_conf_t *cf)
|
|
1032
1079
|
conf->upstream.cache_bypass = NGX_CONF_UNSET_PTR;
|
1033
1080
|
conf->upstream.no_cache = NGX_CONF_UNSET_PTR;
|
1034
1081
|
conf->upstream.cache_valid = NGX_CONF_UNSET_PTR;
|
1082
|
+
conf->upstream.cache_lock = NGX_CONF_UNSET;
|
1083
|
+
conf->upstream.cache_lock_timeout = NGX_CONF_UNSET_MSEC;
|
1035
1084
|
#endif
|
1036
1085
|
|
1037
1086
|
conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
|
@@ -1124,8 +1173,8 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|
1124
1173
|
|
1125
1174
|
if (conf->upstream.busy_buffers_size < size) {
|
1126
1175
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
1127
|
-
"\"scgi_busy_buffers_size\" must be equal or
|
1128
|
-
"than maximum of the value of \"scgi_buffer_size\" and "
|
1176
|
+
"\"scgi_busy_buffers_size\" must be equal to or greater "
|
1177
|
+
"than the maximum of the value of \"scgi_buffer_size\" and "
|
1129
1178
|
"one of the \"scgi_buffers\"");
|
1130
1179
|
|
1131
1180
|
return NGX_CONF_ERROR;
|
@@ -1155,8 +1204,8 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|
1155
1204
|
|
1156
1205
|
if (conf->upstream.temp_file_write_size < size) {
|
1157
1206
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
1158
|
-
"\"scgi_temp_file_write_size\" must be equal or
|
1159
|
-
"maximum of the value of \"scgi_buffer_size\" and "
|
1207
|
+
"\"scgi_temp_file_write_size\" must be equal to or greater than "
|
1208
|
+
"the maximum of the value of \"scgi_buffer_size\" and "
|
1160
1209
|
"one of the \"scgi_buffers\"");
|
1161
1210
|
|
1162
1211
|
return NGX_CONF_ERROR;
|
@@ -1178,8 +1227,8 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|
1178
1227
|
&& conf->upstream.max_temp_file_size < size) {
|
1179
1228
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
1180
1229
|
"\"scgi_max_temp_file_size\" must be equal to zero to disable "
|
1181
|
-
"
|
1182
|
-
"maximum of the value of \"scgi_buffer_size\" and "
|
1230
|
+
"temporary files usage or must be equal to or greater than "
|
1231
|
+
"the maximum of the value of \"scgi_buffer_size\" and "
|
1183
1232
|
"one of the \"scgi_buffers\"");
|
1184
1233
|
|
1185
1234
|
return NGX_CONF_ERROR;
|
@@ -1263,6 +1312,12 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|
1263
1312
|
conf->cache_key = prev->cache_key;
|
1264
1313
|
}
|
1265
1314
|
|
1315
|
+
ngx_conf_merge_value(conf->upstream.cache_lock,
|
1316
|
+
prev->upstream.cache_lock, 0);
|
1317
|
+
|
1318
|
+
ngx_conf_merge_msec_value(conf->upstream.cache_lock_timeout,
|
1319
|
+
prev->upstream.cache_lock_timeout, 5000);
|
1320
|
+
|
1266
1321
|
#endif
|
1267
1322
|
|
1268
1323
|
ngx_conf_merge_value(conf->upstream.pass_request_headers,
|
@@ -1320,9 +1375,9 @@ ngx_http_scgi_merge_params(ngx_conf_t *cf, ngx_http_scgi_loc_conf_t *conf,
|
|
1320
1375
|
#if (NGX_HTTP_CACHE)
|
1321
1376
|
ngx_array_t params_merged;
|
1322
1377
|
#endif
|
1323
|
-
ngx_keyval_t *src;
|
1324
1378
|
ngx_hash_key_t *hk;
|
1325
1379
|
ngx_hash_init_t hash;
|
1380
|
+
ngx_http_upstream_param_t *src;
|
1326
1381
|
ngx_http_script_compile_t sc;
|
1327
1382
|
ngx_http_script_copy_code_t *copy;
|
1328
1383
|
|
@@ -1331,7 +1386,8 @@ ngx_http_scgi_merge_params(ngx_conf_t *cf, ngx_http_scgi_loc_conf_t *conf,
|
|
1331
1386
|
|
1332
1387
|
if (prev->headers_hash.buckets
|
1333
1388
|
#if (NGX_HTTP_CACHE)
|
1334
|
-
&& ((conf->upstream.cache == NULL)
|
1389
|
+
&& ((conf->upstream.cache == NULL)
|
1390
|
+
== (prev->upstream.cache == NULL))
|
1335
1391
|
#endif
|
1336
1392
|
)
|
1337
1393
|
{
|
@@ -1383,9 +1439,11 @@ ngx_http_scgi_merge_params(ngx_conf_t *cf, ngx_http_scgi_loc_conf_t *conf,
|
|
1383
1439
|
#if (NGX_HTTP_CACHE)
|
1384
1440
|
|
1385
1441
|
if (conf->upstream.cache) {
|
1386
|
-
ngx_keyval_t
|
1442
|
+
ngx_keyval_t *h;
|
1443
|
+
ngx_http_upstream_param_t *s;
|
1387
1444
|
|
1388
|
-
if (ngx_array_init(¶ms_merged, cf->temp_pool, 4,
|
1445
|
+
if (ngx_array_init(¶ms_merged, cf->temp_pool, 4,
|
1446
|
+
sizeof(ngx_http_upstream_param_t))
|
1389
1447
|
!= NGX_OK)
|
1390
1448
|
{
|
1391
1449
|
return NGX_ERROR;
|
@@ -1419,7 +1477,9 @@ ngx_http_scgi_merge_params(ngx_conf_t *cf, ngx_http_scgi_loc_conf_t *conf,
|
|
1419
1477
|
return NGX_ERROR;
|
1420
1478
|
}
|
1421
1479
|
|
1422
|
-
|
1480
|
+
s->key = h->key;
|
1481
|
+
s->value = h->value;
|
1482
|
+
s->skip_empty = 0;
|
1423
1483
|
|
1424
1484
|
next:
|
1425
1485
|
|
@@ -1461,6 +1521,15 @@ ngx_http_scgi_merge_params(ngx_conf_t *cf, ngx_http_scgi_loc_conf_t *conf,
|
|
1461
1521
|
copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
|
1462
1522
|
copy->len = src[i].key.len + 1;
|
1463
1523
|
|
1524
|
+
copy = ngx_array_push_n(conf->params_len,
|
1525
|
+
sizeof(ngx_http_script_copy_code_t));
|
1526
|
+
if (copy == NULL) {
|
1527
|
+
return NGX_ERROR;
|
1528
|
+
}
|
1529
|
+
|
1530
|
+
copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
|
1531
|
+
copy->len = src[i].skip_empty;
|
1532
|
+
|
1464
1533
|
|
1465
1534
|
size = (sizeof(ngx_http_script_copy_code_t)
|
1466
1535
|
+ src[i].key.len + 1 + sizeof(uintptr_t) - 1)
|
@@ -97,7 +97,7 @@ ngx_http_split_clients_variable(ngx_http_request_t *r,
|
|
97
97
|
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
98
98
|
"http split: %uD %uD", hash, part[i].percent);
|
99
99
|
|
100
|
-
if (hash < part[i].percent) {
|
100
|
+
if (hash < part[i].percent || part[i].percent == 0) {
|
101
101
|
*v = part[i].value;
|
102
102
|
return NGX_OK;
|
103
103
|
}
|
@@ -111,8 +111,9 @@ static char *
|
|
111
111
|
ngx_conf_split_clients_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
112
112
|
{
|
113
113
|
char *rv;
|
114
|
+
uint32_t sum, last;
|
114
115
|
ngx_str_t *value, name;
|
115
|
-
ngx_uint_t i
|
116
|
+
ngx_uint_t i;
|
116
117
|
ngx_conf_t save;
|
117
118
|
ngx_http_variable_t *var;
|
118
119
|
ngx_http_split_clients_ctx_t *ctx;
|
@@ -175,19 +176,15 @@ ngx_conf_split_clients_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|
175
176
|
for (i = 0; i < ctx->parts.nelts; i++) {
|
176
177
|
sum = part[i].percent ? sum + part[i].percent : 10000;
|
177
178
|
if (sum > 10000) {
|
178
|
-
|
179
|
-
|
180
|
-
|
179
|
+
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
180
|
+
"percent total is greater than 100%%");
|
181
|
+
return NGX_CONF_ERROR;
|
181
182
|
}
|
182
183
|
|
183
184
|
if (part[i].percent) {
|
184
|
-
part[i].percent
|
185
|
-
|
186
|
-
} else {
|
187
|
-
part[i].percent = 0xffffffff;
|
185
|
+
last += part[i].percent * (uint64_t) 0xffffffff / 10000;
|
186
|
+
part[i].percent = last;
|
188
187
|
}
|
189
|
-
|
190
|
-
last = part[i].percent;
|
191
188
|
}
|
192
189
|
|
193
190
|
return rv;
|
@@ -714,7 +714,7 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|
714
714
|
|
715
715
|
if (ctx->params.nelts > NGX_HTTP_SSI_MAX_PARAMS) {
|
716
716
|
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
717
|
-
"too many SSI command
|
717
|
+
"too many SSI command parameters: \"%V\"",
|
718
718
|
&ctx->command);
|
719
719
|
goto ssi_error;
|
720
720
|
}
|
@@ -1204,7 +1204,7 @@ ngx_http_ssi_parse(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx)
|
|
1204
1204
|
|
1205
1205
|
if (ctx->value_buf == NULL) {
|
1206
1206
|
ctx->param->value.data = ngx_pnalloc(r->pool,
|
1207
|
-
ctx->value_len);
|
1207
|
+
ctx->value_len + 1);
|
1208
1208
|
if (ctx->param->value.data == NULL) {
|
1209
1209
|
return NGX_ERROR;
|
1210
1210
|
}
|
@@ -1375,6 +1375,16 @@ ngx_http_ssi_parse(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx)
|
|
1375
1375
|
case ssi_quoted_symbol_state:
|
1376
1376
|
state = ctx->saved_state;
|
1377
1377
|
|
1378
|
+
if (ctx->param->value.len == ctx->value_len) {
|
1379
|
+
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
1380
|
+
"too long \"%V%c...\" value of \"%V\" "
|
1381
|
+
"parameter in \"%V\" SSI command",
|
1382
|
+
&ctx->param->value, ch, &ctx->param->key,
|
1383
|
+
&ctx->command);
|
1384
|
+
state = ssi_error_state;
|
1385
|
+
break;
|
1386
|
+
}
|
1387
|
+
|
1378
1388
|
ctx->param->value.data[ctx->param->value.len++] = ch;
|
1379
1389
|
|
1380
1390
|
break;
|
@@ -1993,7 +2003,7 @@ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
|
1993
2003
|
|
1994
2004
|
if (set && stub) {
|
1995
2005
|
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
1996
|
-
"\"set\" and \"stub\"
|
2006
|
+
"\"set\" and \"stub\" cannot be used together "
|
1997
2007
|
"in \"include\" SSI command");
|
1998
2008
|
return NGX_HTTP_SSI_ERROR;
|
1999
2009
|
}
|
@@ -2001,7 +2011,7 @@ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
|
2001
2011
|
if (wait) {
|
2002
2012
|
if (uri == NULL) {
|
2003
2013
|
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
2004
|
-
"\"wait\"
|
2014
|
+
"\"wait\" cannot be used with file=\"%V\"", file);
|
2005
2015
|
return NGX_HTTP_SSI_ERROR;
|
2006
2016
|
}
|
2007
2017
|
|
@@ -2178,7 +2188,7 @@ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
|
|
2178
2188
|
|
2179
2189
|
} else {
|
2180
2190
|
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
2181
|
-
"only one subrequest
|
2191
|
+
"can only wait for one subrequest at a time");
|
2182
2192
|
}
|
2183
2193
|
|
2184
2194
|
return NGX_OK;
|
@@ -2886,7 +2896,7 @@ ngx_http_ssi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|
2886
2896
|
prev->ignore_recycled_buffers, 0);
|
2887
2897
|
|
2888
2898
|
ngx_conf_merge_size_value(conf->min_file_chunk, prev->min_file_chunk, 1024);
|
2889
|
-
ngx_conf_merge_size_value(conf->value_len, prev->value_len,
|
2899
|
+
ngx_conf_merge_size_value(conf->value_len, prev->value_len, 255);
|
2890
2900
|
|
2891
2901
|
if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types,
|
2892
2902
|
&prev->types_keys, &prev->types,
|
@@ -95,6 +95,10 @@ ngx_http_static_handler(ngx_http_request_t *r)
|
|
95
95
|
of.errors = clcf->open_file_cache_errors;
|
96
96
|
of.events = clcf->open_file_cache_events;
|
97
97
|
|
98
|
+
if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) {
|
99
|
+
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
100
|
+
}
|
101
|
+
|
98
102
|
if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
|
99
103
|
!= NGX_OK)
|
100
104
|
{
|
@@ -112,6 +116,10 @@ ngx_http_static_handler(ngx_http_request_t *r)
|
|
112
116
|
break;
|
113
117
|
|
114
118
|
case NGX_EACCES:
|
119
|
+
#if (NGX_HAVE_OPENAT)
|
120
|
+
case NGX_EMLINK:
|
121
|
+
case NGX_ELOOP:
|
122
|
+
#endif
|
115
123
|
|
116
124
|
level = NGX_LOG_ERR;
|
117
125
|
rc = NGX_HTTP_FORBIDDEN;
|
@@ -186,8 +186,8 @@ ngx_http_upstream_get_ip_hash_peer(ngx_peer_connection_t *pc, void *data)
|
|
186
186
|
break;
|
187
187
|
}
|
188
188
|
|
189
|
-
if (now - peer->
|
190
|
-
peer->
|
189
|
+
if (now - peer->checked > peer->fail_timeout) {
|
190
|
+
peer->checked = now;
|
191
191
|
break;
|
192
192
|
}
|
193
193
|
}
|
@@ -0,0 +1,570 @@
|
|
1
|
+
|
2
|
+
/*
|
3
|
+
* Copyright (C) Maxim Dounin
|
4
|
+
* Copyright (C) Nginx, Inc.
|
5
|
+
*/
|
6
|
+
|
7
|
+
|
8
|
+
#include <ngx_config.h>
|
9
|
+
#include <ngx_core.h>
|
10
|
+
#include <ngx_http.h>
|
11
|
+
|
12
|
+
|
13
|
+
typedef struct {
|
14
|
+
ngx_uint_t max_cached;
|
15
|
+
ngx_uint_t single; /* unsigned:1 */
|
16
|
+
|
17
|
+
ngx_queue_t cache;
|
18
|
+
ngx_queue_t free;
|
19
|
+
|
20
|
+
ngx_http_upstream_init_pt original_init_upstream;
|
21
|
+
ngx_http_upstream_init_peer_pt original_init_peer;
|
22
|
+
|
23
|
+
} ngx_http_upstream_keepalive_srv_conf_t;
|
24
|
+
|
25
|
+
|
26
|
+
typedef struct {
|
27
|
+
ngx_http_upstream_keepalive_srv_conf_t *conf;
|
28
|
+
|
29
|
+
ngx_http_upstream_t *upstream;
|
30
|
+
|
31
|
+
void *data;
|
32
|
+
|
33
|
+
ngx_event_get_peer_pt original_get_peer;
|
34
|
+
ngx_event_free_peer_pt original_free_peer;
|
35
|
+
|
36
|
+
#if (NGX_HTTP_SSL)
|
37
|
+
ngx_event_set_peer_session_pt original_set_session;
|
38
|
+
ngx_event_save_peer_session_pt original_save_session;
|
39
|
+
#endif
|
40
|
+
|
41
|
+
ngx_uint_t failed; /* unsigned:1 */
|
42
|
+
|
43
|
+
} ngx_http_upstream_keepalive_peer_data_t;
|
44
|
+
|
45
|
+
|
46
|
+
typedef struct {
|
47
|
+
ngx_http_upstream_keepalive_srv_conf_t *conf;
|
48
|
+
|
49
|
+
ngx_queue_t queue;
|
50
|
+
ngx_connection_t *connection;
|
51
|
+
|
52
|
+
socklen_t socklen;
|
53
|
+
u_char sockaddr[NGX_SOCKADDRLEN];
|
54
|
+
|
55
|
+
} ngx_http_upstream_keepalive_cache_t;
|
56
|
+
|
57
|
+
|
58
|
+
static ngx_int_t ngx_http_upstream_init_keepalive_peer(ngx_http_request_t *r,
|
59
|
+
ngx_http_upstream_srv_conf_t *us);
|
60
|
+
static ngx_int_t ngx_http_upstream_get_keepalive_peer(ngx_peer_connection_t *pc,
|
61
|
+
void *data);
|
62
|
+
static void ngx_http_upstream_free_keepalive_peer(ngx_peer_connection_t *pc,
|
63
|
+
void *data, ngx_uint_t state);
|
64
|
+
|
65
|
+
static void ngx_http_upstream_keepalive_dummy_handler(ngx_event_t *ev);
|
66
|
+
static void ngx_http_upstream_keepalive_close_handler(ngx_event_t *ev);
|
67
|
+
static void ngx_http_upstream_keepalive_close(ngx_connection_t *c);
|
68
|
+
|
69
|
+
|
70
|
+
#if (NGX_HTTP_SSL)
|
71
|
+
static ngx_int_t ngx_http_upstream_keepalive_set_session(
|
72
|
+
ngx_peer_connection_t *pc, void *data);
|
73
|
+
static void ngx_http_upstream_keepalive_save_session(ngx_peer_connection_t *pc,
|
74
|
+
void *data);
|
75
|
+
#endif
|
76
|
+
|
77
|
+
static void *ngx_http_upstream_keepalive_create_conf(ngx_conf_t *cf);
|
78
|
+
static char *ngx_http_upstream_keepalive(ngx_conf_t *cf, ngx_command_t *cmd,
|
79
|
+
void *conf);
|
80
|
+
|
81
|
+
|
82
|
+
static ngx_command_t ngx_http_upstream_keepalive_commands[] = {
|
83
|
+
|
84
|
+
{ ngx_string("keepalive"),
|
85
|
+
NGX_HTTP_UPS_CONF|NGX_CONF_TAKE12,
|
86
|
+
ngx_http_upstream_keepalive,
|
87
|
+
0,
|
88
|
+
0,
|
89
|
+
NULL },
|
90
|
+
|
91
|
+
ngx_null_command
|
92
|
+
};
|
93
|
+
|
94
|
+
|
95
|
+
static ngx_http_module_t ngx_http_upstream_keepalive_module_ctx = {
|
96
|
+
NULL, /* preconfiguration */
|
97
|
+
NULL, /* postconfiguration */
|
98
|
+
|
99
|
+
NULL, /* create main configuration */
|
100
|
+
NULL, /* init main configuration */
|
101
|
+
|
102
|
+
ngx_http_upstream_keepalive_create_conf, /* create server configuration */
|
103
|
+
NULL, /* merge server configuration */
|
104
|
+
|
105
|
+
NULL, /* create location configuration */
|
106
|
+
NULL /* merge location configuration */
|
107
|
+
};
|
108
|
+
|
109
|
+
|
110
|
+
ngx_module_t ngx_http_upstream_keepalive_module = {
|
111
|
+
NGX_MODULE_V1,
|
112
|
+
&ngx_http_upstream_keepalive_module_ctx, /* module context */
|
113
|
+
ngx_http_upstream_keepalive_commands, /* module directives */
|
114
|
+
NGX_HTTP_MODULE, /* module type */
|
115
|
+
NULL, /* init master */
|
116
|
+
NULL, /* init module */
|
117
|
+
NULL, /* init process */
|
118
|
+
NULL, /* init thread */
|
119
|
+
NULL, /* exit thread */
|
120
|
+
NULL, /* exit process */
|
121
|
+
NULL, /* exit master */
|
122
|
+
NGX_MODULE_V1_PADDING
|
123
|
+
};
|
124
|
+
|
125
|
+
|
126
|
+
static ngx_int_t
|
127
|
+
ngx_http_upstream_init_keepalive(ngx_conf_t *cf,
|
128
|
+
ngx_http_upstream_srv_conf_t *us)
|
129
|
+
{
|
130
|
+
ngx_uint_t i;
|
131
|
+
ngx_http_upstream_keepalive_srv_conf_t *kcf;
|
132
|
+
ngx_http_upstream_keepalive_cache_t *cached;
|
133
|
+
|
134
|
+
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0,
|
135
|
+
"init keepalive");
|
136
|
+
|
137
|
+
kcf = ngx_http_conf_upstream_srv_conf(us,
|
138
|
+
ngx_http_upstream_keepalive_module);
|
139
|
+
|
140
|
+
if (kcf->original_init_upstream(cf, us) != NGX_OK) {
|
141
|
+
return NGX_ERROR;
|
142
|
+
}
|
143
|
+
|
144
|
+
kcf->original_init_peer = us->peer.init;
|
145
|
+
|
146
|
+
us->peer.init = ngx_http_upstream_init_keepalive_peer;
|
147
|
+
|
148
|
+
/* allocate cache items and add to free queue */
|
149
|
+
|
150
|
+
cached = ngx_pcalloc(cf->pool,
|
151
|
+
sizeof(ngx_http_upstream_keepalive_cache_t) * kcf->max_cached);
|
152
|
+
if (cached == NULL) {
|
153
|
+
return NGX_ERROR;
|
154
|
+
}
|
155
|
+
|
156
|
+
ngx_queue_init(&kcf->cache);
|
157
|
+
ngx_queue_init(&kcf->free);
|
158
|
+
|
159
|
+
for (i = 0; i < kcf->max_cached; i++) {
|
160
|
+
ngx_queue_insert_head(&kcf->free, &cached[i].queue);
|
161
|
+
cached[i].conf = kcf;
|
162
|
+
}
|
163
|
+
|
164
|
+
return NGX_OK;
|
165
|
+
}
|
166
|
+
|
167
|
+
|
168
|
+
static ngx_int_t
|
169
|
+
ngx_http_upstream_init_keepalive_peer(ngx_http_request_t *r,
|
170
|
+
ngx_http_upstream_srv_conf_t *us)
|
171
|
+
{
|
172
|
+
ngx_http_upstream_keepalive_peer_data_t *kp;
|
173
|
+
ngx_http_upstream_keepalive_srv_conf_t *kcf;
|
174
|
+
|
175
|
+
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
176
|
+
"init keepalive peer");
|
177
|
+
|
178
|
+
kcf = ngx_http_conf_upstream_srv_conf(us,
|
179
|
+
ngx_http_upstream_keepalive_module);
|
180
|
+
|
181
|
+
kp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_keepalive_peer_data_t));
|
182
|
+
if (kp == NULL) {
|
183
|
+
return NGX_ERROR;
|
184
|
+
}
|
185
|
+
|
186
|
+
if (kcf->original_init_peer(r, us) != NGX_OK) {
|
187
|
+
return NGX_ERROR;
|
188
|
+
}
|
189
|
+
|
190
|
+
kp->conf = kcf;
|
191
|
+
kp->upstream = r->upstream;
|
192
|
+
kp->data = r->upstream->peer.data;
|
193
|
+
kp->original_get_peer = r->upstream->peer.get;
|
194
|
+
kp->original_free_peer = r->upstream->peer.free;
|
195
|
+
|
196
|
+
r->upstream->peer.data = kp;
|
197
|
+
r->upstream->peer.get = ngx_http_upstream_get_keepalive_peer;
|
198
|
+
r->upstream->peer.free = ngx_http_upstream_free_keepalive_peer;
|
199
|
+
|
200
|
+
#if (NGX_HTTP_SSL)
|
201
|
+
kp->original_set_session = r->upstream->peer.set_session;
|
202
|
+
kp->original_save_session = r->upstream->peer.save_session;
|
203
|
+
r->upstream->peer.set_session = ngx_http_upstream_keepalive_set_session;
|
204
|
+
r->upstream->peer.save_session = ngx_http_upstream_keepalive_save_session;
|
205
|
+
#endif
|
206
|
+
|
207
|
+
return NGX_OK;
|
208
|
+
}
|
209
|
+
|
210
|
+
|
211
|
+
static ngx_int_t
|
212
|
+
ngx_http_upstream_get_keepalive_peer(ngx_peer_connection_t *pc, void *data)
|
213
|
+
{
|
214
|
+
ngx_http_upstream_keepalive_peer_data_t *kp = data;
|
215
|
+
ngx_http_upstream_keepalive_cache_t *item;
|
216
|
+
|
217
|
+
ngx_int_t rc;
|
218
|
+
ngx_queue_t *q, *cache;
|
219
|
+
ngx_connection_t *c;
|
220
|
+
|
221
|
+
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0,
|
222
|
+
"get keepalive peer");
|
223
|
+
|
224
|
+
kp->failed = 0;
|
225
|
+
|
226
|
+
/* single pool of cached connections */
|
227
|
+
|
228
|
+
if (kp->conf->single && !ngx_queue_empty(&kp->conf->cache)) {
|
229
|
+
|
230
|
+
q = ngx_queue_head(&kp->conf->cache);
|
231
|
+
|
232
|
+
item = ngx_queue_data(q, ngx_http_upstream_keepalive_cache_t, queue);
|
233
|
+
c = item->connection;
|
234
|
+
|
235
|
+
ngx_queue_remove(q);
|
236
|
+
ngx_queue_insert_head(&kp->conf->free, q);
|
237
|
+
|
238
|
+
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
|
239
|
+
"get keepalive peer: using connection %p", c);
|
240
|
+
|
241
|
+
c->idle = 0;
|
242
|
+
c->log = pc->log;
|
243
|
+
c->read->log = pc->log;
|
244
|
+
c->write->log = pc->log;
|
245
|
+
c->pool->log = pc->log;
|
246
|
+
|
247
|
+
pc->connection = c;
|
248
|
+
pc->cached = 1;
|
249
|
+
|
250
|
+
return NGX_DONE;
|
251
|
+
}
|
252
|
+
|
253
|
+
rc = kp->original_get_peer(pc, kp->data);
|
254
|
+
|
255
|
+
if (kp->conf->single || rc != NGX_OK) {
|
256
|
+
return rc;
|
257
|
+
}
|
258
|
+
|
259
|
+
/* search cache for suitable connection */
|
260
|
+
|
261
|
+
cache = &kp->conf->cache;
|
262
|
+
|
263
|
+
for (q = ngx_queue_head(cache);
|
264
|
+
q != ngx_queue_sentinel(cache);
|
265
|
+
q = ngx_queue_next(q))
|
266
|
+
{
|
267
|
+
item = ngx_queue_data(q, ngx_http_upstream_keepalive_cache_t, queue);
|
268
|
+
c = item->connection;
|
269
|
+
|
270
|
+
if (ngx_memn2cmp((u_char *) &item->sockaddr, (u_char *) pc->sockaddr,
|
271
|
+
item->socklen, pc->socklen)
|
272
|
+
== 0)
|
273
|
+
{
|
274
|
+
ngx_queue_remove(q);
|
275
|
+
ngx_queue_insert_head(&kp->conf->free, q);
|
276
|
+
|
277
|
+
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
|
278
|
+
"get keepalive peer: using connection %p", c);
|
279
|
+
|
280
|
+
c->idle = 0;
|
281
|
+
c->log = pc->log;
|
282
|
+
c->read->log = pc->log;
|
283
|
+
c->write->log = pc->log;
|
284
|
+
c->pool->log = pc->log;
|
285
|
+
|
286
|
+
pc->connection = c;
|
287
|
+
pc->cached = 1;
|
288
|
+
|
289
|
+
return NGX_DONE;
|
290
|
+
}
|
291
|
+
}
|
292
|
+
|
293
|
+
return NGX_OK;
|
294
|
+
}
|
295
|
+
|
296
|
+
|
297
|
+
static void
|
298
|
+
ngx_http_upstream_free_keepalive_peer(ngx_peer_connection_t *pc, void *data,
|
299
|
+
ngx_uint_t state)
|
300
|
+
{
|
301
|
+
ngx_http_upstream_keepalive_peer_data_t *kp = data;
|
302
|
+
ngx_http_upstream_keepalive_cache_t *item;
|
303
|
+
|
304
|
+
ngx_queue_t *q;
|
305
|
+
ngx_connection_t *c;
|
306
|
+
ngx_http_upstream_t *u;
|
307
|
+
|
308
|
+
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0,
|
309
|
+
"free keepalive peer");
|
310
|
+
|
311
|
+
/* remember failed state - peer.free() may be called more than once */
|
312
|
+
|
313
|
+
if (state & NGX_PEER_FAILED) {
|
314
|
+
kp->failed = 1;
|
315
|
+
}
|
316
|
+
|
317
|
+
/* cache valid connections */
|
318
|
+
|
319
|
+
u = kp->upstream;
|
320
|
+
c = pc->connection;
|
321
|
+
|
322
|
+
if (kp->failed
|
323
|
+
|| c == NULL
|
324
|
+
|| c->read->eof
|
325
|
+
|| c->read->error
|
326
|
+
|| c->read->timedout
|
327
|
+
|| c->write->error
|
328
|
+
|| c->write->timedout)
|
329
|
+
{
|
330
|
+
goto invalid;
|
331
|
+
}
|
332
|
+
|
333
|
+
if (!u->keepalive) {
|
334
|
+
goto invalid;
|
335
|
+
}
|
336
|
+
|
337
|
+
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
338
|
+
goto invalid;
|
339
|
+
}
|
340
|
+
|
341
|
+
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
|
342
|
+
"free keepalive peer: saving connection %p", c);
|
343
|
+
|
344
|
+
if (ngx_queue_empty(&kp->conf->free)) {
|
345
|
+
|
346
|
+
q = ngx_queue_last(&kp->conf->cache);
|
347
|
+
ngx_queue_remove(q);
|
348
|
+
|
349
|
+
item = ngx_queue_data(q, ngx_http_upstream_keepalive_cache_t, queue);
|
350
|
+
|
351
|
+
ngx_http_upstream_keepalive_close(item->connection);
|
352
|
+
|
353
|
+
} else {
|
354
|
+
q = ngx_queue_head(&kp->conf->free);
|
355
|
+
ngx_queue_remove(q);
|
356
|
+
|
357
|
+
item = ngx_queue_data(q, ngx_http_upstream_keepalive_cache_t, queue);
|
358
|
+
}
|
359
|
+
|
360
|
+
item->connection = c;
|
361
|
+
ngx_queue_insert_head(&kp->conf->cache, q);
|
362
|
+
|
363
|
+
pc->connection = NULL;
|
364
|
+
|
365
|
+
if (c->read->timer_set) {
|
366
|
+
ngx_del_timer(c->read);
|
367
|
+
}
|
368
|
+
if (c->write->timer_set) {
|
369
|
+
ngx_del_timer(c->write);
|
370
|
+
}
|
371
|
+
|
372
|
+
c->write->handler = ngx_http_upstream_keepalive_dummy_handler;
|
373
|
+
c->read->handler = ngx_http_upstream_keepalive_close_handler;
|
374
|
+
|
375
|
+
c->data = item;
|
376
|
+
c->idle = 1;
|
377
|
+
c->log = ngx_cycle->log;
|
378
|
+
c->read->log = ngx_cycle->log;
|
379
|
+
c->write->log = ngx_cycle->log;
|
380
|
+
c->pool->log = ngx_cycle->log;
|
381
|
+
|
382
|
+
item->socklen = pc->socklen;
|
383
|
+
ngx_memcpy(&item->sockaddr, pc->sockaddr, pc->socklen);
|
384
|
+
|
385
|
+
if (c->read->ready) {
|
386
|
+
ngx_http_upstream_keepalive_close_handler(c->read);
|
387
|
+
}
|
388
|
+
|
389
|
+
invalid:
|
390
|
+
|
391
|
+
kp->original_free_peer(pc, kp->data, state);
|
392
|
+
}
|
393
|
+
|
394
|
+
|
395
|
+
static void
|
396
|
+
ngx_http_upstream_keepalive_dummy_handler(ngx_event_t *ev)
|
397
|
+
{
|
398
|
+
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0,
|
399
|
+
"keepalive dummy handler");
|
400
|
+
}
|
401
|
+
|
402
|
+
|
403
|
+
static void
|
404
|
+
ngx_http_upstream_keepalive_close_handler(ngx_event_t *ev)
|
405
|
+
{
|
406
|
+
ngx_http_upstream_keepalive_srv_conf_t *conf;
|
407
|
+
ngx_http_upstream_keepalive_cache_t *item;
|
408
|
+
|
409
|
+
int n;
|
410
|
+
char buf[1];
|
411
|
+
ngx_connection_t *c;
|
412
|
+
|
413
|
+
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0,
|
414
|
+
"keepalive close handler");
|
415
|
+
|
416
|
+
c = ev->data;
|
417
|
+
|
418
|
+
if (c->close) {
|
419
|
+
goto close;
|
420
|
+
}
|
421
|
+
|
422
|
+
n = recv(c->fd, buf, 1, MSG_PEEK);
|
423
|
+
|
424
|
+
if (n == -1 && ngx_socket_errno == NGX_EAGAIN) {
|
425
|
+
/* stale event */
|
426
|
+
|
427
|
+
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
428
|
+
goto close;
|
429
|
+
}
|
430
|
+
|
431
|
+
return;
|
432
|
+
}
|
433
|
+
|
434
|
+
close:
|
435
|
+
|
436
|
+
item = c->data;
|
437
|
+
conf = item->conf;
|
438
|
+
|
439
|
+
ngx_http_upstream_keepalive_close(c);
|
440
|
+
|
441
|
+
ngx_queue_remove(&item->queue);
|
442
|
+
ngx_queue_insert_head(&conf->free, &item->queue);
|
443
|
+
}
|
444
|
+
|
445
|
+
|
446
|
+
static void
|
447
|
+
ngx_http_upstream_keepalive_close(ngx_connection_t *c)
|
448
|
+
{
|
449
|
+
|
450
|
+
#if (NGX_HTTP_SSL)
|
451
|
+
|
452
|
+
if (c->ssl) {
|
453
|
+
c->ssl->no_wait_shutdown = 1;
|
454
|
+
c->ssl->no_send_shutdown = 1;
|
455
|
+
|
456
|
+
if (ngx_ssl_shutdown(c) == NGX_AGAIN) {
|
457
|
+
c->ssl->handler = ngx_http_upstream_keepalive_close;
|
458
|
+
return;
|
459
|
+
}
|
460
|
+
}
|
461
|
+
|
462
|
+
#endif
|
463
|
+
|
464
|
+
ngx_destroy_pool(c->pool);
|
465
|
+
ngx_close_connection(c);
|
466
|
+
}
|
467
|
+
|
468
|
+
|
469
|
+
#if (NGX_HTTP_SSL)
|
470
|
+
|
471
|
+
static ngx_int_t
|
472
|
+
ngx_http_upstream_keepalive_set_session(ngx_peer_connection_t *pc, void *data)
|
473
|
+
{
|
474
|
+
ngx_http_upstream_keepalive_peer_data_t *kp = data;
|
475
|
+
|
476
|
+
return kp->original_set_session(pc, kp->data);
|
477
|
+
}
|
478
|
+
|
479
|
+
|
480
|
+
static void
|
481
|
+
ngx_http_upstream_keepalive_save_session(ngx_peer_connection_t *pc, void *data)
|
482
|
+
{
|
483
|
+
ngx_http_upstream_keepalive_peer_data_t *kp = data;
|
484
|
+
|
485
|
+
kp->original_save_session(pc, kp->data);
|
486
|
+
return;
|
487
|
+
}
|
488
|
+
|
489
|
+
#endif
|
490
|
+
|
491
|
+
|
492
|
+
static void *
|
493
|
+
ngx_http_upstream_keepalive_create_conf(ngx_conf_t *cf)
|
494
|
+
{
|
495
|
+
ngx_http_upstream_keepalive_srv_conf_t *conf;
|
496
|
+
|
497
|
+
conf = ngx_pcalloc(cf->pool,
|
498
|
+
sizeof(ngx_http_upstream_keepalive_srv_conf_t));
|
499
|
+
if (conf == NULL) {
|
500
|
+
return NULL;
|
501
|
+
}
|
502
|
+
|
503
|
+
/*
|
504
|
+
* set by ngx_pcalloc():
|
505
|
+
*
|
506
|
+
* conf->original_init_upstream = NULL;
|
507
|
+
* conf->original_init_peer = NULL;
|
508
|
+
*/
|
509
|
+
|
510
|
+
conf->max_cached = 1;
|
511
|
+
|
512
|
+
return conf;
|
513
|
+
}
|
514
|
+
|
515
|
+
|
516
|
+
static char *
|
517
|
+
ngx_http_upstream_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
518
|
+
{
|
519
|
+
ngx_http_upstream_srv_conf_t *uscf;
|
520
|
+
ngx_http_upstream_keepalive_srv_conf_t *kcf;
|
521
|
+
|
522
|
+
ngx_int_t n;
|
523
|
+
ngx_str_t *value;
|
524
|
+
ngx_uint_t i;
|
525
|
+
|
526
|
+
uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module);
|
527
|
+
|
528
|
+
kcf = ngx_http_conf_upstream_srv_conf(uscf,
|
529
|
+
ngx_http_upstream_keepalive_module);
|
530
|
+
|
531
|
+
kcf->original_init_upstream = uscf->peer.init_upstream
|
532
|
+
? uscf->peer.init_upstream
|
533
|
+
: ngx_http_upstream_init_round_robin;
|
534
|
+
|
535
|
+
uscf->peer.init_upstream = ngx_http_upstream_init_keepalive;
|
536
|
+
|
537
|
+
/* read options */
|
538
|
+
|
539
|
+
value = cf->args->elts;
|
540
|
+
|
541
|
+
n = ngx_atoi(value[1].data, value[1].len);
|
542
|
+
|
543
|
+
if (n == NGX_ERROR || n == 0) {
|
544
|
+
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
545
|
+
"invalid value \"%V\" in \"%V\" directive",
|
546
|
+
&value[1], &cmd->name);
|
547
|
+
return NGX_CONF_ERROR;
|
548
|
+
}
|
549
|
+
|
550
|
+
kcf->max_cached = n;
|
551
|
+
|
552
|
+
for (i = 2; i < cf->args->nelts; i++) {
|
553
|
+
|
554
|
+
if (ngx_strcmp(value[i].data, "single") == 0) {
|
555
|
+
kcf->single = 1;
|
556
|
+
continue;
|
557
|
+
}
|
558
|
+
|
559
|
+
goto invalid;
|
560
|
+
}
|
561
|
+
|
562
|
+
return NGX_CONF_OK;
|
563
|
+
|
564
|
+
invalid:
|
565
|
+
|
566
|
+
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
567
|
+
"invalid parameter \"%V\"", &value[i]);
|
568
|
+
|
569
|
+
return NGX_CONF_ERROR;
|
570
|
+
}
|