Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.15.11 ]​[ nginx-1.14.2 ]​

0001 
0002 /*
0003  * Copyright (C) Unbit S.a.s. 2009-2010
0004  * Copyright (C) 2008 Manlio Perillo (manlio.perillo@gmail.com)
0005  * Copyright (C) Igor Sysoev
0006  * Copyright (C) Nginx, Inc.
0007  */
0008 
0009 
0010 #include <ngx_config.h>
0011 #include <ngx_core.h>
0012 #include <ngx_http.h>
0013 
0014 
0015 typedef struct {
0016     ngx_array_t                caches;  /* ngx_http_file_cache_t * */
0017 } ngx_http_uwsgi_main_conf_t;
0018 
0019 
0020 typedef struct {
0021     ngx_array_t               *flushes;
0022     ngx_array_t               *lengths;
0023     ngx_array_t               *values;
0024     ngx_uint_t                 number;
0025     ngx_hash_t                 hash;
0026 } ngx_http_uwsgi_params_t;
0027 
0028 
0029 typedef struct {
0030     ngx_http_upstream_conf_t   upstream;
0031 
0032     ngx_http_uwsgi_params_t    params;
0033 #if (NGX_HTTP_CACHE)
0034     ngx_http_uwsgi_params_t    params_cache;
0035 #endif
0036     ngx_array_t               *params_source;
0037 
0038     ngx_array_t               *uwsgi_lengths;
0039     ngx_array_t               *uwsgi_values;
0040 
0041 #if (NGX_HTTP_CACHE)
0042     ngx_http_complex_value_t   cache_key;
0043 #endif
0044 
0045     ngx_str_t                  uwsgi_string;
0046 
0047     ngx_uint_t                 modifier1;
0048     ngx_uint_t                 modifier2;
0049 
0050 #if (NGX_HTTP_SSL)
0051     ngx_uint_t                 ssl;
0052     ngx_uint_t                 ssl_protocols;
0053     ngx_str_t                  ssl_ciphers;
0054     ngx_uint_t                 ssl_verify_depth;
0055     ngx_str_t                  ssl_trusted_certificate;
0056     ngx_str_t                  ssl_crl;
0057     ngx_str_t                  ssl_certificate;
0058     ngx_str_t                  ssl_certificate_key;
0059     ngx_array_t               *ssl_passwords;
0060 #endif
0061 } ngx_http_uwsgi_loc_conf_t;
0062 
0063 
0064 static ngx_int_t ngx_http_uwsgi_eval(ngx_http_request_t *r,
0065     ngx_http_uwsgi_loc_conf_t *uwcf);
0066 static ngx_int_t ngx_http_uwsgi_create_request(ngx_http_request_t *r);
0067 static ngx_int_t ngx_http_uwsgi_reinit_request(ngx_http_request_t *r);
0068 static ngx_int_t ngx_http_uwsgi_process_status_line(ngx_http_request_t *r);
0069 static ngx_int_t ngx_http_uwsgi_process_header(ngx_http_request_t *r);
0070 static void ngx_http_uwsgi_abort_request(ngx_http_request_t *r);
0071 static void ngx_http_uwsgi_finalize_request(ngx_http_request_t *r,
0072     ngx_int_t rc);
0073 
0074 static void *ngx_http_uwsgi_create_main_conf(ngx_conf_t *cf);
0075 static void *ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf);
0076 static char *ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent,
0077     void *child);
0078 static ngx_int_t ngx_http_uwsgi_init_params(ngx_conf_t *cf,
0079     ngx_http_uwsgi_loc_conf_t *conf, ngx_http_uwsgi_params_t *params,
0080     ngx_keyval_t *default_params);
0081 
0082 static char *ngx_http_uwsgi_pass(ngx_conf_t *cf, ngx_command_t *cmd,
0083     void *conf);
0084 static char *ngx_http_uwsgi_store(ngx_conf_t *cf, ngx_command_t *cmd,
0085     void *conf);
0086 
0087 #if (NGX_HTTP_CACHE)
0088 static ngx_int_t ngx_http_uwsgi_create_key(ngx_http_request_t *r);
0089 static char *ngx_http_uwsgi_cache(ngx_conf_t *cf, ngx_command_t *cmd,
0090     void *conf);
0091 static char *ngx_http_uwsgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd,
0092     void *conf);
0093 #endif
0094 
0095 #if (NGX_HTTP_SSL)
0096 static char *ngx_http_uwsgi_ssl_password_file(ngx_conf_t *cf,
0097     ngx_command_t *cmd, void *conf);
0098 static ngx_int_t ngx_http_uwsgi_set_ssl(ngx_conf_t *cf,
0099     ngx_http_uwsgi_loc_conf_t *uwcf);
0100 #endif
0101 
0102 
0103 static ngx_conf_num_bounds_t  ngx_http_uwsgi_modifier_bounds = {
0104     ngx_conf_check_num_bounds, 0, 255
0105 };
0106 
0107 
0108 static ngx_conf_bitmask_t ngx_http_uwsgi_next_upstream_masks[] = {
0109     { ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR },
0110     { ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT },
0111     { ngx_string("invalid_header"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER },
0112     { ngx_string("non_idempotent"), NGX_HTTP_UPSTREAM_FT_NON_IDEMPOTENT },
0113     { ngx_string("http_500"), NGX_HTTP_UPSTREAM_FT_HTTP_500 },
0114     { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
0115     { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 },
0116     { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
0117     { ngx_string("http_429"), NGX_HTTP_UPSTREAM_FT_HTTP_429 },
0118     { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
0119     { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
0120     { ngx_null_string, 0 }
0121 };
0122 
0123 
0124 #if (NGX_HTTP_SSL)
0125 
0126 static ngx_conf_bitmask_t  ngx_http_uwsgi_ssl_protocols[] = {
0127     { ngx_string("SSLv2"), NGX_SSL_SSLv2 },
0128     { ngx_string("SSLv3"), NGX_SSL_SSLv3 },
0129     { ngx_string("TLSv1"), NGX_SSL_TLSv1 },
0130     { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
0131     { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
0132     { ngx_string("TLSv1.3"), NGX_SSL_TLSv1_3 },
0133     { ngx_null_string, 0 }
0134 };
0135 
0136 #endif
0137 
0138 
0139 ngx_module_t  ngx_http_uwsgi_module;
0140 
0141 
0142 static ngx_command_t ngx_http_uwsgi_commands[] = {
0143 
0144     { ngx_string("uwsgi_pass"),
0145       NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
0146       ngx_http_uwsgi_pass,
0147       NGX_HTTP_LOC_CONF_OFFSET,
0148       0,
0149       NULL },
0150 
0151     { ngx_string("uwsgi_modifier1"),
0152       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0153       ngx_conf_set_num_slot,
0154       NGX_HTTP_LOC_CONF_OFFSET,
0155       offsetof(ngx_http_uwsgi_loc_conf_t, modifier1),
0156       &ngx_http_uwsgi_modifier_bounds },
0157 
0158     { ngx_string("uwsgi_modifier2"),
0159       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0160       ngx_conf_set_num_slot,
0161       NGX_HTTP_LOC_CONF_OFFSET,
0162       offsetof(ngx_http_uwsgi_loc_conf_t, modifier2),
0163       &ngx_http_uwsgi_modifier_bounds },
0164 
0165     { ngx_string("uwsgi_store"),
0166       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0167       ngx_http_uwsgi_store,
0168       NGX_HTTP_LOC_CONF_OFFSET,
0169       0,
0170       NULL },
0171 
0172     { ngx_string("uwsgi_store_access"),
0173       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
0174       ngx_conf_set_access_slot,
0175       NGX_HTTP_LOC_CONF_OFFSET,
0176       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.store_access),
0177       NULL },
0178 
0179     { ngx_string("uwsgi_buffering"),
0180       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
0181       ngx_conf_set_flag_slot,
0182       NGX_HTTP_LOC_CONF_OFFSET,
0183       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.buffering),
0184       NULL },
0185 
0186     { ngx_string("uwsgi_request_buffering"),
0187       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
0188       ngx_conf_set_flag_slot,
0189       NGX_HTTP_LOC_CONF_OFFSET,
0190       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.request_buffering),
0191       NULL },
0192 
0193     { ngx_string("uwsgi_ignore_client_abort"),
0194       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
0195       ngx_conf_set_flag_slot,
0196       NGX_HTTP_LOC_CONF_OFFSET,
0197       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.ignore_client_abort),
0198       NULL },
0199 
0200     { ngx_string("uwsgi_bind"),
0201       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
0202       ngx_http_upstream_bind_set_slot,
0203       NGX_HTTP_LOC_CONF_OFFSET,
0204       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.local),
0205       NULL },
0206 
0207     { ngx_string("uwsgi_socket_keepalive"),
0208       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
0209       ngx_conf_set_flag_slot,
0210       NGX_HTTP_LOC_CONF_OFFSET,
0211       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.socket_keepalive),
0212       NULL },
0213 
0214     { ngx_string("uwsgi_connect_timeout"),
0215       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0216       ngx_conf_set_msec_slot,
0217       NGX_HTTP_LOC_CONF_OFFSET,
0218       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.connect_timeout),
0219       NULL },
0220 
0221     { ngx_string("uwsgi_send_timeout"),
0222       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0223       ngx_conf_set_msec_slot,
0224       NGX_HTTP_LOC_CONF_OFFSET,
0225       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.send_timeout),
0226       NULL },
0227 
0228     { ngx_string("uwsgi_buffer_size"),
0229       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0230       ngx_conf_set_size_slot,
0231       NGX_HTTP_LOC_CONF_OFFSET,
0232       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.buffer_size),
0233       NULL },
0234 
0235     { ngx_string("uwsgi_pass_request_headers"),
0236       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
0237       ngx_conf_set_flag_slot,
0238       NGX_HTTP_LOC_CONF_OFFSET,
0239       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.pass_request_headers),
0240       NULL },
0241 
0242     { ngx_string("uwsgi_pass_request_body"),
0243       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
0244       ngx_conf_set_flag_slot,
0245       NGX_HTTP_LOC_CONF_OFFSET,
0246       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.pass_request_body),
0247       NULL },
0248 
0249     { ngx_string("uwsgi_intercept_errors"),
0250       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
0251       ngx_conf_set_flag_slot,
0252       NGX_HTTP_LOC_CONF_OFFSET,
0253       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.intercept_errors),
0254       NULL },
0255 
0256     { ngx_string("uwsgi_read_timeout"),
0257       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0258       ngx_conf_set_msec_slot,
0259       NGX_HTTP_LOC_CONF_OFFSET,
0260       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.read_timeout),
0261       NULL },
0262 
0263     { ngx_string("uwsgi_buffers"),
0264       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
0265       ngx_conf_set_bufs_slot,
0266       NGX_HTTP_LOC_CONF_OFFSET,
0267       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.bufs),
0268       NULL },
0269 
0270     { ngx_string("uwsgi_busy_buffers_size"),
0271       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0272       ngx_conf_set_size_slot,
0273       NGX_HTTP_LOC_CONF_OFFSET,
0274       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.busy_buffers_size_conf),
0275       NULL },
0276 
0277     { ngx_string("uwsgi_force_ranges"),
0278       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
0279       ngx_conf_set_flag_slot,
0280       NGX_HTTP_LOC_CONF_OFFSET,
0281       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.force_ranges),
0282       NULL },
0283 
0284     { ngx_string("uwsgi_limit_rate"),
0285       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0286       ngx_conf_set_size_slot,
0287       NGX_HTTP_LOC_CONF_OFFSET,
0288       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.limit_rate),
0289       NULL },
0290 
0291 #if (NGX_HTTP_CACHE)
0292 
0293     { ngx_string("uwsgi_cache"),
0294       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0295       ngx_http_uwsgi_cache,
0296       NGX_HTTP_LOC_CONF_OFFSET,
0297       0,
0298       NULL },
0299 
0300     { ngx_string("uwsgi_cache_key"),
0301       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0302       ngx_http_uwsgi_cache_key,
0303       NGX_HTTP_LOC_CONF_OFFSET,
0304       0,
0305       NULL },
0306 
0307     { ngx_string("uwsgi_cache_path"),
0308       NGX_HTTP_MAIN_CONF|NGX_CONF_2MORE,
0309       ngx_http_file_cache_set_slot,
0310       NGX_HTTP_MAIN_CONF_OFFSET,
0311       offsetof(ngx_http_uwsgi_main_conf_t, caches),
0312       &ngx_http_uwsgi_module },
0313 
0314     { ngx_string("uwsgi_cache_bypass"),
0315       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
0316       ngx_http_set_predicate_slot,
0317       NGX_HTTP_LOC_CONF_OFFSET,
0318       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_bypass),
0319       NULL },
0320 
0321     { ngx_string("uwsgi_no_cache"),
0322       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
0323       ngx_http_set_predicate_slot,
0324       NGX_HTTP_LOC_CONF_OFFSET,
0325       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.no_cache),
0326       NULL },
0327 
0328     { ngx_string("uwsgi_cache_valid"),
0329       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
0330       ngx_http_file_cache_valid_set_slot,
0331       NGX_HTTP_LOC_CONF_OFFSET,
0332       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_valid),
0333       NULL },
0334 
0335     { ngx_string("uwsgi_cache_min_uses"),
0336       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0337       ngx_conf_set_num_slot,
0338       NGX_HTTP_LOC_CONF_OFFSET,
0339       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_min_uses),
0340       NULL },
0341 
0342     { ngx_string("uwsgi_cache_max_range_offset"),
0343       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0344       ngx_conf_set_off_slot,
0345       NGX_HTTP_LOC_CONF_OFFSET,
0346       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_max_range_offset),
0347       NULL },
0348 
0349     { ngx_string("uwsgi_cache_use_stale"),
0350       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
0351       ngx_conf_set_bitmask_slot,
0352       NGX_HTTP_LOC_CONF_OFFSET,
0353       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_use_stale),
0354       &ngx_http_uwsgi_next_upstream_masks },
0355 
0356     { ngx_string("uwsgi_cache_methods"),
0357       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
0358       ngx_conf_set_bitmask_slot,
0359       NGX_HTTP_LOC_CONF_OFFSET,
0360       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_methods),
0361       &ngx_http_upstream_cache_method_mask },
0362 
0363     { ngx_string("uwsgi_cache_lock"),
0364       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
0365       ngx_conf_set_flag_slot,
0366       NGX_HTTP_LOC_CONF_OFFSET,
0367       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_lock),
0368       NULL },
0369 
0370     { ngx_string("uwsgi_cache_lock_timeout"),
0371       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0372       ngx_conf_set_msec_slot,
0373       NGX_HTTP_LOC_CONF_OFFSET,
0374       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_lock_timeout),
0375       NULL },
0376 
0377     { ngx_string("uwsgi_cache_lock_age"),
0378       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0379       ngx_conf_set_msec_slot,
0380       NGX_HTTP_LOC_CONF_OFFSET,
0381       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_lock_age),
0382       NULL },
0383 
0384     { ngx_string("uwsgi_cache_revalidate"),
0385       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
0386       ngx_conf_set_flag_slot,
0387       NGX_HTTP_LOC_CONF_OFFSET,
0388       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_revalidate),
0389       NULL },
0390 
0391     { ngx_string("uwsgi_cache_background_update"),
0392       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0393       ngx_conf_set_flag_slot,
0394       NGX_HTTP_LOC_CONF_OFFSET,
0395       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_background_update),
0396       NULL },
0397 
0398 #endif
0399 
0400     { ngx_string("uwsgi_temp_path"),
0401       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
0402       ngx_conf_set_path_slot,
0403       NGX_HTTP_LOC_CONF_OFFSET,
0404       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.temp_path),
0405       NULL },
0406 
0407     { ngx_string("uwsgi_max_temp_file_size"),
0408       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0409       ngx_conf_set_size_slot,
0410       NGX_HTTP_LOC_CONF_OFFSET,
0411       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.max_temp_file_size_conf),
0412       NULL },
0413 
0414     { ngx_string("uwsgi_temp_file_write_size"),
0415       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0416       ngx_conf_set_size_slot,
0417       NGX_HTTP_LOC_CONF_OFFSET,
0418       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.temp_file_write_size_conf),
0419       NULL },
0420 
0421     { ngx_string("uwsgi_next_upstream"),
0422       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
0423       ngx_conf_set_bitmask_slot,
0424       NGX_HTTP_LOC_CONF_OFFSET,
0425       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.next_upstream),
0426       &ngx_http_uwsgi_next_upstream_masks },
0427 
0428     { ngx_string("uwsgi_next_upstream_tries"),
0429       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0430       ngx_conf_set_num_slot,
0431       NGX_HTTP_LOC_CONF_OFFSET,
0432       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.next_upstream_tries),
0433       NULL },
0434 
0435     { ngx_string("uwsgi_next_upstream_timeout"),
0436       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0437       ngx_conf_set_msec_slot,
0438       NGX_HTTP_LOC_CONF_OFFSET,
0439       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.next_upstream_timeout),
0440       NULL },
0441 
0442     { ngx_string("uwsgi_param"),
0443       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE23,
0444       ngx_http_upstream_param_set_slot,
0445       NGX_HTTP_LOC_CONF_OFFSET,
0446       offsetof(ngx_http_uwsgi_loc_conf_t, params_source),
0447       NULL },
0448 
0449     { ngx_string("uwsgi_string"),
0450       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0451       ngx_conf_set_str_slot,
0452       NGX_HTTP_LOC_CONF_OFFSET,
0453       offsetof(ngx_http_uwsgi_loc_conf_t, uwsgi_string),
0454       NULL },
0455 
0456     { ngx_string("uwsgi_pass_header"),
0457       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0458       ngx_conf_set_str_array_slot,
0459       NGX_HTTP_LOC_CONF_OFFSET,
0460       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.pass_headers),
0461       NULL },
0462 
0463     { ngx_string("uwsgi_hide_header"),
0464       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0465       ngx_conf_set_str_array_slot,
0466       NGX_HTTP_LOC_CONF_OFFSET,
0467       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.hide_headers),
0468       NULL },
0469 
0470     { ngx_string("uwsgi_ignore_headers"),
0471       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
0472       ngx_conf_set_bitmask_slot,
0473       NGX_HTTP_LOC_CONF_OFFSET,
0474       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.ignore_headers),
0475       &ngx_http_upstream_ignore_headers_masks },
0476 
0477 #if (NGX_HTTP_SSL)
0478 
0479     { ngx_string("uwsgi_ssl_session_reuse"),
0480       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
0481       ngx_conf_set_flag_slot,
0482       NGX_HTTP_LOC_CONF_OFFSET,
0483       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.ssl_session_reuse),
0484       NULL },
0485 
0486     { ngx_string("uwsgi_ssl_protocols"),
0487       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
0488       ngx_conf_set_bitmask_slot,
0489       NGX_HTTP_LOC_CONF_OFFSET,
0490       offsetof(ngx_http_uwsgi_loc_conf_t, ssl_protocols),
0491       &ngx_http_uwsgi_ssl_protocols },
0492 
0493     { ngx_string("uwsgi_ssl_ciphers"),
0494       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0495       ngx_conf_set_str_slot,
0496       NGX_HTTP_LOC_CONF_OFFSET,
0497       offsetof(ngx_http_uwsgi_loc_conf_t, ssl_ciphers),
0498       NULL },
0499 
0500     { ngx_string("uwsgi_ssl_name"),
0501       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0502       ngx_http_set_complex_value_slot,
0503       NGX_HTTP_LOC_CONF_OFFSET,
0504       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.ssl_name),
0505       NULL },
0506 
0507     { ngx_string("uwsgi_ssl_server_name"),
0508       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
0509       ngx_conf_set_flag_slot,
0510       NGX_HTTP_LOC_CONF_OFFSET,
0511       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.ssl_server_name),
0512       NULL },
0513 
0514     { ngx_string("uwsgi_ssl_verify"),
0515       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
0516       ngx_conf_set_flag_slot,
0517       NGX_HTTP_LOC_CONF_OFFSET,
0518       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.ssl_verify),
0519       NULL },
0520 
0521     { ngx_string("uwsgi_ssl_verify_depth"),
0522       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0523       ngx_conf_set_num_slot,
0524       NGX_HTTP_LOC_CONF_OFFSET,
0525       offsetof(ngx_http_uwsgi_loc_conf_t, ssl_verify_depth),
0526       NULL },
0527 
0528     { ngx_string("uwsgi_ssl_trusted_certificate"),
0529       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0530       ngx_conf_set_str_slot,
0531       NGX_HTTP_LOC_CONF_OFFSET,
0532       offsetof(ngx_http_uwsgi_loc_conf_t, ssl_trusted_certificate),
0533       NULL },
0534 
0535     { ngx_string("uwsgi_ssl_crl"),
0536       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0537       ngx_conf_set_str_slot,
0538       NGX_HTTP_LOC_CONF_OFFSET,
0539       offsetof(ngx_http_uwsgi_loc_conf_t, ssl_crl),
0540       NULL },
0541 
0542     { ngx_string("uwsgi_ssl_certificate"),
0543       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0544       ngx_conf_set_str_slot,
0545       NGX_HTTP_LOC_CONF_OFFSET,
0546       offsetof(ngx_http_uwsgi_loc_conf_t, ssl_certificate),
0547       NULL },
0548 
0549     { ngx_string("uwsgi_ssl_certificate_key"),
0550       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0551       ngx_conf_set_str_slot,
0552       NGX_HTTP_LOC_CONF_OFFSET,
0553       offsetof(ngx_http_uwsgi_loc_conf_t, ssl_certificate_key),
0554       NULL },
0555 
0556     { ngx_string("uwsgi_ssl_password_file"),
0557       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
0558       ngx_http_uwsgi_ssl_password_file,
0559       NGX_HTTP_LOC_CONF_OFFSET,
0560       0,
0561       NULL },
0562 
0563 #endif
0564 
0565       ngx_null_command
0566 };
0567 
0568 
0569 static ngx_http_module_t ngx_http_uwsgi_module_ctx = {
0570     NULL,                                  /* preconfiguration */
0571     NULL,                                  /* postconfiguration */
0572 
0573     ngx_http_uwsgi_create_main_conf,       /* create main configuration */
0574     NULL,                                  /* init main configuration */
0575 
0576     NULL,                                  /* create server configuration */
0577     NULL,                                  /* merge server configuration */
0578 
0579     ngx_http_uwsgi_create_loc_conf,        /* create location configuration */
0580     ngx_http_uwsgi_merge_loc_conf          /* merge location configuration */
0581 };
0582 
0583 
0584 ngx_module_t ngx_http_uwsgi_module = {
0585     NGX_MODULE_V1,
0586     &ngx_http_uwsgi_module_ctx,            /* module context */
0587     ngx_http_uwsgi_commands,               /* module directives */
0588     NGX_HTTP_MODULE,                       /* module type */
0589     NULL,                                  /* init master */
0590     NULL,                                  /* init module */
0591     NULL,                                  /* init process */
0592     NULL,                                  /* init thread */
0593     NULL,                                  /* exit thread */
0594     NULL,                                  /* exit process */
0595     NULL,                                  /* exit master */
0596     NGX_MODULE_V1_PADDING
0597 };
0598 
0599 
0600 static ngx_str_t ngx_http_uwsgi_hide_headers[] = {
0601     ngx_string("X-Accel-Expires"),
0602     ngx_string("X-Accel-Redirect"),
0603     ngx_string("X-Accel-Limit-Rate"),
0604     ngx_string("X-Accel-Buffering"),
0605     ngx_string("X-Accel-Charset"),
0606     ngx_null_string
0607 };
0608 
0609 
0610 #if (NGX_HTTP_CACHE)
0611 
0612 static ngx_keyval_t  ngx_http_uwsgi_cache_headers[] = {
0613     { ngx_string("HTTP_IF_MODIFIED_SINCE"),
0614       ngx_string("$upstream_cache_last_modified") },
0615     { ngx_string("HTTP_IF_UNMODIFIED_SINCE"), ngx_string("") },
0616     { ngx_string("HTTP_IF_NONE_MATCH"), ngx_string("$upstream_cache_etag") },
0617     { ngx_string("HTTP_IF_MATCH"), ngx_string("") },
0618     { ngx_string("HTTP_RANGE"), ngx_string("") },
0619     { ngx_string("HTTP_IF_RANGE"), ngx_string("") },
0620     { ngx_null_string, ngx_null_string }
0621 };
0622 
0623 #endif
0624 
0625 
0626 static ngx_path_init_t ngx_http_uwsgi_temp_path = {
0627     ngx_string(NGX_HTTP_UWSGI_TEMP_PATH), { 1, 2, 0 }
0628 };
0629 
0630 
0631 static ngx_int_t
0632 ngx_http_uwsgi_handler(ngx_http_request_t *r)
0633 {
0634     ngx_int_t                    rc;
0635     ngx_http_status_t           *status;
0636     ngx_http_upstream_t         *u;
0637     ngx_http_uwsgi_loc_conf_t   *uwcf;
0638 #if (NGX_HTTP_CACHE)
0639     ngx_http_uwsgi_main_conf_t  *uwmcf;
0640 #endif
0641 
0642     if (ngx_http_upstream_create(r) != NGX_OK) {
0643         return NGX_HTTP_INTERNAL_SERVER_ERROR;
0644     }
0645 
0646     status = ngx_pcalloc(r->pool, sizeof(ngx_http_status_t));
0647     if (status == NULL) {
0648         return NGX_HTTP_INTERNAL_SERVER_ERROR;
0649     }
0650 
0651     ngx_http_set_ctx(r, status, ngx_http_uwsgi_module);
0652 
0653     uwcf = ngx_http_get_module_loc_conf(r, ngx_http_uwsgi_module);
0654 
0655     u = r->upstream;
0656 
0657     if (uwcf->uwsgi_lengths == NULL) {
0658 
0659 #if (NGX_HTTP_SSL)
0660         u->ssl = (uwcf->upstream.ssl != NULL);
0661 
0662         if (u->ssl) {
0663             ngx_str_set(&u->schema, "suwsgi://");
0664 
0665         } else {
0666             ngx_str_set(&u->schema, "uwsgi://");
0667         }
0668 #else
0669         ngx_str_set(&u->schema, "uwsgi://");
0670 #endif
0671 
0672     } else {
0673         if (ngx_http_uwsgi_eval(r, uwcf) != NGX_OK) {
0674             return NGX_HTTP_INTERNAL_SERVER_ERROR;
0675         }
0676     }
0677 
0678     u->output.tag = (ngx_buf_tag_t) &ngx_http_uwsgi_module;
0679 
0680     u->conf = &uwcf->upstream;
0681 
0682 #if (NGX_HTTP_CACHE)
0683     uwmcf = ngx_http_get_module_main_conf(r, ngx_http_uwsgi_module);
0684 
0685     u->caches = &uwmcf->caches;
0686     u->create_key = ngx_http_uwsgi_create_key;
0687 #endif
0688 
0689     u->create_request = ngx_http_uwsgi_create_request;
0690     u->reinit_request = ngx_http_uwsgi_reinit_request;
0691     u->process_header = ngx_http_uwsgi_process_status_line;
0692     u->abort_request = ngx_http_uwsgi_abort_request;
0693     u->finalize_request = ngx_http_uwsgi_finalize_request;
0694     r->state = 0;
0695 
0696     u->buffering = uwcf->upstream.buffering;
0697 
0698     u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t));
0699     if (u->pipe == NULL) {
0700         return NGX_HTTP_INTERNAL_SERVER_ERROR;
0701     }
0702 
0703     u->pipe->input_filter = ngx_event_pipe_copy_input_filter;
0704     u->pipe->input_ctx = r;
0705 
0706     if (!uwcf->upstream.request_buffering
0707         && uwcf->upstream.pass_request_body
0708         && !r->headers_in.chunked)
0709     {
0710         r->request_body_no_buffering = 1;
0711     }
0712 
0713     rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init);
0714 
0715     if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
0716         return rc;
0717     }
0718 
0719     return NGX_DONE;
0720 }
0721 
0722 
0723 static ngx_int_t
0724 ngx_http_uwsgi_eval(ngx_http_request_t *r, ngx_http_uwsgi_loc_conf_t * uwcf)
0725 {
0726     size_t                add;
0727     ngx_url_t             url;
0728     ngx_http_upstream_t  *u;
0729 
0730     ngx_memzero(&url, sizeof(ngx_url_t));
0731 
0732     if (ngx_http_script_run(r, &url.url, uwcf->uwsgi_lengths->elts, 0,
0733                             uwcf->uwsgi_values->elts)
0734         == NULL)
0735     {
0736         return NGX_ERROR;
0737     }
0738 
0739     if (url.url.len > 8
0740         && ngx_strncasecmp(url.url.data, (u_char *) "uwsgi://", 8) == 0)
0741     {
0742         add = 8;
0743 
0744     } else if (url.url.len > 9
0745                && ngx_strncasecmp(url.url.data, (u_char *) "suwsgi://", 9) == 0)
0746     {
0747 
0748 #if (NGX_HTTP_SSL)
0749         add = 9;
0750         r->upstream->ssl = 1;
0751 #else
0752         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
0753                       "suwsgi protocol requires SSL support");
0754         return NGX_ERROR;
0755 #endif
0756 
0757     } else {
0758         add = 0;
0759     }
0760 
0761     u = r->upstream;
0762 
0763     if (add) {
0764         u->schema.len = add;
0765         u->schema.data = url.url.data;
0766 
0767         url.url.data += add;
0768         url.url.len -= add;
0769 
0770     } else {
0771         ngx_str_set(&u->schema, "uwsgi://");
0772     }
0773 
0774     url.no_resolve = 1;
0775 
0776     if (ngx_parse_url(r->pool, &url) != NGX_OK) {
0777         if (url.err) {
0778             ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
0779                           "%s in upstream \"%V\"", url.err, &url.url);
0780         }
0781 
0782         return NGX_ERROR;
0783     }
0784 
0785     u->resolved = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t));
0786     if (u->resolved == NULL) {
0787         return NGX_ERROR;
0788     }
0789 
0790     if (url.addrs) {
0791         u->resolved->sockaddr = url.addrs[0].sockaddr;
0792         u->resolved->socklen = url.addrs[0].socklen;
0793         u->resolved->name = url.addrs[0].name;
0794         u->resolved->naddrs = 1;
0795     }
0796 
0797     u->resolved->host = url.host;
0798     u->resolved->port = url.port;
0799     u->resolved->no_port = url.no_port;
0800 
0801     return NGX_OK;
0802 }
0803 
0804 
0805 #if (NGX_HTTP_CACHE)
0806 
0807 static ngx_int_t
0808 ngx_http_uwsgi_create_key(ngx_http_request_t *r)
0809 {
0810     ngx_str_t                  *key;
0811     ngx_http_uwsgi_loc_conf_t  *uwcf;
0812 
0813     key = ngx_array_push(&r->cache->keys);
0814     if (key == NULL) {
0815         return NGX_ERROR;
0816     }
0817 
0818     uwcf = ngx_http_get_module_loc_conf(r, ngx_http_uwsgi_module);
0819 
0820     if (ngx_http_complex_value(r, &uwcf->cache_key, key) != NGX_OK) {
0821         return NGX_ERROR;
0822     }
0823 
0824     return NGX_OK;
0825 }
0826 
0827 #endif
0828 
0829 
0830 static ngx_int_t
0831 ngx_http_uwsgi_create_request(ngx_http_request_t *r)
0832 {
0833     u_char                        ch, *lowcase_key;
0834     size_t                        key_len, val_len, len, allocated;
0835     ngx_uint_t                    i, n, hash, skip_empty, header_params;
0836     ngx_buf_t                    *b;
0837     ngx_chain_t                  *cl, *body;
0838     ngx_list_part_t              *part;
0839     ngx_table_elt_t              *header, **ignored;
0840     ngx_http_uwsgi_params_t      *params;
0841     ngx_http_script_code_pt       code;
0842     ngx_http_script_engine_t      e, le;
0843     ngx_http_uwsgi_loc_conf_t    *uwcf;
0844     ngx_http_script_len_code_pt   lcode;
0845 
0846     len = 0;
0847     header_params = 0;
0848     ignored = NULL;
0849 
0850     uwcf = ngx_http_get_module_loc_conf(r, ngx_http_uwsgi_module);
0851 
0852 #if (NGX_HTTP_CACHE)
0853     params = r->upstream->cacheable ? &uwcf->params_cache : &uwcf->params;
0854 #else
0855     params = &uwcf->params;
0856 #endif
0857 
0858     if (params->lengths) {
0859         ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
0860 
0861         ngx_http_script_flush_no_cacheable_variables(r, params->flushes);
0862         le.flushed = 1;
0863 
0864         le.ip = params->lengths->elts;
0865         le.request = r;
0866 
0867         while (*(uintptr_t *) le.ip) {
0868 
0869             lcode = *(ngx_http_script_len_code_pt *) le.ip;
0870             key_len = lcode(&le);
0871 
0872             lcode = *(ngx_http_script_len_code_pt *) le.ip;
0873             skip_empty = lcode(&le);
0874 
0875             for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) {
0876                 lcode = *(ngx_http_script_len_code_pt *) le.ip;
0877             }
0878             le.ip += sizeof(uintptr_t);
0879 
0880             if (skip_empty && val_len == 0) {
0881                 continue;
0882             }
0883 
0884             len += 2 + key_len + 2 + val_len;
0885         }
0886     }
0887 
0888     if (uwcf->upstream.pass_request_headers) {
0889 
0890         allocated = 0;
0891         lowcase_key = NULL;
0892 
0893         if (params->number) {
0894             n = 0;
0895             part = &r->headers_in.headers.part;
0896 
0897             while (part) {
0898                 n += part->nelts;
0899                 part = part->next;
0900             }
0901 
0902             ignored = ngx_palloc(r->pool, n * sizeof(void *));
0903             if (ignored == NULL) {
0904                 return NGX_ERROR;
0905             }
0906         }
0907 
0908         part = &r->headers_in.headers.part;
0909         header = part->elts;
0910 
0911         for (i = 0; /* void */ ; i++) {
0912 
0913             if (i >= part->nelts) {
0914                 if (part->next == NULL) {
0915                     break;
0916                 }
0917 
0918                 part = part->next;
0919                 header = part->elts;
0920                 i = 0;
0921             }
0922 
0923             if (params->number) {
0924                 if (allocated < header[i].key.len) {
0925                     allocated = header[i].key.len + 16;
0926                     lowcase_key = ngx_pnalloc(r->pool, allocated);
0927                     if (lowcase_key == NULL) {
0928                         return NGX_ERROR;
0929                     }
0930                 }
0931 
0932                 hash = 0;
0933 
0934                 for (n = 0; n < header[i].key.len; n++) {
0935                     ch = header[i].key.data[n];
0936 
0937                     if (ch >= 'A' && ch <= 'Z') {
0938                         ch |= 0x20;
0939 
0940                     } else if (ch == '-') {
0941                         ch = '_';
0942                     }
0943 
0944                     hash = ngx_hash(hash, ch);
0945                     lowcase_key[n] = ch;
0946                 }
0947 
0948                 if (ngx_hash_find(&params->hash, hash, lowcase_key, n)) {
0949                     ignored[header_params++] = &header[i];
0950                     continue;
0951                 }
0952             }
0953 
0954             len += 2 + sizeof("HTTP_") - 1 + header[i].key.len
0955                  + 2 + header[i].value.len;
0956         }
0957     }
0958 
0959     len += uwcf->uwsgi_string.len;
0960 
0961 #if 0
0962     /* allow custom uwsgi packet */
0963     if (len > 0 && len < 2) {
0964         ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
0965                       "uwsgi request is too little: %uz", len);
0966         return NGX_ERROR;
0967     }
0968 #endif
0969 
0970     if (len > 65535) {
0971         ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
0972                       "uwsgi request is too big: %uz", len);
0973         return NGX_ERROR;
0974     }
0975 
0976     b = ngx_create_temp_buf(r->pool, len + 4);
0977     if (b == NULL) {
0978         return NGX_ERROR;
0979     }
0980 
0981     cl = ngx_alloc_chain_link(r->pool);
0982     if (cl == NULL) {
0983         return NGX_ERROR;
0984     }
0985 
0986     cl->buf = b;
0987 
0988     *b->last++ = (u_char) uwcf->modifier1;
0989     *b->last++ = (u_char) (len & 0xff);
0990     *b->last++ = (u_char) ((len >> 8) & 0xff);
0991     *b->last++ = (u_char) uwcf->modifier2;
0992 
0993     if (params->lengths) {
0994         ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
0995 
0996         e.ip = params->values->elts;
0997         e.pos = b->last;
0998         e.request = r;
0999         e.flushed = 1;
1000 
1001         le.ip = params->lengths->elts;
1002 
1003         while (*(uintptr_t *) le.ip) {
1004 
1005             lcode = *(ngx_http_script_len_code_pt *) le.ip;
1006             key_len = (u_char) lcode(&le);
1007 
1008             lcode = *(ngx_http_script_len_code_pt *) le.ip;
1009             skip_empty = lcode(&le);
1010 
1011             for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) {
1012                 lcode = *(ngx_http_script_len_code_pt *) le.ip;
1013             }
1014             le.ip += sizeof(uintptr_t);
1015 
1016             if (skip_empty && val_len == 0) {
1017                 e.skip = 1;
1018 
1019                 while (*(uintptr_t *) e.ip) {
1020                     code = *(ngx_http_script_code_pt *) e.ip;
1021                     code((ngx_http_script_engine_t *) &e);
1022                 }
1023                 e.ip += sizeof(uintptr_t);
1024 
1025                 e.skip = 0;
1026 
1027                 continue;
1028             }
1029 
1030             *e.pos++ = (u_char) (key_len & 0xff);
1031             *e.pos++ = (u_char) ((key_len >> 8) & 0xff);
1032 
1033             code = *(ngx_http_script_code_pt *) e.ip;
1034             code((ngx_http_script_engine_t *) &e);
1035 
1036             *e.pos++ = (u_char) (val_len & 0xff);
1037             *e.pos++ = (u_char) ((val_len >> 8) & 0xff);
1038 
1039             while (*(uintptr_t *) e.ip) {
1040                 code = *(ngx_http_script_code_pt *) e.ip;
1041                 code((ngx_http_script_engine_t *) &e);
1042             }
1043 
1044             e.ip += sizeof(uintptr_t);
1045 
1046             ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1047                            "uwsgi param: \"%*s: %*s\"",
1048                            key_len, e.pos - (key_len + 2 + val_len),
1049                            val_len, e.pos - val_len);
1050         }
1051 
1052         b->last = e.pos;
1053     }
1054 
1055     if (uwcf->upstream.pass_request_headers) {
1056 
1057         part = &r->headers_in.headers.part;
1058         header = part->elts;
1059 
1060         for (i = 0; /* void */ ; i++) {
1061 
1062             if (i >= part->nelts) {
1063                 if (part->next == NULL) {
1064                     break;
1065                 }
1066 
1067                 part = part->next;
1068                 header = part->elts;
1069                 i = 0;
1070             }
1071 
1072             for (n = 0; n < header_params; n++) {
1073                 if (&header[i] == ignored[n]) {
1074                     goto next;
1075                 }
1076             }
1077 
1078             key_len = sizeof("HTTP_") - 1 + header[i].key.len;
1079             *b->last++ = (u_char) (key_len & 0xff);
1080             *b->last++ = (u_char) ((key_len >> 8) & 0xff);
1081 
1082             b->last = ngx_cpymem(b->last, "HTTP_", sizeof("HTTP_") - 1);
1083             for (n = 0; n < header[i].key.len; n++) {
1084                 ch = header[i].key.data[n];
1085 
1086                 if (ch >= 'a' && ch <= 'z') {
1087                     ch &= ~0x20;
1088 
1089                 } else if (ch == '-') {
1090                     ch = '_';
1091                 }
1092 
1093                 *b->last++ = ch;
1094             }
1095 
1096             val_len = header[i].value.len;
1097             *b->last++ = (u_char) (val_len & 0xff);
1098             *b->last++ = (u_char) ((val_len >> 8) & 0xff);
1099             b->last = ngx_copy(b->last, header[i].value.data, val_len);
1100 
1101             ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1102                            "uwsgi param: \"%*s: %*s\"",
1103                            key_len, b->last - (key_len + 2 + val_len),
1104                            val_len, b->last - val_len);
1105         next:
1106 
1107             continue;
1108         }
1109     }
1110 
1111     b->last = ngx_copy(b->last, uwcf->uwsgi_string.data,
1112                        uwcf->uwsgi_string.len);
1113 
1114     if (r->request_body_no_buffering) {
1115         r->upstream->request_bufs = cl;
1116 
1117     } else if (uwcf->upstream.pass_request_body) {
1118         body = r->upstream->request_bufs;
1119         r->upstream->request_bufs = cl;
1120 
1121         while (body) {
1122             b = ngx_alloc_buf(r->pool);
1123             if (b == NULL) {
1124                 return NGX_ERROR;
1125             }
1126 
1127             ngx_memcpy(b, body->buf, sizeof(ngx_buf_t));
1128 
1129             cl->next = ngx_alloc_chain_link(r->pool);
1130             if (cl->next == NULL) {
1131                 return NGX_ERROR;
1132             }
1133 
1134             cl = cl->next;
1135             cl->buf = b;
1136 
1137             body = body->next;
1138         }
1139 
1140     } else {
1141         r->upstream->request_bufs = cl;
1142     }
1143 
1144     cl->next = NULL;
1145 
1146     return NGX_OK;
1147 }
1148 
1149 
1150 static ngx_int_t
1151 ngx_http_uwsgi_reinit_request(ngx_http_request_t *r)
1152 {
1153     ngx_http_status_t  *status;
1154 
1155     status = ngx_http_get_module_ctx(r, ngx_http_uwsgi_module);
1156 
1157     if (status == NULL) {
1158         return NGX_OK;
1159     }
1160 
1161     status->code = 0;
1162     status->count = 0;
1163     status->start = NULL;
1164     status->end = NULL;
1165 
1166     r->upstream->process_header = ngx_http_uwsgi_process_status_line;
1167     r->state = 0;
1168 
1169     return NGX_OK;
1170 }
1171 
1172 
1173 static ngx_int_t
1174 ngx_http_uwsgi_process_status_line(ngx_http_request_t *r)
1175 {
1176     size_t                 len;
1177     ngx_int_t              rc;
1178     ngx_http_status_t     *status;
1179     ngx_http_upstream_t   *u;
1180 
1181     status = ngx_http_get_module_ctx(r, ngx_http_uwsgi_module);
1182 
1183     if (status == NULL) {
1184         return NGX_ERROR;
1185     }
1186 
1187     u = r->upstream;
1188 
1189     rc = ngx_http_parse_status_line(r, &u->buffer, status);
1190 
1191     if (rc == NGX_AGAIN) {
1192         return rc;
1193     }
1194 
1195     if (rc == NGX_ERROR) {
1196         u->process_header = ngx_http_uwsgi_process_header;
1197         return ngx_http_uwsgi_process_header(r);
1198     }
1199 
1200     if (u->state && u->state->status == 0) {
1201         u->state->status = status->code;
1202     }
1203 
1204     u->headers_in.status_n = status->code;
1205 
1206     len = status->end - status->start;
1207     u->headers_in.status_line.len = len;
1208 
1209     u->headers_in.status_line.data = ngx_pnalloc(r->pool, len);
1210     if (u->headers_in.status_line.data == NULL) {
1211         return NGX_ERROR;
1212     }
1213 
1214     ngx_memcpy(u->headers_in.status_line.data, status->start, len);
1215 
1216     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1217                    "http uwsgi status %ui \"%V\"",
1218                    u->headers_in.status_n, &u->headers_in.status_line);
1219 
1220     u->process_header = ngx_http_uwsgi_process_header;
1221 
1222     return ngx_http_uwsgi_process_header(r);
1223 }
1224 
1225 
1226 static ngx_int_t
1227 ngx_http_uwsgi_process_header(ngx_http_request_t *r)
1228 {
1229     ngx_str_t                      *status_line;
1230     ngx_int_t                       rc, status;
1231     ngx_table_elt_t                *h;
1232     ngx_http_upstream_t            *u;
1233     ngx_http_upstream_header_t     *hh;
1234     ngx_http_upstream_main_conf_t  *umcf;
1235 
1236     umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
1237 
1238     for ( ;; ) {
1239 
1240         rc = ngx_http_parse_header_line(r, &r->upstream->buffer, 1);
1241 
1242         if (rc == NGX_OK) {
1243 
1244             /* a header line has been parsed successfully */
1245 
1246             h = ngx_list_push(&r->upstream->headers_in.headers);
1247             if (h == NULL) {
1248                 return NGX_ERROR;
1249             }
1250 
1251             h->hash = r->header_hash;
1252 
1253             h->key.len = r->header_name_end - r->header_name_start;
1254             h->value.len = r->header_end - r->header_start;
1255 
1256             h->key.data = ngx_pnalloc(r->pool,
1257                                       h->key.len + 1 + h->value.len + 1
1258                                       + h->key.len);
1259             if (h->key.data == NULL) {
1260                 h->hash = 0;
1261                 return NGX_ERROR;
1262             }
1263 
1264             h->value.data = h->key.data + h->key.len + 1;
1265             h->lowcase_key = h->key.data + h->key.len + 1 + h->value.len + 1;
1266 
1267             ngx_memcpy(h->key.data, r->header_name_start, h->key.len);
1268             h->key.data[h->key.len] = '\0';
1269             ngx_memcpy(h->value.data, r->header_start, h->value.len);
1270             h->value.data[h->value.len] = '\0';
1271 
1272             if (h->key.len == r->lowcase_index) {
1273                 ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);
1274 
1275             } else {
1276                 ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
1277             }
1278 
1279             hh = ngx_hash_find(&umcf->headers_in_hash, h->hash,
1280                                h->lowcase_key, h->key.len);
1281 
1282             if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
1283                 return NGX_ERROR;
1284             }
1285 
1286             ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1287                            "http uwsgi header: \"%V: %V\"", &h->key, &h->value);
1288 
1289             continue;
1290         }
1291 
1292         if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
1293 
1294             /* a whole header has been parsed successfully */
1295 
1296             ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1297                            "http uwsgi header done");
1298 
1299             u = r->upstream;
1300 
1301             if (u->headers_in.status_n) {
1302                 goto done;
1303             }
1304 
1305             if (u->headers_in.status) {
1306                 status_line = &u->headers_in.status->value;
1307 
1308                 status = ngx_atoi(status_line->data, 3);
1309                 if (status == NGX_ERROR) {
1310                     ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1311                                   "upstream sent invalid status \"%V\"",
1312                                   status_line);
1313                     return NGX_HTTP_UPSTREAM_INVALID_HEADER;
1314                 }
1315 
1316                 u->headers_in.status_n = status;
1317                 u->headers_in.status_line = *status_line;
1318 
1319             } else if (u->headers_in.location) {
1320                 u->headers_in.status_n = 302;
1321                 ngx_str_set(&u->headers_in.status_line,
1322                             "302 Moved Temporarily");
1323 
1324             } else {
1325                 u->headers_in.status_n = 200;
1326                 ngx_str_set(&u->headers_in.status_line, "200 OK");
1327             }
1328 
1329             if (u->state && u->state->status == 0) {
1330                 u->state->status = u->headers_in.status_n;
1331             }
1332 
1333         done:
1334 
1335             if (u->headers_in.status_n == NGX_HTTP_SWITCHING_PROTOCOLS
1336                 && r->headers_in.upgrade)
1337             {
1338                 u->upgrade = 1;
1339             }
1340 
1341             return NGX_OK;
1342         }
1343 
1344         if (rc == NGX_AGAIN) {
1345             return NGX_AGAIN;
1346         }
1347 
1348         /* there was error while a header line parsing */
1349 
1350         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1351                       "upstream sent invalid header");
1352 
1353         return NGX_HTTP_UPSTREAM_INVALID_HEADER;
1354     }
1355 }
1356 
1357 
1358 static void
1359 ngx_http_uwsgi_abort_request(ngx_http_request_t *r)
1360 {
1361     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1362                    "abort http uwsgi request");
1363 
1364     return;
1365 }
1366 
1367 
1368 static void
1369 ngx_http_uwsgi_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
1370 {
1371     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1372                    "finalize http uwsgi request");
1373 
1374     return;
1375 }
1376 
1377 
1378 static void *
1379 ngx_http_uwsgi_create_main_conf(ngx_conf_t *cf)
1380 {
1381     ngx_http_uwsgi_main_conf_t  *conf;
1382 
1383     conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_uwsgi_main_conf_t));
1384     if (conf == NULL) {
1385         return NULL;
1386     }
1387 
1388 #if (NGX_HTTP_CACHE)
1389     if (ngx_array_init(&conf->caches, cf->pool, 4,
1390                        sizeof(ngx_http_file_cache_t *))
1391         != NGX_OK)
1392     {
1393         return NULL;
1394     }
1395 #endif
1396 
1397     return conf;
1398 }
1399 
1400 
1401 static void *
1402 ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf)
1403 {
1404     ngx_http_uwsgi_loc_conf_t  *conf;
1405 
1406     conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_uwsgi_loc_conf_t));
1407     if (conf == NULL) {
1408         return NULL;
1409     }
1410 
1411     conf->modifier1 = NGX_CONF_UNSET_UINT;
1412     conf->modifier2 = NGX_CONF_UNSET_UINT;
1413 
1414     conf->upstream.store = NGX_CONF_UNSET;
1415     conf->upstream.store_access = NGX_CONF_UNSET_UINT;
1416     conf->upstream.next_upstream_tries = NGX_CONF_UNSET_UINT;
1417     conf->upstream.buffering = NGX_CONF_UNSET;
1418     conf->upstream.request_buffering = NGX_CONF_UNSET;
1419     conf->upstream.ignore_client_abort = NGX_CONF_UNSET;
1420     conf->upstream.force_ranges = NGX_CONF_UNSET;
1421 
1422     conf->upstream.local = NGX_CONF_UNSET_PTR;
1423     conf->upstream.socket_keepalive = NGX_CONF_UNSET;
1424 
1425     conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC;
1426     conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC;
1427     conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC;
1428     conf->upstream.next_upstream_timeout = NGX_CONF_UNSET_MSEC;
1429 
1430     conf->upstream.send_lowat = NGX_CONF_UNSET_SIZE;
1431     conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE;
1432     conf->upstream.limit_rate = NGX_CONF_UNSET_SIZE;
1433 
1434     conf->upstream.busy_buffers_size_conf = NGX_CONF_UNSET_SIZE;
1435     conf->upstream.max_temp_file_size_conf = NGX_CONF_UNSET_SIZE;
1436     conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE;
1437 
1438     conf->upstream.pass_request_headers = NGX_CONF_UNSET;
1439     conf->upstream.pass_request_body = NGX_CONF_UNSET;
1440 
1441 #if (NGX_HTTP_CACHE)
1442     conf->upstream.cache = NGX_CONF_UNSET;
1443     conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT;
1444     conf->upstream.cache_max_range_offset = NGX_CONF_UNSET;
1445     conf->upstream.cache_bypass = NGX_CONF_UNSET_PTR;
1446     conf->upstream.no_cache = NGX_CONF_UNSET_PTR;
1447     conf->upstream.cache_valid = NGX_CONF_UNSET_PTR;
1448     conf->upstream.cache_lock = NGX_CONF_UNSET;
1449     conf->upstream.cache_lock_timeout = NGX_CONF_UNSET_MSEC;
1450     conf->upstream.cache_lock_age = NGX_CONF_UNSET_MSEC;
1451     conf->upstream.cache_revalidate = NGX_CONF_UNSET;
1452     conf->upstream.cache_background_update = NGX_CONF_UNSET;
1453 #endif
1454 
1455     conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
1456     conf->upstream.pass_headers = NGX_CONF_UNSET_PTR;
1457 
1458     conf->upstream.intercept_errors = NGX_CONF_UNSET;
1459 
1460 #if (NGX_HTTP_SSL)
1461     conf->upstream.ssl_session_reuse = NGX_CONF_UNSET;
1462     conf->upstream.ssl_server_name = NGX_CONF_UNSET;
1463     conf->upstream.ssl_verify = NGX_CONF_UNSET;
1464     conf->ssl_verify_depth = NGX_CONF_UNSET_UINT;
1465     conf->ssl_passwords = NGX_CONF_UNSET_PTR;
1466 #endif
1467 
1468     /* "uwsgi_cyclic_temp_file" is disabled */
1469     conf->upstream.cyclic_temp_file = 0;
1470 
1471     conf->upstream.change_buffering = 1;
1472 
1473     ngx_str_set(&conf->upstream.module, "uwsgi");
1474 
1475     return conf;
1476 }
1477 
1478 
1479 static char *
1480 ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
1481 {
1482     ngx_http_uwsgi_loc_conf_t *prev = parent;
1483     ngx_http_uwsgi_loc_conf_t *conf = child;
1484 
1485     size_t                        size;
1486     ngx_int_t                     rc;
1487     ngx_hash_init_t               hash;
1488     ngx_http_core_loc_conf_t     *clcf;
1489 
1490 #if (NGX_HTTP_CACHE)
1491 
1492     if (conf->upstream.store > 0) {
1493         conf->upstream.cache = 0;
1494     }
1495 
1496     if (conf->upstream.cache > 0) {
1497         conf->upstream.store = 0;
1498     }
1499 
1500 #endif
1501 
1502     if (conf->upstream.store == NGX_CONF_UNSET) {
1503         ngx_conf_merge_value(conf->upstream.store, prev->upstream.store, 0);
1504 
1505         conf->upstream.store_lengths = prev->upstream.store_lengths;
1506         conf->upstream.store_values = prev->upstream.store_values;
1507     }
1508 
1509     ngx_conf_merge_uint_value(conf->upstream.store_access,
1510                               prev->upstream.store_access, 0600);
1511 
1512     ngx_conf_merge_uint_value(conf->upstream.next_upstream_tries,
1513                               prev->upstream.next_upstream_tries, 0);
1514 
1515     ngx_conf_merge_value(conf->upstream.buffering,
1516                               prev->upstream.buffering, 1);
1517 
1518     ngx_conf_merge_value(conf->upstream.request_buffering,
1519                               prev->upstream.request_buffering, 1);
1520 
1521     ngx_conf_merge_value(conf->upstream.ignore_client_abort,
1522                               prev->upstream.ignore_client_abort, 0);
1523 
1524     ngx_conf_merge_value(conf->upstream.force_ranges,
1525                               prev->upstream.force_ranges, 0);
1526 
1527     ngx_conf_merge_ptr_value(conf->upstream.local,
1528                               prev->upstream.local, NULL);
1529 
1530     ngx_conf_merge_value(conf->upstream.socket_keepalive,
1531                               prev->upstream.socket_keepalive, 0);
1532 
1533     ngx_conf_merge_msec_value(conf->upstream.connect_timeout,
1534                               prev->upstream.connect_timeout, 60000);
1535 
1536     ngx_conf_merge_msec_value(conf->upstream.send_timeout,
1537                               prev->upstream.send_timeout, 60000);
1538 
1539     ngx_conf_merge_msec_value(conf->upstream.read_timeout,
1540                               prev->upstream.read_timeout, 60000);
1541 
1542     ngx_conf_merge_msec_value(conf->upstream.next_upstream_timeout,
1543                               prev->upstream.next_upstream_timeout, 0);
1544 
1545     ngx_conf_merge_size_value(conf->upstream.send_lowat,
1546                               prev->upstream.send_lowat, 0);
1547 
1548     ngx_conf_merge_size_value(conf->upstream.buffer_size,
1549                               prev->upstream.buffer_size,
1550                               (size_t) ngx_pagesize);
1551 
1552     ngx_conf_merge_size_value(conf->upstream.limit_rate,
1553                               prev->upstream.limit_rate, 0);
1554 
1555 
1556     ngx_conf_merge_bufs_value(conf->upstream.bufs, prev->upstream.bufs,
1557                               8, ngx_pagesize);
1558 
1559     if (conf->upstream.bufs.num < 2) {
1560         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1561                            "there must be at least 2 \"uwsgi_buffers\"");
1562         return NGX_CONF_ERROR;
1563     }
1564 
1565 
1566     size = conf->upstream.buffer_size;
1567     if (size < conf->upstream.bufs.size) {
1568         size = conf->upstream.bufs.size;
1569     }
1570 
1571 
1572     ngx_conf_merge_size_value(conf->upstream.busy_buffers_size_conf,
1573                               prev->upstream.busy_buffers_size_conf,
1574                               NGX_CONF_UNSET_SIZE);
1575 
1576     if (conf->upstream.busy_buffers_size_conf == NGX_CONF_UNSET_SIZE) {
1577         conf->upstream.busy_buffers_size = 2 * size;
1578     } else {
1579         conf->upstream.busy_buffers_size =
1580             conf->upstream.busy_buffers_size_conf;
1581     }
1582 
1583     if (conf->upstream.busy_buffers_size < size) {
1584         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1585             "\"uwsgi_busy_buffers_size\" must be equal to or greater "
1586             "than the maximum of the value of \"uwsgi_buffer_size\" and "
1587             "one of the \"uwsgi_buffers\"");
1588 
1589         return NGX_CONF_ERROR;
1590     }
1591 
1592     if (conf->upstream.busy_buffers_size
1593         > (conf->upstream.bufs.num - 1) * conf->upstream.bufs.size)
1594     {
1595         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1596             "\"uwsgi_busy_buffers_size\" must be less than "
1597             "the size of all \"uwsgi_buffers\" minus one buffer");
1598 
1599         return NGX_CONF_ERROR;
1600     }
1601 
1602 
1603     ngx_conf_merge_size_value(conf->upstream.temp_file_write_size_conf,
1604                               prev->upstream.temp_file_write_size_conf,
1605                               NGX_CONF_UNSET_SIZE);
1606 
1607     if (conf->upstream.temp_file_write_size_conf == NGX_CONF_UNSET_SIZE) {
1608         conf->upstream.temp_file_write_size = 2 * size;
1609     } else {
1610         conf->upstream.temp_file_write_size =
1611             conf->upstream.temp_file_write_size_conf;
1612     }
1613 
1614     if (conf->upstream.temp_file_write_size < size) {
1615         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1616             "\"uwsgi_temp_file_write_size\" must be equal to or greater than "
1617             "the maximum of the value of \"uwsgi_buffer_size\" and "
1618             "one of the \"uwsgi_buffers\"");
1619 
1620         return NGX_CONF_ERROR;
1621     }
1622 
1623 
1624     ngx_conf_merge_size_value(conf->upstream.max_temp_file_size_conf,
1625                               prev->upstream.max_temp_file_size_conf,
1626                               NGX_CONF_UNSET_SIZE);
1627 
1628     if (conf->upstream.max_temp_file_size_conf == NGX_CONF_UNSET_SIZE) {
1629         conf->upstream.max_temp_file_size = 1024 * 1024 * 1024;
1630     } else {
1631         conf->upstream.max_temp_file_size =
1632             conf->upstream.max_temp_file_size_conf;
1633     }
1634 
1635     if (conf->upstream.max_temp_file_size != 0
1636         && conf->upstream.max_temp_file_size < size)
1637     {
1638         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1639             "\"uwsgi_max_temp_file_size\" must be equal to zero to disable "
1640             "temporary files usage or must be equal to or greater than "
1641             "the maximum of the value of \"uwsgi_buffer_size\" and "
1642             "one of the \"uwsgi_buffers\"");
1643 
1644         return NGX_CONF_ERROR;
1645     }
1646 
1647 
1648     ngx_conf_merge_bitmask_value(conf->upstream.ignore_headers,
1649                                  prev->upstream.ignore_headers,
1650                                  NGX_CONF_BITMASK_SET);
1651 
1652 
1653     ngx_conf_merge_bitmask_value(conf->upstream.next_upstream,
1654                                  prev->upstream.next_upstream,
1655                                  (NGX_CONF_BITMASK_SET
1656                                   |NGX_HTTP_UPSTREAM_FT_ERROR
1657                                   |NGX_HTTP_UPSTREAM_FT_TIMEOUT));
1658 
1659     if (conf->upstream.next_upstream & NGX_HTTP_UPSTREAM_FT_OFF) {
1660         conf->upstream.next_upstream = NGX_CONF_BITMASK_SET
1661                                        |NGX_HTTP_UPSTREAM_FT_OFF;
1662     }
1663 
1664     if (ngx_conf_merge_path_value(cf, &conf->upstream.temp_path,
1665                                   prev->upstream.temp_path,
1666                                   &ngx_http_uwsgi_temp_path)
1667         != NGX_OK)
1668     {
1669         return NGX_CONF_ERROR;
1670     }
1671 
1672 #if (NGX_HTTP_CACHE)
1673 
1674     if (conf->upstream.cache == NGX_CONF_UNSET) {
1675         ngx_conf_merge_value(conf->upstream.cache,
1676                               prev->upstream.cache, 0);
1677 
1678         conf->upstream.cache_zone = prev->upstream.cache_zone;
1679         conf->upstream.cache_value = prev->upstream.cache_value;
1680     }
1681 
1682     if (conf->upstream.cache_zone && conf->upstream.cache_zone->data == NULL) {
1683         ngx_shm_zone_t  *shm_zone;
1684 
1685         shm_zone = conf->upstream.cache_zone;
1686 
1687         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1688                            "\"uwsgi_cache\" zone \"%V\" is unknown",
1689                            &shm_zone->shm.name);
1690 
1691         return NGX_CONF_ERROR;
1692     }
1693 
1694     ngx_conf_merge_uint_value(conf->upstream.cache_min_uses,
1695                               prev->upstream.cache_min_uses, 1);
1696 
1697     ngx_conf_merge_off_value(conf->upstream.cache_max_range_offset,
1698                               prev->upstream.cache_max_range_offset,
1699                               NGX_MAX_OFF_T_VALUE);
1700 
1701     ngx_conf_merge_bitmask_value(conf->upstream.cache_use_stale,
1702                               prev->upstream.cache_use_stale,
1703                               (NGX_CONF_BITMASK_SET
1704                                |NGX_HTTP_UPSTREAM_FT_OFF));
1705 
1706     if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_OFF) {
1707         conf->upstream.cache_use_stale = NGX_CONF_BITMASK_SET
1708                                          |NGX_HTTP_UPSTREAM_FT_OFF;
1709     }
1710 
1711     if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_ERROR) {
1712         conf->upstream.cache_use_stale |= NGX_HTTP_UPSTREAM_FT_NOLIVE;
1713     }
1714 
1715     if (conf->upstream.cache_methods == 0) {
1716         conf->upstream.cache_methods = prev->upstream.cache_methods;
1717     }
1718 
1719     conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD;
1720 
1721     ngx_conf_merge_ptr_value(conf->upstream.cache_bypass,
1722                              prev->upstream.cache_bypass, NULL);
1723 
1724     ngx_conf_merge_ptr_value(conf->upstream.no_cache,
1725                              prev->upstream.no_cache, NULL);
1726 
1727     ngx_conf_merge_ptr_value(conf->upstream.cache_valid,
1728                              prev->upstream.cache_valid, NULL);
1729 
1730     if (conf->cache_key.value.data == NULL) {
1731         conf->cache_key = prev->cache_key;
1732     }
1733 
1734     if (conf->upstream.cache && conf->cache_key.value.data == NULL) {
1735         ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1736                            "no \"uwsgi_cache_key\" for \"uwsgi_cache\"");
1737     }
1738 
1739     ngx_conf_merge_value(conf->upstream.cache_lock,
1740                               prev->upstream.cache_lock, 0);
1741 
1742     ngx_conf_merge_msec_value(conf->upstream.cache_lock_timeout,
1743                               prev->upstream.cache_lock_timeout, 5000);
1744 
1745     ngx_conf_merge_msec_value(conf->upstream.cache_lock_age,
1746                               prev->upstream.cache_lock_age, 5000);
1747 
1748     ngx_conf_merge_value(conf->upstream.cache_revalidate,
1749                               prev->upstream.cache_revalidate, 0);
1750 
1751     ngx_conf_merge_value(conf->upstream.cache_background_update,
1752                               prev->upstream.cache_background_update, 0);
1753 
1754 #endif
1755 
1756     ngx_conf_merge_value(conf->upstream.pass_request_headers,
1757                          prev->upstream.pass_request_headers, 1);
1758     ngx_conf_merge_value(conf->upstream.pass_request_body,
1759                          prev->upstream.pass_request_body, 1);
1760 
1761     ngx_conf_merge_value(conf->upstream.intercept_errors,
1762                          prev->upstream.intercept_errors, 0);
1763 
1764 #if (NGX_HTTP_SSL)
1765 
1766     ngx_conf_merge_value(conf->upstream.ssl_session_reuse,
1767                               prev->upstream.ssl_session_reuse, 1);
1768 
1769     ngx_conf_merge_bitmask_value(conf->ssl_protocols, prev->ssl_protocols,
1770                                  (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1
1771                                   |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2));
1772 
1773     ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers,
1774                              "DEFAULT");
1775 
1776     if (conf->upstream.ssl_name == NULL) {
1777         conf->upstream.ssl_name = prev->upstream.ssl_name;
1778     }
1779 
1780     ngx_conf_merge_value(conf->upstream.ssl_server_name,
1781                               prev->upstream.ssl_server_name, 0);
1782     ngx_conf_merge_value(conf->upstream.ssl_verify,
1783                               prev->upstream.ssl_verify, 0);
1784     ngx_conf_merge_uint_value(conf->ssl_verify_depth,
1785                               prev->ssl_verify_depth, 1);
1786     ngx_conf_merge_str_value(conf->ssl_trusted_certificate,
1787                               prev->ssl_trusted_certificate, "");
1788     ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, "");
1789 
1790     ngx_conf_merge_str_value(conf->ssl_certificate,
1791                               prev->ssl_certificate, "");
1792     ngx_conf_merge_str_value(conf->ssl_certificate_key,
1793                               prev->ssl_certificate_key, "");
1794     ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL);
1795 
1796     if (conf->ssl && ngx_http_uwsgi_set_ssl(cf, conf) != NGX_OK) {
1797         return NGX_CONF_ERROR;
1798     }
1799 
1800 #endif
1801 
1802     ngx_conf_merge_str_value(conf->uwsgi_string, prev->uwsgi_string, "");
1803 
1804     hash.max_size = 512;
1805     hash.bucket_size = ngx_align(64, ngx_cacheline_size);
1806     hash.name = "uwsgi_hide_headers_hash";
1807 
1808     if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream,
1809             &prev->upstream, ngx_http_uwsgi_hide_headers, &hash)
1810         != NGX_OK)
1811     {
1812         return NGX_CONF_ERROR;
1813     }
1814 
1815     clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
1816 
1817     if (clcf->noname
1818         && conf->upstream.upstream == NULL && conf->uwsgi_lengths == NULL)
1819     {
1820         conf->upstream.upstream = prev->upstream.upstream;
1821 
1822         conf->uwsgi_lengths = prev->uwsgi_lengths;
1823         conf->uwsgi_values = prev->uwsgi_values;
1824 
1825 #if (NGX_HTTP_SSL)
1826         conf->upstream.ssl = prev->upstream.ssl;
1827 #endif
1828     }
1829 
1830     if (clcf->lmt_excpt && clcf->handler == NULL
1831         && (conf->upstream.upstream || conf->uwsgi_lengths))
1832     {
1833         clcf->handler = ngx_http_uwsgi_handler;
1834     }
1835 
1836     ngx_conf_merge_uint_value(conf->modifier1, prev->modifier1, 0);
1837     ngx_conf_merge_uint_value(conf->modifier2, prev->modifier2, 0);
1838 
1839     if (conf->params_source == NULL) {
1840         conf->params = prev->params;
1841 #if (NGX_HTTP_CACHE)
1842         conf->params_cache = prev->params_cache;
1843 #endif
1844         conf->params_source = prev->params_source;
1845     }
1846 
1847     rc = ngx_http_uwsgi_init_params(cf, conf, &conf->params, NULL);
1848     if (rc != NGX_OK) {
1849         return NGX_CONF_ERROR;
1850     }
1851 
1852 #if (NGX_HTTP_CACHE)
1853 
1854     if (conf->upstream.cache) {
1855         rc = ngx_http_uwsgi_init_params(cf, conf, &conf->params_cache,
1856                                         ngx_http_uwsgi_cache_headers);
1857         if (rc != NGX_OK) {
1858             return NGX_CONF_ERROR;
1859         }
1860     }
1861 
1862 #endif
1863 
1864     /*
1865      * special handling to preserve conf->params in the "http" section
1866      * to inherit it to all servers
1867      */
1868 
1869     if (prev->params.hash.buckets == NULL
1870         && conf->params_source == prev->params_source)
1871     {
1872         prev->params = conf->params;
1873 #if (NGX_HTTP_CACHE)
1874         prev->params_cache = conf->params_cache;
1875 #endif
1876     }
1877 
1878     return NGX_CONF_OK;
1879 }
1880 
1881 
1882 static ngx_int_t
1883 ngx_http_uwsgi_init_params(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *conf,
1884     ngx_http_uwsgi_params_t *params, ngx_keyval_t *default_params)
1885 {
1886     u_char                       *p;
1887     size_t                        size;
1888     uintptr_t                    *code;
1889     ngx_uint_t                    i, nsrc;
1890     ngx_array_t                   headers_names, params_merged;
1891     ngx_keyval_t                 *h;
1892     ngx_hash_key_t               *hk;
1893     ngx_hash_init_t               hash;
1894     ngx_http_upstream_param_t    *src, *s;
1895     ngx_http_script_compile_t     sc;
1896     ngx_http_script_copy_code_t  *copy;
1897 
1898     if (params->hash.buckets) {
1899         return NGX_OK;
1900     }
1901 
1902     if (conf->params_source == NULL && default_params == NULL) {
1903         params->hash.buckets = (void *) 1;
1904         return NGX_OK;
1905     }
1906 
1907     params->lengths = ngx_array_create(cf->pool, 64, 1);
1908     if (params->lengths == NULL) {
1909         return NGX_ERROR;
1910     }
1911 
1912     params->values = ngx_array_create(cf->pool, 512, 1);
1913     if (params->values == NULL) {
1914         return NGX_ERROR;
1915     }
1916 
1917     if (ngx_array_init(&headers_names, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
1918         != NGX_OK)
1919     {
1920         return NGX_ERROR;
1921     }
1922 
1923     if (conf->params_source) {
1924         src = conf->params_source->elts;
1925         nsrc = conf->params_source->nelts;
1926 
1927     } else {
1928         src = NULL;
1929         nsrc = 0;
1930     }
1931 
1932     if (default_params) {
1933         if (ngx_array_init(&params_merged, cf->temp_pool, 4,
1934                            sizeof(ngx_http_upstream_param_t))
1935             != NGX_OK)
1936         {
1937             return NGX_ERROR;
1938         }
1939 
1940         for (i = 0; i < nsrc; i++) {
1941 
1942             s = ngx_array_push(&params_merged);
1943             if (s == NULL) {
1944                 return NGX_ERROR;
1945             }
1946 
1947             *s = src[i];
1948         }
1949 
1950         h = default_params;
1951 
1952         while (h->key.len) {
1953 
1954             src = params_merged.elts;
1955             nsrc = params_merged.nelts;
1956 
1957             for (i = 0; i < nsrc; i++) {
1958                 if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) {
1959                     goto next;
1960                 }
1961             }
1962 
1963             s = ngx_array_push(&params_merged);
1964             if (s == NULL) {
1965                 return NGX_ERROR;
1966             }
1967 
1968             s->key = h->key;
1969             s->value = h->value;
1970             s->skip_empty = 1;
1971 
1972         next:
1973 
1974             h++;
1975         }
1976 
1977         src = params_merged.elts;
1978         nsrc = params_merged.nelts;
1979     }
1980 
1981     for (i = 0; i < nsrc; i++) {
1982 
1983         if (src[i].key.len > sizeof("HTTP_") - 1
1984             && ngx_strncmp(src[i].key.data, "HTTP_", sizeof("HTTP_") - 1) == 0)
1985         {
1986             hk = ngx_array_push(&headers_names);
1987             if (hk == NULL) {
1988                 return NGX_ERROR;
1989             }
1990 
1991             hk->key.len = src[i].key.len - 5;
1992             hk->key.data = src[i].key.data + 5;
1993             hk->key_hash = ngx_hash_key_lc(hk->key.data, hk->key.len);
1994             hk->value = (void *) 1;
1995 
1996             if (src[i].value.len == 0) {
1997                 continue;
1998             }
1999         }
2000 
2001         copy = ngx_array_push_n(params->lengths,
2002                                 sizeof(ngx_http_script_copy_code_t));
2003         if (copy == NULL) {
2004             return NGX_ERROR;
2005         }
2006 
2007         copy->code = (ngx_http_script_code_pt) (void *)
2008                                                  ngx_http_script_copy_len_code;
2009         copy->len = src[i].key.len;
2010 
2011         copy = ngx_array_push_n(params->lengths,
2012                                 sizeof(ngx_http_script_copy_code_t));
2013         if (copy == NULL) {
2014             return NGX_ERROR;
2015         }
2016 
2017         copy->code = (ngx_http_script_code_pt) (void *)
2018                                                  ngx_http_script_copy_len_code;
2019         copy->len = src[i].skip_empty;
2020 
2021 
2022         size = (sizeof(ngx_http_script_copy_code_t)
2023                 + src[i].key.len + sizeof(uintptr_t) - 1)
2024                & ~(sizeof(uintptr_t) - 1);
2025 
2026         copy = ngx_array_push_n(params->values, size);
2027         if (copy == NULL) {
2028             return NGX_ERROR;
2029         }
2030 
2031         copy->code = ngx_http_script_copy_code;
2032         copy->len = src[i].key.len;
2033 
2034         p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t);
2035         ngx_memcpy(p, src[i].key.data, src[i].key.len);
2036 
2037 
2038         ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
2039 
2040         sc.cf = cf;
2041         sc.source = &src[i].value;
2042         sc.flushes = &params->flushes;
2043         sc.lengths = &params->lengths;
2044         sc.values = &params->values;
2045 
2046         if (ngx_http_script_compile(&sc) != NGX_OK) {
2047             return NGX_ERROR;
2048         }
2049 
2050         code = ngx_array_push_n(params->lengths, sizeof(uintptr_t));
2051         if (code == NULL) {
2052             return NGX_ERROR;
2053         }
2054 
2055         *code = (uintptr_t) NULL;
2056 
2057 
2058         code = ngx_array_push_n(params->values, sizeof(uintptr_t));
2059         if (code == NULL) {
2060             return NGX_ERROR;
2061         }
2062 
2063         *code = (uintptr_t) NULL;
2064     }
2065 
2066     code = ngx_array_push_n(params->lengths, sizeof(uintptr_t));
2067     if (code == NULL) {
2068         return NGX_ERROR;
2069     }
2070 
2071     *code = (uintptr_t) NULL;
2072 
2073     params->number = headers_names.nelts;
2074 
2075     hash.hash = &params->hash;
2076     hash.key = ngx_hash_key_lc;
2077     hash.max_size = 512;
2078     hash.bucket_size = 64;
2079     hash.name = "uwsgi_params_hash";
2080     hash.pool = cf->pool;
2081     hash.temp_pool = NULL;
2082 
2083     return ngx_hash_init(&hash, headers_names.elts, headers_names.nelts);
2084 }
2085 
2086 
2087 static char *
2088 ngx_http_uwsgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2089 {
2090     ngx_http_uwsgi_loc_conf_t *uwcf = conf;
2091 
2092     size_t                      add;
2093     ngx_url_t                   u;
2094     ngx_str_t                  *value, *url;
2095     ngx_uint_t                  n;
2096     ngx_http_core_loc_conf_t   *clcf;
2097     ngx_http_script_compile_t   sc;
2098 
2099     if (uwcf->upstream.upstream || uwcf->uwsgi_lengths) {
2100         return "is duplicate";
2101     }
2102 
2103     clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
2104     clcf->handler = ngx_http_uwsgi_handler;
2105 
2106     value = cf->args->elts;
2107 
2108     url = &value[1];
2109 
2110     n = ngx_http_script_variables_count(url);
2111 
2112     if (n) {
2113 
2114         ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
2115 
2116         sc.cf = cf;
2117         sc.source = url;
2118         sc.lengths = &uwcf->uwsgi_lengths;
2119         sc.values = &uwcf->uwsgi_values;
2120         sc.variables = n;
2121         sc.complete_lengths = 1;
2122         sc.complete_values = 1;
2123 
2124         if (ngx_http_script_compile(&sc) != NGX_OK) {
2125             return NGX_CONF_ERROR;
2126         }
2127 
2128 #if (NGX_HTTP_SSL)
2129         uwcf->ssl = 1;
2130 #endif
2131 
2132         return NGX_CONF_OK;
2133     }
2134 
2135     if (ngx_strncasecmp(url->data, (u_char *) "uwsgi://", 8) == 0) {
2136         add = 8;
2137 
2138     } else if (ngx_strncasecmp(url->data, (u_char *) "suwsgi://", 9) == 0) {
2139 
2140 #if (NGX_HTTP_SSL)
2141         add = 9;
2142         uwcf->ssl = 1;
2143 #else
2144         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2145                            "suwsgi protocol requires SSL support");
2146         return NGX_CONF_ERROR;
2147 #endif
2148 
2149     } else {
2150         add = 0;
2151     }
2152 
2153     ngx_memzero(&u, sizeof(ngx_url_t));
2154 
2155     u.url.len = url->len - add;
2156     u.url.data = url->data + add;
2157     u.no_resolve = 1;
2158 
2159     uwcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0);
2160     if (uwcf->upstream.upstream == NULL) {
2161         return NGX_CONF_ERROR;
2162     }
2163 
2164     if (clcf->name.len && clcf->name.data[clcf->name.len - 1] == '/') {
2165         clcf->auto_redirect = 1;
2166     }
2167 
2168     return NGX_CONF_OK;
2169 }
2170 
2171 
2172 static char *
2173 ngx_http_uwsgi_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2174 {
2175     ngx_http_uwsgi_loc_conf_t *uwcf = conf;
2176 
2177     ngx_str_t                  *value;
2178     ngx_http_script_compile_t   sc;
2179 
2180     if (uwcf->upstream.store != NGX_CONF_UNSET) {
2181         return "is duplicate";
2182     }
2183 
2184     value = cf->args->elts;
2185 
2186     if (ngx_strcmp(value[1].data, "off") == 0) {
2187         uwcf->upstream.store = 0;
2188         return NGX_CONF_OK;
2189     }
2190 
2191 #if (NGX_HTTP_CACHE)
2192 
2193     if (uwcf->upstream.cache > 0) {
2194         return "is incompatible with \"uwsgi_cache\"";
2195     }
2196 
2197 #endif
2198 
2199     uwcf->upstream.store = 1;
2200 
2201     if (ngx_strcmp(value[1].data, "on") == 0) {
2202         return NGX_CONF_OK;
2203     }
2204 
2205     /* include the terminating '\0' into script */
2206     value[1].len++;
2207 
2208     ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
2209 
2210     sc.cf = cf;
2211     sc.source = &value[1];
2212     sc.lengths = &uwcf->upstream.store_lengths;
2213     sc.values = &uwcf->upstream.store_values;
2214     sc.variables = ngx_http_script_variables_count(&value[1]);
2215     sc.complete_lengths = 1;
2216     sc.complete_values = 1;
2217 
2218     if (ngx_http_script_compile(&sc) != NGX_OK) {
2219         return NGX_CONF_ERROR;
2220     }
2221 
2222     return NGX_CONF_OK;
2223 }
2224 
2225 
2226 #if (NGX_HTTP_CACHE)
2227 
2228 static char *
2229 ngx_http_uwsgi_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2230 {
2231     ngx_http_uwsgi_loc_conf_t *uwcf = conf;
2232 
2233     ngx_str_t                         *value;
2234     ngx_http_complex_value_t           cv;
2235     ngx_http_compile_complex_value_t   ccv;
2236 
2237     value = cf->args->elts;
2238 
2239     if (uwcf->upstream.cache != NGX_CONF_UNSET) {
2240         return "is duplicate";
2241     }
2242 
2243     if (ngx_strcmp(value[1].data, "off") == 0) {
2244         uwcf->upstream.cache = 0;
2245         return NGX_CONF_OK;
2246     }
2247 
2248     if (uwcf->upstream.store > 0) {
2249         return "is incompatible with \"uwsgi_store\"";
2250     }
2251 
2252     uwcf->upstream.cache = 1;
2253 
2254     ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
2255 
2256     ccv.cf = cf;
2257     ccv.value = &value[1];
2258     ccv.complex_value = &cv;
2259 
2260     if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
2261         return NGX_CONF_ERROR;
2262     }
2263 
2264     if (cv.lengths != NULL) {
2265 
2266         uwcf->upstream.cache_value = ngx_palloc(cf->pool,
2267                                              sizeof(ngx_http_complex_value_t));
2268         if (uwcf->upstream.cache_value == NULL) {
2269             return NGX_CONF_ERROR;
2270         }
2271 
2272         *uwcf->upstream.cache_value = cv;
2273 
2274         return NGX_CONF_OK;
2275     }
2276 
2277     uwcf->upstream.cache_zone = ngx_shared_memory_add(cf, &value[1], 0,
2278                                                       &ngx_http_uwsgi_module);
2279     if (uwcf->upstream.cache_zone == NULL) {
2280         return NGX_CONF_ERROR;
2281     }
2282 
2283     return NGX_CONF_OK;
2284 }
2285 
2286 
2287 static char *
2288 ngx_http_uwsgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2289 {
2290     ngx_http_uwsgi_loc_conf_t *uwcf = conf;
2291 
2292     ngx_str_t                         *value;
2293     ngx_http_compile_complex_value_t   ccv;
2294 
2295     value = cf->args->elts;
2296 
2297     if (uwcf->cache_key.value.data) {
2298         return "is duplicate";
2299     }
2300 
2301     ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
2302 
2303     ccv.cf = cf;
2304     ccv.value = &value[1];
2305     ccv.complex_value = &uwcf->cache_key;
2306 
2307     if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
2308         return NGX_CONF_ERROR;
2309     }
2310 
2311     return NGX_CONF_OK;
2312 }
2313 
2314 #endif
2315 
2316 
2317 #if (NGX_HTTP_SSL)
2318 
2319 static char *
2320 ngx_http_uwsgi_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2321 {
2322     ngx_http_uwsgi_loc_conf_t *uwcf = conf;
2323 
2324     ngx_str_t  *value;
2325 
2326     if (uwcf->ssl_passwords != NGX_CONF_UNSET_PTR) {
2327         return "is duplicate";
2328     }
2329 
2330     value = cf->args->elts;
2331 
2332     uwcf->ssl_passwords = ngx_ssl_read_password_file(cf, &value[1]);
2333 
2334     if (uwcf->ssl_passwords == NULL) {
2335         return NGX_CONF_ERROR;
2336     }
2337 
2338     return NGX_CONF_OK;
2339 }
2340 
2341 
2342 static ngx_int_t
2343 ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *uwcf)
2344 {
2345     ngx_pool_cleanup_t  *cln;
2346 
2347     uwcf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
2348     if (uwcf->upstream.ssl == NULL) {
2349         return NGX_ERROR;
2350     }
2351 
2352     uwcf->upstream.ssl->log = cf->log;
2353 
2354     if (ngx_ssl_create(uwcf->upstream.ssl, uwcf->ssl_protocols, NULL)
2355         != NGX_OK)
2356     {
2357         return NGX_ERROR;
2358     }
2359 
2360     cln = ngx_pool_cleanup_add(cf->pool, 0);
2361     if (cln == NULL) {
2362         ngx_ssl_cleanup_ctx(uwcf->upstream.ssl);
2363         return NGX_ERROR;
2364     }
2365 
2366     cln->handler = ngx_ssl_cleanup_ctx;
2367     cln->data = uwcf->upstream.ssl;
2368 
2369     if (uwcf->ssl_certificate.len) {
2370 
2371         if (uwcf->ssl_certificate_key.len == 0) {
2372             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
2373                           "no \"uwsgi_ssl_certificate_key\" is defined "
2374                           "for certificate \"%V\"", &uwcf->ssl_certificate);
2375             return NGX_ERROR;
2376         }
2377 
2378         if (ngx_ssl_certificate(cf, uwcf->upstream.ssl, &uwcf->ssl_certificate,
2379                                 &uwcf->ssl_certificate_key, uwcf->ssl_passwords)
2380             != NGX_OK)
2381         {
2382             return NGX_ERROR;
2383         }
2384     }
2385 
2386     if (ngx_ssl_ciphers(cf, uwcf->upstream.ssl, &uwcf->ssl_ciphers, 0)
2387         != NGX_OK)
2388     {
2389         return NGX_ERROR;
2390     }
2391 
2392     if (uwcf->upstream.ssl_verify) {
2393         if (uwcf->ssl_trusted_certificate.len == 0) {
2394             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
2395                       "no uwsgi_ssl_trusted_certificate for uwsgi_ssl_verify");
2396             return NGX_ERROR;
2397         }
2398 
2399         if (ngx_ssl_trusted_certificate(cf, uwcf->upstream.ssl,
2400                                         &uwcf->ssl_trusted_certificate,
2401                                         uwcf->ssl_verify_depth)
2402             != NGX_OK)
2403         {
2404             return NGX_ERROR;
2405         }
2406 
2407         if (ngx_ssl_crl(cf, uwcf->upstream.ssl, &uwcf->ssl_crl) != NGX_OK) {
2408             return NGX_ERROR;
2409         }
2410     }
2411 
2412     if (ngx_ssl_client_session_cache(cf, uwcf->upstream.ssl,
2413                                      uwcf->upstream.ssl_session_reuse)
2414         != NGX_OK)
2415     {
2416         return NGX_ERROR;
2417     }
2418 
2419     return NGX_OK;
2420 }
2421 
2422 #endif