src/http/modules/ngx_http_uwsgi_module.c - nginx-1.7.10

Global variables defined

Data types defined

Functions defined

Source code


  1. /*
  2. * Copyright (C) Unbit S.a.s. 2009-2010
  3. * Copyright (C) 2008 Manlio Perillo (manlio.perillo@gmail.com)
  4. * Copyright (C) Igor Sysoev
  5. * Copyright (C) Nginx, Inc.
  6. */


  7. #include <ngx_config.h>
  8. #include <ngx_core.h>
  9. #include <ngx_http.h>


  10. typedef struct {
  11.     ngx_array_t                caches;  /* ngx_http_file_cache_t * */
  12. } ngx_http_uwsgi_main_conf_t;


  13. typedef struct {
  14.     ngx_array_t               *flushes;
  15.     ngx_array_t               *lengths;
  16.     ngx_array_t               *values;
  17.     ngx_uint_t                 number;
  18.     ngx_hash_t                 hash;
  19. } ngx_http_uwsgi_params_t;


  20. typedef struct {
  21.     ngx_http_upstream_conf_t   upstream;

  22.     ngx_http_uwsgi_params_t    params;
  23. #if (NGX_HTTP_CACHE)
  24.     ngx_http_uwsgi_params_t    params_cache;
  25. #endif
  26.     ngx_array_t               *params_source;

  27.     ngx_array_t               *uwsgi_lengths;
  28.     ngx_array_t               *uwsgi_values;

  29. #if (NGX_HTTP_CACHE)
  30.     ngx_http_complex_value_t   cache_key;
  31. #endif

  32.     ngx_str_t                  uwsgi_string;

  33.     ngx_uint_t                 modifier1;
  34.     ngx_uint_t                 modifier2;

  35. #if (NGX_HTTP_SSL)
  36.     ngx_uint_t                 ssl;
  37.     ngx_uint_t                 ssl_protocols;
  38.     ngx_str_t                  ssl_ciphers;
  39.     ngx_uint_t                 ssl_verify_depth;
  40.     ngx_str_t                  ssl_trusted_certificate;
  41.     ngx_str_t                  ssl_crl;
  42.     ngx_str_t                  ssl_certificate;
  43.     ngx_str_t                  ssl_certificate_key;
  44.     ngx_array_t               *ssl_passwords;
  45. #endif
  46. } ngx_http_uwsgi_loc_conf_t;


  47. static ngx_int_t ngx_http_uwsgi_eval(ngx_http_request_t *r,
  48.     ngx_http_uwsgi_loc_conf_t *uwcf);
  49. static ngx_int_t ngx_http_uwsgi_create_request(ngx_http_request_t *r);
  50. static ngx_int_t ngx_http_uwsgi_reinit_request(ngx_http_request_t *r);
  51. static ngx_int_t ngx_http_uwsgi_process_status_line(ngx_http_request_t *r);
  52. static ngx_int_t ngx_http_uwsgi_process_header(ngx_http_request_t *r);
  53. static void ngx_http_uwsgi_abort_request(ngx_http_request_t *r);
  54. static void ngx_http_uwsgi_finalize_request(ngx_http_request_t *r,
  55.     ngx_int_t rc);

  56. static void *ngx_http_uwsgi_create_main_conf(ngx_conf_t *cf);
  57. static void *ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf);
  58. static char *ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent,
  59.     void *child);
  60. static ngx_int_t ngx_http_uwsgi_init_params(ngx_conf_t *cf,
  61.     ngx_http_uwsgi_loc_conf_t *conf, ngx_http_uwsgi_params_t *params,
  62.     ngx_keyval_t *default_params);

  63. static char *ngx_http_uwsgi_pass(ngx_conf_t *cf, ngx_command_t *cmd,
  64.     void *conf);
  65. static char *ngx_http_uwsgi_store(ngx_conf_t *cf, ngx_command_t *cmd,
  66.     void *conf);

  67. #if (NGX_HTTP_CACHE)
  68. static ngx_int_t ngx_http_uwsgi_create_key(ngx_http_request_t *r);
  69. static char *ngx_http_uwsgi_cache(ngx_conf_t *cf, ngx_command_t *cmd,
  70.     void *conf);
  71. static char *ngx_http_uwsgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd,
  72.     void *conf);
  73. #endif

  74. #if (NGX_HTTP_SSL)
  75. static char *ngx_http_uwsgi_ssl_password_file(ngx_conf_t *cf,
  76.     ngx_command_t *cmd, void *conf);
  77. static ngx_int_t ngx_http_uwsgi_set_ssl(ngx_conf_t *cf,
  78.     ngx_http_uwsgi_loc_conf_t *uwcf);
  79. #endif


  80. static ngx_conf_num_bounds_t  ngx_http_uwsgi_modifier_bounds = {
  81.     ngx_conf_check_num_bounds, 0, 255
  82. };


  83. static ngx_conf_bitmask_t ngx_http_uwsgi_next_upstream_masks[] = {
  84.     { ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR },
  85.     { ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT },
  86.     { ngx_string("invalid_header"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER },
  87.     { ngx_string("http_500"), NGX_HTTP_UPSTREAM_FT_HTTP_500 },
  88.     { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
  89.     { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 },
  90.     { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
  91.     { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
  92.     { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
  93.     { ngx_null_string, 0 }
  94. };


  95. #if (NGX_HTTP_SSL)

  96. static ngx_conf_bitmask_t  ngx_http_uwsgi_ssl_protocols[] = {
  97.     { ngx_string("SSLv2"), NGX_SSL_SSLv2 },
  98.     { ngx_string("SSLv3"), NGX_SSL_SSLv3 },
  99.     { ngx_string("TLSv1"), NGX_SSL_TLSv1 },
  100.     { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
  101.     { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
  102.     { ngx_null_string, 0 }
  103. };

  104. #endif


  105. ngx_module_t  ngx_http_uwsgi_module;


  106. static ngx_command_t ngx_http_uwsgi_commands[] = {

  107.     { ngx_string("uwsgi_pass"),
  108.       NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
  109.       ngx_http_uwsgi_pass,
  110.       NGX_HTTP_LOC_CONF_OFFSET,
  111.       0,
  112.       NULL },

  113.     { ngx_string("uwsgi_modifier1"),
  114.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  115.       ngx_conf_set_num_slot,
  116.       NGX_HTTP_LOC_CONF_OFFSET,
  117.       offsetof(ngx_http_uwsgi_loc_conf_t, modifier1),
  118.       &ngx_http_uwsgi_modifier_bounds },

  119.     { ngx_string("uwsgi_modifier2"),
  120.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  121.       ngx_conf_set_num_slot,
  122.       NGX_HTTP_LOC_CONF_OFFSET,
  123.       offsetof(ngx_http_uwsgi_loc_conf_t, modifier2),
  124.       &ngx_http_uwsgi_modifier_bounds },

  125.     { ngx_string("uwsgi_store"),
  126.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  127.       ngx_http_uwsgi_store,
  128.       NGX_HTTP_LOC_CONF_OFFSET,
  129.       0,
  130.       NULL },

  131.     { ngx_string("uwsgi_store_access"),
  132.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
  133.       ngx_conf_set_access_slot,
  134.       NGX_HTTP_LOC_CONF_OFFSET,
  135.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.store_access),
  136.       NULL },

  137.     { ngx_string("uwsgi_buffering"),
  138.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  139.       ngx_conf_set_flag_slot,
  140.       NGX_HTTP_LOC_CONF_OFFSET,
  141.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.buffering),
  142.       NULL },

  143.     { ngx_string("uwsgi_ignore_client_abort"),
  144.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  145.       ngx_conf_set_flag_slot,
  146.       NGX_HTTP_LOC_CONF_OFFSET,
  147.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.ignore_client_abort),
  148.       NULL },

  149.     { ngx_string("uwsgi_bind"),
  150.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  151.       ngx_http_upstream_bind_set_slot,
  152.       NGX_HTTP_LOC_CONF_OFFSET,
  153.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.local),
  154.       NULL },

  155.     { ngx_string("uwsgi_connect_timeout"),
  156.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  157.       ngx_conf_set_msec_slot,
  158.       NGX_HTTP_LOC_CONF_OFFSET,
  159.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.connect_timeout),
  160.       NULL },

  161.     { ngx_string("uwsgi_send_timeout"),
  162.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  163.       ngx_conf_set_msec_slot,
  164.       NGX_HTTP_LOC_CONF_OFFSET,
  165.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.send_timeout),
  166.       NULL },

  167.     { ngx_string("uwsgi_buffer_size"),
  168.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  169.       ngx_conf_set_size_slot,
  170.       NGX_HTTP_LOC_CONF_OFFSET,
  171.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.buffer_size),
  172.       NULL },

  173.     { ngx_string("uwsgi_pass_request_headers"),
  174.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  175.       ngx_conf_set_flag_slot,
  176.       NGX_HTTP_LOC_CONF_OFFSET,
  177.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.pass_request_headers),
  178.       NULL },

  179.     { ngx_string("uwsgi_pass_request_body"),
  180.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  181.       ngx_conf_set_flag_slot,
  182.       NGX_HTTP_LOC_CONF_OFFSET,
  183.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.pass_request_body),
  184.       NULL },

  185.     { ngx_string("uwsgi_intercept_errors"),
  186.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  187.       ngx_conf_set_flag_slot,
  188.       NGX_HTTP_LOC_CONF_OFFSET,
  189.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.intercept_errors),
  190.       NULL },

  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.     { ngx_string("uwsgi_buffers"),
  198.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
  199.       ngx_conf_set_bufs_slot,
  200.       NGX_HTTP_LOC_CONF_OFFSET,
  201.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.bufs),
  202.       NULL },

  203.     { ngx_string("uwsgi_busy_buffers_size"),
  204.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  205.       ngx_conf_set_size_slot,
  206.       NGX_HTTP_LOC_CONF_OFFSET,
  207.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.busy_buffers_size_conf),
  208.       NULL },

  209.     { ngx_string("uwsgi_force_ranges"),
  210.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  211.       ngx_conf_set_flag_slot,
  212.       NGX_HTTP_LOC_CONF_OFFSET,
  213.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.force_ranges),
  214.       NULL },

  215.     { ngx_string("uwsgi_limit_rate"),
  216.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  217.       ngx_conf_set_size_slot,
  218.       NGX_HTTP_LOC_CONF_OFFSET,
  219.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.limit_rate),
  220.       NULL },

  221. #if (NGX_HTTP_CACHE)

  222.     { ngx_string("uwsgi_cache"),
  223.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  224.       ngx_http_uwsgi_cache,
  225.       NGX_HTTP_LOC_CONF_OFFSET,
  226.       0,
  227.       NULL },

  228.     { ngx_string("uwsgi_cache_key"),
  229.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  230.       ngx_http_uwsgi_cache_key,
  231.       NGX_HTTP_LOC_CONF_OFFSET,
  232.       0,
  233.       NULL },

  234.     { ngx_string("uwsgi_cache_path"),
  235.       NGX_HTTP_MAIN_CONF|NGX_CONF_2MORE,
  236.       ngx_http_file_cache_set_slot,
  237.       NGX_HTTP_MAIN_CONF_OFFSET,
  238.       offsetof(ngx_http_uwsgi_main_conf_t, caches),
  239.       &ngx_http_uwsgi_module },

  240.     { ngx_string("uwsgi_cache_bypass"),
  241.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  242.       ngx_http_set_predicate_slot,
  243.       NGX_HTTP_LOC_CONF_OFFSET,
  244.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_bypass),
  245.       NULL },

  246.     { ngx_string("uwsgi_no_cache"),
  247.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  248.       ngx_http_set_predicate_slot,
  249.       NGX_HTTP_LOC_CONF_OFFSET,
  250.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.no_cache),
  251.       NULL },

  252.     { ngx_string("uwsgi_cache_valid"),
  253.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  254.       ngx_http_file_cache_valid_set_slot,
  255.       NGX_HTTP_LOC_CONF_OFFSET,
  256.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_valid),
  257.       NULL },

  258.     { ngx_string("uwsgi_cache_min_uses"),
  259.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  260.       ngx_conf_set_num_slot,
  261.       NGX_HTTP_LOC_CONF_OFFSET,
  262.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_min_uses),
  263.       NULL },

  264.     { ngx_string("uwsgi_cache_use_stale"),
  265.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  266.       ngx_conf_set_bitmask_slot,
  267.       NGX_HTTP_LOC_CONF_OFFSET,
  268.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_use_stale),
  269.       &ngx_http_uwsgi_next_upstream_masks },

  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.     { ngx_string("uwsgi_cache_lock"),
  277.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  278.       ngx_conf_set_flag_slot,
  279.       NGX_HTTP_LOC_CONF_OFFSET,
  280.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_lock),
  281.       NULL },

  282.     { ngx_string("uwsgi_cache_lock_timeout"),
  283.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  284.       ngx_conf_set_msec_slot,
  285.       NGX_HTTP_LOC_CONF_OFFSET,
  286.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_lock_timeout),
  287.       NULL },

  288.     { ngx_string("uwsgi_cache_lock_age"),
  289.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  290.       ngx_conf_set_msec_slot,
  291.       NGX_HTTP_LOC_CONF_OFFSET,
  292.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_lock_age),
  293.       NULL },

  294.     { ngx_string("uwsgi_cache_revalidate"),
  295.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  296.       ngx_conf_set_flag_slot,
  297.       NGX_HTTP_LOC_CONF_OFFSET,
  298.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_revalidate),
  299.       NULL },

  300. #endif

  301.     { ngx_string("uwsgi_temp_path"),
  302.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
  303.       ngx_conf_set_path_slot,
  304.       NGX_HTTP_LOC_CONF_OFFSET,
  305.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.temp_path),
  306.       NULL },

  307.     { ngx_string("uwsgi_max_temp_file_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.max_temp_file_size_conf),
  312.       NULL },

  313.     { ngx_string("uwsgi_temp_file_write_size"),
  314.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  315.       ngx_conf_set_size_slot,
  316.       NGX_HTTP_LOC_CONF_OFFSET,
  317.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.temp_file_write_size_conf),
  318.       NULL },

  319.     { ngx_string("uwsgi_next_upstream"),
  320.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  321.       ngx_conf_set_bitmask_slot,
  322.       NGX_HTTP_LOC_CONF_OFFSET,
  323.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.next_upstream),
  324.       &ngx_http_uwsgi_next_upstream_masks },

  325.     { ngx_string("uwsgi_next_upstream_tries"),
  326.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  327.       ngx_conf_set_num_slot,
  328.       NGX_HTTP_LOC_CONF_OFFSET,
  329.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.next_upstream_tries),
  330.       NULL },

  331.     { ngx_string("uwsgi_next_upstream_timeout"),
  332.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  333.       ngx_conf_set_msec_slot,
  334.       NGX_HTTP_LOC_CONF_OFFSET,
  335.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.next_upstream_timeout),
  336.       NULL },

  337.     { ngx_string("uwsgi_param"),
  338.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE23,
  339.       ngx_http_upstream_param_set_slot,
  340.       NGX_HTTP_LOC_CONF_OFFSET,
  341.       offsetof(ngx_http_uwsgi_loc_conf_t, params_source),
  342.       NULL },

  343.     { ngx_string("uwsgi_string"),
  344.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  345.       ngx_conf_set_str_slot,
  346.       NGX_HTTP_LOC_CONF_OFFSET,
  347.       offsetof(ngx_http_uwsgi_loc_conf_t, uwsgi_string),
  348.       NULL },

  349.     { ngx_string("uwsgi_pass_header"),
  350.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  351.       ngx_conf_set_str_array_slot,
  352.       NGX_HTTP_LOC_CONF_OFFSET,
  353.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.pass_headers),
  354.       NULL },

  355.     { ngx_string("uwsgi_hide_header"),
  356.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  357.       ngx_conf_set_str_array_slot,
  358.       NGX_HTTP_LOC_CONF_OFFSET,
  359.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.hide_headers),
  360.       NULL },

  361.     { ngx_string("uwsgi_ignore_headers"),
  362.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  363.       ngx_conf_set_bitmask_slot,
  364.       NGX_HTTP_LOC_CONF_OFFSET,
  365.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.ignore_headers),
  366.       &ngx_http_upstream_ignore_headers_masks },

  367. #if (NGX_HTTP_SSL)

  368.     { ngx_string("uwsgi_ssl_session_reuse"),
  369.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  370.       ngx_conf_set_flag_slot,
  371.       NGX_HTTP_LOC_CONF_OFFSET,
  372.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.ssl_session_reuse),
  373.       NULL },

  374.     { ngx_string("uwsgi_ssl_protocols"),
  375.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  376.       ngx_conf_set_bitmask_slot,
  377.       NGX_HTTP_LOC_CONF_OFFSET,
  378.       offsetof(ngx_http_uwsgi_loc_conf_t, ssl_protocols),
  379.       &ngx_http_uwsgi_ssl_protocols },

  380.     { ngx_string("uwsgi_ssl_ciphers"),
  381.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  382.       ngx_conf_set_str_slot,
  383.       NGX_HTTP_LOC_CONF_OFFSET,
  384.       offsetof(ngx_http_uwsgi_loc_conf_t, ssl_ciphers),
  385.       NULL },

  386.     { ngx_string("uwsgi_ssl_name"),
  387.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  388.       ngx_http_set_complex_value_slot,
  389.       NGX_HTTP_LOC_CONF_OFFSET,
  390.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.ssl_name),
  391.       NULL },

  392.     { ngx_string("uwsgi_ssl_server_name"),
  393.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  394.       ngx_conf_set_flag_slot,
  395.       NGX_HTTP_LOC_CONF_OFFSET,
  396.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.ssl_server_name),
  397.       NULL },

  398.     { ngx_string("uwsgi_ssl_verify"),
  399.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  400.       ngx_conf_set_flag_slot,
  401.       NGX_HTTP_LOC_CONF_OFFSET,
  402.       offsetof(ngx_http_uwsgi_loc_conf_t, upstream.ssl_verify),
  403.       NULL },

  404.     { ngx_string("uwsgi_ssl_verify_depth"),
  405.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  406.       ngx_conf_set_num_slot,
  407.       NGX_HTTP_LOC_CONF_OFFSET,
  408.       offsetof(ngx_http_uwsgi_loc_conf_t, ssl_verify_depth),
  409.       NULL },

  410.     { ngx_string("uwsgi_ssl_trusted_certificate"),
  411.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  412.       ngx_conf_set_str_slot,
  413.       NGX_HTTP_LOC_CONF_OFFSET,
  414.       offsetof(ngx_http_uwsgi_loc_conf_t, ssl_trusted_certificate),
  415.       NULL },

  416.     { ngx_string("uwsgi_ssl_crl"),
  417.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  418.       ngx_conf_set_str_slot,
  419.       NGX_HTTP_LOC_CONF_OFFSET,
  420.       offsetof(ngx_http_uwsgi_loc_conf_t, ssl_crl),
  421.       NULL },

  422.     { ngx_string("uwsgi_ssl_certificate"),
  423.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  424.       ngx_conf_set_str_slot,
  425.       NGX_HTTP_LOC_CONF_OFFSET,
  426.       offsetof(ngx_http_uwsgi_loc_conf_t, ssl_certificate),
  427.       NULL },

  428.     { ngx_string("uwsgi_ssl_certificate_key"),
  429.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  430.       ngx_conf_set_str_slot,
  431.       NGX_HTTP_LOC_CONF_OFFSET,
  432.       offsetof(ngx_http_uwsgi_loc_conf_t, ssl_certificate_key),
  433.       NULL },

  434.     { ngx_string("uwsgi_ssl_password_file"),
  435.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  436.       ngx_http_uwsgi_ssl_password_file,
  437.       NGX_HTTP_LOC_CONF_OFFSET,
  438.       0,
  439.       NULL },

  440. #endif

  441.       ngx_null_command
  442. };


  443. static ngx_http_module_t ngx_http_uwsgi_module_ctx = {
  444.     NULL,                                  /* preconfiguration */
  445.     NULL,                                  /* postconfiguration */

  446.     ngx_http_uwsgi_create_main_conf,       /* create main configuration */
  447.     NULL,                                  /* init main configuration */

  448.     NULL,                                  /* create server configuration */
  449.     NULL,                                  /* merge server configuration */

  450.     ngx_http_uwsgi_create_loc_conf,        /* create location configuration */
  451.     ngx_http_uwsgi_merge_loc_conf          /* merge location configuration */
  452. };


  453. ngx_module_t ngx_http_uwsgi_module = {
  454.     NGX_MODULE_V1,
  455.     &ngx_http_uwsgi_module_ctx,            /* module context */
  456.     ngx_http_uwsgi_commands,               /* module directives */
  457.     NGX_HTTP_MODULE,                       /* module type */
  458.     NULL,                                  /* init master */
  459.     NULL,                                  /* init module */
  460.     NULL,                                  /* init process */
  461.     NULL,                                  /* init thread */
  462.     NULL,                                  /* exit thread */
  463.     NULL,                                  /* exit process */
  464.     NULL,                                  /* exit master */
  465.     NGX_MODULE_V1_PADDING
  466. };


  467. static ngx_str_t ngx_http_uwsgi_hide_headers[] = {
  468.     ngx_string("X-Accel-Expires"),
  469.     ngx_string("X-Accel-Redirect"),
  470.     ngx_string("X-Accel-Limit-Rate"),
  471.     ngx_string("X-Accel-Buffering"),
  472.     ngx_string("X-Accel-Charset"),
  473.     ngx_null_string
  474. };


  475. #if (NGX_HTTP_CACHE)

  476. static ngx_keyval_t  ngx_http_uwsgi_cache_headers[] = {
  477.     { ngx_string("HTTP_IF_MODIFIED_SINCE"),
  478.       ngx_string("$upstream_cache_last_modified") },
  479.     { ngx_string("HTTP_IF_UNMODIFIED_SINCE"), ngx_string("") },
  480.     { ngx_string("HTTP_IF_NONE_MATCH"), ngx_string("$upstream_cache_etag") },
  481.     { ngx_string("HTTP_IF_MATCH"), ngx_string("") },
  482.     { ngx_string("HTTP_RANGE"), ngx_string("") },
  483.     { ngx_string("HTTP_IF_RANGE"), ngx_string("") },
  484.     { ngx_null_string, ngx_null_string }
  485. };

  486. #endif


  487. static ngx_path_init_t ngx_http_uwsgi_temp_path = {
  488.     ngx_string(NGX_HTTP_UWSGI_TEMP_PATH), { 1, 2, 0 }
  489. };


  490. static ngx_int_t
  491. ngx_http_uwsgi_handler(ngx_http_request_t *r)
  492. {
  493.     ngx_int_t                    rc;
  494.     ngx_http_status_t           *status;
  495.     ngx_http_upstream_t         *u;
  496.     ngx_http_uwsgi_loc_conf_t   *uwcf;
  497. #if (NGX_HTTP_CACHE)
  498.     ngx_http_uwsgi_main_conf_t  *uwmcf;
  499. #endif

  500.     if (ngx_http_upstream_create(r) != NGX_OK) {
  501.         return NGX_HTTP_INTERNAL_SERVER_ERROR;
  502.     }

  503.     status = ngx_pcalloc(r->pool, sizeof(ngx_http_status_t));
  504.     if (status == NULL) {
  505.         return NGX_HTTP_INTERNAL_SERVER_ERROR;
  506.     }

  507.     ngx_http_set_ctx(r, status, ngx_http_uwsgi_module);

  508.     uwcf = ngx_http_get_module_loc_conf(r, ngx_http_uwsgi_module);

  509.     u = r->upstream;

  510.     if (uwcf->uwsgi_lengths == NULL) {

  511. #if (NGX_HTTP_SSL)
  512.         u->ssl = (uwcf->upstream.ssl != NULL);

  513.         if (u->ssl) {
  514.             ngx_str_set(&u->schema, "suwsgi://");

  515.         } else {
  516.             ngx_str_set(&u->schema, "uwsgi://");
  517.         }
  518. #else
  519.         ngx_str_set(&u->schema, "uwsgi://");
  520. #endif

  521.     } else {
  522.         if (ngx_http_uwsgi_eval(r, uwcf) != NGX_OK) {
  523.             return NGX_HTTP_INTERNAL_SERVER_ERROR;
  524.         }
  525.     }

  526.     u->output.tag = (ngx_buf_tag_t) &ngx_http_uwsgi_module;

  527.     u->conf = &uwcf->upstream;

  528. #if (NGX_HTTP_CACHE)
  529.     uwmcf = ngx_http_get_module_main_conf(r, ngx_http_uwsgi_module);

  530.     u->caches = &uwmcf->caches;
  531.     u->create_key = ngx_http_uwsgi_create_key;
  532. #endif

  533.     u->create_request = ngx_http_uwsgi_create_request;
  534.     u->reinit_request = ngx_http_uwsgi_reinit_request;
  535.     u->process_header = ngx_http_uwsgi_process_status_line;
  536.     u->abort_request = ngx_http_uwsgi_abort_request;
  537.     u->finalize_request = ngx_http_uwsgi_finalize_request;
  538.     r->state = 0;

  539.     u->buffering = uwcf->upstream.buffering;

  540.     u->pipe = ngx_pcalloc(r->pool, sizeof(ngx_event_pipe_t));
  541.     if (u->pipe == NULL) {
  542.         return NGX_HTTP_INTERNAL_SERVER_ERROR;
  543.     }

  544.     u->pipe->input_filter = ngx_event_pipe_copy_input_filter;
  545.     u->pipe->input_ctx = r;

  546.     rc = ngx_http_read_client_request_body(r, ngx_http_upstream_init);

  547.     if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
  548.         return rc;
  549.     }

  550.     return NGX_DONE;
  551. }


  552. static ngx_int_t
  553. ngx_http_uwsgi_eval(ngx_http_request_t *r, ngx_http_uwsgi_loc_conf_t * uwcf)
  554. {
  555.     size_t                add;
  556.     ngx_url_t             url;
  557.     ngx_http_upstream_t  *u;

  558.     ngx_memzero(&url, sizeof(ngx_url_t));

  559.     if (ngx_http_script_run(r, &url.url, uwcf->uwsgi_lengths->elts, 0,
  560.                             uwcf->uwsgi_values->elts)
  561.         == NULL)
  562.     {
  563.         return NGX_ERROR;
  564.     }

  565.     if (url.url.len > 8
  566.         && ngx_strncasecmp(url.url.data, (u_char *) "uwsgi://", 8) == 0)
  567.     {
  568.         add = 8;

  569.     } else if (url.url.len > 9
  570.                && ngx_strncasecmp(url.url.data, (u_char *) "suwsgi://", 9) == 0)
  571.     {

  572. #if (NGX_HTTP_SSL)
  573.         add = 9;
  574.         r->upstream->ssl = 1;
  575. #else
  576.         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  577.                       "suwsgi protocol requires SSL support");
  578.         return NGX_ERROR;
  579. #endif

  580.     } else {
  581.         add = 0;
  582.     }

  583.     u = r->upstream;

  584.     if (add) {
  585.         u->schema.len = add;
  586.         u->schema.data = url.url.data;

  587.         url.url.data += add;
  588.         url.url.len -= add;

  589.     } else {
  590.         ngx_str_set(&u->schema, "uwsgi://");
  591.     }

  592.     url.no_resolve = 1;

  593.     if (ngx_parse_url(r->pool, &url) != NGX_OK) {
  594.         if (url.err) {
  595.             ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  596.                           "%s in upstream \"%V\"", url.err, &url.url);
  597.         }

  598.         return NGX_ERROR;
  599.     }

  600.     u->resolved = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t));
  601.     if (u->resolved == NULL) {
  602.         return NGX_ERROR;
  603.     }

  604.     if (url.addrs && url.addrs[0].sockaddr) {
  605.         u->resolved->sockaddr = url.addrs[0].sockaddr;
  606.         u->resolved->socklen = url.addrs[0].socklen;
  607.         u->resolved->naddrs = 1;
  608.         u->resolved->host = url.addrs[0].name;

  609.     } else {
  610.         u->resolved->host = url.host;
  611.         u->resolved->port = url.port;
  612.         u->resolved->no_port = url.no_port;
  613.     }

  614.     return NGX_OK;
  615. }


  616. #if (NGX_HTTP_CACHE)

  617. static ngx_int_t
  618. ngx_http_uwsgi_create_key(ngx_http_request_t *r)
  619. {
  620.     ngx_str_t                  *key;
  621.     ngx_http_uwsgi_loc_conf_t  *uwcf;

  622.     key = ngx_array_push(&r->cache->keys);
  623.     if (key == NULL) {
  624.         return NGX_ERROR;
  625.     }

  626.     uwcf = ngx_http_get_module_loc_conf(r, ngx_http_uwsgi_module);

  627.     if (ngx_http_complex_value(r, &uwcf->cache_key, key) != NGX_OK) {
  628.         return NGX_ERROR;
  629.     }

  630.     return NGX_OK;
  631. }

  632. #endif


  633. static ngx_int_t
  634. ngx_http_uwsgi_create_request(ngx_http_request_t *r)
  635. {
  636.     u_char                        ch, *lowcase_key;
  637.     size_t                        key_len, val_len, len, allocated;
  638.     ngx_uint_t                    i, n, hash, skip_empty, header_params;
  639.     ngx_buf_t                    *b;
  640.     ngx_chain_t                  *cl, *body;
  641.     ngx_list_part_t              *part;
  642.     ngx_table_elt_t              *header, **ignored;
  643.     ngx_http_uwsgi_params_t      *params;
  644.     ngx_http_script_code_pt       code;
  645.     ngx_http_script_engine_t      e, le;
  646.     ngx_http_uwsgi_loc_conf_t    *uwcf;
  647.     ngx_http_script_len_code_pt   lcode;

  648.     len = 0;
  649.     header_params = 0;
  650.     ignored = NULL;

  651.     uwcf = ngx_http_get_module_loc_conf(r, ngx_http_uwsgi_module);

  652. #if (NGX_HTTP_CACHE)
  653.     params = r->upstream->cacheable ? &uwcf->params_cache : &uwcf->params;
  654. #else
  655.     params = &uwcf->params;
  656. #endif

  657.     if (params->lengths) {
  658.         ngx_memzero(&le, sizeof(ngx_http_script_engine_t));

  659.         ngx_http_script_flush_no_cacheable_variables(r, params->flushes);
  660.         le.flushed = 1;

  661.         le.ip = params->lengths->elts;
  662.         le.request = r;

  663.         while (*(uintptr_t *) le.ip) {

  664.             lcode = *(ngx_http_script_len_code_pt *) le.ip;
  665.             key_len = lcode(&le);

  666.             lcode = *(ngx_http_script_len_code_pt *) le.ip;
  667.             skip_empty = lcode(&le);

  668.             for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode (&le)) {
  669.                 lcode = *(ngx_http_script_len_code_pt *) le.ip;
  670.             }
  671.             le.ip += sizeof(uintptr_t);

  672.             if (skip_empty && val_len == 0) {
  673.                 continue;
  674.             }

  675.             len += 2 + key_len + 2 + val_len;
  676.         }
  677.     }

  678.     if (uwcf->upstream.pass_request_headers) {

  679.         allocated = 0;
  680.         lowcase_key = NULL;

  681.         if (params->number) {
  682.             n = 0;
  683.             part = &r->headers_in.headers.part;

  684.             while (part) {
  685.                 n += part->nelts;
  686.                 part = part->next;
  687.             }

  688.             ignored = ngx_palloc(r->pool, n * sizeof(void *));
  689.             if (ignored == NULL) {
  690.                 return NGX_ERROR;
  691.             }
  692.         }

  693.         part = &r->headers_in.headers.part;
  694.         header = part->elts;

  695.         for (i = 0; /* void */ ; i++) {

  696.             if (i >= part->nelts) {
  697.                 if (part->next == NULL) {
  698.                     break;
  699.                 }

  700.                 part = part->next;
  701.                 header = part->elts;
  702.                 i = 0;
  703.             }

  704.             if (params->number) {
  705.                 if (allocated < header[i].key.len) {
  706.                     allocated = header[i].key.len + 16;
  707.                     lowcase_key = ngx_pnalloc(r->pool, allocated);
  708.                     if (lowcase_key == NULL) {
  709.                         return NGX_ERROR;
  710.                     }
  711.                 }

  712.                 hash = 0;

  713.                 for (n = 0; n < header[i].key.len; n++) {
  714.                     ch = header[i].key.data[n];

  715.                     if (ch >= 'A' && ch <= 'Z') {
  716.                         ch |= 0x20;

  717.                     } else if (ch == '-') {
  718.                         ch = '_';
  719.                     }

  720.                     hash = ngx_hash(hash, ch);
  721.                     lowcase_key[n] = ch;
  722.                 }

  723.                 if (ngx_hash_find(&params->hash, hash, lowcase_key, n)) {
  724.                     ignored[header_params++] = &header[i];
  725.                     continue;
  726.                 }
  727.             }

  728.             len += 2 + sizeof("HTTP_") - 1 + header[i].key.len
  729.                  + 2 + header[i].value.len;
  730.         }
  731.     }

  732.     len += uwcf->uwsgi_string.len;

  733. #if 0
  734.     /* allow custom uwsgi packet */
  735.     if (len > 0 && len < 2) {
  736.         ngx_log_error (NGX_LOG_ALERT, r->connection->log, 0,
  737.                        "uwsgi request is too little: %uz", len);
  738.         return NGX_ERROR;
  739.     }
  740. #endif

  741.     b = ngx_create_temp_buf(r->pool, len + 4);
  742.     if (b == NULL) {
  743.         return NGX_ERROR;
  744.     }

  745.     cl = ngx_alloc_chain_link(r->pool);
  746.     if (cl == NULL) {
  747.         return NGX_ERROR;
  748.     }

  749.     cl->buf = b;

  750.     *b->last++ = (u_char) uwcf->modifier1;
  751.     *b->last++ = (u_char) (len & 0xff);
  752.     *b->last++ = (u_char) ((len >> 8) & 0xff);
  753.     *b->last++ = (u_char) uwcf->modifier2;

  754.     if (params->lengths) {
  755.         ngx_memzero(&e, sizeof(ngx_http_script_engine_t));

  756.         e.ip = params->values->elts;
  757.         e.pos = b->last;
  758.         e.request = r;
  759.         e.flushed = 1;

  760.         le.ip = params->lengths->elts;

  761.         while (*(uintptr_t *) le.ip) {

  762.             lcode = *(ngx_http_script_len_code_pt *) le.ip;
  763.             key_len = (u_char) lcode (&le);

  764.             lcode = *(ngx_http_script_len_code_pt *) le.ip;
  765.             skip_empty = lcode(&le);

  766.             for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) {
  767.                 lcode = *(ngx_http_script_len_code_pt *) le.ip;
  768.             }
  769.             le.ip += sizeof(uintptr_t);

  770.             if (skip_empty && val_len == 0) {
  771.                 e.skip = 1;

  772.                 while (*(uintptr_t *) e.ip) {
  773.                     code = *(ngx_http_script_code_pt *) e.ip;
  774.                     code((ngx_http_script_engine_t *) &e);
  775.                 }
  776.                 e.ip += sizeof(uintptr_t);

  777.                 e.skip = 0;

  778.                 continue;
  779.             }

  780.             *e.pos++ = (u_char) (key_len & 0xff);
  781.             *e.pos++ = (u_char) ((key_len >> 8) & 0xff);

  782.             code = *(ngx_http_script_code_pt *) e.ip;
  783.             code((ngx_http_script_engine_t *) & e);

  784.             *e.pos++ = (u_char) (val_len & 0xff);
  785.             *e.pos++ = (u_char) ((val_len >> 8) & 0xff);

  786.             while (*(uintptr_t *) e.ip) {
  787.                 code = *(ngx_http_script_code_pt *) e.ip;
  788.                 code((ngx_http_script_engine_t *) & e);
  789.             }

  790.             e.ip += sizeof(uintptr_t);

  791.             ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  792.                            "uwsgi param: \"%*s: %*s\"",
  793.                            key_len, e.pos - (key_len + 2 + val_len),
  794.                            val_len, e.pos - val_len);
  795.         }

  796.         b->last = e.pos;
  797.     }

  798.     if (uwcf->upstream.pass_request_headers) {

  799.         part = &r->headers_in.headers.part;
  800.         header = part->elts;

  801.         for (i = 0; /* void */ ; i++) {

  802.             if (i >= part->nelts) {
  803.                 if (part->next == NULL) {
  804.                     break;
  805.                 }

  806.                 part = part->next;
  807.                 header = part->elts;
  808.                 i = 0;
  809.             }

  810.             for (n = 0; n < header_params; n++) {
  811.                 if (&header[i] == ignored[n]) {
  812.                     goto next;
  813.                 }
  814.             }

  815.             key_len = sizeof("HTTP_") - 1 + header[i].key.len;
  816.             *b->last++ = (u_char) (key_len & 0xff);
  817.             *b->last++ = (u_char) ((key_len >> 8) & 0xff);

  818.             b->last = ngx_cpymem(b->last, "HTTP_", sizeof("HTTP_") - 1);
  819.             for (n = 0; n < header[i].key.len; n++) {
  820.                 ch = header[i].key.data[n];

  821.                 if (ch >= 'a' && ch <= 'z') {
  822.                     ch &= ~0x20;

  823.                 } else if (ch == '-') {
  824.                     ch = '_';
  825.                 }

  826.                 *b->last++ = ch;
  827.             }

  828.             val_len = header[i].value.len;
  829.             *b->last++ = (u_char) (val_len & 0xff);
  830.             *b->last++ = (u_char) ((val_len >> 8) & 0xff);
  831.             b->last = ngx_copy(b->last, header[i].value.data, val_len);

  832.             ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  833.                            "uwsgi param: \"%*s: %*s\"",
  834.                            key_len, b->last - (key_len + 2 + val_len),
  835.                            val_len, b->last - val_len);
  836.         next:

  837.             continue;
  838.         }
  839.     }

  840.     b->last = ngx_copy(b->last, uwcf->uwsgi_string.data,
  841.                        uwcf->uwsgi_string.len);

  842.     if (uwcf->upstream.pass_request_body) {
  843.         body = r->upstream->request_bufs;
  844.         r->upstream->request_bufs = cl;

  845.         while (body) {
  846.             b = ngx_alloc_buf(r->pool);
  847.             if (b == NULL) {
  848.                 return NGX_ERROR;
  849.             }

  850.             ngx_memcpy(b, body->buf, sizeof(ngx_buf_t));

  851.             cl->next = ngx_alloc_chain_link(r->pool);
  852.             if (cl->next == NULL) {
  853.                 return NGX_ERROR;
  854.             }

  855.             cl = cl->next;
  856.             cl->buf = b;

  857.             body = body->next;
  858.         }

  859.     } else {
  860.         r->upstream->request_bufs = cl;
  861.     }

  862.     cl->next = NULL;

  863.     return NGX_OK;
  864. }


  865. static ngx_int_t
  866. ngx_http_uwsgi_reinit_request(ngx_http_request_t *r)
  867. {
  868.     ngx_http_status_t  *status;

  869.     status = ngx_http_get_module_ctx(r, ngx_http_uwsgi_module);

  870.     if (status == NULL) {
  871.         return NGX_OK;
  872.     }

  873.     status->code = 0;
  874.     status->count = 0;
  875.     status->start = NULL;
  876.     status->end = NULL;

  877.     r->upstream->process_header = ngx_http_uwsgi_process_status_line;
  878.     r->state = 0;

  879.     return NGX_OK;
  880. }


  881. static ngx_int_t
  882. ngx_http_uwsgi_process_status_line(ngx_http_request_t *r)
  883. {
  884.     size_t                 len;
  885.     ngx_int_t              rc;
  886.     ngx_http_status_t     *status;
  887.     ngx_http_upstream_t   *u;

  888.     status = ngx_http_get_module_ctx(r, ngx_http_uwsgi_module);

  889.     if (status == NULL) {
  890.         return NGX_ERROR;
  891.     }

  892.     u = r->upstream;

  893.     rc = ngx_http_parse_status_line(r, &u->buffer, status);

  894.     if (rc == NGX_AGAIN) {
  895.         return rc;
  896.     }

  897.     if (rc == NGX_ERROR) {
  898.         u->process_header = ngx_http_uwsgi_process_header;
  899.         return ngx_http_uwsgi_process_header(r);
  900.     }

  901.     if (u->state && u->state->status == 0) {
  902.         u->state->status = status->code;
  903.     }

  904.     u->headers_in.status_n = status->code;

  905.     len = status->end - status->start;
  906.     u->headers_in.status_line.len = len;

  907.     u->headers_in.status_line.data = ngx_pnalloc(r->pool, len);
  908.     if (u->headers_in.status_line.data == NULL) {
  909.         return NGX_ERROR;
  910.     }

  911.     ngx_memcpy(u->headers_in.status_line.data, status->start, len);

  912.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  913.                    "http uwsgi status %ui \"%V\"",
  914.                    u->headers_in.status_n, &u->headers_in.status_line);

  915.     u->process_header = ngx_http_uwsgi_process_header;

  916.     return ngx_http_uwsgi_process_header(r);
  917. }


  918. static ngx_int_t
  919. ngx_http_uwsgi_process_header(ngx_http_request_t *r)
  920. {
  921.     ngx_str_t                      *status_line;
  922.     ngx_int_t                       rc, status;
  923.     ngx_table_elt_t                *h;
  924.     ngx_http_upstream_t            *u;
  925.     ngx_http_upstream_header_t     *hh;
  926.     ngx_http_upstream_main_conf_t  *umcf;

  927.     umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);

  928.     for ( ;; ) {

  929.         rc = ngx_http_parse_header_line(r, &r->upstream->buffer, 1);

  930.         if (rc == NGX_OK) {

  931.             /* a header line has been parsed successfully */

  932.             h = ngx_list_push(&r->upstream->headers_in.headers);
  933.             if (h == NULL) {
  934.                 return NGX_ERROR;
  935.             }

  936.             h->hash = r->header_hash;

  937.             h->key.len = r->header_name_end - r->header_name_start;
  938.             h->value.len = r->header_end - r->header_start;

  939.             h->key.data = ngx_pnalloc(r->pool,
  940.                                       h->key.len + 1 + h->value.len + 1
  941.                                       + h->key.len);
  942.             if (h->key.data == NULL) {
  943.                 return NGX_ERROR;
  944.             }

  945.             h->value.data = h->key.data + h->key.len + 1;
  946.             h->lowcase_key = h->key.data + h->key.len + 1 + h->value.len + 1;

  947.             ngx_memcpy(h->key.data, r->header_name_start, h->key.len);
  948.             h->key.data[h->key.len] = '\0';
  949.             ngx_memcpy(h->value.data, r->header_start, h->value.len);
  950.             h->value.data[h->value.len] = '\0';

  951.             if (h->key.len == r->lowcase_index) {
  952.                 ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len);

  953.             } else {
  954.                 ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
  955.             }

  956.             hh = ngx_hash_find(&umcf->headers_in_hash, h->hash,
  957.                                h->lowcase_key, h->key.len);

  958.             if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
  959.                 return NGX_ERROR;
  960.             }

  961.             ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  962.                            "http uwsgi header: \"%V: %V\"", &h->key, &h->value);

  963.             continue;
  964.         }

  965.         if (rc == NGX_HTTP_PARSE_HEADER_DONE) {

  966.             /* a whole header has been parsed successfully */

  967.             ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  968.                            "http uwsgi header done");

  969.             u = r->upstream;

  970.             if (u->headers_in.status_n) {
  971.                 goto done;
  972.             }

  973.             if (u->headers_in.status) {
  974.                 status_line = &u->headers_in.status->value;

  975.                 status = ngx_atoi(status_line->data, 3);
  976.                 if (status == NGX_ERROR) {
  977.                     ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  978.                                   "upstream sent invalid status \"%V\"",
  979.                                   status_line);
  980.                     return NGX_HTTP_UPSTREAM_INVALID_HEADER;
  981.                 }

  982.                 u->headers_in.status_n = status;
  983.                 u->headers_in.status_line = *status_line;

  984.             } else if (u->headers_in.location) {
  985.                 u->headers_in.status_n = 302;
  986.                 ngx_str_set(&u->headers_in.status_line,
  987.                             "302 Moved Temporarily");

  988.             } else {
  989.                 u->headers_in.status_n = 200;
  990.                 ngx_str_set(&u->headers_in.status_line, "200 OK");
  991.             }

  992.             if (u->state && u->state->status == 0) {
  993.                 u->state->status = u->headers_in.status_n;
  994.             }

  995.         done:

  996.             if (u->headers_in.status_n == NGX_HTTP_SWITCHING_PROTOCOLS
  997.                 && r->headers_in.upgrade)
  998.             {
  999.                 u->upgrade = 1;
  1000.             }

  1001.             return NGX_OK;
  1002.         }

  1003.         if (rc == NGX_AGAIN) {
  1004.             return NGX_AGAIN;
  1005.         }

  1006.         /* there was error while a header line parsing */

  1007.         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  1008.                       "upstream sent invalid header");

  1009.         return NGX_HTTP_UPSTREAM_INVALID_HEADER;
  1010.     }
  1011. }


  1012. static void
  1013. ngx_http_uwsgi_abort_request(ngx_http_request_t *r)
  1014. {
  1015.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  1016.                    "abort http uwsgi request");

  1017.     return;
  1018. }


  1019. static void
  1020. ngx_http_uwsgi_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
  1021. {
  1022.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  1023.                    "finalize http uwsgi request");

  1024.     return;
  1025. }


  1026. static void *
  1027. ngx_http_uwsgi_create_main_conf(ngx_conf_t *cf)
  1028. {
  1029.     ngx_http_uwsgi_main_conf_t  *conf;

  1030.     conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_uwsgi_main_conf_t));
  1031.     if (conf == NULL) {
  1032.         return NULL;
  1033.     }

  1034. #if (NGX_HTTP_CACHE)
  1035.     if (ngx_array_init(&conf->caches, cf->pool, 4,
  1036.                        sizeof(ngx_http_file_cache_t *))
  1037.         != NGX_OK)
  1038.     {
  1039.         return NULL;
  1040.     }
  1041. #endif

  1042.     return conf;
  1043. }


  1044. static void *
  1045. ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf)
  1046. {
  1047.     ngx_http_uwsgi_loc_conf_t  *conf;

  1048.     conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_uwsgi_loc_conf_t));
  1049.     if (conf == NULL) {
  1050.         return NULL;
  1051.     }

  1052.     conf->modifier1 = NGX_CONF_UNSET_UINT;
  1053.     conf->modifier2 = NGX_CONF_UNSET_UINT;

  1054.     conf->upstream.store = NGX_CONF_UNSET;
  1055.     conf->upstream.store_access = NGX_CONF_UNSET_UINT;
  1056.     conf->upstream.next_upstream_tries = NGX_CONF_UNSET_UINT;
  1057.     conf->upstream.buffering = NGX_CONF_UNSET;
  1058.     conf->upstream.ignore_client_abort = NGX_CONF_UNSET;
  1059.     conf->upstream.force_ranges = NGX_CONF_UNSET;

  1060.     conf->upstream.local = NGX_CONF_UNSET_PTR;

  1061.     conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC;
  1062.     conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC;
  1063.     conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC;
  1064.     conf->upstream.next_upstream_timeout = NGX_CONF_UNSET_MSEC;

  1065.     conf->upstream.send_lowat = NGX_CONF_UNSET_SIZE;
  1066.     conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE;
  1067.     conf->upstream.limit_rate = NGX_CONF_UNSET_SIZE;

  1068.     conf->upstream.busy_buffers_size_conf = NGX_CONF_UNSET_SIZE;
  1069.     conf->upstream.max_temp_file_size_conf = NGX_CONF_UNSET_SIZE;
  1070.     conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE;

  1071.     conf->upstream.pass_request_headers = NGX_CONF_UNSET;
  1072.     conf->upstream.pass_request_body = NGX_CONF_UNSET;

  1073. #if (NGX_HTTP_CACHE)
  1074.     conf->upstream.cache = NGX_CONF_UNSET;
  1075.     conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT;
  1076.     conf->upstream.cache_bypass = NGX_CONF_UNSET_PTR;
  1077.     conf->upstream.no_cache = NGX_CONF_UNSET_PTR;
  1078.     conf->upstream.cache_valid = NGX_CONF_UNSET_PTR;
  1079.     conf->upstream.cache_lock = NGX_CONF_UNSET;
  1080.     conf->upstream.cache_lock_timeout = NGX_CONF_UNSET_MSEC;
  1081.     conf->upstream.cache_lock_age = NGX_CONF_UNSET_MSEC;
  1082.     conf->upstream.cache_revalidate = NGX_CONF_UNSET;
  1083. #endif

  1084.     conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
  1085.     conf->upstream.pass_headers = NGX_CONF_UNSET_PTR;

  1086.     conf->upstream.intercept_errors = NGX_CONF_UNSET;

  1087. #if (NGX_HTTP_SSL)
  1088.     conf->upstream.ssl_session_reuse = NGX_CONF_UNSET;
  1089.     conf->upstream.ssl_server_name = NGX_CONF_UNSET;
  1090.     conf->upstream.ssl_verify = NGX_CONF_UNSET;
  1091.     conf->ssl_verify_depth = NGX_CONF_UNSET_UINT;
  1092.     conf->ssl_passwords = NGX_CONF_UNSET_PTR;
  1093. #endif

  1094.     /* "uwsgi_cyclic_temp_file" is disabled */
  1095.     conf->upstream.cyclic_temp_file = 0;

  1096.     conf->upstream.change_buffering = 1;

  1097.     ngx_str_set(&conf->upstream.module, "uwsgi");

  1098.     return conf;
  1099. }


  1100. static char *
  1101. ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
  1102. {
  1103.     ngx_http_uwsgi_loc_conf_t *prev = parent;
  1104.     ngx_http_uwsgi_loc_conf_t *conf = child;

  1105.     size_t                        size;
  1106.     ngx_int_t                     rc;
  1107.     ngx_hash_init_t               hash;
  1108.     ngx_http_core_loc_conf_t     *clcf;

  1109. #if (NGX_HTTP_CACHE)

  1110.     if (conf->upstream.store > 0) {
  1111.         conf->upstream.cache = 0;
  1112.     }

  1113.     if (conf->upstream.cache > 0) {
  1114.         conf->upstream.store = 0;
  1115.     }

  1116. #endif

  1117.     if (conf->upstream.store == NGX_CONF_UNSET) {
  1118.         ngx_conf_merge_value(conf->upstream.store, prev->upstream.store, 0);

  1119.         conf->upstream.store_lengths = prev->upstream.store_lengths;
  1120.         conf->upstream.store_values = prev->upstream.store_values;
  1121.     }

  1122.     ngx_conf_merge_uint_value(conf->upstream.store_access,
  1123.                               prev->upstream.store_access, 0600);

  1124.     ngx_conf_merge_uint_value(conf->upstream.next_upstream_tries,
  1125.                               prev->upstream.next_upstream_tries, 0);

  1126.     ngx_conf_merge_value(conf->upstream.buffering,
  1127.                               prev->upstream.buffering, 1);

  1128.     ngx_conf_merge_value(conf->upstream.ignore_client_abort,
  1129.                               prev->upstream.ignore_client_abort, 0);

  1130.     ngx_conf_merge_value(conf->upstream.force_ranges,
  1131.                               prev->upstream.force_ranges, 0);

  1132.     ngx_conf_merge_ptr_value(conf->upstream.local,
  1133.                               prev->upstream.local, NULL);

  1134.     ngx_conf_merge_msec_value(conf->upstream.connect_timeout,
  1135.                               prev->upstream.connect_timeout, 60000);

  1136.     ngx_conf_merge_msec_value(conf->upstream.send_timeout,
  1137.                               prev->upstream.send_timeout, 60000);

  1138.     ngx_conf_merge_msec_value(conf->upstream.read_timeout,
  1139.                               prev->upstream.read_timeout, 60000);

  1140.     ngx_conf_merge_msec_value(conf->upstream.next_upstream_timeout,
  1141.                               prev->upstream.next_upstream_timeout, 0);

  1142.     ngx_conf_merge_size_value(conf->upstream.send_lowat,
  1143.                               prev->upstream.send_lowat, 0);

  1144.     ngx_conf_merge_size_value(conf->upstream.buffer_size,
  1145.                               prev->upstream.buffer_size,
  1146.                               (size_t) ngx_pagesize);

  1147.     ngx_conf_merge_size_value(conf->upstream.limit_rate,
  1148.                               prev->upstream.limit_rate, 0);


  1149.     ngx_conf_merge_bufs_value(conf->upstream.bufs, prev->upstream.bufs,
  1150.                               8, ngx_pagesize);

  1151.     if (conf->upstream.bufs.num < 2) {
  1152.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  1153.                            "there must be at least 2 \"uwsgi_buffers\"");
  1154.         return NGX_CONF_ERROR;
  1155.     }


  1156.     size = conf->upstream.buffer_size;
  1157.     if (size < conf->upstream.bufs.size) {
  1158.         size = conf->upstream.bufs.size;
  1159.     }


  1160.     ngx_conf_merge_size_value(conf->upstream.busy_buffers_size_conf,
  1161.                               prev->upstream.busy_buffers_size_conf,
  1162.                               NGX_CONF_UNSET_SIZE);

  1163.     if (conf->upstream.busy_buffers_size_conf == NGX_CONF_UNSET_SIZE) {
  1164.         conf->upstream.busy_buffers_size = 2 * size;
  1165.     } else {
  1166.         conf->upstream.busy_buffers_size =
  1167.             conf->upstream.busy_buffers_size_conf;
  1168.     }

  1169.     if (conf->upstream.busy_buffers_size < size) {
  1170.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  1171.             "\"uwsgi_busy_buffers_size\" must be equal to or greater "
  1172.             "than the maximum of the value of \"uwsgi_buffer_size\" and "
  1173.             "one of the \"uwsgi_buffers\"");

  1174.         return NGX_CONF_ERROR;
  1175.     }

  1176.     if (conf->upstream.busy_buffers_size
  1177.         > (conf->upstream.bufs.num - 1) * conf->upstream.bufs.size)
  1178.     {
  1179.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  1180.             "\"uwsgi_busy_buffers_size\" must be less than "
  1181.             "the size of all \"uwsgi_buffers\" minus one buffer");

  1182.         return NGX_CONF_ERROR;
  1183.     }


  1184.     ngx_conf_merge_size_value(conf->upstream.temp_file_write_size_conf,
  1185.                               prev->upstream.temp_file_write_size_conf,
  1186.                               NGX_CONF_UNSET_SIZE);

  1187.     if (conf->upstream.temp_file_write_size_conf == NGX_CONF_UNSET_SIZE) {
  1188.         conf->upstream.temp_file_write_size = 2 * size;
  1189.     } else {
  1190.         conf->upstream.temp_file_write_size =
  1191.             conf->upstream.temp_file_write_size_conf;
  1192.     }

  1193.     if (conf->upstream.temp_file_write_size < size) {
  1194.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  1195.             "\"uwsgi_temp_file_write_size\" must be equal to or greater than "
  1196.             "the maximum of the value of \"uwsgi_buffer_size\" and "
  1197.             "one of the \"uwsgi_buffers\"");

  1198.         return NGX_CONF_ERROR;
  1199.     }


  1200.     ngx_conf_merge_size_value(conf->upstream.max_temp_file_size_conf,
  1201.                               prev->upstream.max_temp_file_size_conf,
  1202.                               NGX_CONF_UNSET_SIZE);

  1203.     if (conf->upstream.max_temp_file_size_conf == NGX_CONF_UNSET_SIZE) {
  1204.         conf->upstream.max_temp_file_size = 1024 * 1024 * 1024;
  1205.     } else {
  1206.         conf->upstream.max_temp_file_size =
  1207.             conf->upstream.max_temp_file_size_conf;
  1208.     }

  1209.     if (conf->upstream.max_temp_file_size != 0
  1210.         && conf->upstream.max_temp_file_size < size)
  1211.     {
  1212.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  1213.             "\"uwsgi_max_temp_file_size\" must be equal to zero to disable "
  1214.             "temporary files usage or must be equal to or greater than "
  1215.             "the maximum of the value of \"uwsgi_buffer_size\" and "
  1216.             "one of the \"uwsgi_buffers\"");

  1217.         return NGX_CONF_ERROR;
  1218.     }


  1219.     ngx_conf_merge_bitmask_value(conf->upstream.ignore_headers,
  1220.                                  prev->upstream.ignore_headers,
  1221.                                  NGX_CONF_BITMASK_SET);


  1222.     ngx_conf_merge_bitmask_value(conf->upstream.next_upstream,
  1223.                                  prev->upstream.next_upstream,
  1224.                                  (NGX_CONF_BITMASK_SET
  1225.                                   |NGX_HTTP_UPSTREAM_FT_ERROR
  1226.                                   |NGX_HTTP_UPSTREAM_FT_TIMEOUT));

  1227.     if (conf->upstream.next_upstream & NGX_HTTP_UPSTREAM_FT_OFF) {
  1228.         conf->upstream.next_upstream = NGX_CONF_BITMASK_SET
  1229.                                        |NGX_HTTP_UPSTREAM_FT_OFF;
  1230.     }

  1231.     if (ngx_conf_merge_path_value(cf, &conf->upstream.temp_path,
  1232.                                   prev->upstream.temp_path,
  1233.                                   &ngx_http_uwsgi_temp_path)
  1234.         != NGX_OK)
  1235.     {
  1236.         return NGX_CONF_ERROR;
  1237.     }

  1238. #if (NGX_HTTP_CACHE)

  1239.     if (conf->upstream.cache == NGX_CONF_UNSET) {
  1240.         ngx_conf_merge_value(conf->upstream.cache,
  1241.                               prev->upstream.cache, 0);

  1242.         conf->upstream.cache_zone = prev->upstream.cache_zone;
  1243.         conf->upstream.cache_value = prev->upstream.cache_value;
  1244.     }

  1245.     if (conf->upstream.cache_zone && conf->upstream.cache_zone->data == NULL) {
  1246.         ngx_shm_zone_t  *shm_zone;

  1247.         shm_zone = conf->upstream.cache_zone;

  1248.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  1249.                            "\"uwsgi_cache\" zone \"%V\" is unknown",
  1250.                            &shm_zone->shm.name);

  1251.         return NGX_CONF_ERROR;
  1252.     }

  1253.     ngx_conf_merge_uint_value(conf->upstream.cache_min_uses,
  1254.                               prev->upstream.cache_min_uses, 1);

  1255.     ngx_conf_merge_bitmask_value(conf->upstream.cache_use_stale,
  1256.                               prev->upstream.cache_use_stale,
  1257.                               (NGX_CONF_BITMASK_SET
  1258.                                |NGX_HTTP_UPSTREAM_FT_OFF));

  1259.     if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_OFF) {
  1260.         conf->upstream.cache_use_stale = NGX_CONF_BITMASK_SET
  1261.                                          |NGX_HTTP_UPSTREAM_FT_OFF;
  1262.     }

  1263.     if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_ERROR) {
  1264.         conf->upstream.cache_use_stale |= NGX_HTTP_UPSTREAM_FT_NOLIVE;
  1265.     }

  1266.     if (conf->upstream.cache_methods == 0) {
  1267.         conf->upstream.cache_methods = prev->upstream.cache_methods;
  1268.     }

  1269.     conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD;

  1270.     ngx_conf_merge_ptr_value(conf->upstream.cache_bypass,
  1271.                              prev->upstream.cache_bypass, NULL);

  1272.     ngx_conf_merge_ptr_value(conf->upstream.no_cache,
  1273.                              prev->upstream.no_cache, NULL);

  1274.     ngx_conf_merge_ptr_value(conf->upstream.cache_valid,
  1275.                              prev->upstream.cache_valid, NULL);

  1276.     if (conf->cache_key.value.data == NULL) {
  1277.         conf->cache_key = prev->cache_key;
  1278.     }

  1279.     if (conf->upstream.cache && conf->cache_key.value.data == NULL) {
  1280.         ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
  1281.                            "no \"uwsgi_cache_key\" for \"uwsgi_cache\"");
  1282.     }

  1283.     ngx_conf_merge_value(conf->upstream.cache_lock,
  1284.                               prev->upstream.cache_lock, 0);

  1285.     ngx_conf_merge_msec_value(conf->upstream.cache_lock_timeout,
  1286.                               prev->upstream.cache_lock_timeout, 5000);

  1287.     ngx_conf_merge_msec_value(conf->upstream.cache_lock_age,
  1288.                               prev->upstream.cache_lock_age, 5000);

  1289.     ngx_conf_merge_value(conf->upstream.cache_revalidate,
  1290.                               prev->upstream.cache_revalidate, 0);

  1291. #endif

  1292.     ngx_conf_merge_value(conf->upstream.pass_request_headers,
  1293.                          prev->upstream.pass_request_headers, 1);
  1294.     ngx_conf_merge_value(conf->upstream.pass_request_body,
  1295.                          prev->upstream.pass_request_body, 1);

  1296.     ngx_conf_merge_value(conf->upstream.intercept_errors,
  1297.                          prev->upstream.intercept_errors, 0);

  1298. #if (NGX_HTTP_SSL)

  1299.     ngx_conf_merge_value(conf->upstream.ssl_session_reuse,
  1300.                               prev->upstream.ssl_session_reuse, 1);

  1301.     ngx_conf_merge_bitmask_value(conf->ssl_protocols, prev->ssl_protocols,
  1302.                                  (NGX_CONF_BITMASK_SET|NGX_SSL_SSLv3
  1303.                                   |NGX_SSL_TLSv1|NGX_SSL_TLSv1_1
  1304.                                   |NGX_SSL_TLSv1_2));

  1305.     ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers,
  1306.                              "DEFAULT");

  1307.     if (conf->upstream.ssl_name == NULL) {
  1308.         conf->upstream.ssl_name = prev->upstream.ssl_name;
  1309.     }

  1310.     ngx_conf_merge_value(conf->upstream.ssl_server_name,
  1311.                               prev->upstream.ssl_server_name, 0);
  1312.     ngx_conf_merge_value(conf->upstream.ssl_verify,
  1313.                               prev->upstream.ssl_verify, 0);
  1314.     ngx_conf_merge_uint_value(conf->ssl_verify_depth,
  1315.                               prev->ssl_verify_depth, 1);
  1316.     ngx_conf_merge_str_value(conf->ssl_trusted_certificate,
  1317.                               prev->ssl_trusted_certificate, "");
  1318.     ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, "");

  1319.     ngx_conf_merge_str_value(conf->ssl_certificate,
  1320.                               prev->ssl_certificate, "");
  1321.     ngx_conf_merge_str_value(conf->ssl_certificate_key,
  1322.                               prev->ssl_certificate_key, "");
  1323.     ngx_conf_merge_ptr_value(conf->ssl_passwords, prev->ssl_passwords, NULL);

  1324.     if (conf->ssl && ngx_http_uwsgi_set_ssl(cf, conf) != NGX_OK) {
  1325.         return NGX_CONF_ERROR;
  1326.     }

  1327. #endif

  1328.     ngx_conf_merge_str_value(conf->uwsgi_string, prev->uwsgi_string, "");

  1329.     hash.max_size = 512;
  1330.     hash.bucket_size = ngx_align(64, ngx_cacheline_size);
  1331.     hash.name = "uwsgi_hide_headers_hash";

  1332.     if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream,
  1333.             &prev->upstream, ngx_http_uwsgi_hide_headers, &hash)
  1334.         != NGX_OK)
  1335.     {
  1336.         return NGX_CONF_ERROR;
  1337.     }

  1338.     clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);

  1339.     if (clcf->noname
  1340.         && conf->upstream.upstream == NULL && conf->uwsgi_lengths == NULL)
  1341.     {
  1342.         conf->upstream.upstream = prev->upstream.upstream;

  1343.         conf->uwsgi_lengths = prev->uwsgi_lengths;
  1344.         conf->uwsgi_values = prev->uwsgi_values;

  1345. #if (NGX_HTTP_SSL)
  1346.         conf->upstream.ssl = prev->upstream.ssl;
  1347. #endif
  1348.     }

  1349.     if (clcf->lmt_excpt && clcf->handler == NULL
  1350.         && (conf->upstream.upstream || conf->uwsgi_lengths))
  1351.     {
  1352.         clcf->handler = ngx_http_uwsgi_handler;
  1353.     }

  1354.     ngx_conf_merge_uint_value(conf->modifier1, prev->modifier1, 0);
  1355.     ngx_conf_merge_uint_value(conf->modifier2, prev->modifier2, 0);

  1356.     if (conf->params_source == NULL) {
  1357.         conf->params = prev->params;
  1358. #if (NGX_HTTP_CACHE)
  1359.         conf->params_cache = prev->params_cache;
  1360. #endif
  1361.         conf->params_source = prev->params_source;
  1362.     }

  1363.     rc = ngx_http_uwsgi_init_params(cf, conf, &conf->params, NULL);
  1364.     if (rc != NGX_OK) {
  1365.         return NGX_CONF_ERROR;
  1366.     }

  1367. #if (NGX_HTTP_CACHE)

  1368.     if (conf->upstream.cache) {
  1369.         rc = ngx_http_uwsgi_init_params(cf, conf, &conf->params_cache,
  1370.                                         ngx_http_uwsgi_cache_headers);
  1371.         if (rc != NGX_OK) {
  1372.             return NGX_CONF_ERROR;
  1373.         }
  1374.     }

  1375. #endif

  1376.     return NGX_CONF_OK;
  1377. }


  1378. static ngx_int_t
  1379. ngx_http_uwsgi_init_params(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *conf,
  1380.     ngx_http_uwsgi_params_t *params, ngx_keyval_t *default_params)
  1381. {
  1382.     u_char                       *p;
  1383.     size_t                        size;
  1384.     uintptr_t                    *code;
  1385.     ngx_uint_t                    i, nsrc;
  1386.     ngx_array_t                   headers_names, params_merged;
  1387.     ngx_keyval_t                 *h;
  1388.     ngx_hash_key_t               *hk;
  1389.     ngx_hash_init_t               hash;
  1390.     ngx_http_upstream_param_t    *src, *s;
  1391.     ngx_http_script_compile_t     sc;
  1392.     ngx_http_script_copy_code_t  *copy;

  1393.     if (params->hash.buckets) {
  1394.         return NGX_OK;
  1395.     }

  1396.     if (conf->params_source == NULL && default_params == NULL) {
  1397.         params->hash.buckets = (void *) 1;
  1398.         return NGX_OK;
  1399.     }

  1400.     params->lengths = ngx_array_create(cf->pool, 64, 1);
  1401.     if (params->lengths == NULL) {
  1402.         return NGX_ERROR;
  1403.     }

  1404.     params->values = ngx_array_create(cf->pool, 512, 1);
  1405.     if (params->values == NULL) {
  1406.         return NGX_ERROR;
  1407.     }

  1408.     if (ngx_array_init(&headers_names, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
  1409.         != NGX_OK)
  1410.     {
  1411.         return NGX_ERROR;
  1412.     }

  1413.     if (conf->params_source) {
  1414.         src = conf->params_source->elts;
  1415.         nsrc = conf->params_source->nelts;

  1416.     } else {
  1417.         src = NULL;
  1418.         nsrc = 0;
  1419.     }

  1420.     if (default_params) {
  1421.         if (ngx_array_init(&params_merged, cf->temp_pool, 4,
  1422.                            sizeof(ngx_http_upstream_param_t))
  1423.             != NGX_OK)
  1424.         {
  1425.             return NGX_ERROR;
  1426.         }

  1427.         for (i = 0; i < nsrc; i++) {

  1428.             s = ngx_array_push(&params_merged);
  1429.             if (s == NULL) {
  1430.                 return NGX_ERROR;
  1431.             }

  1432.             *s = src[i];
  1433.         }

  1434.         h = default_params;

  1435.         while (h->key.len) {

  1436.             src = params_merged.elts;
  1437.             nsrc = params_merged.nelts;

  1438.             for (i = 0; i < nsrc; i++) {
  1439.                 if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) {
  1440.                     goto next;
  1441.                 }
  1442.             }

  1443.             s = ngx_array_push(&params_merged);
  1444.             if (s == NULL) {
  1445.                 return NGX_ERROR;
  1446.             }

  1447.             s->key = h->key;
  1448.             s->value = h->value;
  1449.             s->skip_empty = 1;

  1450.         next:

  1451.             h++;
  1452.         }

  1453.         src = params_merged.elts;
  1454.         nsrc = params_merged.nelts;
  1455.     }

  1456.     for (i = 0; i < nsrc; i++) {

  1457.         if (src[i].key.len > sizeof("HTTP_") - 1
  1458.             && ngx_strncmp(src[i].key.data, "HTTP_", sizeof("HTTP_") - 1) == 0)
  1459.         {
  1460.             hk = ngx_array_push(&headers_names);
  1461.             if (hk == NULL) {
  1462.                 return NGX_ERROR;
  1463.             }

  1464.             hk->key.len = src[i].key.len - 5;
  1465.             hk->key.data = src[i].key.data + 5;
  1466.             hk->key_hash = ngx_hash_key_lc(hk->key.data, hk->key.len);
  1467.             hk->value = (void *) 1;

  1468.             if (src[i].value.len == 0) {
  1469.                 continue;
  1470.             }
  1471.         }

  1472.         copy = ngx_array_push_n(params->lengths,
  1473.                                 sizeof(ngx_http_script_copy_code_t));
  1474.         if (copy == NULL) {
  1475.             return NGX_ERROR;
  1476.         }

  1477.         copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
  1478.         copy->len = src[i].key.len;

  1479.         copy = ngx_array_push_n(params->lengths,
  1480.                                 sizeof(ngx_http_script_copy_code_t));
  1481.         if (copy == NULL) {
  1482.             return NGX_ERROR;
  1483.         }

  1484.         copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
  1485.         copy->len = src[i].skip_empty;


  1486.         size = (sizeof(ngx_http_script_copy_code_t)
  1487.                 + src[i].key.len + sizeof(uintptr_t) - 1)
  1488.                & ~(sizeof(uintptr_t) - 1);

  1489.         copy = ngx_array_push_n(params->values, size);
  1490.         if (copy == NULL) {
  1491.             return NGX_ERROR;
  1492.         }

  1493.         copy->code = ngx_http_script_copy_code;
  1494.         copy->len = src[i].key.len;

  1495.         p = (u_char *) copy + sizeof(ngx_http_script_copy_code_t);
  1496.         ngx_memcpy(p, src[i].key.data, src[i].key.len);


  1497.         ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));

  1498.         sc.cf = cf;
  1499.         sc.source = &src[i].value;
  1500.         sc.flushes = &params->flushes;
  1501.         sc.lengths = &params->lengths;
  1502.         sc.values = &params->values;

  1503.         if (ngx_http_script_compile(&sc) != NGX_OK) {
  1504.             return NGX_ERROR;
  1505.         }

  1506.         code = ngx_array_push_n(params->lengths, sizeof(uintptr_t));
  1507.         if (code == NULL) {
  1508.             return NGX_ERROR;
  1509.         }

  1510.         *code = (uintptr_t) NULL;


  1511.         code = ngx_array_push_n(params->values, sizeof(uintptr_t));
  1512.         if (code == NULL) {
  1513.             return NGX_ERROR;
  1514.         }

  1515.         *code = (uintptr_t) NULL;
  1516.     }

  1517.     code = ngx_array_push_n(params->lengths, sizeof(uintptr_t));
  1518.     if (code == NULL) {
  1519.         return NGX_ERROR;
  1520.     }

  1521.     *code = (uintptr_t) NULL;

  1522.     params->number = headers_names.nelts;

  1523.     hash.hash = &params->hash;
  1524.     hash.key = ngx_hash_key_lc;
  1525.     hash.max_size = 512;
  1526.     hash.bucket_size = 64;
  1527.     hash.name = "uwsgi_params_hash";
  1528.     hash.pool = cf->pool;
  1529.     hash.temp_pool = NULL;

  1530.     return ngx_hash_init(&hash, headers_names.elts, headers_names.nelts);
  1531. }


  1532. static char *
  1533. ngx_http_uwsgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  1534. {
  1535.     ngx_http_uwsgi_loc_conf_t *uwcf = conf;

  1536.     size_t                      add;
  1537.     ngx_url_t                   u;
  1538.     ngx_str_t                  *value, *url;
  1539.     ngx_uint_t                  n;
  1540.     ngx_http_core_loc_conf_t   *clcf;
  1541.     ngx_http_script_compile_t   sc;

  1542.     if (uwcf->upstream.upstream || uwcf->uwsgi_lengths) {
  1543.         return "is duplicate";
  1544.     }

  1545.     clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
  1546.     clcf->handler = ngx_http_uwsgi_handler;

  1547.     value = cf->args->elts;

  1548.     url = &value[1];

  1549.     n = ngx_http_script_variables_count(url);

  1550.     if (n) {

  1551.         ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));

  1552.         sc.cf = cf;
  1553.         sc.source = url;
  1554.         sc.lengths = &uwcf->uwsgi_lengths;
  1555.         sc.values = &uwcf->uwsgi_values;
  1556.         sc.variables = n;
  1557.         sc.complete_lengths = 1;
  1558.         sc.complete_values = 1;

  1559.         if (ngx_http_script_compile(&sc) != NGX_OK) {
  1560.             return NGX_CONF_ERROR;
  1561.         }

  1562. #if (NGX_HTTP_SSL)
  1563.         uwcf->ssl = 1;
  1564. #endif

  1565.         return NGX_CONF_OK;
  1566.     }

  1567.     if (ngx_strncasecmp(url->data, (u_char *) "uwsgi://", 8) == 0) {
  1568.         add = 8;

  1569.     } else if (ngx_strncasecmp(url->data, (u_char *) "suwsgi://", 9) == 0) {

  1570. #if (NGX_HTTP_SSL)
  1571.         add = 9;
  1572.         uwcf->ssl = 1;
  1573. #else
  1574.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  1575.                            "suwsgi protocol requires SSL support");
  1576.         return NGX_CONF_ERROR;
  1577. #endif

  1578.     } else {
  1579.         add = 0;
  1580.     }

  1581.     ngx_memzero(&u, sizeof(ngx_url_t));

  1582.     u.url.len = url->len - add;
  1583.     u.url.data = url->data + add;
  1584.     u.no_resolve = 1;

  1585.     uwcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0);
  1586.     if (uwcf->upstream.upstream == NULL) {
  1587.         return NGX_CONF_ERROR;
  1588.     }

  1589.     if (clcf->name.data[clcf->name.len - 1] == '/') {
  1590.         clcf->auto_redirect = 1;
  1591.     }

  1592.     return NGX_CONF_OK;
  1593. }


  1594. static char *
  1595. ngx_http_uwsgi_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  1596. {
  1597.     ngx_http_uwsgi_loc_conf_t *uwcf = conf;

  1598.     ngx_str_t                  *value;
  1599.     ngx_http_script_compile_t   sc;

  1600.     if (uwcf->upstream.store != NGX_CONF_UNSET) {
  1601.         return "is duplicate";
  1602.     }

  1603.     value = cf->args->elts;

  1604.     if (ngx_strcmp(value[1].data, "off") == 0) {
  1605.         uwcf->upstream.store = 0;
  1606.         return NGX_CONF_OK;
  1607.     }

  1608. #if (NGX_HTTP_CACHE)

  1609.     if (uwcf->upstream.cache > 0) {
  1610.         return "is incompatible with \"uwsgi_cache\"";
  1611.     }

  1612. #endif

  1613.     uwcf->upstream.store = 1;

  1614.     if (ngx_strcmp(value[1].data, "on") == 0) {
  1615.         return NGX_CONF_OK;
  1616.     }

  1617.     /* include the terminating '\0' into script */
  1618.     value[1].len++;

  1619.     ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));

  1620.     sc.cf = cf;
  1621.     sc.source = &value[1];
  1622.     sc.lengths = &uwcf->upstream.store_lengths;
  1623.     sc.values = &uwcf->upstream.store_values;
  1624.     sc.variables = ngx_http_script_variables_count(&value[1]);
  1625.     sc.complete_lengths = 1;
  1626.     sc.complete_values = 1;

  1627.     if (ngx_http_script_compile(&sc) != NGX_OK) {
  1628.         return NGX_CONF_ERROR;
  1629.     }

  1630.     return NGX_CONF_OK;
  1631. }


  1632. #if (NGX_HTTP_CACHE)

  1633. static char *
  1634. ngx_http_uwsgi_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  1635. {
  1636.     ngx_http_uwsgi_loc_conf_t *uwcf = conf;

  1637.     ngx_str_t                         *value;
  1638.     ngx_http_complex_value_t           cv;
  1639.     ngx_http_compile_complex_value_t   ccv;

  1640.     value = cf->args->elts;

  1641.     if (uwcf->upstream.cache != NGX_CONF_UNSET) {
  1642.         return "is duplicate";
  1643.     }

  1644.     if (ngx_strcmp(value[1].data, "off") == 0) {
  1645.         uwcf->upstream.cache = 0;
  1646.         return NGX_CONF_OK;
  1647.     }

  1648.     if (uwcf->upstream.store > 0) {
  1649.         return "is incompatible with \"uwsgi_store\"";
  1650.     }

  1651.     uwcf->upstream.cache = 1;

  1652.     ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));

  1653.     ccv.cf = cf;
  1654.     ccv.value = &value[1];
  1655.     ccv.complex_value = &cv;

  1656.     if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
  1657.         return NGX_CONF_ERROR;
  1658.     }

  1659.     if (cv.lengths != NULL) {

  1660.         uwcf->upstream.cache_value = ngx_palloc(cf->pool,
  1661.                                              sizeof(ngx_http_complex_value_t));
  1662.         if (uwcf->upstream.cache_value == NULL) {
  1663.             return NGX_CONF_ERROR;
  1664.         }

  1665.         *uwcf->upstream.cache_value = cv;

  1666.         return NGX_CONF_OK;
  1667.     }

  1668.     uwcf->upstream.cache_zone = ngx_shared_memory_add(cf, &value[1], 0,
  1669.                                                       &ngx_http_uwsgi_module);
  1670.     if (uwcf->upstream.cache_zone == NULL) {
  1671.         return NGX_CONF_ERROR;
  1672.     }

  1673.     return NGX_CONF_OK;
  1674. }


  1675. static char *
  1676. ngx_http_uwsgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  1677. {
  1678.     ngx_http_uwsgi_loc_conf_t *uwcf = conf;

  1679.     ngx_str_t                         *value;
  1680.     ngx_http_compile_complex_value_t   ccv;

  1681.     value = cf->args->elts;

  1682.     if (uwcf->cache_key.value.data) {
  1683.         return "is duplicate";
  1684.     }

  1685.     ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));

  1686.     ccv.cf = cf;
  1687.     ccv.value = &value[1];
  1688.     ccv.complex_value = &uwcf->cache_key;

  1689.     if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
  1690.         return NGX_CONF_ERROR;
  1691.     }

  1692.     return NGX_CONF_OK;
  1693. }

  1694. #endif


  1695. #if (NGX_HTTP_SSL)

  1696. static char *
  1697. ngx_http_uwsgi_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  1698. {
  1699.     ngx_http_uwsgi_loc_conf_t *uwcf = conf;

  1700.     ngx_str_t  *value;

  1701.     if (uwcf->ssl_passwords != NGX_CONF_UNSET_PTR) {
  1702.         return "is duplicate";
  1703.     }

  1704.     value = cf->args->elts;

  1705.     uwcf->ssl_passwords = ngx_ssl_read_password_file(cf, &value[1]);

  1706.     if (uwcf->ssl_passwords == NULL) {
  1707.         return NGX_CONF_ERROR;
  1708.     }

  1709.     return NGX_CONF_OK;
  1710. }


  1711. static ngx_int_t
  1712. ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *uwcf)
  1713. {
  1714.     ngx_pool_cleanup_t  *cln;

  1715.     uwcf->upstream.ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
  1716.     if (uwcf->upstream.ssl == NULL) {
  1717.         return NGX_ERROR;
  1718.     }

  1719.     uwcf->upstream.ssl->log = cf->log;

  1720.     if (ngx_ssl_create(uwcf->upstream.ssl, uwcf->ssl_protocols, NULL)
  1721.         != NGX_OK)
  1722.     {
  1723.         return NGX_ERROR;
  1724.     }

  1725.     cln = ngx_pool_cleanup_add(cf->pool, 0);
  1726.     if (cln == NULL) {
  1727.         return NGX_ERROR;
  1728.     }

  1729.     cln->handler = ngx_ssl_cleanup_ctx;
  1730.     cln->data = uwcf->upstream.ssl;

  1731.     if (uwcf->ssl_certificate.len) {

  1732.         if (uwcf->ssl_certificate_key.len == 0) {
  1733.             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
  1734.                           "no \"uwsgi_ssl_certificate_key\" is defined "
  1735.                           "for certificate \"%V\"", &uwcf->ssl_certificate);
  1736.             return NGX_ERROR;
  1737.         }

  1738.         if (ngx_ssl_certificate(cf, uwcf->upstream.ssl, &uwcf->ssl_certificate,
  1739.                                 &uwcf->ssl_certificate_key, uwcf->ssl_passwords)
  1740.             != NGX_OK)
  1741.         {
  1742.             return NGX_ERROR;
  1743.         }
  1744.     }

  1745.     if (SSL_CTX_set_cipher_list(uwcf->upstream.ssl->ctx,
  1746.                                 (const char *) uwcf->ssl_ciphers.data)
  1747.         == 0)
  1748.     {
  1749.         ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
  1750.                       "SSL_CTX_set_cipher_list(\"%V\") failed",
  1751.                       &uwcf->ssl_ciphers);
  1752.         return NGX_ERROR;
  1753.     }

  1754.     if (uwcf->upstream.ssl_verify) {
  1755.         if (uwcf->ssl_trusted_certificate.len == 0) {
  1756.             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
  1757.                       "no uwsgi_ssl_trusted_certificate for uwsgi_ssl_verify");
  1758.             return NGX_ERROR;
  1759.         }

  1760.         if (ngx_ssl_trusted_certificate(cf, uwcf->upstream.ssl,
  1761.                                         &uwcf->ssl_trusted_certificate,
  1762.                                         uwcf->ssl_verify_depth)
  1763.             != NGX_OK)
  1764.         {
  1765.             return NGX_ERROR;
  1766.         }

  1767.         if (ngx_ssl_crl(cf, uwcf->upstream.ssl, &uwcf->ssl_crl) != NGX_OK) {
  1768.             return NGX_ERROR;
  1769.         }
  1770.     }

  1771.     return NGX_OK;
  1772. }

  1773. #endif