~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Nginx/http/modules/ngx_http_uwsgi_module.c

Version: ~ [ nginx-1.4.1 ] ~ [ nginx-1.5.0 ] ~

  1 
  2 /*
  3  * Copyright (C) Unbit S.a.s. 2009-2010
  4  * Copyright (C) 2008 Manlio Perillo (manlio.perillo@gmail.com)
  5  * Copyright (C) Igor Sysoev
  6  * Copyright (C) Nginx, Inc.
  7  */
  8 
  9 
 10 #include <ngx_config.h>
 11 #include <ngx_core.h>
 12 #include <ngx_http.h>
 13 
 14 
 15 typedef struct {
 16     ngx_http_upstream_conf_t   upstream;
 17 
 18     ngx_array_t               *flushes;
 19     ngx_array_t               *params_len;
 20     ngx_array_t               *params;
 21     ngx_array_t               *params_source;
 22 
 23     ngx_hash_t                 headers_hash;
 24     ngx_uint_t                 header_params;
 25 
 26     ngx_array_t               *uwsgi_lengths;
 27     ngx_array_t               *uwsgi_values;
 28 
 29 #if (NGX_HTTP_CACHE)
 30     ngx_http_complex_value_t   cache_key;
 31 #endif
 32 
 33     ngx_str_t                  uwsgi_string;
 34 
 35     ngx_uint_t                 modifier1;
 36     ngx_uint_t                 modifier2;
 37 } ngx_http_uwsgi_loc_conf_t;
 38 
 39 
 40 static ngx_int_t ngx_http_uwsgi_eval(ngx_http_request_t *r,
 41     ngx_http_uwsgi_loc_conf_t *uwcf);
 42 static ngx_int_t ngx_http_uwsgi_create_request(ngx_http_request_t *r);
 43 static ngx_int_t ngx_http_uwsgi_reinit_request(ngx_http_request_t *r);
 44 static ngx_int_t ngx_http_uwsgi_process_status_line(ngx_http_request_t *r);
 45 static ngx_int_t ngx_http_uwsgi_process_header(ngx_http_request_t *r);
 46 static void ngx_http_uwsgi_abort_request(ngx_http_request_t *r);
 47 static void ngx_http_uwsgi_finalize_request(ngx_http_request_t *r,
 48     ngx_int_t rc);
 49 
 50 static void *ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf);
 51 static char *ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent,
 52     void *child);
 53 static ngx_int_t ngx_http_uwsgi_merge_params(ngx_conf_t *cf,
 54     ngx_http_uwsgi_loc_conf_t *conf, ngx_http_uwsgi_loc_conf_t *prev);
 55 
 56 static char *ngx_http_uwsgi_pass(ngx_conf_t *cf, ngx_command_t *cmd,
 57     void *conf);
 58 static char *ngx_http_uwsgi_store(ngx_conf_t *cf, ngx_command_t *cmd,
 59     void *conf);
 60 
 61 #if (NGX_HTTP_CACHE)
 62 static ngx_int_t ngx_http_uwsgi_create_key(ngx_http_request_t *r);
 63 static char *ngx_http_uwsgi_cache(ngx_conf_t *cf, ngx_command_t *cmd,
 64     void *conf);
 65 static char *ngx_http_uwsgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd,
 66     void *conf);
 67 #endif
 68 
 69 
 70 static ngx_conf_num_bounds_t  ngx_http_uwsgi_modifier_bounds = {
 71     ngx_conf_check_num_bounds, 0, 255
 72 };
 73 
 74 
 75 static ngx_conf_bitmask_t ngx_http_uwsgi_next_upstream_masks[] = {
 76     { ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR },
 77     { ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT },
 78     { ngx_string("invalid_header"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER },
 79     { ngx_string("http_500"), NGX_HTTP_UPSTREAM_FT_HTTP_500 },
 80     { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
 81     { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
 82     { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
 83     { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
 84     { ngx_null_string, 0 }
 85 };
 86 
 87 
 88 ngx_module_t  ngx_http_uwsgi_module;
 89 
 90 
 91 static ngx_command_t ngx_http_uwsgi_commands[] = {
 92 
 93     { ngx_string("uwsgi_pass"),
 94       NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
 95       ngx_http_uwsgi_pass,
 96       NGX_HTTP_LOC_CONF_OFFSET,
 97       0,
 98       NULL },
 99 
100     { ngx_string("uwsgi_modifier1"),
101       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
102       ngx_conf_set_num_slot,
103       NGX_HTTP_LOC_CONF_OFFSET,
104       offsetof(ngx_http_uwsgi_loc_conf_t, modifier1),
105       &ngx_http_uwsgi_modifier_bounds },
106 
107     { ngx_string("uwsgi_modifier2"),
108       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
109       ngx_conf_set_num_slot,
110       NGX_HTTP_LOC_CONF_OFFSET,
111       offsetof(ngx_http_uwsgi_loc_conf_t, modifier2),
112       &ngx_http_uwsgi_modifier_bounds },
113 
114     { ngx_string("uwsgi_store"),
115       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
116       ngx_http_uwsgi_store,
117       NGX_HTTP_LOC_CONF_OFFSET,
118       0,
119       NULL },
120 
121     { ngx_string("uwsgi_store_access"),
122       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
123       ngx_conf_set_access_slot,
124       NGX_HTTP_LOC_CONF_OFFSET,
125       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.store_access),
126       NULL },
127 
128     { ngx_string("uwsgi_buffering"),
129       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
130       ngx_conf_set_flag_slot,
131       NGX_HTTP_LOC_CONF_OFFSET,
132       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.buffering),
133       NULL },
134 
135     { ngx_string("uwsgi_ignore_client_abort"),
136       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
137       ngx_conf_set_flag_slot,
138       NGX_HTTP_LOC_CONF_OFFSET,
139       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.ignore_client_abort),
140       NULL },
141 
142     { ngx_string("uwsgi_bind"),
143       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
144       ngx_http_upstream_bind_set_slot,
145       NGX_HTTP_LOC_CONF_OFFSET,
146       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.local),
147       NULL },
148 
149     { ngx_string("uwsgi_connect_timeout"),
150       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
151       ngx_conf_set_msec_slot,
152       NGX_HTTP_LOC_CONF_OFFSET,
153       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.connect_timeout),
154       NULL },
155 
156     { ngx_string("uwsgi_send_timeout"),
157       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
158       ngx_conf_set_msec_slot,
159       NGX_HTTP_LOC_CONF_OFFSET,
160       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.send_timeout),
161       NULL },
162 
163     { ngx_string("uwsgi_buffer_size"),
164       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
165       ngx_conf_set_size_slot,
166       NGX_HTTP_LOC_CONF_OFFSET,
167       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.buffer_size),
168       NULL },
169 
170     { ngx_string("uwsgi_pass_request_headers"),
171       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
172       ngx_conf_set_flag_slot,
173       NGX_HTTP_LOC_CONF_OFFSET,
174       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.pass_request_headers),
175       NULL },
176 
177     { ngx_string("uwsgi_pass_request_body"),
178       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
179       ngx_conf_set_flag_slot,
180       NGX_HTTP_LOC_CONF_OFFSET,
181       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.pass_request_body),
182       NULL },
183 
184     { ngx_string("uwsgi_intercept_errors"),
185       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
186       ngx_conf_set_flag_slot,
187       NGX_HTTP_LOC_CONF_OFFSET,
188       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.intercept_errors),
189       NULL },
190 
191     { ngx_string("uwsgi_read_timeout"),
192       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
193       ngx_conf_set_msec_slot,
194       NGX_HTTP_LOC_CONF_OFFSET,
195       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.read_timeout),
196       NULL },
197 
198     { ngx_string("uwsgi_buffers"),
199       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
200       ngx_conf_set_bufs_slot,
201       NGX_HTTP_LOC_CONF_OFFSET,
202       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.bufs),
203       NULL },
204 
205     { ngx_string("uwsgi_busy_buffers_size"),
206       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
207       ngx_conf_set_size_slot,
208       NGX_HTTP_LOC_CONF_OFFSET,
209       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.busy_buffers_size_conf),
210       NULL },
211 
212 #if (NGX_HTTP_CACHE)
213 
214     { ngx_string("uwsgi_cache"),
215       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
216       ngx_http_uwsgi_cache,
217       NGX_HTTP_LOC_CONF_OFFSET,
218       0,
219       NULL },
220 
221     { ngx_string("uwsgi_cache_key"),
222       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
223       ngx_http_uwsgi_cache_key,
224       NGX_HTTP_LOC_CONF_OFFSET,
225       0,
226       NULL },
227 
228     { ngx_string("uwsgi_cache_path"),
229       NGX_HTTP_MAIN_CONF|NGX_CONF_2MORE,
230       ngx_http_file_cache_set_slot,
231       0,
232       0,
233       &ngx_http_uwsgi_module },
234 
235     { ngx_string("uwsgi_cache_bypass"),
236       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
237       ngx_http_set_predicate_slot,
238       NGX_HTTP_LOC_CONF_OFFSET,
239       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_bypass),
240       NULL },
241 
242     { ngx_string("uwsgi_no_cache"),
243       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
244       ngx_http_set_predicate_slot,
245       NGX_HTTP_LOC_CONF_OFFSET,
246       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.no_cache),
247       NULL },
248 
249     { ngx_string("uwsgi_cache_valid"),
250       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
251       ngx_http_file_cache_valid_set_slot,
252       NGX_HTTP_LOC_CONF_OFFSET,
253       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_valid),
254       NULL },
255 
256     { ngx_string("uwsgi_cache_min_uses"),
257       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
258       ngx_conf_set_num_slot,
259       NGX_HTTP_LOC_CONF_OFFSET,
260       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_min_uses),
261       NULL },
262 
263     { ngx_string("uwsgi_cache_use_stale"),
264       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
265       ngx_conf_set_bitmask_slot,
266       NGX_HTTP_LOC_CONF_OFFSET,
267       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_use_stale),
268       &ngx_http_uwsgi_next_upstream_masks },
269 
270     { ngx_string("uwsgi_cache_methods"),
271       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
272       ngx_conf_set_bitmask_slot,
273       NGX_HTTP_LOC_CONF_OFFSET,
274       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_methods),
275       &ngx_http_upstream_cache_method_mask },
276 
277     { ngx_string("uwsgi_cache_lock"),
278       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
279       ngx_conf_set_flag_slot,
280       NGX_HTTP_LOC_CONF_OFFSET,
281       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_lock),
282       NULL },
283 
284     { ngx_string("uwsgi_cache_lock_timeout"),
285       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
286       ngx_conf_set_msec_slot,
287       NGX_HTTP_LOC_CONF_OFFSET,
288       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_lock_timeout),
289       NULL },
290 
291 #endif
292 
293     { ngx_string("uwsgi_temp_path"),
294       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
295       ngx_conf_set_path_slot,
296       NGX_HTTP_LOC_CONF_OFFSET,
297       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.temp_path),
298       NULL },
299 
300     { ngx_string("uwsgi_max_temp_file_size"),
301       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
302       ngx_conf_set_size_slot,
303       NGX_HTTP_LOC_CONF_OFFSET,
304       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.max_temp_file_size_conf),
305       NULL },
306 
307     { ngx_string("uwsgi_temp_file_write_size"),
308       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
309       ngx_conf_set_size_slot,
310       NGX_HTTP_LOC_CONF_OFFSET,
311       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.temp_file_write_size_conf),
312       NULL },
313 
314     { ngx_string("uwsgi_next_upstream"),
315       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
316       ngx_conf_set_bitmask_slot,
317       NGX_HTTP_LOC_CONF_OFFSET,
318       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.next_upstream),
319       &ngx_http_uwsgi_next_upstream_masks },
320 
321     { ngx_string("uwsgi_param"),
322       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE23,
323       ngx_http_upstream_param_set_slot,
324       NGX_HTTP_LOC_CONF_OFFSET,
325       offsetof(ngx_http_uwsgi_loc_conf_t, params_source),
326       NULL },
327 
328     { ngx_string("uwsgi_string"),
329       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
330       ngx_conf_set_str_slot,
331       NGX_HTTP_LOC_CONF_OFFSET,
332       offsetof(ngx_http_uwsgi_loc_conf_t, uwsgi_string),
333       NULL },
334 
335     { ngx_string("uwsgi_pass_header"),
336       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
337       ngx_conf_set_str_array_slot,
338       NGX_HTTP_LOC_CONF_OFFSET,
339       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.pass_headers),
340       NULL },
341 
342     { ngx_string("uwsgi_hide_header"),
343       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
344       ngx_conf_set_str_array_slot,
345       NGX_HTTP_LOC_CONF_OFFSET,
346       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.hide_headers),
347       NULL },
348 
349     { ngx_string("uwsgi_ignore_headers"),
350       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
351       ngx_conf_set_bitmask_slot,
352       NGX_HTTP_LOC_CONF_OFFSET,
353       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.ignore_headers),
354       &ngx_http_upstream_ignore_headers_masks },
355 
356       ngx_null_command
357 };
358 
359 
360 static ngx_http_module_t ngx_http_uwsgi_module_ctx = {
361     NULL,                                  /* preconfiguration */
362     NULL,                                  /* postconfiguration */
363 
364     NULL,                                  /* create main configuration */
365     NULL,                                  /* init main configuration */
366 
367     NULL,                                  /* create server configuration */
368     NULL,                                  /* merge server configuration */
369 
370     ngx_http_uwsgi_create_loc_conf,        /* create location configuration */
371     ngx_http_uwsgi_merge_loc_conf          /* merge location configuration */
372 };
373 
374 
375 ngx_module_t ngx_http_uwsgi_module = {
376     NGX_MODULE_V1,
377     &ngx_http_uwsgi_module_ctx,            /* module context */
378     ngx_http_uwsgi_commands,               /* module directives */
379     NGX_HTTP_MODULE,                       /* module type */
380     NULL,                                  /* init master */
381     NULL,                                  /* init module */
382     NULL,                                  /* init process */
383     NULL,                                  /* init thread */
384     NULL,                                  /* exit thread */
385     NULL,                                  /* exit process */
386     NULL,                                  /* exit master */
387     NGX_MODULE_V1_PADDING
388 };
389 
390 
391 static ngx_str_t ngx_http_uwsgi_hide_headers[] = {
392     ngx_string("X-Accel-Expires"),
393     ngx_string("X-Accel-Redirect"),
394     ngx_string("X-Accel-Limit-Rate"),
395     ngx_string("X-Accel-Buffering"),
396     ngx_string("X-Accel-Charset"),
397     ngx_null_string
398 };
399 
400 
401 #if (NGX_HTTP_CACHE)
402 
403 static ngx_keyval_t  ngx_http_uwsgi_cache_headers[] = {
404     { ngx_string("HTTP_IF_MODIFIED_SINCE"), ngx_string("") },
405     { ngx_string("HTTP_IF_UNMODIFIED_SINCE"), ngx_string("") },
406     { ngx_string("HTTP_IF_NONE_MATCH"), ngx_string("") },
407     { ngx_string("HTTP_IF_MATCH"), ngx_string("") },
408     { ngx_string("HTTP_RANGE"), ngx_string("") },
409     { ngx_string("HTTP_IF_RANGE"), ngx_string("") },
410     { ngx_null_string, ngx_null_string }
411 };
412 
413 #endif
414 
415 
416 static ngx_path_init_t ngx_http_uwsgi_temp_path = {
417     ngx_string(NGX_HTTP_UWSGI_TEMP_PATH), { 1, 2, 0 }
418 };
419 
420 
421 static ngx_int_t
422 ngx_http_uwsgi_handler(ngx_http_request_t *r)
423 {
424     ngx_int_t                   rc;
425     ngx_http_status_t          *status;
426     ngx_http_upstream_t        *u;
427     ngx_http_uwsgi_loc_conf_t  *uwcf;
428 
429     if (r->subrequest_in_memory) {
430         ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
431                       "ngx_http_uwsgi_module does not support "
432                       "subrequests in memory");
433         return NGX_HTTP_INTERNAL_SERVER_ERROR;
434     }
435 
436     if (ngx_http_upstream_create(r) != NGX_OK) {
437         return NGX_HTTP_INTERNAL_SERVER_ERROR;
438     }
439 
440     status = ngx_pcalloc(r->pool, sizeof(ngx_http_status_t));
441     if (status == NULL) {
442         return NGX_HTTP_INTERNAL_SERVER_ERROR;
443     }
444 
445     ngx_http_set_ctx(r, status, ngx_http_uwsgi_module);
446 
447     uwcf = ngx_http_get_module_loc_conf(r, ngx_http_uwsgi_module);
448 
449     if (uwcf->uwsgi_lengths) {
450         if (ngx_http_uwsgi_eval(r, uwcf) != NGX_OK) {
451             return NGX_HTTP_INTERNAL_SERVER_ERROR;
452         }
453     }
454 
455     u = r->upstream;
456 
457     ngx_str_set(&u->schema, "uwsgi://");
458     u->output.tag = (ngx_buf_tag_t) &ngx_http_uwsgi_module;
459 
460     u->conf = &uwcf->upstream;
461 
462 #if (NGX_HTTP_CACHE)
463     u->create_key = ngx_http_uwsgi_create_key;
464 #endif
465     u->create_request = ngx_http_uwsgi_create_request;
466     u->reinit_request = ngx_http_uwsgi_reinit_request;
467     u->process_header = ngx_http_uwsgi_process_status_line;
468     u->abort_request = ngx_http_uwsgi_abort_request;
469     u->finalize_request = ngx_http_uwsgi_finalize_request;
470     r->state = 0;
471 
472     u->buffering = uwcf->upstream.buffering;
473 
474     u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t));
475     if (u->pipe == NULL) {
476         return NGX_HTTP_INTERNAL_SERVER_ERROR;
477     }
478 
479     u->pipe->input_filter = ngx_event_pipe_copy_input_filter;
480     u->pipe->input_ctx = r;
481 
482     rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init);
483 
484     if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
485         return rc;
486     }
487 
488     return NGX_DONE;
489 }
490 
491 
492 static ngx_int_t
493 ngx_http_uwsgi_eval(ngx_http_request_t *r, ngx_http_uwsgi_loc_conf_t * uwcf)
494 {
495     ngx_url_t             url;
496     ngx_http_upstream_t  *u;
497 
498     ngx_memzero(&url, sizeof(ngx_url_t));
499 
500     if (ngx_http_script_run(r, &url.url, uwcf->uwsgi_lengths->elts, 0,
501                             uwcf->uwsgi_values->elts)
502         == NULL)
503     {
504         return NGX_ERROR;
505     }
506 
507     url.no_resolve = 1;
508 
509     if (ngx_parse_url(r->pool, &url) != NGX_OK) {
510         if (url.err) {
511             ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
512                           "%s in upstream \"%V\"", url.err, &url.url);
513         }
514 
515         return NGX_ERROR;
516     }
517 
518     u = r->upstream;
519 
520     u->resolved = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t));
521     if (u->resolved == NULL) {
522         return NGX_ERROR;
523     }
524 
525     if (url.addrs && url.addrs[0].sockaddr) {
526         u->resolved->sockaddr = url.addrs[0].sockaddr;
527         u->resolved->socklen = url.addrs[0].socklen;
528         u->resolved->naddrs = 1;
529         u->resolved->host = url.addrs[0].name;
530 
531     } else {
532         u->resolved->host = url.host;
533         u->resolved->port = url.port;
534         u->resolved->no_port = url.no_port;
535     }
536 
537     return NGX_OK;
538 }
539 
540 
541 #if (NGX_HTTP_CACHE)
542 
543 static ngx_int_t
544 ngx_http_uwsgi_create_key(ngx_http_request_t *r)
545 {
546     ngx_str_t                  *key;
547     ngx_http_uwsgi_loc_conf_t  *uwcf;
548 
549     key = ngx_array_push(&r->cache->keys);
550     if (key == NULL) {
551         return NGX_ERROR;
552     }
553 
554     uwcf = ngx_http_get_module_loc_conf(r, ngx_http_uwsgi_module);
555 
556     if (ngx_http_complex_value(r, &uwcf->cache_key, key) != NGX_OK) {
557         return NGX_ERROR;
558     }
559 
560     return NGX_OK;
561 }
562 
563 #endif
564 
565 
566 static ngx_int_t
567 ngx_http_uwsgi_create_request(ngx_http_request_t *r)
568 {
569     u_char                        ch, *lowcase_key;
570     size_t                        key_len, val_len, len, allocated;
571     ngx_uint_t                    i, n, hash, skip_empty, header_params;
572     ngx_buf_t                    *b;
573     ngx_chain_t                  *cl, *body;
574     ngx_list_part_t              *part;
575     ngx_table_elt_t              *header, **ignored;
576     ngx_http_script_code_pt       code;
577     ngx_http_script_engine_t      e, le;
578     ngx_http_uwsgi_loc_conf_t    *uwcf;
579     ngx_http_script_len_code_pt   lcode;
580 
581     len = 0;
582     header_params = 0;
583     ignored = NULL;
584 
585     uwcf = ngx_http_get_module_loc_conf(r, ngx_http_uwsgi_module);
586 
587     if (uwcf->params_len) {
588         ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
589 
590         ngx_http_script_flush_no_cacheable_variables(r, uwcf->flushes);
591         le.flushed = 1;
592 
593         le.ip = uwcf->params_len->elts;
594         le.request = r;
595 
596         while (*(uintptr_t *) le.ip) {
597 
598             lcode = *(ngx_http_script_len_code_pt *) le.ip;
599             key_len = lcode(&le);
600 
601             lcode = *(ngx_http_script_len_code_pt *) le.ip;
602             skip_empty = lcode(&le);
603 
604             for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode (&le)) {
605                 lcode = *(ngx_http_script_len_code_pt *) le.ip;
606             }
607             le.ip += sizeof(uintptr_t);
608 
609             if (skip_empty && val_len == 0) {
610                 continue;
611             }
612 
613             len += 2 + key_len + 2 + val_len;
614         }
615     }
616 
617     if (uwcf->upstream.pass_request_headers) {
618 
619         allocated = 0;
620         lowcase_key = NULL;
621 
622         if (uwcf->header_params) {
623             n = 0;
624             part = &r->headers_in.headers.part;
625 
626             while (part) {
627                 n += part->nelts;
628                 part = part->next;
629             }
630 
631             ignored = ngx_palloc(r->pool, n * sizeof(void *));
632             if (ignored == NULL) {
633                 return NGX_ERROR;
634             }
635         }
636 
637         part = &r->headers_in.headers.part;
638         header = part->elts;
639 
640         for (i = 0; /* void */ ; i++) {
641 
642             if (i >= part->nelts) {
643                 if (part->next == NULL) {
644                     break;
645                 }
646 
647                 part = part->next;
648                 header = part->elts;
649                 i = 0;
650             }
651 
652             if (uwcf->header_params) {
653                 if (allocated < header[i].key.len) {
654                     allocated = header[i].key.len + 16;
655                     lowcase_key = ngx_pnalloc(r->pool, allocated);
656                     if (lowcase_key == NULL) {
657                         return NGX_ERROR;
658                     }
659                 }
660 
661                 hash = 0;
662 
663                 for (n = 0; n < header[i].key.len; n++) {
664                     ch = header[i].key.data[n];
665 
666                     if (ch >= 'A' && ch <= 'Z') {
667                         ch |= 0x20;
668 
669                     } else if (ch == '-') {
670                         ch = '_';
671                     }
672 
673                     hash = ngx_hash(hash, ch);
674                     lowcase_key[n] = ch;
675                 }
676 
677                 if (ngx_hash_find(&uwcf->headers_hash, hash, lowcase_key, n)) {
678                     ignored[header_params++] = &header[i];
679                     continue;
680                 }
681             }
682 
683             len += 2 + sizeof("HTTP_") - 1 + header[i].key.len
684                  + 2 + header[i].value.len;
685         }
686     }
687 
688     len += uwcf->uwsgi_string.len;
689 
690 #if 0
691     /* allow custom uwsgi packet */
692     if (len > 0 && len < 2) {
693         ngx_log_error (NGX_LOG_ALERT, r->connection->log, 0,
694                        "uwsgi request is too little: %uz", len);
695         return NGX_ERROR;
696     }
697 #endif
698 
699     b = ngx_create_temp_buf(r->pool, len + 4);
700     if (b == NULL) {
701         return NGX_ERROR;
702     }
703 
704     cl = ngx_alloc_chain_link(r->pool);
705     if (cl == NULL) {
706         return NGX_ERROR;
707     }
708 
709     cl->buf = b;
710 
711     *b->last++ = (u_char) uwcf->modifier1;
712     *b->last++ = (u_char) (len & 0xff);
713     *b->last++ = (u_char) ((len >> 8) & 0xff);
714     *b->last++ = (u_char) uwcf->modifier2;
715 
716     if (uwcf->params_len) {
717         ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
718 
719         e.ip = uwcf->params->elts;
720         e.pos = b->last;
721         e.request = r;
722         e.flushed = 1;
723 
724         le.ip = uwcf->params_len->elts;
725 
726         while (*(uintptr_t *) le.ip) {
727 
728             lcode = *(ngx_http_script_len_code_pt *) le.ip;
729             key_len = (u_char) lcode (&le);
730 
731             lcode = *(ngx_http_script_len_code_pt *) le.ip;
732             skip_empty = lcode(&le);
733 
734             for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) {
735                 lcode = *(ngx_http_script_len_code_pt *) le.ip;
736             }
737             le.ip += sizeof(uintptr_t);
738 
739             if (skip_empty && val_len == 0) {
740                 e.skip = 1;
741 
742                 while (*(uintptr_t *) e.ip) {
743                     code = *(ngx_http_script_code_pt *) e.ip;
744                     code((ngx_http_script_engine_t *) &e);
745                 }
746                 e.ip += sizeof(uintptr_t);
747 
748                 e.skip = 0;
749 
750                 continue;
751             }
752 
753             *e.pos++ = (u_char) (key_len & 0xff);
754             *e.pos++ = (u_char) ((key_len >> 8) & 0xff);
755 
756             code = *(ngx_http_script_code_pt *) e.ip;
757             code((ngx_http_script_engine_t *) & e);
758 
759             *e.pos++ = (u_char) (val_len & 0xff);
760             *e.pos++ = (u_char) ((val_len >> 8) & 0xff);
761 
762             while (*(uintptr_t *) e.ip) {
763                 code = *(ngx_http_script_code_pt *) e.ip;
764                 code((ngx_http_script_engine_t *) & e);
765             }
766 
767             e.ip += sizeof(uintptr_t);
768 
769             ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
770                            "uwsgi param: \"%*s: %*s\"",
771                            key_len, e.pos - (key_len + 2 + val_len),
772                            val_len, e.pos - val_len);
773         }
774 
775         b->last = e.pos;
776     }
777 
778     if (uwcf->upstream.pass_request_headers) {
779 
780         part = &r->headers_in.headers.part;
781         header = part->elts;
782 
783         for (i = 0; /* void */ ; i++) {
784 
785             if (i >= part->nelts) {
786                 if (part->next == NULL) {
787                     break;
788                 }
789 
790                 part = part->next;
791                 header = part->elts;
792                 i = 0;
793             }
794 
795             for (n = 0; n < header_params; n++) {
796                 if (&header[i] == ignored[n]) {
797                     goto next;
798                 }
799             }
800 
801             key_len = sizeof("HTTP_") - 1 + header[i].key.len;
802             *b->last++ = (u_char) (key_len & 0xff);
803             *b->last++ = (u_char) ((key_len >> 8) & 0xff);
804 
805             b->last = ngx_cpymem(b->last, "HTTP_", sizeof("HTTP_") - 1);
806             for (n = 0; n < header[i].key.len; n++) {
807                 ch = header[i].key.data[n];
808 
809                 if (ch >= 'a' && ch <= 'z') {
810                     ch &= ~0x20;
811 
812                 } else if (ch == '-') {
813                     ch = '_';
814                 }
815 
816                 *b->last++ = ch;
817             }
818 
819             val_len = header[i].value.len;
820             *b->last++ = (u_char) (val_len & 0xff);
821             *b->last++ = (u_char) ((val_len >> 8) & 0xff);
822             b->last = ngx_copy(b->last, header[i].value.data, val_len);
823 
824             ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
825                            "uwsgi param: \"%*s: %*s\"",
826                            key_len, b->last - (key_len + 2 + val_len),
827                            val_len, b->last - val_len);
828         next:
829 
830             continue;
831         }
832     }
833 
834     b->last = ngx_copy(b->last, uwcf->uwsgi_string.data,
835                        uwcf->uwsgi_string.len);
836 
837     if (uwcf->upstream.pass_request_body) {
838         body = r->upstream->request_bufs;
839         r->upstream->request_bufs = cl;
840 
841         while (body) {
842             b = ngx_alloc_buf(r->pool);
843             if (b == NULL) {
844                 return NGX_ERROR;
845             }
846 
847             ngx_memcpy(b, body->buf, sizeof(ngx_buf_t));
848 
849             cl->next = ngx_alloc_chain_link(r->pool);
850             if (cl->next == NULL) {
851                 return NGX_ERROR;
852             }
853 
854             cl = cl->next;
855             cl->buf = b;
856 
857             body = body->next;
858         }
859 
860     } else {
861         r->upstream->request_bufs = cl;
862     }
863 
864     cl->next = NULL;
865 
866     return NGX_OK;
867 }
868 
869 
870 static ngx_int_t
871 ngx_http_uwsgi_reinit_request(ngx_http_request_t *r)
872 {
873     ngx_http_status_t  *status;
874 
875     status = ngx_http_get_module_ctx(r, ngx_http_uwsgi_module);
876 
877     if (status == NULL) {
878         return NGX_OK;
879     }
880 
881     status->code = 0;
882     status->count = 0;
883     status->start = NULL;
884     status->end = NULL;
885 
886     r->upstream->process_header = ngx_http_uwsgi_process_status_line;
887     r->state = 0;
888 
889     return NGX_OK;
890 }
891 
892 
893 static ngx_int_t
894 ngx_http_uwsgi_process_status_line(ngx_http_request_t *r)
895 {
896     size_t                 len;
897     ngx_int_t              rc;
898     ngx_http_status_t     *status;
899     ngx_http_upstream_t   *u;
900 
901     status = ngx_http_get_module_ctx(r, ngx_http_uwsgi_module);
902 
903     if (status == NULL) {
904         return NGX_ERROR;
905     }
906 
907     u = r->upstream;
908 
909     rc = ngx_http_parse_status_line(r, &u->buffer, status);
910 
911     if (rc == NGX_AGAIN) {
912         return rc;
913     }
914 
915     if (rc == NGX_ERROR) {
916         u->process_header = ngx_http_uwsgi_process_header;
917         return ngx_http_uwsgi_process_header(r);
918     }
919 
920     if (u->state) {
921         u->state->status = status->code;
922     }
923 
924     u->headers_in.status_n = status->code;
925 
926     len = status->end - status->start;
927     u->headers_in.status_line.len = len;
928 
929     u->headers_in.status_line.data = ngx_pnalloc(r->pool, len);
930     if (u->headers_in.status_line.data == NULL) {
931         return NGX_ERROR;
932     }
933 
934     ngx_memcpy(u->headers_in.status_line.data, status->start, len);
935 
936     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
937                    "http uwsgi status %ui \"%V\"",
938                    u->headers_in.status_n, &u->headers_in.status_line);
939 
940     u->process_header = ngx_http_uwsgi_process_header;
941 
942     return ngx_http_uwsgi_process_header(r);
943 }
944 
945 
946 static ngx_int_t
947 ngx_http_uwsgi_process_header(ngx_http_request_t *r)
948 {
949     ngx_str_t                      *status_line;
950     ngx_int_t                       rc, status;
951     ngx_table_elt_t                *h;
952     ngx_http_upstream_t            *u;
953     ngx_http_upstream_header_t     *hh;
954     ngx_http_upstream_main_conf_t  *umcf;
955 
956     umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
957 
958     for ( ;; ) {
959 
960         rc = ngx_http_parse_header_line(r, &r->upstream->buffer, 1);
961 
962         if (rc == NGX_OK) {
963 
964             /* a header line has been parsed successfully */
965 
966             h = ngx_list_push(&r->upstream->headers_in.headers);
967             if (h == NULL) {
968                 return NGX_ERROR;
969             }
970 
971             h->hash = r->header_hash;
972 
973             h->key.len = r->header_name_end - r->header_name_start;
974             h->value.len = r->header_end - r->header_start;
975 
976             h->key.data = ngx_pnalloc(r->pool,
977                                       h->key.len + 1 + h->value.len + 1
978                                       + h->key.len);
979             if (h->key.data == NULL) {
980                 return NGX_ERROR;
981             }
982 
983             h->value.data = h->key.data + h->key.len + 1;
984             h->lowcase_key = h->key.data + h->key.len + 1 + h->value.len + 1;
985 
986             ngx_memcpy(h->key.data, r->header_name_start, h->key.len);
987             h->key.data[h->key.len] = '\0';
988             ngx_memcpy(h->value.data, r->header_start, h->value.len);
989             h->value.data[h->value.len] = '\0';
990 
991             if (h->key.len == r->lowcase_index) {
992                 ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);
993 
994             } else {
995                 ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
996             }
997 
998             hh = ngx_hash_find(&umcf->headers_in_hash, h->hash,
999                                h->lowcase_key, h->key.len);
1000 
1001             if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
1002                 return NGX_ERROR;
1003             }
1004 
1005             ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1006                            "http uwsgi header: \"%V: %V\"", &h->key, &h->value);
1007 
1008             continue;
1009         }
1010 
1011         if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
1012 
1013             /* a whole header has been parsed successfully */
1014 
1015             ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1016                            "http uwsgi header done");
1017 
1018             u = r->upstream;
1019 
1020             if (u->headers_in.status_n) {
1021                 goto done;
1022             }
1023 
1024             if (u->headers_in.status) {
1025                 status_line = &u->headers_in.status->value;
1026 
1027                 status = ngx_atoi(status_line->data, 3);
1028                 if (status == NGX_ERROR) {
1029                     ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1030                                   "upstream sent invalid status \"%V\"",
1031                                   status_line);
1032                     return NGX_HTTP_UPSTREAM_INVALID_HEADER;
1033                 }
1034 
1035                 u->headers_in.status_n = status;
1036                 u->headers_in.status_line = *status_line;
1037 
1038             } else if (u->headers_in.location) {
1039                 u->headers_in.status_n = 302;
1040                 ngx_str_set(&u->headers_in.status_line,
1041                             "302 Moved Temporarily");
1042 
1043             } else {
1044                 u->headers_in.status_n = 200;
1045                 ngx_str_set(&u->headers_in.status_line, "200 OK");
1046             }
1047 
1048             if (u->state) {
1049                 u->state->status = u->headers_in.status_n;
1050             }
1051 
1052         done:
1053 
1054             if (u->headers_in.status_n == NGX_HTTP_SWITCHING_PROTOCOLS
1055                 && r->headers_in.upgrade)
1056             {
1057                 u->upgrade = 1;
1058             }
1059 
1060             return NGX_OK;
1061         }
1062 
1063         if (rc == NGX_AGAIN) {
1064             return NGX_AGAIN;
1065         }
1066 
1067         /* there was error while a header line parsing */
1068 
1069         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1070                       "upstream sent invalid header");
1071 
1072         return NGX_HTTP_UPSTREAM_INVALID_HEADER;
1073     }
1074 }
1075 
1076 
1077 static void
1078 ngx_http_uwsgi_abort_request(ngx_http_request_t *r)
1079 {
1080     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1081                    "abort http uwsgi request");
1082 
1083     return;
1084 }
1085 
1086 
1087 static void
1088 ngx_http_uwsgi_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
1089 {
1090     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1091                    "finalize http uwsgi request");
1092 
1093     return;
1094 }
1095 
1096 
1097 static void *
1098 ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf)
1099 {
1100     ngx_http_uwsgi_loc_conf_t  *conf;
1101 
1102     conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_uwsgi_loc_conf_t));
1103     if (conf == NULL) {
1104         return NULL;
1105     }
1106 
1107     conf->modifier1 = NGX_CONF_UNSET_UINT;
1108     conf->modifier2 = NGX_CONF_UNSET_UINT;
1109 
1110     conf->upstream.store = NGX_CONF_UNSET;
1111     conf->upstream.store_access = NGX_CONF_UNSET_UINT;
1112     conf->upstream.buffering = NGX_CONF_UNSET;
1113     conf->upstream.ignore_client_abort = NGX_CONF_UNSET;
1114 
1115     conf->upstream.local = NGX_CONF_UNSET_PTR;
1116 
1117     conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC;
1118     conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC;
1119     conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC;
1120 
1121     conf->upstream.send_lowat = NGX_CONF_UNSET_SIZE;
1122     conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE;
1123 
1124     conf->upstream.busy_buffers_size_conf = NGX_CONF_UNSET_SIZE;
1125     conf->upstream.max_temp_file_size_conf = NGX_CONF_UNSET_SIZE;
1126     conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE;
1127 
1128     conf->upstream.pass_request_headers = NGX_CONF_UNSET;
1129     conf->upstream.pass_request_body = NGX_CONF_UNSET;
1130 
1131 #if (NGX_HTTP_CACHE)
1132     conf->upstream.cache = NGX_CONF_UNSET_PTR;
1133     conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT;
1134     conf->upstream.cache_bypass = NGX_CONF_UNSET_PTR;
1135     conf->upstream.no_cache = NGX_CONF_UNSET_PTR;
1136     conf->upstream.cache_valid = NGX_CONF_UNSET_PTR;
1137     conf->upstream.cache_lock = NGX_CONF_UNSET;
1138     conf->upstream.cache_lock_timeout = NGX_CONF_UNSET_MSEC;
1139 #endif
1140 
1141     conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
1142     conf->upstream.pass_headers = NGX_CONF_UNSET_PTR;
1143 
1144     conf->upstream.intercept_errors = NGX_CONF_UNSET;
1145 
1146     /* "uwsgi_cyclic_temp_file" is disabled */
1147     conf->upstream.cyclic_temp_file = 0;
1148 
1149     conf->upstream.change_buffering = 1;
1150 
1151     ngx_str_set(&conf->upstream.module, "uwsgi");
1152 
1153     return conf;
1154 }
1155 
1156 
1157 static char *
1158 ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
1159 {
1160     ngx_http_uwsgi_loc_conf_t *prev = parent;
1161     ngx_http_uwsgi_loc_conf_t *conf = child;
1162 
1163     size_t                        size;
1164     ngx_hash_init_t               hash;
1165     ngx_http_core_loc_conf_t     *clcf;
1166 
1167     if (conf->upstream.store != 0) {
1168         ngx_conf_merge_value(conf->upstream.store, prev->upstream.store, 0);
1169 
1170         if (conf->upstream.store_lengths == NULL) {
1171             conf->upstream.store_lengths = prev->upstream.store_lengths;
1172             conf->upstream.store_values = prev->upstream.store_values;
1173         }
1174     }
1175 
1176     ngx_conf_merge_uint_value(conf->upstream.store_access,
1177                               prev->upstream.store_access, 0600);
1178 
1179     ngx_conf_merge_value(conf->upstream.buffering,
1180                               prev->upstream.buffering, 1);
1181 
1182     ngx_conf_merge_value(conf->upstream.ignore_client_abort,
1183                               prev->upstream.ignore_client_abort, 0);
1184 
1185     ngx_conf_merge_ptr_value(conf->upstream.local,
1186                               prev->upstream.local, NULL);
1187 
1188     ngx_conf_merge_msec_value(conf->upstream.connect_timeout,
1189                               prev->upstream.connect_timeout, 60000);
1190 
1191     ngx_conf_merge_msec_value(conf->upstream.send_timeout,
1192                               prev->upstream.send_timeout, 60000);
1193 
1194     ngx_conf_merge_msec_value(conf->upstream.read_timeout,
1195                               prev->upstream.read_timeout, 60000);
1196 
1197     ngx_conf_merge_size_value(conf->upstream.send_lowat,
1198                               prev->upstream.send_lowat, 0);
1199 
1200     ngx_conf_merge_size_value(conf->upstream.buffer_size,
1201                               prev->upstream.buffer_size,
1202                               (size_t) ngx_pagesize);
1203 
1204 
1205     ngx_conf_merge_bufs_value(conf->upstream.bufs, prev->upstream.bufs,
1206                               8, ngx_pagesize);
1207 
1208     if (conf->upstream.bufs.num < 2) {
1209         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1210                            "there must be at least 2 \"uwsgi_buffers\"");
1211         return NGX_CONF_ERROR;
1212     }
1213 
1214 
1215     size = conf->upstream.buffer_size;
1216     if (size < conf->upstream.bufs.size) {
1217         size = conf->upstream.bufs.size;
1218     }
1219 
1220 
1221     ngx_conf_merge_size_value(conf->upstream.busy_buffers_size_conf,
1222                               prev->upstream.busy_buffers_size_conf,
1223                               NGX_CONF_UNSET_SIZE);
1224 
1225     if (conf->upstream.busy_buffers_size_conf == NGX_CONF_UNSET_SIZE) {
1226         conf->upstream.busy_buffers_size = 2 * size;
1227     } else {
1228         conf->upstream.busy_buffers_size =
1229             conf->upstream.busy_buffers_size_conf;
1230     }
1231 
1232     if (conf->upstream.busy_buffers_size < size) {
1233         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1234             "\"uwsgi_busy_buffers_size\" must be equal to or greater "
1235             "than the maximum of the value of \"uwsgi_buffer_size\" and "
1236             "one of the \"uwsgi_buffers\"");
1237 
1238         return NGX_CONF_ERROR;
1239     }
1240 
1241     if (conf->upstream.busy_buffers_size
1242         > (conf->upstream.bufs.num - 1) * conf->upstream.bufs.size)
1243     {
1244         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1245             "\"uwsgi_busy_buffers_size\" must be less than "
1246             "the size of all \"uwsgi_buffers\" minus one buffer");
1247 
1248         return NGX_CONF_ERROR;
1249     }
1250 
1251 
1252     ngx_conf_merge_size_value(conf->upstream.temp_file_write_size_conf,
1253                               prev->upstream.temp_file_write_size_conf,
1254                               NGX_CONF_UNSET_SIZE);
1255 
1256     if (conf->upstream.temp_file_write_size_conf == NGX_CONF_UNSET_SIZE) {
1257         conf->upstream.temp_file_write_size = 2 * size;
1258     } else {
1259         conf->upstream.temp_file_write_size =
1260             conf->upstream.temp_file_write_size_conf;
1261     }
1262 
1263     if (conf->upstream.temp_file_write_size < size) {
1264         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1265             "\"uwsgi_temp_file_write_size\" must be equal to or greater than "
1266             "the maximum of the value of \"uwsgi_buffer_size\" and "
1267             "one of the \"uwsgi_buffers\"");
1268 
1269         return NGX_CONF_ERROR;
1270     }
1271 
1272 
1273     ngx_conf_merge_size_value(conf->upstream.max_temp_file_size_conf,
1274                               prev->upstream.max_temp_file_size_conf,
1275                               NGX_CONF_UNSET_SIZE);
1276 
1277     if (conf->upstream.max_temp_file_size_conf == NGX_CONF_UNSET_SIZE) {
1278         conf->upstream.max_temp_file_size = 1024 * 1024 * 1024;
1279     } else {
1280         conf->upstream.max_temp_file_size =
1281             conf->upstream.max_temp_file_size_conf;
1282     }
1283 
1284     if (conf->upstream.max_temp_file_size != 0
1285         && conf->upstream.max_temp_file_size < size) {
1286         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1287             "\"uwsgi_max_temp_file_size\" must be equal to zero to disable "
1288             "temporary files usage or must be equal to or greater than "
1289             "the maximum of the value of \"uwsgi_buffer_size\" and "
1290             "one of the \"uwsgi_buffers\"");
1291 
1292         return NGX_CONF_ERROR;
1293     }
1294 
1295 
1296     ngx_conf_merge_bitmask_value(conf->upstream.ignore_headers,
1297                                  prev->upstream.ignore_headers,
1298                                  NGX_CONF_BITMASK_SET);
1299 
1300 
1301     ngx_conf_merge_bitmask_value(conf->upstream.next_upstream,
1302                                  prev->upstream.next_upstream,
1303                                  (NGX_CONF_BITMASK_SET
1304                                   |NGX_HTTP_UPSTREAM_FT_ERROR
1305                                   |NGX_HTTP_UPSTREAM_FT_TIMEOUT));
1306 
1307     if (conf->upstream.next_upstream & NGX_HTTP_UPSTREAM_FT_OFF) {
1308         conf->upstream.next_upstream = NGX_CONF_BITMASK_SET
1309                                        |NGX_HTTP_UPSTREAM_FT_OFF;
1310     }
1311 
1312     if (ngx_conf_merge_path_value(cf, &conf->upstream.temp_path,
1313                                   prev->upstream.temp_path,
1314                                   &ngx_http_uwsgi_temp_path)
1315         != NGX_OK)
1316     {
1317         return NGX_CONF_ERROR;
1318     }
1319 
1320 #if (NGX_HTTP_CACHE)
1321 
1322     ngx_conf_merge_ptr_value(conf->upstream.cache,
1323                               prev->upstream.cache, NULL);
1324 
1325     if (conf->upstream.cache && conf->upstream.cache->data == NULL) {
1326         ngx_shm_zone_t  *shm_zone;
1327 
1328         shm_zone = conf->upstream.cache;
1329 
1330         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1331                            "\"uwsgi_cache\" zone \"%V\" is unknown",
1332                            &shm_zone->shm.name);
1333 
1334         return NGX_CONF_ERROR;
1335     }
1336 
1337     ngx_conf_merge_uint_value(conf->upstream.cache_min_uses,
1338                               prev->upstream.cache_min_uses, 1);
1339 
1340     ngx_conf_merge_bitmask_value(conf->upstream.cache_use_stale,
1341                               prev->upstream.cache_use_stale,
1342                               (NGX_CONF_BITMASK_SET
1343                                |NGX_HTTP_UPSTREAM_FT_OFF));
1344 
1345     if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_OFF) {
1346         conf->upstream.cache_use_stale = NGX_CONF_BITMASK_SET
1347                                          |NGX_HTTP_UPSTREAM_FT_OFF;
1348     }
1349 
1350     if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_ERROR) {
1351         conf->upstream.cache_use_stale |= NGX_HTTP_UPSTREAM_FT_NOLIVE;
1352     }
1353 
1354     if (conf->upstream.cache_methods == 0) {
1355         conf->upstream.cache_methods = prev->upstream.cache_methods;
1356     }
1357 
1358     conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD;
1359 
1360     ngx_conf_merge_ptr_value(conf->upstream.cache_bypass,
1361                              prev->upstream.cache_bypass, NULL);
1362 
1363     ngx_conf_merge_ptr_value(conf->upstream.no_cache,
1364                              prev->upstream.no_cache, NULL);
1365 
1366     ngx_conf_merge_ptr_value(conf->upstream.cache_valid,
1367                              prev->upstream.cache_valid, NULL);
1368 
1369     if (conf->cache_key.value.data == NULL) {
1370         conf->cache_key = prev->cache_key;
1371     }
1372 
1373     ngx_conf_merge_value(conf->upstream.cache_lock,
1374                               prev->upstream.cache_lock, 0);
1375 
1376     ngx_conf_merge_msec_value(conf->upstream.cache_lock_timeout,
1377                               prev->upstream.cache_lock_timeout, 5000);
1378 
1379 #endif
1380 
1381     ngx_conf_merge_value(conf->upstream.pass_request_headers,
1382                          prev->upstream.pass_request_headers, 1);
1383     ngx_conf_merge_value(conf->upstream.pass_request_body,
1384                          prev->upstream.pass_request_body, 1);
1385 
1386     ngx_conf_merge_value(conf->upstream.intercept_errors,
1387                          prev->upstream.intercept_errors, 0);
1388 
1389     ngx_conf_merge_str_value(conf->uwsgi_string, prev->uwsgi_string, "");
1390 
1391     hash.max_size = 512;
1392     hash.bucket_size = ngx_align(64, ngx_cacheline_size);
1393     hash.name = "uwsgi_hide_headers_hash";
1394 
1395     if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream,
1396             &prev->upstream, ngx_http_uwsgi_hide_headers, &hash)
1397         != NGX_OK)
1398     {
1399         return NGX_CONF_ERROR;
1400     }
1401 
1402     if (conf->upstream.upstream == NULL) {
1403         conf->upstream.upstream = prev->upstream.upstream;
1404     }
1405 
1406     if (conf->uwsgi_lengths == NULL) {
1407         conf->uwsgi_lengths = prev->uwsgi_lengths;
1408         conf->uwsgi_values = prev->uwsgi_values;
1409     }
1410 
1411     if (conf->upstream.upstream || conf->uwsgi_lengths) {
1412         clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
1413         if (clcf->handler == NULL && clcf->lmt_excpt) {
1414             clcf->handler = ngx_http_uwsgi_handler;
1415         }
1416     }
1417 
1418     ngx_conf_merge_uint_value(conf->modifier1, prev->modifier1, 0);
1419     ngx_conf_merge_uint_value(conf->modifier2, prev->modifier2, 0);
1420 
1421     if (ngx_http_uwsgi_merge_params(cf, conf, prev) != NGX_OK) {
1422         return NGX_CONF_ERROR;
1423     }
1424 
1425     return NGX_CONF_OK;
1426 }
1427 
1428 
1429 static ngx_int_t
1430 ngx_http_uwsgi_merge_params(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *conf,
1431     ngx_http_uwsgi_loc_conf_t *prev)
1432 {
1433     u_char                       *p;
1434     size_t                        size;
1435     uintptr_t                    *code;
1436     ngx_uint_t                    i, nsrc;
1437     ngx_array_t                   headers_names;
1438 #if (NGX_HTTP_CACHE)
1439     ngx_array_t                   params_merged;
1440 #endif
1441     ngx_hash_key_t               *hk;
1442     ngx_hash_init_t               hash;
1443     ngx_http_upstream_param_t    *src;
1444     ngx_http_script_compile_t     sc;
1445     ngx_http_script_copy_code_t  *copy;
1446 
1447     if (conf->params_source == NULL) {
1448         conf->params_source = prev->params_source;
1449 
1450         if (prev->headers_hash.buckets
1451 #if (NGX_HTTP_CACHE)
1452             && ((conf->upstream.cache == NULL)
1453                 == (prev->upstream.cache == NULL))
1454 #endif
1455            )
1456         {
1457             conf->flushes = prev->flushes;
1458             conf->params_len = prev->params_len;
1459             conf->params = prev->params;
1460             conf->headers_hash = prev->headers_hash;
1461             conf->header_params = prev->header_params;
1462 
1463             return NGX_OK;
1464         }
1465     }
1466 
1467     if (conf->params_source == NULL
1468 #if (NGX_HTTP_CACHE)
1469         && (conf->upstream.cache == NULL)
1470 #endif
1471        )
1472     {
1473         conf->headers_hash.buckets = (void *) 1;
1474         return NGX_OK;
1475     }
1476 
1477     conf->params_len = ngx_array_create(cf->pool, 64, 1);
1478     if (conf->params_len == NULL) {
1479         return NGX_ERROR;
1480     }
1481 
1482     conf->params = ngx_array_create(cf->pool, 512, 1);
1483     if (conf->params == NULL) {
1484         return NGX_ERROR;
1485     }
1486 
1487     if (ngx_array_init(&headers_names, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
1488         != NGX_OK)
1489     {
1490         return NGX_ERROR;
1491     }
1492 
1493     if (conf->params_source) {
1494         src = conf->params_source->elts;
1495         nsrc = conf->params_source->nelts;
1496 
1497     } else {
1498         src = NULL;
1499         nsrc = 0;
1500     }
1501 
1502 #if (NGX_HTTP_CACHE)
1503 
1504     if (conf->upstream.cache) {
1505         ngx_keyval_t               *h;
1506         ngx_http_upstream_param_t  *s;
1507 
1508         if (ngx_array_init(&params_merged, cf->temp_pool, 4,
1509                            sizeof(ngx_http_upstream_param_t))
1510             != NGX_OK)
1511         {
1512             return NGX_ERROR;
1513         }
1514 
1515         for (i = 0; i < nsrc; i++) {
1516 
1517             s = ngx_array_push(&params_merged);
1518             if (s == NULL) {
1519                 return NGX_ERROR;
1520             }
1521 
1522             *s = src[i];
1523         }
1524 
1525         h = ngx_http_uwsgi_cache_headers;
1526 
1527         while (h->key.len) {
1528 
1529             src = params_merged.elts;
1530             nsrc = params_merged.nelts;
1531 
1532             for (i = 0; i < nsrc; i++) {
1533                 if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) {
1534                     goto next;
1535                 }
1536             }
1537 
1538             s = ngx_array_push(&params_merged);
1539             if (s == NULL) {
1540                 return NGX_ERROR;
1541             }
1542 
1543             s->key = h->key;
1544             s->value = h->value;
1545             s->skip_empty = 0;
1546 
1547         next:
1548 
1549             h++;
1550         }
1551 
1552         src = params_merged.elts;
1553         nsrc = params_merged.nelts;
1554     }
1555 
1556 #endif
1557 
1558     for (i = 0; i < nsrc; i++) {
1559 
1560         if (src[i].key.len > sizeof("HTTP_") - 1
1561             && ngx_strncmp(src[i].key.data, "HTTP_", sizeof("HTTP_") - 1) == 0)
1562         {
1563             hk = ngx_array_push(&headers_names);
1564             if (hk == NULL) {
1565                 return NGX_ERROR;
1566             }
1567 
1568             hk->key.len = src[i].key.len - 5;
1569             hk->key.data = src[i].key.data + 5;
1570             hk->key_hash = ngx_hash_key_lc(hk->key.data, hk->key.len);
1571             hk->value = (void *) 1;
1572 
1573             if (src[i].value.len == 0) {
1574                 continue;
1575             }
1576         }
1577 
1578         copy = ngx_array_push_n(conf->params_len,
1579                                 sizeof(ngx_http_script_copy_code_t));
1580         if (copy == NULL) {
1581             return NGX_ERROR;
1582         }
1583 
1584         copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
1585         copy->len = src[i].key.len;
1586 
1587         copy = ngx_array_push_n(conf->params_len,
1588                                 sizeof(ngx_http_script_copy_code_t));
1589         if (copy == NULL) {
1590             return NGX_ERROR;
1591         }
1592 
1593         copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
1594         copy->len = src[i].skip_empty;
1595 
1596 
1597         size = (sizeof(ngx_http_script_copy_code_t)
1598                 + src[i].key.len + sizeof(uintptr_t) - 1)
1599                & ~(sizeof(uintptr_t) - 1);
1600 
1601         copy = ngx_array_push_n(conf->params, size);
1602         if (copy == NULL) {
1603             return NGX_ERROR;
1604         }
1605 
1606         copy->code = ngx_http_script_copy_code;
1607         copy->len = src[i].key.len;
1608 
1609         p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t);
1610         ngx_memcpy(p, src[i].key.data, src[i].key.len);
1611 
1612 
1613         ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
1614 
1615         sc.cf = cf;
1616         sc.source = &src[i].value;
1617         sc.flushes = &conf->flushes;
1618         sc.lengths = &conf->params_len;
1619         sc.values = &conf->params;
1620 
1621         if (ngx_http_script_compile(&sc) != NGX_OK) {
1622             return NGX_ERROR;
1623         }
1624 
1625         code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t));
1626         if (code == NULL) {
1627             return NGX_ERROR;
1628         }
1629 
1630         *code = (uintptr_t) NULL;
1631 
1632 
1633         code = ngx_array_push_n(conf->params, sizeof(uintptr_t));
1634         if (code == NULL) {
1635             return NGX_ERROR;
1636         }
1637 
1638         *code = (uintptr_t) NULL;
1639     }
1640 
1641     code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t));
1642     if (code == NULL) {
1643         return NGX_ERROR;
1644     }
1645 
1646     *code = (uintptr_t) NULL;
1647 
1648     conf->header_params = headers_names.nelts;
1649 
1650     hash.hash = &conf->headers_hash;
1651     hash.key = ngx_hash_key_lc;
1652     hash.max_size = 512;
1653     hash.bucket_size = 64;
1654     hash.name = "uwsgi_params_hash";
1655     hash.pool = cf->pool;
1656     hash.temp_pool = NULL;
1657 
1658     return ngx_hash_init(&hash, headers_names.elts, headers_names.nelts);
1659 }
1660 
1661 
1662 static char *
1663 ngx_http_uwsgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1664 {
1665     ngx_http_uwsgi_loc_conf_t *uwcf = conf;
1666 
1667     ngx_url_t                   u;
1668     ngx_str_t                  *value, *url;
1669     ngx_uint_t                  n;
1670     ngx_http_core_loc_conf_t   *clcf;
1671     ngx_http_script_compile_t   sc;
1672 
1673     if (uwcf->upstream.upstream || uwcf->uwsgi_lengths) {
1674         return "is duplicate";
1675     }
1676 
1677     clcf = ngx_http_conf_get_module_loc_conf (cf, ngx_http_core_module);
1678     clcf->handler = ngx_http_uwsgi_handler;
1679 
1680     value = cf->args->elts;
1681 
1682     url = &value[1];
1683 
1684     n = ngx_http_script_variables_count(url);
1685 
1686     if (n) {
1687 
1688         ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
1689 
1690         sc.cf = cf;
1691         sc.source = url;
1692         sc.lengths = &uwcf->uwsgi_lengths;
1693         sc.values = &uwcf->uwsgi_values;
1694         sc.variables = n;
1695         sc.complete_lengths = 1;
1696         sc.complete_values = 1;
1697 
1698         if (ngx_http_script_compile(&sc) != NGX_OK) {
1699             return NGX_CONF_ERROR;
1700         }
1701 
1702         return NGX_CONF_OK;
1703     }
1704 
1705     ngx_memzero(&u, sizeof(ngx_url_t));
1706 
1707     u.url = value[1];
1708     u.no_resolve = 1;
1709 
1710     uwcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0);
1711     if (uwcf->upstream.upstream == NULL) {
1712         return NGX_CONF_ERROR;
1713     }
1714 
1715     if (clcf->name.data[clcf->name.len - 1] == '/') {
1716         clcf->auto_redirect = 1;
1717     }
1718 
1719     return NGX_CONF_OK;
1720 }
1721 
1722 
1723 static char *
1724 ngx_http_uwsgi_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1725 {
1726     ngx_http_uwsgi_loc_conf_t *uwcf = conf;
1727 
1728     ngx_str_t                  *value;
1729     ngx_http_script_compile_t   sc;
1730 
1731     if (uwcf->upstream.store != NGX_CONF_UNSET || uwcf->upstream.store_lengths)
1732     {
1733         return "is duplicate";
1734     }
1735 
1736     value = cf->args->elts;
1737 
1738     if (ngx_strcmp(value[1].data, "off") == 0) {
1739         uwcf->upstream.store = 0;
1740         return NGX_CONF_OK;
1741     }
1742 
1743 #if (NGX_HTTP_CACHE)
1744 
1745     if (uwcf->upstream.cache != NGX_CONF_UNSET_PTR
1746         && uwcf->upstream.cache != NULL)
1747     {
1748         return "is incompatible with \"uwsgi_cache\"";
1749     }
1750 
1751 #endif
1752 
1753     if (ngx_strcmp(value[1].data, "on") == 0) {
1754         uwcf->upstream.store = 1;
1755         return NGX_CONF_OK;
1756     }
1757 
1758     /* include the terminating '\0' into script */
1759     value[1].len++;
1760 
1761     ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
1762 
1763     sc.cf = cf;
1764     sc.source = &value[1];
1765     sc.lengths = &uwcf->upstream.store_lengths;
1766     sc.values = &uwcf->upstream.store_values;
1767     sc.variables = ngx_http_script_variables_count(&value[1]);;
1768     sc.complete_lengths = 1;
1769     sc.complete_values = 1;
1770 
1771     if (ngx_http_script_compile(&sc) != NGX_OK) {
1772         return NGX_CONF_ERROR;
1773     }
1774 
1775     return NGX_CONF_OK;
1776 }
1777 
1778 
1779 #if (NGX_HTTP_CACHE)
1780 
1781 static char *
1782 ngx_http_uwsgi_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1783 {
1784     ngx_http_uwsgi_loc_conf_t *uwcf = conf;
1785 
1786     ngx_str_t  *value;
1787 
1788     value = cf->args->elts;
1789 
1790     if (uwcf->upstream.cache != NGX_CONF_UNSET_PTR) {
1791         return "is duplicate";
1792     }
1793 
1794     if (ngx_strcmp(value[1].data, "off") == 0) {
1795         uwcf->upstream.cache = NULL;
1796         return NGX_CONF_OK;
1797     }
1798 
1799     if (uwcf->upstream.store > 0 || uwcf->upstream.store_lengths) {
1800         return "is incompatible with \"uwsgi_store\"";
1801     }
1802 
1803     uwcf->upstream.cache = ngx_shared_memory_add(cf, &value[1], 0,
1804                                                  &ngx_http_uwsgi_module);
1805     if (uwcf->upstream.cache == NULL) {
1806         return NGX_CONF_ERROR;
1807     }
1808 
1809     return NGX_CONF_OK;
1810 }
1811 
1812 
1813 static char *
1814 ngx_http_uwsgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1815 {
1816     ngx_http_uwsgi_loc_conf_t *uwcf = conf;
1817 
1818     ngx_str_t                         *value;
1819     ngx_http_compile_complex_value_t   ccv;
1820 
1821     value = cf->args->elts;
1822 
1823     if (uwcf->cache_key.value.data) {
1824         return "is duplicate";
1825     }
1826 
1827     ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
1828 
1829     ccv.cf = cf;
1830     ccv.value = &value[1];
1831     ccv.complex_value = &uwcf->cache_key;
1832 
1833     if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
1834         return NGX_CONF_ERROR;
1835     }
1836 
1837     return NGX_CONF_OK;
1838 }
1839 
1840 #endif
1841 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.