src/http/ngx_http_core_module.c - nginx-1.31.7 nginx/ @ 939334eff

Global variables defined

Data types defined

Functions defined

Macros defined

Source code


  1. /*
  2. * Copyright (C) Igor Sysoev
  3. * Copyright (C) Nginx, Inc.
  4. */


  5. #include <ngx_config.h>
  6. #include <ngx_core.h>
  7. #include <ngx_http.h>


  8. ‌typedef struct {
  9.     u_char    *name;
  10.     uint32_t   method;
  11. ‌} ngx_http_method_name_t;


  12. ‌#define NGX_HTTP_REQUEST_BODY_FILE_OFF    0
  13. ‌#define NGX_HTTP_REQUEST_BODY_FILE_ON     1
  14. ‌#define NGX_HTTP_REQUEST_BODY_FILE_CLEAN  2


  15. static ngx_int_t ngx_http_core_auth_delay(ngx_http_request_t *r);
  16. static void ngx_http_core_auth_delay_handler(ngx_http_request_t *r);

  17. static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r);
  18. static ngx_int_t ngx_http_core_find_static_location(ngx_http_request_t *r,
  19.     ngx_http_location_tree_node_t *node);

  20. static ngx_int_t ngx_http_core_preconfiguration(ngx_conf_t *cf);
  21. static ngx_int_t ngx_http_core_postconfiguration(ngx_conf_t *cf);
  22. static void *ngx_http_core_create_main_conf(ngx_conf_t *cf);
  23. static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf);
  24. static void *ngx_http_core_create_srv_conf(ngx_conf_t *cf);
  25. static char *ngx_http_core_merge_srv_conf(ngx_conf_t *cf,
  26.     void *parent, void *child);
  27. static void *ngx_http_core_create_loc_conf(ngx_conf_t *cf);
  28. static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
  29.     void *parent, void *child);

  30. static char *ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd,
  31.     void *dummy);
  32. static char *ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd,
  33.     void *dummy);
  34. static ngx_int_t ngx_http_core_regex_location(ngx_conf_t *cf,
  35.     ngx_http_core_loc_conf_t *clcf, ngx_str_t *regex, ngx_uint_t caseless);

  36. static char *ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd,
  37.     void *conf);
  38. static char *ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy,
  39.     void *conf);

  40. static char *ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd,
  41.     void *conf);
  42. static char *ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd,
  43.     void *conf);
  44. static char *ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
  45. static char *ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd,
  46.     void *conf);
  47. static char *ngx_http_core_set_aio(ngx_conf_t *cf, ngx_command_t *cmd,
  48.     void *conf);
  49. static char *ngx_http_core_directio(ngx_conf_t *cf, ngx_command_t *cmd,
  50.     void *conf);
  51. static char *ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd,
  52.     void *conf);
  53. static char *ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd,
  54.     void *conf);
  55. static char *ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd,
  56.     void *conf);
  57. static char *ngx_http_core_keepalive(ngx_conf_t *cf, ngx_command_t *cmd,
  58.     void *conf);
  59. static char *ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd,
  60.     void *conf);
  61. static char *ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd,
  62.     void *conf);
  63. #if (NGX_HTTP_GZIP)
  64. static ngx_int_t ngx_http_gzip_accept_encoding(ngx_str_t *ae);
  65. static ngx_uint_t ngx_http_gzip_quantity(u_char *p, u_char *last);
  66. static char *ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd,
  67.     void *conf);
  68. #endif
  69. static ngx_int_t ngx_http_get_forwarded_addr_internal(ngx_http_request_t *r,
  70.     ngx_addr_t *addr, u_char *xff, size_t xfflen, ngx_array_t *proxies,
  71.     int recursive);
  72. #if (NGX_HAVE_OPENAT)
  73. static char *ngx_http_disable_symlinks(ngx_conf_t *cf, ngx_command_t *cmd,
  74.     void *conf);
  75. #endif

  76. static char *ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data);
  77. static char *ngx_http_core_pool_size(ngx_conf_t *cf, void *post, void *data);

  78. ‌static ngx_conf_post_t  ngx_http_core_lowat_post =
  79.     { ngx_http_core_lowat_check };

  80. ‌static ngx_conf_post_handler_pt  ngx_http_core_pool_size_p =
  81.     ngx_http_core_pool_size;


  82. ‌static ngx_conf_enum_t  ngx_http_core_request_body_in_file[] = {
  83.     { ngx_string("off"), NGX_HTTP_REQUEST_BODY_FILE_OFF },
  84.     { ngx_string("on"), NGX_HTTP_REQUEST_BODY_FILE_ON },
  85.     { ngx_string("clean"), NGX_HTTP_REQUEST_BODY_FILE_CLEAN },
  86.     { ngx_null_string, 0 }
  87. };


  88. ‌static ngx_conf_enum_t  ngx_http_core_satisfy[] = {
  89.     { ngx_string("all"), NGX_HTTP_SATISFY_ALL },
  90.     { ngx_string("any"), NGX_HTTP_SATISFY_ANY },
  91.     { ngx_null_string, 0 }
  92. };


  93. ‌static ngx_conf_enum_t  ngx_http_core_lingering_close[] = {
  94.     { ngx_string("off"), NGX_HTTP_LINGERING_OFF },
  95.     { ngx_string("on"), NGX_HTTP_LINGERING_ON },
  96.     { ngx_string("always"), NGX_HTTP_LINGERING_ALWAYS },
  97.     { ngx_null_string, 0 }
  98. };


  99. ‌static ngx_conf_enum_t  ngx_http_core_server_tokens[] = {
  100.     { ngx_string("off"), NGX_HTTP_SERVER_TOKENS_OFF },
  101.     { ngx_string("on"), NGX_HTTP_SERVER_TOKENS_ON },
  102.     { ngx_string("build"), NGX_HTTP_SERVER_TOKENS_BUILD },
  103.     { ngx_null_string, 0 }
  104. };


  105. ‌static ngx_conf_enum_t  ngx_http_core_if_modified_since[] = {
  106.     { ngx_string("off"), NGX_HTTP_IMS_OFF },
  107.     { ngx_string("exact"), NGX_HTTP_IMS_EXACT },
  108.     { ngx_string("before"), NGX_HTTP_IMS_BEFORE },
  109.     { ngx_null_string, 0 }
  110. };


  111. ‌static ngx_conf_bitmask_t  ngx_http_core_keepalive_disable[] = {
  112.     { ngx_string("none"), NGX_HTTP_KEEPALIVE_DISABLE_NONE },
  113.     { ngx_string("msie6"), NGX_HTTP_KEEPALIVE_DISABLE_MSIE6 },
  114.     { ngx_string("safari"), NGX_HTTP_KEEPALIVE_DISABLE_SAFARI },
  115.     { ngx_null_string, 0 }
  116. };


  117. ‌static ngx_path_init_t  ngx_http_client_temp_path = {
  118.     ngx_string(NGX_HTTP_CLIENT_TEMP_PATH), { 0, 0, 0 }
  119. };


  120. #if (NGX_HTTP_GZIP)

  121. ‌static ngx_conf_enum_t  ngx_http_gzip_http_version[] = {
  122.     { ngx_string("1.0"), NGX_HTTP_VERSION_10 },
  123.     { ngx_string("1.1"), NGX_HTTP_VERSION_11 },
  124.     { ngx_null_string, 0 }
  125. };


  126. ‌static ngx_conf_bitmask_t  ngx_http_gzip_proxied_mask[] = {
  127.     { ngx_string("off"), NGX_HTTP_GZIP_PROXIED_OFF },
  128.     { ngx_string("expired"), NGX_HTTP_GZIP_PROXIED_EXPIRED },
  129.     { ngx_string("no-cache"), NGX_HTTP_GZIP_PROXIED_NO_CACHE },
  130.     { ngx_string("no-store"), NGX_HTTP_GZIP_PROXIED_NO_STORE },
  131.     { ngx_string("private"), NGX_HTTP_GZIP_PROXIED_PRIVATE },
  132.     { ngx_string("no_last_modified"), NGX_HTTP_GZIP_PROXIED_NO_LM },
  133.     { ngx_string("no_etag"), NGX_HTTP_GZIP_PROXIED_NO_ETAG },
  134.     { ngx_string("auth"), NGX_HTTP_GZIP_PROXIED_AUTH },
  135.     { ngx_string("any"), NGX_HTTP_GZIP_PROXIED_ANY },
  136.     { ngx_null_string, 0 }
  137. };


  138. ‌static ngx_str_t  ngx_http_gzip_no_cache = ngx_string("no-cache");
  139. ‌static ngx_str_t  ngx_http_gzip_no_store = ngx_string("no-store");
  140. ‌static ngx_str_t  ngx_http_gzip_private = ngx_string("private");

  141. #endif


  142. ‌static ngx_command_t  ngx_http_core_commands[] = {

  143.     { ngx_string("variables_hash_max_size"),
  144.       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
  145.       ngx_conf_set_num_slot,
  146.       NGX_HTTP_MAIN_CONF_OFFSET,
  147.       offsetof(ngx_http_core_main_conf_t, variables_hash_max_size),
  148.       NULL },

  149.     { ngx_string("variables_hash_bucket_size"),
  150.       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
  151.       ngx_conf_set_num_slot,
  152.       NGX_HTTP_MAIN_CONF_OFFSET,
  153.       offsetof(ngx_http_core_main_conf_t, variables_hash_bucket_size),
  154.       NULL },

  155.     { ngx_string("server_names_hash_max_size"),
  156.       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
  157.       ngx_conf_set_num_slot,
  158.       NGX_HTTP_MAIN_CONF_OFFSET,
  159.       offsetof(ngx_http_core_main_conf_t, server_names_hash_max_size),
  160.       NULL },

  161.     { ngx_string("server_names_hash_bucket_size"),
  162.       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
  163.       ngx_conf_set_num_slot,
  164.       NGX_HTTP_MAIN_CONF_OFFSET,
  165.       offsetof(ngx_http_core_main_conf_t, server_names_hash_bucket_size),
  166.       NULL },

  167.     { ngx_string("server"),
  168.       NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
  169.       ngx_http_core_server,
  170.       0,
  171.       0,
  172.       NULL },

  173.     { ngx_string("connection_pool_size"),
  174.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
  175.       ngx_conf_set_size_slot,
  176.       NGX_HTTP_SRV_CONF_OFFSET,
  177.       offsetof(ngx_http_core_srv_conf_t, connection_pool_size),
  178.       &ngx_http_core_pool_size_p },

  179.     { ngx_string("request_pool_size"),
  180.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
  181.       ngx_conf_set_size_slot,
  182.       NGX_HTTP_SRV_CONF_OFFSET,
  183.       offsetof(ngx_http_core_srv_conf_t, request_pool_size),
  184.       &ngx_http_core_pool_size_p },

  185.     { ngx_string("client_header_timeout"),
  186.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
  187.       ngx_conf_set_msec_slot,
  188.       NGX_HTTP_SRV_CONF_OFFSET,
  189.       offsetof(ngx_http_core_srv_conf_t, client_header_timeout),
  190.       NULL },

  191.     { ngx_string("client_header_buffer_size"),
  192.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
  193.       ngx_conf_set_size_slot,
  194.       NGX_HTTP_SRV_CONF_OFFSET,
  195.       offsetof(ngx_http_core_srv_conf_t, client_header_buffer_size),
  196.       &ngx_conf_size_nonzero_post },

  197.     { ngx_string("large_client_header_buffers"),
  198.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE2,
  199.       ngx_conf_set_bufs_slot,
  200.       NGX_HTTP_SRV_CONF_OFFSET,
  201.       offsetof(ngx_http_core_srv_conf_t, large_client_header_buffers),
  202.       NULL },

  203.     { ngx_string("max_headers"),
  204.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
  205.       ngx_conf_set_num_slot,
  206.       NGX_HTTP_SRV_CONF_OFFSET,
  207.       offsetof(ngx_http_core_srv_conf_t, max_headers),
  208.       NULL },

  209.     { ngx_string("ignore_invalid_headers"),
  210.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
  211.       ngx_conf_set_flag_slot,
  212.       NGX_HTTP_SRV_CONF_OFFSET,
  213.       offsetof(ngx_http_core_srv_conf_t, ignore_invalid_headers),
  214.       NULL },

  215.     { ngx_string("merge_slashes"),
  216.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
  217.       ngx_conf_set_flag_slot,
  218.       NGX_HTTP_SRV_CONF_OFFSET,
  219.       offsetof(ngx_http_core_srv_conf_t, merge_slashes),
  220.       NULL },

  221.     { ngx_string("underscores_in_headers"),
  222.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
  223.       ngx_conf_set_flag_slot,
  224.       NGX_HTTP_SRV_CONF_OFFSET,
  225.       offsetof(ngx_http_core_srv_conf_t, underscores_in_headers),
  226.       NULL },

  227.     { ngx_string("location"),
  228.       NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12,
  229.       ngx_http_core_location,
  230.       NGX_HTTP_SRV_CONF_OFFSET,
  231.       0,
  232.       NULL },

  233.     { ngx_string("listen"),
  234.       NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
  235.       ngx_http_core_listen,
  236.       NGX_HTTP_SRV_CONF_OFFSET,
  237.       0,
  238.       NULL },

  239.     { ngx_string("server_name"),
  240.       NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
  241.       ngx_http_core_server_name,
  242.       NGX_HTTP_SRV_CONF_OFFSET,
  243.       0,
  244.       NULL },

  245.     { ngx_string("types_hash_max_size"),
  246.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  247.       ngx_conf_set_num_slot,
  248.       NGX_HTTP_LOC_CONF_OFFSET,
  249.       offsetof(ngx_http_core_loc_conf_t, types_hash_max_size),
  250.       NULL },

  251.     { ngx_string("types_hash_bucket_size"),
  252.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  253.       ngx_conf_set_num_slot,
  254.       NGX_HTTP_LOC_CONF_OFFSET,
  255.       offsetof(ngx_http_core_loc_conf_t, types_hash_bucket_size),
  256.       NULL },

  257.     { ngx_string("types"),
  258.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
  259.                                           |NGX_CONF_BLOCK|NGX_CONF_NOARGS,
  260.       ngx_http_core_types,
  261.       NGX_HTTP_LOC_CONF_OFFSET,
  262.       0,
  263.       NULL },

  264.     { ngx_string("default_type"),
  265.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  266.       ngx_conf_set_str_slot,
  267.       NGX_HTTP_LOC_CONF_OFFSET,
  268.       offsetof(ngx_http_core_loc_conf_t, default_type),
  269.       NULL },

  270.     { ngx_string("root"),
  271.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
  272.                         |NGX_CONF_TAKE1,
  273.       ngx_http_core_root,
  274.       NGX_HTTP_LOC_CONF_OFFSET,
  275.       0,
  276.       NULL },

  277.     { ngx_string("alias"),
  278.       NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  279.       ngx_http_core_root,
  280.       NGX_HTTP_LOC_CONF_OFFSET,
  281.       0,
  282.       NULL },

  283.     { ngx_string("limit_except"),
  284.       NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_1MORE,
  285.       ngx_http_core_limit_except,
  286.       NGX_HTTP_LOC_CONF_OFFSET,
  287.       0,
  288.       NULL },

  289.     { ngx_string("client_max_body_size"),
  290.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  291.       ngx_conf_set_off_slot,
  292.       NGX_HTTP_LOC_CONF_OFFSET,
  293.       offsetof(ngx_http_core_loc_conf_t, client_max_body_size),
  294.       NULL },

  295.     { ngx_string("client_body_buffer_size"),
  296.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  297.       ngx_conf_set_size_slot,
  298.       NGX_HTTP_LOC_CONF_OFFSET,
  299.       offsetof(ngx_http_core_loc_conf_t, client_body_buffer_size),
  300.       &ngx_conf_size_nonzero_post },

  301.     { ngx_string("client_body_timeout"),
  302.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  303.       ngx_conf_set_msec_slot,
  304.       NGX_HTTP_LOC_CONF_OFFSET,
  305.       offsetof(ngx_http_core_loc_conf_t, client_body_timeout),
  306.       NULL },

  307.     { ngx_string("client_body_temp_path"),
  308.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
  309.       ngx_conf_set_path_slot,
  310.       NGX_HTTP_LOC_CONF_OFFSET,
  311.       offsetof(ngx_http_core_loc_conf_t, client_body_temp_path),
  312.       NULL },

  313.     { ngx_string("client_body_in_file_only"),
  314.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  315.       ngx_conf_set_enum_slot,
  316.       NGX_HTTP_LOC_CONF_OFFSET,
  317.       offsetof(ngx_http_core_loc_conf_t, client_body_in_file_only),
  318.       &ngx_http_core_request_body_in_file },

  319.     { ngx_string("client_body_in_single_buffer"),
  320.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  321.       ngx_conf_set_flag_slot,
  322.       NGX_HTTP_LOC_CONF_OFFSET,
  323.       offsetof(ngx_http_core_loc_conf_t, client_body_in_single_buffer),
  324.       NULL },

  325.     { ngx_string("client_body_early_read"),
  326.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
  327.       ngx_http_set_predicate_slot,
  328.       NGX_HTTP_SRV_CONF_OFFSET,
  329.       offsetof(ngx_http_core_srv_conf_t, client_body_early_read),
  330.       NULL },

  331.     { ngx_string("sendfile"),
  332.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
  333.                         |NGX_CONF_FLAG,
  334.       ngx_conf_set_flag_slot,
  335.       NGX_HTTP_LOC_CONF_OFFSET,
  336.       offsetof(ngx_http_core_loc_conf_t, sendfile),
  337.       NULL },

  338.     { ngx_string("sendfile_max_chunk"),
  339.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  340.       ngx_conf_set_size_slot,
  341.       NGX_HTTP_LOC_CONF_OFFSET,
  342.       offsetof(ngx_http_core_loc_conf_t, sendfile_max_chunk),
  343.       NULL },

  344.     { ngx_string("subrequest_output_buffer_size"),
  345.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  346.       ngx_conf_set_size_slot,
  347.       NGX_HTTP_LOC_CONF_OFFSET,
  348.       offsetof(ngx_http_core_loc_conf_t, subrequest_output_buffer_size),
  349.       &ngx_conf_size_nonzero_post },

  350.     { ngx_string("aio"),
  351.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  352.       ngx_http_core_set_aio,
  353.       NGX_HTTP_LOC_CONF_OFFSET,
  354.       0,
  355.       NULL },

  356.     { ngx_string("aio_write"),
  357.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  358.       ngx_conf_set_flag_slot,
  359.       NGX_HTTP_LOC_CONF_OFFSET,
  360.       offsetof(ngx_http_core_loc_conf_t, aio_write),
  361.       NULL },

  362.     { ngx_string("read_ahead"),
  363.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  364.       ngx_conf_set_size_slot,
  365.       NGX_HTTP_LOC_CONF_OFFSET,
  366.       offsetof(ngx_http_core_loc_conf_t, read_ahead),
  367.       NULL },

  368.     { ngx_string("directio"),
  369.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  370.       ngx_http_core_directio,
  371.       NGX_HTTP_LOC_CONF_OFFSET,
  372.       0,
  373.       NULL },

  374.     { ngx_string("directio_alignment"),
  375.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  376.       ngx_conf_set_off_slot,
  377.       NGX_HTTP_LOC_CONF_OFFSET,
  378.       offsetof(ngx_http_core_loc_conf_t, directio_alignment),
  379.       NULL },

  380.     { ngx_string("tcp_nopush"),
  381.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  382.       ngx_conf_set_flag_slot,
  383.       NGX_HTTP_LOC_CONF_OFFSET,
  384.       offsetof(ngx_http_core_loc_conf_t, tcp_nopush),
  385.       NULL },

  386.     { ngx_string("tcp_nodelay"),
  387.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  388.       ngx_conf_set_flag_slot,
  389.       NGX_HTTP_LOC_CONF_OFFSET,
  390.       offsetof(ngx_http_core_loc_conf_t, tcp_nodelay),
  391.       NULL },

  392.     { ngx_string("send_timeout"),
  393.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  394.       ngx_conf_set_msec_slot,
  395.       NGX_HTTP_LOC_CONF_OFFSET,
  396.       offsetof(ngx_http_core_loc_conf_t, send_timeout),
  397.       NULL },

  398.     { ngx_string("send_lowat"),
  399.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  400.       ngx_conf_set_size_slot,
  401.       NGX_HTTP_LOC_CONF_OFFSET,
  402.       offsetof(ngx_http_core_loc_conf_t, send_lowat),
  403.       &ngx_http_core_lowat_post },

  404.     { ngx_string("postpone_output"),
  405.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  406.       ngx_conf_set_size_slot,
  407.       NGX_HTTP_LOC_CONF_OFFSET,
  408.       offsetof(ngx_http_core_loc_conf_t, postpone_output),
  409.       NULL },

  410.     { ngx_string("limit_rate"),
  411.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
  412.                         |NGX_CONF_TAKE1,
  413.       ngx_http_set_complex_value_size_slot,
  414.       NGX_HTTP_LOC_CONF_OFFSET,
  415.       offsetof(ngx_http_core_loc_conf_t, limit_rate),
  416.       NULL },

  417.     { ngx_string("limit_rate_after"),
  418.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
  419.                         |NGX_CONF_TAKE1,
  420.       ngx_http_set_complex_value_size_slot,
  421.       NGX_HTTP_LOC_CONF_OFFSET,
  422.       offsetof(ngx_http_core_loc_conf_t, limit_rate_after),
  423.       NULL },

  424.     { ngx_string("keepalive_time"),
  425.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  426.       ngx_conf_set_msec_slot,
  427.       NGX_HTTP_LOC_CONF_OFFSET,
  428.       offsetof(ngx_http_core_loc_conf_t, keepalive_time),
  429.       NULL },

  430.     { ngx_string("keepalive_timeout"),
  431.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
  432.       ngx_http_core_keepalive,
  433.       NGX_HTTP_LOC_CONF_OFFSET,
  434.       0,
  435.       NULL },

  436.     { ngx_string("keepalive_min_timeout"),
  437.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  438.       ngx_conf_set_msec_slot,
  439.       NGX_HTTP_LOC_CONF_OFFSET,
  440.       offsetof(ngx_http_core_loc_conf_t, keepalive_min_timeout),
  441.       NULL },

  442.     { ngx_string("keepalive_requests"),
  443.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  444.       ngx_conf_set_num_slot,
  445.       NGX_HTTP_LOC_CONF_OFFSET,
  446.       offsetof(ngx_http_core_loc_conf_t, keepalive_requests),
  447.       NULL },

  448.     { ngx_string("keepalive_disable"),
  449.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
  450.       ngx_conf_set_bitmask_slot,
  451.       NGX_HTTP_LOC_CONF_OFFSET,
  452.       offsetof(ngx_http_core_loc_conf_t, keepalive_disable),
  453.       &ngx_http_core_keepalive_disable },

  454.     { ngx_string("satisfy"),
  455.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  456.       ngx_conf_set_enum_slot,
  457.       NGX_HTTP_LOC_CONF_OFFSET,
  458.       offsetof(ngx_http_core_loc_conf_t, satisfy),
  459.       &ngx_http_core_satisfy },

  460.     { ngx_string("auth_delay"),
  461.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  462.       ngx_conf_set_msec_slot,
  463.       NGX_HTTP_LOC_CONF_OFFSET,
  464.       offsetof(ngx_http_core_loc_conf_t, auth_delay),
  465.       NULL },

  466.     { ngx_string("internal"),
  467.       NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
  468.       ngx_http_core_internal,
  469.       NGX_HTTP_LOC_CONF_OFFSET,
  470.       0,
  471.       NULL },

  472.     { ngx_string("lingering_close"),
  473.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  474.       ngx_conf_set_enum_slot,
  475.       NGX_HTTP_LOC_CONF_OFFSET,
  476.       offsetof(ngx_http_core_loc_conf_t, lingering_close),
  477.       &ngx_http_core_lingering_close },

  478.     { ngx_string("lingering_time"),
  479.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  480.       ngx_conf_set_msec_slot,
  481.       NGX_HTTP_LOC_CONF_OFFSET,
  482.       offsetof(ngx_http_core_loc_conf_t, lingering_time),
  483.       NULL },

  484.     { ngx_string("lingering_timeout"),
  485.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  486.       ngx_conf_set_msec_slot,
  487.       NGX_HTTP_LOC_CONF_OFFSET,
  488.       offsetof(ngx_http_core_loc_conf_t, lingering_timeout),
  489.       NULL },

  490.     { ngx_string("reset_timedout_connection"),
  491.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  492.       ngx_conf_set_flag_slot,
  493.       NGX_HTTP_LOC_CONF_OFFSET,
  494.       offsetof(ngx_http_core_loc_conf_t, reset_timedout_connection),
  495.       NULL },

  496.     { ngx_string("absolute_redirect"),
  497.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  498.       ngx_conf_set_flag_slot,
  499.       NGX_HTTP_LOC_CONF_OFFSET,
  500.       offsetof(ngx_http_core_loc_conf_t, absolute_redirect),
  501.       NULL },

  502.     { ngx_string("server_name_in_redirect"),
  503.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  504.       ngx_conf_set_flag_slot,
  505.       NGX_HTTP_LOC_CONF_OFFSET,
  506.       offsetof(ngx_http_core_loc_conf_t, server_name_in_redirect),
  507.       NULL },

  508.     { ngx_string("port_in_redirect"),
  509.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  510.       ngx_conf_set_flag_slot,
  511.       NGX_HTTP_LOC_CONF_OFFSET,
  512.       offsetof(ngx_http_core_loc_conf_t, port_in_redirect),
  513.       NULL },

  514.     { ngx_string("msie_padding"),
  515.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  516.       ngx_conf_set_flag_slot,
  517.       NGX_HTTP_LOC_CONF_OFFSET,
  518.       offsetof(ngx_http_core_loc_conf_t, msie_padding),
  519.       NULL },

  520.     { ngx_string("msie_refresh"),
  521.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  522.       ngx_conf_set_flag_slot,
  523.       NGX_HTTP_LOC_CONF_OFFSET,
  524.       offsetof(ngx_http_core_loc_conf_t, msie_refresh),
  525.       NULL },

  526.     { ngx_string("log_not_found"),
  527.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  528.       ngx_conf_set_flag_slot,
  529.       NGX_HTTP_LOC_CONF_OFFSET,
  530.       offsetof(ngx_http_core_loc_conf_t, log_not_found),
  531.       NULL },

  532.     { ngx_string("log_subrequest"),
  533.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  534.       ngx_conf_set_flag_slot,
  535.       NGX_HTTP_LOC_CONF_OFFSET,
  536.       offsetof(ngx_http_core_loc_conf_t, log_subrequest),
  537.       NULL },

  538.     { ngx_string("recursive_error_pages"),
  539.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  540.       ngx_conf_set_flag_slot,
  541.       NGX_HTTP_LOC_CONF_OFFSET,
  542.       offsetof(ngx_http_core_loc_conf_t, recursive_error_pages),
  543.       NULL },

  544.     { ngx_string("server_tokens"),
  545.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  546.       ngx_conf_set_enum_slot,
  547.       NGX_HTTP_LOC_CONF_OFFSET,
  548.       offsetof(ngx_http_core_loc_conf_t, server_tokens),
  549.       &ngx_http_core_server_tokens },

  550.     { ngx_string("if_modified_since"),
  551.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  552.       ngx_conf_set_enum_slot,
  553.       NGX_HTTP_LOC_CONF_OFFSET,
  554.       offsetof(ngx_http_core_loc_conf_t, if_modified_since),
  555.       &ngx_http_core_if_modified_since },

  556.     { ngx_string("max_ranges"),
  557.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  558.       ngx_conf_set_num_slot,
  559.       NGX_HTTP_LOC_CONF_OFFSET,
  560.       offsetof(ngx_http_core_loc_conf_t, max_ranges),
  561.       NULL },

  562.     { ngx_string("chunked_transfer_encoding"),
  563.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  564.       ngx_conf_set_flag_slot,
  565.       NGX_HTTP_LOC_CONF_OFFSET,
  566.       offsetof(ngx_http_core_loc_conf_t, chunked_transfer_encoding),
  567.       NULL },

  568.     { ngx_string("etag"),
  569.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  570.       ngx_conf_set_flag_slot,
  571.       NGX_HTTP_LOC_CONF_OFFSET,
  572.       offsetof(ngx_http_core_loc_conf_t, etag),
  573.       NULL },

  574.     { ngx_string("early_hints"),
  575.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  576.       ngx_http_set_predicate_slot,
  577.       NGX_HTTP_LOC_CONF_OFFSET,
  578.       offsetof(ngx_http_core_loc_conf_t, early_hints),
  579.       NULL },

  580.     { ngx_string("error_page"),
  581.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
  582.                         |NGX_CONF_2MORE,
  583.       ngx_http_core_error_page,
  584.       NGX_HTTP_LOC_CONF_OFFSET,
  585.       0,
  586.       NULL },

  587.     { ngx_string("post_action"),
  588.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
  589.                         |NGX_CONF_TAKE1,
  590.       ngx_conf_set_str_slot,
  591.       NGX_HTTP_LOC_CONF_OFFSET,
  592.       offsetof(ngx_http_core_loc_conf_t, post_action),
  593.       NULL },

  594.     { ngx_string("error_log"),
  595.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  596.       ngx_http_core_error_log,
  597.       NGX_HTTP_LOC_CONF_OFFSET,
  598.       0,
  599.       NULL },

  600.     { ngx_string("open_file_cache"),
  601.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
  602.       ngx_http_core_open_file_cache,
  603.       NGX_HTTP_LOC_CONF_OFFSET,
  604.       offsetof(ngx_http_core_loc_conf_t, open_file_cache),
  605.       NULL },

  606.     { ngx_string("open_file_cache_valid"),
  607.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  608.       ngx_conf_set_sec_slot,
  609.       NGX_HTTP_LOC_CONF_OFFSET,
  610.       offsetof(ngx_http_core_loc_conf_t, open_file_cache_valid),
  611.       NULL },

  612.     { ngx_string("open_file_cache_min_uses"),
  613.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  614.       ngx_conf_set_num_slot,
  615.       NGX_HTTP_LOC_CONF_OFFSET,
  616.       offsetof(ngx_http_core_loc_conf_t, open_file_cache_min_uses),
  617.       NULL },

  618.     { ngx_string("open_file_cache_errors"),
  619.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  620.       ngx_conf_set_flag_slot,
  621.       NGX_HTTP_LOC_CONF_OFFSET,
  622.       offsetof(ngx_http_core_loc_conf_t, open_file_cache_errors),
  623.       NULL },

  624.     { ngx_string("open_file_cache_events"),
  625.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  626.       ngx_conf_set_flag_slot,
  627.       NGX_HTTP_LOC_CONF_OFFSET,
  628.       offsetof(ngx_http_core_loc_conf_t, open_file_cache_events),
  629.       NULL },

  630.     { ngx_string("resolver"),
  631.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  632.       ngx_http_core_resolver,
  633.       NGX_HTTP_LOC_CONF_OFFSET,
  634.       0,
  635.       NULL },

  636.     { ngx_string("resolver_timeout"),
  637.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  638.       ngx_conf_set_msec_slot,
  639.       NGX_HTTP_LOC_CONF_OFFSET,
  640.       offsetof(ngx_http_core_loc_conf_t, resolver_timeout),
  641.       NULL },

  642. #if (NGX_HTTP_GZIP)

  643.     { ngx_string("gzip_vary"),
  644.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  645.       ngx_conf_set_flag_slot,
  646.       NGX_HTTP_LOC_CONF_OFFSET,
  647.       offsetof(ngx_http_core_loc_conf_t, gzip_vary),
  648.       NULL },

  649.     { ngx_string("gzip_http_version"),
  650.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  651.       ngx_conf_set_enum_slot,
  652.       NGX_HTTP_LOC_CONF_OFFSET,
  653.       offsetof(ngx_http_core_loc_conf_t, gzip_http_version),
  654.       &ngx_http_gzip_http_version },

  655.     { ngx_string("gzip_proxied"),
  656.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  657.       ngx_conf_set_bitmask_slot,
  658.       NGX_HTTP_LOC_CONF_OFFSET,
  659.       offsetof(ngx_http_core_loc_conf_t, gzip_proxied),
  660.       &ngx_http_gzip_proxied_mask },

  661.     { ngx_string("gzip_disable"),
  662.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  663.       ngx_http_gzip_disable,
  664.       NGX_HTTP_LOC_CONF_OFFSET,
  665.       0,
  666.       NULL },

  667. #endif

  668. #if (NGX_HAVE_OPENAT)

  669.     { ngx_string("disable_symlinks"),
  670.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
  671.       ngx_http_disable_symlinks,
  672.       NGX_HTTP_LOC_CONF_OFFSET,
  673.       0,
  674.       NULL },

  675. #endif

  676.       ngx_null_command
  677. };


  678. ‌static ngx_http_module_t  ngx_http_core_module_ctx = {
  679.     ngx_http_core_preconfiguration,        /* preconfiguration */
  680.     ngx_http_core_postconfiguration,       /* postconfiguration */

  681.     ngx_http_core_create_main_conf,        /* create main configuration */
  682.     ngx_http_core_init_main_conf,          /* init main configuration */

  683.     ngx_http_core_create_srv_conf,         /* create server configuration */
  684.     ngx_http_core_merge_srv_conf,          /* merge server configuration */

  685.     ngx_http_core_create_loc_conf,         /* create location configuration */
  686.     ngx_http_core_merge_loc_conf           /* merge location configuration */
  687. };


  688. ‌ngx_module_t  ngx_http_core_module = {
  689.     NGX_MODULE_V1,
  690.     &ngx_http_core_module_ctx,             /* module context */
  691.     ngx_http_core_commands,                /* module directives */
  692.     NGX_HTTP_MODULE,                       /* module type */
  693.     NULL,                                  /* init master */
  694.     NULL,                                  /* init module */
  695.     NULL,                                  /* init process */
  696.     NULL,                                  /* init thread */
  697.     NULL,                                  /* exit thread */
  698.     NULL,                                  /* exit process */
  699.     NULL,                                  /* exit master */
  700.     NGX_MODULE_V1_PADDING
  701. };


  702. ‌ngx_str_t  ngx_http_core_get_method = { 3, (u_char *) "GET" };


  703. void
  704. ‌ngx_http_handler(ngx_http_request_t *r)
  705. {
  706.     ngx_http_core_main_conf_t  *cmcf;

  707.     r->connection->log->action = NULL;

  708.     if (!r->internal) {

  709.         if (r->method != NGX_HTTP_CONNECT) {
  710.             switch (r->headers_in.connection_type) {
  711.             case 0:
  712.                 r->keepalive = (r->http_version > NGX_HTTP_VERSION_10);
  713.                 break;

  714.             case NGX_HTTP_CONNECTION_CLOSE:
  715.                 r->keepalive = 0;
  716.                 break;

  717.             case NGX_HTTP_CONNECTION_KEEP_ALIVE:
  718.                 r->keepalive = 1;
  719.                 break;
  720.             }
  721.         }

  722.         r->lingering_close = (r->headers_in.content_length_n > 0
  723.                               || r->headers_in.chunked);
  724.         r->phase_handler = 0;

  725.     } else {
  726.         cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
  727.         r->phase_handler = cmcf->phase_engine.server_rewrite_index;
  728.     }

  729.     r->valid_location = 1;
  730. #if (NGX_HTTP_GZIP)
  731.     r->gzip_tested = 0;
  732.     r->gzip_ok = 0;
  733.     r->gzip_vary = 0;
  734. #endif

  735.     r->write_event_handler = ngx_http_core_run_phases;
  736.     ngx_http_core_run_phases(r);
  737. }


  738. void
  739. ‌ngx_http_core_run_phases(ngx_http_request_t *r)
  740. {
  741.     ngx_int_t                   rc;
  742.     ngx_http_phase_handler_t   *ph;
  743.     ngx_http_core_main_conf_t  *cmcf;

  744.     cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

  745.     ph = cmcf->phase_engine.handlers;

  746.     while (ph[r->phase_handler].checker) {

  747.         rc = ph[r->phase_handler].checker(r, &ph[r->phase_handler]);

  748.         if (rc == NGX_OK) {
  749.             return;
  750.         }
  751.     }
  752. }


  753. ngx_int_t
  754. ‌ngx_http_core_generic_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
  755. {
  756.     ngx_int_t  rc;

  757.     /*
  758.      * generic phase checker,
  759.      * used by the post read and pre-access phases
  760.      */

  761.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  762.                    "generic phase: %ui", r->phase_handler);

  763.     rc = ph->handler(r);

  764.     if (rc == NGX_OK) {
  765.         r->phase_handler = ph->next;
  766.         return NGX_AGAIN;
  767.     }

  768.     if (rc == NGX_DECLINED) {
  769.         r->phase_handler++;
  770.         return NGX_AGAIN;
  771.     }

  772.     if (rc == NGX_AGAIN || rc == NGX_DONE) {
  773.         return NGX_OK;
  774.     }

  775.     /* rc == NGX_ERROR || rc == NGX_HTTP_...  */

  776.     ngx_http_finalize_request(r, rc);

  777.     return NGX_OK;
  778. }


  779. ngx_int_t
  780. ‌ngx_http_core_rewrite_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
  781. {
  782.     ngx_int_t  rc;

  783.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  784.                    "rewrite phase: %ui", r->phase_handler);

  785.     rc = ph->handler(r);

  786.     if (rc == NGX_DECLINED) {
  787.         r->phase_handler++;
  788.         return NGX_AGAIN;
  789.     }

  790.     if (rc == NGX_DONE) {
  791.         return NGX_OK;
  792.     }

  793.     /* NGX_OK, NGX_AGAIN, NGX_ERROR, NGX_HTTP_...  */

  794.     ngx_http_finalize_request(r, rc);

  795.     return NGX_OK;
  796. }


  797. ngx_int_t
  798. ‌ngx_http_core_find_config_phase(ngx_http_request_t *r,
  799.     ngx_http_phase_handler_t *ph)
  800. {
  801.     u_char                    *p;
  802.     size_t                     len;
  803.     ngx_int_t                  rc;
  804.     ngx_http_core_loc_conf_t  *clcf;

  805.     r->content_handler = NULL;
  806.     r->uri_changed = 0;

  807.     rc = ngx_http_core_find_location(r);

  808.     if (rc == NGX_ERROR) {
  809.         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  810.         return NGX_OK;
  811.     }

  812.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  813.     if (!r->internal && clcf->internal) {
  814.         ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
  815.         return NGX_OK;
  816.     }

  817.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  818.                    "using configuration \"%s%V\"",
  819.                    (clcf->noname ? "*" : (clcf->exact_match ? "=" : "")),
  820.                    &clcf->name);

  821.     ngx_http_update_location_config(r);

  822.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  823.                    "http cl:%O max:%O",
  824.                    r->headers_in.content_length_n, clcf->client_max_body_size);

  825.     if (r->headers_in.content_length_n != -1
  826.         && !r->discard_body
  827.         && clcf->client_max_body_size
  828.         && clcf->client_max_body_size < r->headers_in.content_length_n)
  829.     {
  830.         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  831.                       "client intended to send too large body: %O bytes",
  832.                       r->headers_in.content_length_n);

  833.         r->expect_tested = 1;
  834.         (void) ngx_http_discard_request_body(r);
  835.         ngx_http_finalize_request(r, NGX_HTTP_REQUEST_ENTITY_TOO_LARGE);
  836.         return NGX_OK;
  837.     }

  838.     if (rc == NGX_DONE) {
  839.         ngx_http_clear_location(r);

  840.         r->headers_out.location = ngx_list_push(&r->headers_out.headers);
  841.         if (r->headers_out.location == NULL) {
  842.             ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  843.             return NGX_OK;
  844.         }

  845.         r->headers_out.location->hash = 1;
  846.         r->headers_out.location->next = NULL;
  847.         ngx_str_set(&r->headers_out.location->key, "Location");

  848.         if (r->args.len == 0) {
  849.             r->headers_out.location->value = clcf->escaped_name;

  850.         } else {
  851.             len = clcf->escaped_name.len + 1 + r->args.len;
  852.             p = ngx_pnalloc(r->pool, len);

  853.             if (p == NULL) {
  854.                 ngx_http_clear_location(r);
  855.                 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  856.                 return NGX_OK;
  857.             }

  858.             r->headers_out.location->value.len = len;
  859.             r->headers_out.location->value.data = p;

  860.             p = ngx_cpymem(p, clcf->escaped_name.data, clcf->escaped_name.len);
  861.             *p++ = '?';
  862.             ngx_memcpy(p, r->args.data, r->args.len);
  863.         }

  864.         ngx_http_finalize_request(r, NGX_HTTP_MOVED_PERMANENTLY);
  865.         return NGX_OK;
  866.     }

  867.     r->phase_handler++;
  868.     return NGX_AGAIN;
  869. }


  870. ngx_int_t
  871. ‌ngx_http_core_post_rewrite_phase(ngx_http_request_t *r,
  872.     ngx_http_phase_handler_t *ph)
  873. {
  874.     ngx_http_core_srv_conf_t  *cscf;

  875.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  876.                    "post rewrite phase: %ui", r->phase_handler);

  877.     if (!r->uri_changed) {
  878.         r->phase_handler++;
  879.         return NGX_AGAIN;
  880.     }

  881.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  882.                    "uri changes: %d", r->uri_changes);

  883.     /*
  884.      * gcc before 3.3 compiles the broken code for
  885.      *     if (r->uri_changes-- == 0)
  886.      * if the r->uri_changes is defined as
  887.      *     unsigned  uri_changes:4
  888.      */

  889.     r->uri_changes--;

  890.     if (r->uri_changes == 0) {
  891.         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  892.                       "rewrite or internal redirection cycle "
  893.                       "while processing \"%V\"", &r->uri);

  894.         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  895.         return NGX_OK;
  896.     }

  897.     r->phase_handler = ph->next;

  898.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
  899.     r->loc_conf = cscf->ctx->loc_conf;

  900.     return NGX_AGAIN;
  901. }


  902. ngx_int_t
  903. ‌ngx_http_core_access_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
  904. {
  905.     ngx_int_t                  rc;
  906.     ngx_table_elt_t           *h;
  907.     ngx_http_core_loc_conf_t  *clcf;

  908.     if (r != r->main) {
  909.         r->phase_handler = ph->next;
  910.         return NGX_AGAIN;
  911.     }

  912.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  913.                    "access phase: %ui", r->phase_handler);

  914.     rc = ph->handler(r);

  915.     if (rc == NGX_DECLINED) {
  916.         r->phase_handler++;
  917.         return NGX_AGAIN;
  918.     }

  919.     if (rc == NGX_AGAIN || rc == NGX_DONE) {
  920.         return NGX_OK;
  921.     }

  922.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  923.     if (clcf->satisfy == NGX_HTTP_SATISFY_ALL) {

  924.         if (rc == NGX_OK) {
  925.             r->phase_handler++;
  926.             return NGX_AGAIN;
  927.         }

  928.     } else {
  929.         if (rc == NGX_OK) {
  930.             r->access_code = 0;

  931.             h = ngx_http_proxy_auth(r) ? r->headers_out.proxy_authenticate
  932.                                        : r->headers_out.www_authenticate;

  933.             for ( /* void */ ; h; h = h->next) {
  934.                 h->hash = 0;
  935.             }

  936.             r->phase_handler = ph->next;
  937.             return NGX_AGAIN;
  938.         }

  939.         if (rc == NGX_HTTP_FORBIDDEN
  940.             || rc == NGX_HTTP_UNAUTHORIZED
  941.             || rc == NGX_HTTP_PROXY_AUTH_REQUIRED)
  942.         {
  943.             if (r->access_code != NGX_HTTP_UNAUTHORIZED
  944.                 && r->access_code != NGX_HTTP_PROXY_AUTH_REQUIRED)
  945.             {
  946.                 r->access_code = rc;
  947.             }

  948.             r->phase_handler++;
  949.             return NGX_AGAIN;
  950.         }
  951.     }

  952.     /* rc == NGX_ERROR || rc == NGX_HTTP_...  */

  953.     if (rc == NGX_HTTP_UNAUTHORIZED || rc == NGX_HTTP_PROXY_AUTH_REQUIRED) {
  954.         r->access_code = rc;
  955.         return ngx_http_core_auth_delay(r);
  956.     }

  957.     ngx_http_finalize_request(r, rc);
  958.     return NGX_OK;
  959. }


  960. ngx_int_t
  961. ‌ngx_http_core_post_access_phase(ngx_http_request_t *r,
  962.     ngx_http_phase_handler_t *ph)
  963. {
  964.     ngx_int_t  access_code;

  965.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  966.                    "post access phase: %ui", r->phase_handler);

  967.     access_code = r->access_code;

  968.     if (access_code) {
  969.         if (access_code == NGX_HTTP_FORBIDDEN) {
  970.             ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  971.                           "access forbidden by rule");
  972.         }

  973.         if (access_code == NGX_HTTP_UNAUTHORIZED
  974.             || access_code == NGX_HTTP_PROXY_AUTH_REQUIRED)
  975.         {
  976.             return ngx_http_core_auth_delay(r);
  977.         }

  978.         r->access_code = 0;

  979.         ngx_http_finalize_request(r, access_code);
  980.         return NGX_OK;
  981.     }

  982.     r->phase_handler++;
  983.     return NGX_AGAIN;
  984. }


  985. static ngx_int_t
  986. ‌ngx_http_core_auth_delay(ngx_http_request_t *r)
  987. {
  988.     ngx_int_t                  access_code;
  989.     ngx_http_core_loc_conf_t  *clcf;

  990.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  991.     if (clcf->auth_delay == 0) {
  992.         access_code = r->access_code;
  993.         r->access_code = 0;

  994.         ngx_http_finalize_request(r, access_code);
  995.         return NGX_OK;
  996.     }

  997.     ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
  998.                   "delaying unauthorized request");

  999.     if (r->connection->read->ready) {
  1000.         ngx_post_event(r->connection->read, &ngx_posted_events);

  1001.     } else {
  1002.         if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
  1003.             return NGX_HTTP_INTERNAL_SERVER_ERROR;
  1004.         }
  1005.     }

  1006.     r->read_event_handler = ngx_http_test_reading;
  1007.     r->write_event_handler = ngx_http_core_auth_delay_handler;

  1008.     r->connection->write->delayed = 1;
  1009.     ngx_add_timer(r->connection->write, clcf->auth_delay);

  1010.     /*
  1011.      * trigger an additional event loop iteration
  1012.      * to ensure constant-time processing
  1013.      */

  1014.     ngx_post_event(r->connection->write, &ngx_posted_next_events);

  1015.     return NGX_OK;
  1016. }


  1017. static void
  1018. ‌ngx_http_core_auth_delay_handler(ngx_http_request_t *r)
  1019. {
  1020.     ngx_int_t     access_code;
  1021.     ngx_event_t  *wev;

  1022.     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  1023.                    "auth delay handler");

  1024.     wev = r->connection->write;

  1025.     if (wev->delayed) {

  1026.         if (ngx_handle_write_event(wev, 0) != NGX_OK) {
  1027.             ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1028.         }

  1029.         return;
  1030.     }

  1031.     access_code = r->access_code;
  1032.     r->access_code = 0;

  1033.     ngx_http_finalize_request(r, access_code);
  1034. }


  1035. ngx_int_t
  1036. ‌ngx_http_core_content_phase(ngx_http_request_t *r,
  1037.     ngx_http_phase_handler_t *ph)
  1038. {
  1039.     size_t     root;
  1040.     ngx_int_t  rc;
  1041.     ngx_str_t  path;

  1042.     if (r->content_handler) {
  1043.         r->write_event_handler = ngx_http_request_empty_handler;
  1044.         ngx_http_finalize_request(r, r->content_handler(r));
  1045.         return NGX_OK;
  1046.     }

  1047.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  1048.                    "content phase: %ui", r->phase_handler);

  1049.     rc = ph->handler(r);

  1050.     if (rc != NGX_DECLINED) {
  1051.         ngx_http_finalize_request(r, rc);
  1052.         return NGX_OK;
  1053.     }

  1054.     /* rc == NGX_DECLINED */

  1055.     ph++;

  1056.     if (ph->checker) {
  1057.         r->phase_handler++;
  1058.         return NGX_AGAIN;
  1059.     }

  1060.     /* no content handler was found */

  1061.     if (r->uri.data[r->uri.len - 1] == '/') {

  1062.         if (ngx_http_map_uri_to_path(r, &path, &root, 0) != NULL) {
  1063.             ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  1064.                           "directory index of \"%s\" is forbidden", path.data);
  1065.         }

  1066.         ngx_http_finalize_request(r, NGX_HTTP_FORBIDDEN);
  1067.         return NGX_OK;
  1068.     }

  1069.     ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no handler found");

  1070.     ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
  1071.     return NGX_OK;
  1072. }


  1073. void
  1074. ‌ngx_http_update_location_config(ngx_http_request_t *r)
  1075. {
  1076.     ngx_http_core_loc_conf_t  *clcf;

  1077.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1078.     if (r->method & clcf->limit_except) {
  1079.         r->loc_conf = clcf->limit_except_loc_conf;
  1080.         clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
  1081.     }

  1082.     if (r == r->main) {
  1083.         ngx_set_connection_log(r->connection, clcf->error_log);
  1084.     }

  1085.     if ((ngx_io.flags & NGX_IO_SENDFILE) && clcf->sendfile) {
  1086.         r->connection->sendfile = 1;

  1087.     } else {
  1088.         r->connection->sendfile = 0;
  1089.     }

  1090.     if (clcf->client_body_in_file_only) {
  1091.         r->request_body_in_file_only = 1;
  1092.         r->request_body_in_persistent_file = 1;
  1093.         r->request_body_in_clean_file =
  1094.             clcf->client_body_in_file_only == NGX_HTTP_REQUEST_BODY_FILE_CLEAN;
  1095.         r->request_body_file_log_level = NGX_LOG_NOTICE;

  1096.     } else {
  1097.         r->request_body_file_log_level = NGX_LOG_WARN;
  1098.     }

  1099.     r->request_body_in_single_buf = clcf->client_body_in_single_buffer;

  1100.     if (r->keepalive) {
  1101.         if (clcf->keepalive_timeout == 0) {
  1102.             r->keepalive = 0;

  1103.         } else if (r->connection->requests >= clcf->keepalive_requests) {
  1104.             r->keepalive = 0;

  1105.         } else if (ngx_current_msec - r->connection->start_time
  1106.                    > clcf->keepalive_time)
  1107.         {
  1108.             r->keepalive = 0;

  1109.         } else if (r->headers_in.msie6
  1110.                    && r->method == NGX_HTTP_POST
  1111.                    && (clcf->keepalive_disable
  1112.                        & NGX_HTTP_KEEPALIVE_DISABLE_MSIE6))
  1113.         {
  1114.             /*
  1115.              * MSIE may wait for some time if an response for
  1116.              * a POST request was sent over a keepalive connection
  1117.              */
  1118.             r->keepalive = 0;

  1119.         } else if (r->headers_in.safari
  1120.                    && (clcf->keepalive_disable
  1121.                        & NGX_HTTP_KEEPALIVE_DISABLE_SAFARI))
  1122.         {
  1123.             /*
  1124.              * Safari may send a POST request to a closed keepalive
  1125.              * connection and may stall for some time, see
  1126.              *     https://bugs.webkit.org/show_bug.cgi?id=5760
  1127.              */
  1128.             r->keepalive = 0;
  1129.         }
  1130.     }

  1131.     if (!clcf->tcp_nopush) {
  1132.         /* disable TCP_NOPUSH/TCP_CORK use */
  1133.         r->connection->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
  1134.     }

  1135.     if (clcf->handler) {
  1136.         r->content_handler = clcf->handler;
  1137.     }
  1138. }


  1139. /*
  1140. * NGX_OK       - exact, regex or predicate match
  1141. * NGX_DONE     - auto redirect
  1142. * NGX_AGAIN    - inclusive match
  1143. * NGX_ERROR    - regex or predicate error
  1144. * NGX_DECLINED - no match
  1145. */

  1146. static ngx_int_t
  1147. ‌ngx_http_core_find_location(ngx_http_request_t *r)
  1148. {
  1149.     ngx_int_t                   rc;
  1150.     ngx_uint_t                  noregex;
  1151.     ngx_http_core_loc_conf_t   *clcf, *pclcf, **clcfp;
  1152.     ngx_http_variable_value_t  *vv;
  1153. #if (NGX_PCRE)
  1154.     ngx_int_t                   n;
  1155. #endif

  1156.     noregex = 0;

  1157.     pclcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1158.     rc = ngx_http_core_find_static_location(r, pclcf->static_locations);

  1159.     if (rc == NGX_AGAIN) {

  1160.         clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1161.         noregex = clcf->noregex;

  1162.         /* look up nested locations */

  1163.         rc = ngx_http_core_find_location(r);
  1164.     }

  1165.     if (rc == NGX_OK || rc == NGX_DONE || rc == NGX_ERROR) {
  1166.         return rc;
  1167.     }

  1168.     /* rc == NGX_DECLINED or rc == NGX_AGAIN in nested location */

  1169. #if (NGX_PCRE)

  1170.     if (noregex == 0 && pclcf->regex_locations) {

  1171.         for (clcfp = pclcf->regex_locations; *clcfp; clcfp++) {

  1172.             ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  1173.                            "test location: ~ \"%V\"", &(*clcfp)->name);

  1174.             n = ngx_http_regex_exec(r, (*clcfp)->regex, &r->uri);

  1175.             if (n == NGX_OK) {
  1176.                 r->loc_conf = (*clcfp)->loc_conf;

  1177.                 /* look up nested locations */

  1178.                 rc = ngx_http_core_find_location(r);

  1179.                 return (rc == NGX_ERROR) ? rc : NGX_OK;
  1180.             }

  1181.             if (n == NGX_DECLINED) {
  1182.                 continue;
  1183.             }

  1184.             return NGX_ERROR;
  1185.         }
  1186.     }
  1187. #endif

  1188.     if (noregex == 0 && pclcf->predicate_locations) {

  1189.         for (clcfp = pclcf->predicate_locations; *clcfp; clcfp++) {

  1190.             ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  1191.                            "test location: \"%V\"", &(*clcfp)->name);

  1192.             vv = ngx_http_get_flushed_variable(r, (*clcfp)->predicate - 1);
  1193.             if (vv == NULL) {
  1194.                 return NGX_ERROR;
  1195.             }

  1196.             if (vv->len && (vv->len != 1 || vv->data[0] != '0')) {
  1197.                 r->loc_conf = (*clcfp)->loc_conf;

  1198.                 /* look up nested locations */

  1199.                 rc = ngx_http_core_find_location(r);

  1200.                 return (rc == NGX_ERROR || rc == NGX_DONE) ? rc : NGX_OK;
  1201.             }
  1202.         }
  1203.     }

  1204.     return rc;
  1205. }


  1206. /*
  1207. * NGX_OK       - exact match
  1208. * NGX_DONE     - auto redirect
  1209. * NGX_AGAIN    - inclusive match
  1210. * NGX_DECLINED - no match
  1211. */

  1212. static ngx_int_t
  1213. ‌ngx_http_core_find_static_location(ngx_http_request_t *r,
  1214.     ngx_http_location_tree_node_t *node)
  1215. {
  1216.     u_char     *uri;
  1217.     size_t      len, n;
  1218.     ngx_int_t   rc, rv;

  1219.     len = r->uri.len;
  1220.     uri = r->uri.data;

  1221.     rv = NGX_DECLINED;

  1222.     for ( ;; ) {

  1223.         if (node == NULL) {
  1224.             return rv;
  1225.         }

  1226.         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  1227.                        "test location: \"%*s\"",
  1228.                        (size_t) node->len, node->name);

  1229.         n = (len <= (size_t) node->len) ? len : node->len;

  1230.         rc = ngx_filename_cmp(uri, node->name, n);

  1231.         if (rc != 0) {
  1232.             node = (rc < 0) ? node->left : node->right;

  1233.             continue;
  1234.         }

  1235.         if (len > (size_t) node->len) {

  1236.             if (node->inclusive) {

  1237.                 r->loc_conf = node->inclusive->loc_conf;
  1238.                 rv = NGX_AGAIN;

  1239.                 node = node->tree;
  1240.                 uri += n;
  1241.                 len -= n;

  1242.                 continue;
  1243.             }

  1244.             /* exact only */

  1245.             node = node->right;

  1246.             continue;
  1247.         }

  1248.         if (len == (size_t) node->len) {

  1249.             if (node->exact) {
  1250.                 r->loc_conf = node->exact->loc_conf;
  1251.                 return NGX_OK;

  1252.             } else {
  1253.                 r->loc_conf = node->inclusive->loc_conf;
  1254.                 return NGX_AGAIN;
  1255.             }
  1256.         }

  1257.         /* len < node->len */

  1258.         if (len + 1 == (size_t) node->len && node->auto_redirect) {

  1259.             r->loc_conf = (node->exact) ? node->exact->loc_conf:
  1260.                                           node->inclusive->loc_conf;
  1261.             rv = NGX_DONE;
  1262.         }

  1263.         node = node->left;
  1264.     }
  1265. }


  1266. void *
  1267. ‌ngx_http_test_content_type(ngx_http_request_t *r, ngx_hash_t *types_hash)
  1268. {
  1269.     u_char      c, *lowcase;
  1270.     size_t      len;
  1271.     ngx_uint_t  i, hash;

  1272.     if (types_hash->size == 0) {
  1273.         return (void *) 4;
  1274.     }

  1275.     if (r->headers_out.content_type.len == 0) {
  1276.         return NULL;
  1277.     }

  1278.     len = r->headers_out.content_type_len;

  1279.     if (r->headers_out.content_type_lowcase == NULL) {

  1280.         lowcase = ngx_pnalloc(r->pool, len);
  1281.         if (lowcase == NULL) {
  1282.             return NULL;
  1283.         }

  1284.         r->headers_out.content_type_lowcase = lowcase;

  1285.         hash = 0;

  1286.         for (i = 0; i < len; i++) {
  1287.             c = ngx_tolower(r->headers_out.content_type.data[i]);
  1288.             hash = ngx_hash(hash, c);
  1289.             lowcase[i] = c;
  1290.         }

  1291.         r->headers_out.content_type_hash = hash;
  1292.     }

  1293.     return ngx_hash_find(types_hash, r->headers_out.content_type_hash,
  1294.                          r->headers_out.content_type_lowcase, len);
  1295. }


  1296. ngx_int_t
  1297. ‌ngx_http_set_content_type(ngx_http_request_t *r)
  1298. {
  1299.     u_char                     c, *exten;
  1300.     ngx_str_t                 *type;
  1301.     ngx_uint_t                 i, hash;
  1302.     ngx_http_core_loc_conf_t  *clcf;

  1303.     if (r->headers_out.content_type.len) {
  1304.         return NGX_OK;
  1305.     }

  1306.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1307.     if (r->exten.len) {

  1308.         hash = 0;

  1309.         for (i = 0; i < r->exten.len; i++) {
  1310.             c = r->exten.data[i];

  1311.             if (c >= 'A' && c <= 'Z') {

  1312.                 exten = ngx_pnalloc(r->pool, r->exten.len);
  1313.                 if (exten == NULL) {
  1314.                     return NGX_ERROR;
  1315.                 }

  1316.                 hash = ngx_hash_strlow(exten, r->exten.data, r->exten.len);

  1317.                 r->exten.data = exten;

  1318.                 break;
  1319.             }

  1320.             hash = ngx_hash(hash, c);
  1321.         }

  1322.         type = ngx_hash_find(&clcf->types_hash, hash,
  1323.                              r->exten.data, r->exten.len);

  1324.         if (type) {
  1325.             r->headers_out.content_type_len = type->len;
  1326.             r->headers_out.content_type = *type;

  1327.             return NGX_OK;
  1328.         }
  1329.     }

  1330.     r->headers_out.content_type_len = clcf->default_type.len;
  1331.     r->headers_out.content_type = clcf->default_type;

  1332.     return NGX_OK;
  1333. }


  1334. void
  1335. ‌ngx_http_set_exten(ngx_http_request_t *r)
  1336. {
  1337.     ngx_int_t  i;

  1338.     ngx_str_null(&r->exten);

  1339.     for (i = r->uri.len - 1; i > 1; i--) {
  1340.         if (r->uri.data[i] == '.' && r->uri.data[i - 1] != '/') {

  1341.             r->exten.len = r->uri.len - i - 1;
  1342.             r->exten.data = &r->uri.data[i + 1];

  1343.             return;

  1344.         } else if (r->uri.data[i] == '/') {
  1345.             return;
  1346.         }
  1347.     }

  1348.     return;
  1349. }


  1350. ngx_int_t
  1351. ‌ngx_http_set_etag(ngx_http_request_t *r)
  1352. {
  1353.     ngx_table_elt_t           *etag;
  1354.     ngx_http_core_loc_conf_t  *clcf;

  1355.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1356.     if (!clcf->etag) {
  1357.         return NGX_OK;
  1358.     }

  1359.     etag = ngx_list_push(&r->headers_out.headers);
  1360.     if (etag == NULL) {
  1361.         return NGX_ERROR;
  1362.     }

  1363.     etag->hash = 1;
  1364.     etag->next = NULL;
  1365.     ngx_str_set(&etag->key, "ETag");

  1366.     etag->value.data = ngx_pnalloc(r->pool, NGX_OFF_T_LEN + NGX_TIME_T_LEN + 3);
  1367.     if (etag->value.data == NULL) {
  1368.         etag->hash = 0;
  1369.         return NGX_ERROR;
  1370.     }

  1371.     etag->value.len = ngx_sprintf(etag->value.data, "\"%xT-%xO\"",
  1372.                                   r->headers_out.last_modified_time,
  1373.                                   r->headers_out.content_length_n)
  1374.                       - etag->value.data;

  1375.     r->headers_out.etag = etag;

  1376.     return NGX_OK;
  1377. }


  1378. void
  1379. ‌ngx_http_weak_etag(ngx_http_request_t *r)
  1380. {
  1381.     size_t            len;
  1382.     u_char           *p;
  1383.     ngx_table_elt_t  *etag;

  1384.     etag = r->headers_out.etag;

  1385.     if (etag == NULL) {
  1386.         return;
  1387.     }

  1388.     if (etag->value.len > 2
  1389.         && etag->value.data[0] == 'W'
  1390.         && etag->value.data[1] == '/')
  1391.     {
  1392.         return;
  1393.     }

  1394.     if (etag->value.len < 1 || etag->value.data[0] != '"') {
  1395.         r->headers_out.etag->hash = 0;
  1396.         r->headers_out.etag = NULL;
  1397.         return;
  1398.     }

  1399.     p = ngx_pnalloc(r->pool, etag->value.len + 2);
  1400.     if (p == NULL) {
  1401.         r->headers_out.etag->hash = 0;
  1402.         r->headers_out.etag = NULL;
  1403.         return;
  1404.     }

  1405.     len = ngx_sprintf(p, "W/%V", &etag->value) - p;

  1406.     etag->value.data = p;
  1407.     etag->value.len = len;
  1408. }


  1409. ngx_int_t
  1410. ‌ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
  1411.     ngx_str_t *ct, ngx_http_complex_value_t *cv)
  1412. {
  1413.     ngx_int_t     rc;
  1414.     ngx_str_t     val;
  1415.     ngx_buf_t    *b;
  1416.     ngx_chain_t   out;

  1417.     rc = ngx_http_discard_request_body(r);

  1418.     if (rc != NGX_OK) {
  1419.         return rc;
  1420.     }

  1421.     r->headers_out.status = status;

  1422.     if (ngx_http_complex_value(r, cv, &val) != NGX_OK) {
  1423.         return NGX_HTTP_INTERNAL_SERVER_ERROR;
  1424.     }

  1425.     if (status == NGX_HTTP_MOVED_PERMANENTLY
  1426.         || status == NGX_HTTP_MOVED_TEMPORARILY
  1427.         || status == NGX_HTTP_SEE_OTHER
  1428.         || status == NGX_HTTP_TEMPORARY_REDIRECT
  1429.         || status == NGX_HTTP_PERMANENT_REDIRECT)
  1430.     {
  1431.         ngx_http_clear_location(r);

  1432.         r->headers_out.location = ngx_list_push(&r->headers_out.headers);
  1433.         if (r->headers_out.location == NULL) {
  1434.             return NGX_HTTP_INTERNAL_SERVER_ERROR;
  1435.         }

  1436.         r->headers_out.location->hash = 1;
  1437.         r->headers_out.location->next = NULL;
  1438.         ngx_str_set(&r->headers_out.location->key, "Location");
  1439.         r->headers_out.location->value = val;

  1440.         return status;
  1441.     }

  1442.     r->headers_out.content_length_n = val.len;

  1443.     if (ct) {
  1444.         r->headers_out.content_type_len = ct->len;
  1445.         r->headers_out.content_type = *ct;

  1446.     } else {
  1447.         if (ngx_http_set_content_type(r) != NGX_OK) {
  1448.             return NGX_HTTP_INTERNAL_SERVER_ERROR;
  1449.         }
  1450.     }

  1451.     b = ngx_calloc_buf(r->pool);
  1452.     if (b == NULL) {
  1453.         return NGX_HTTP_INTERNAL_SERVER_ERROR;
  1454.     }

  1455.     b->pos = val.data;
  1456.     b->last = val.data + val.len;
  1457.     b->memory = val.len ? 1 : 0;
  1458.     b->last_buf = (r == r->main) ? 1 : 0;
  1459.     b->last_in_chain = 1;
  1460.     b->sync = (b->last_buf || b->memory) ? 0 : 1;

  1461.     out.buf = b;
  1462.     out.next = NULL;

  1463.     rc = ngx_http_send_header(r);

  1464.     if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
  1465.         return rc;
  1466.     }

  1467.     return ngx_http_output_filter(r, &out);
  1468. }


  1469. ngx_int_t
  1470. ‌ngx_http_send_header(ngx_http_request_t *r)
  1471. {
  1472.     if (r->post_action) {
  1473.         return NGX_OK;
  1474.     }

  1475.     if (r->header_sent) {
  1476.         ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
  1477.                       "header already sent");
  1478.         return NGX_ERROR;
  1479.     }

  1480.     if (r->err_status) {
  1481.         r->headers_out.status = r->err_status;
  1482.         r->headers_out.status_line.len = 0;
  1483.     }

  1484.     return ngx_http_top_header_filter(r);
  1485. }


  1486. ngx_int_t
  1487. ‌ngx_http_send_early_hints(ngx_http_request_t *r)
  1488. {
  1489.     ngx_int_t                  rc;
  1490.     ngx_http_core_loc_conf_t  *clcf;

  1491.     if (r->post_action) {
  1492.         return NGX_OK;
  1493.     }

  1494.     if (r->header_sent) {
  1495.         ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
  1496.                       "header already sent");
  1497.         return NGX_ERROR;
  1498.     }

  1499.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1500.     rc = ngx_http_test_predicates(r, clcf->early_hints);

  1501.     if (rc != NGX_DECLINED) {
  1502.         return rc;
  1503.     }

  1504.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  1505.                    "http send early hints \"%V?%V\"", &r->uri, &r->args);

  1506.     return ngx_http_top_early_hints_filter(r);
  1507. }


  1508. ngx_int_t
  1509. ‌ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in)
  1510. {
  1511.     ngx_int_t          rc;
  1512.     ngx_connection_t  *c;

  1513.     c = r->connection;

  1514.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
  1515.                    "http output filter \"%V?%V\"", &r->uri, &r->args);

  1516.     rc = ngx_http_top_body_filter(r, in);

  1517.     if (rc == NGX_ERROR) {
  1518.         /* NGX_ERROR may be returned by any filter */
  1519.         c->error = 1;
  1520.     }

  1521.     return rc;
  1522. }


  1523. u_char *
  1524. ‌ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *path,
  1525.     size_t *root_length, size_t reserved)
  1526. {
  1527.     u_char                    *last;
  1528.     size_t                     alias;
  1529.     ngx_http_core_loc_conf_t  *clcf;

  1530.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1531.     alias = clcf->alias;

  1532.     if (alias && !r->valid_location) {
  1533.         ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
  1534.                       "\"alias\" cannot be used in location \"%V\" "
  1535.                       "where URI was rewritten", &clcf->name);
  1536.         return NULL;
  1537.     }

  1538.     if (alias > r->uri.len && alias != NGX_MAX_SIZE_T_VALUE) {
  1539.         ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
  1540.                       "URI shorter than aliased URI part");
  1541.         return NULL;
  1542.     }

  1543.     if (clcf->root_lengths == NULL) {

  1544.         *root_length = clcf->root.len;

  1545.         path->len = clcf->root.len + reserved + r->uri.len - alias + 1;

  1546.         path->data = ngx_pnalloc(r->pool, path->len);
  1547.         if (path->data == NULL) {
  1548.             return NULL;
  1549.         }

  1550.         last = ngx_copy(path->data, clcf->root.data, clcf->root.len);

  1551.     } else {

  1552.         if (alias == NGX_MAX_SIZE_T_VALUE) {
  1553.             reserved += r->add_uri_to_alias ? r->uri.len + 1 : 1;

  1554.         } else {
  1555.             reserved += r->uri.len - alias + 1;
  1556.         }

  1557.         if (ngx_http_script_run(r, path, clcf->root_lengths->elts, reserved,
  1558.                                 clcf->root_values->elts)
  1559.             == NULL)
  1560.         {
  1561.             return NULL;
  1562.         }

  1563.         if (ngx_get_full_name(r->pool, (ngx_str_t *) &ngx_cycle->prefix, path)
  1564.             != NGX_OK)
  1565.         {
  1566.             return NULL;
  1567.         }

  1568.         *root_length = path->len - reserved;
  1569.         last = path->data + *root_length;

  1570.         if (alias == NGX_MAX_SIZE_T_VALUE) {
  1571.             if (!r->add_uri_to_alias) {
  1572.                 *last = '\0';
  1573.                 return last;
  1574.             }

  1575.             alias = 0;
  1576.         }
  1577.     }

  1578.     last = ngx_copy(last, r->uri.data + alias, r->uri.len - alias);
  1579.     *last = '\0';

  1580.     return last;
  1581. }


  1582. ngx_int_t
  1583. ‌ngx_http_auth_basic_user(ngx_http_request_t *r)
  1584. {
  1585.     ngx_str_t         auth, encoded;
  1586.     ngx_uint_t        len;
  1587.     ngx_table_elt_t  *h;

  1588.     if (r->headers_in.user.len == 0 && r->headers_in.user.data != NULL) {
  1589.         return NGX_DECLINED;
  1590.     }

  1591.     h = ngx_http_proxy_auth(r) ? r->headers_in.proxy_authorization
  1592.                                : r->headers_in.authorization;

  1593.     if (h == NULL) {
  1594.         r->headers_in.user.data = (u_char *) "";
  1595.         return NGX_DECLINED;
  1596.     }

  1597.     encoded = h->value;

  1598.     if (encoded.len < sizeof("Basic ") - 1
  1599.         || ngx_strncasecmp(encoded.data, (u_char *) "Basic ",
  1600.                            sizeof("Basic ") - 1)
  1601.            != 0)
  1602.     {
  1603.         r->headers_in.user.data = (u_char *) "";
  1604.         return NGX_DECLINED;
  1605.     }

  1606.     encoded.len -= sizeof("Basic ") - 1;
  1607.     encoded.data += sizeof("Basic ") - 1;

  1608.     while (encoded.len && encoded.data[0] == ' ') {
  1609.         encoded.len--;
  1610.         encoded.data++;
  1611.     }

  1612.     if (encoded.len == 0) {
  1613.         r->headers_in.user.data = (u_char *) "";
  1614.         return NGX_DECLINED;
  1615.     }

  1616.     auth.len = ngx_base64_decoded_length(encoded.len);
  1617.     auth.data = ngx_pnalloc(r->pool, auth.len + 1);
  1618.     if (auth.data == NULL) {
  1619.         return NGX_ERROR;
  1620.     }

  1621.     if (ngx_decode_base64(&auth, &encoded) != NGX_OK) {
  1622.         r->headers_in.user.data = (u_char *) "";
  1623.         return NGX_DECLINED;
  1624.     }

  1625.     auth.data[auth.len] = '\0';

  1626.     for (len = 0; len < auth.len; len++) {
  1627.         if (auth.data[len] == ':') {
  1628.             break;
  1629.         }
  1630.     }

  1631.     if (len == 0 || len == auth.len) {
  1632.         r->headers_in.user.data = (u_char *) "";
  1633.         return NGX_DECLINED;
  1634.     }

  1635.     r->headers_in.user.len = len;
  1636.     r->headers_in.user.data = auth.data;
  1637.     r->headers_in.passwd.len = auth.len - len - 1;
  1638.     r->headers_in.passwd.data = &auth.data[len + 1];

  1639.     return NGX_OK;
  1640. }


  1641. #if (NGX_HTTP_GZIP)

  1642. ngx_int_t
  1643. ‌ngx_http_gzip_ok(ngx_http_request_t *r)
  1644. {
  1645.     time_t                     date, expires;
  1646.     ngx_uint_t                 p;
  1647.     ngx_table_elt_t           *e, *d, *ae, *cc;
  1648.     ngx_http_core_loc_conf_t  *clcf;

  1649.     r->gzip_tested = 1;

  1650.     if (r != r->main) {
  1651.         return NGX_DECLINED;
  1652.     }

  1653.     ae = r->headers_in.accept_encoding;
  1654.     if (ae == NULL) {
  1655.         return NGX_DECLINED;
  1656.     }

  1657.     if (ae->value.len < sizeof("gzip") - 1) {
  1658.         return NGX_DECLINED;
  1659.     }

  1660.     /*
  1661.      * test first for the most common case "gzip,...":
  1662.      *   MSIE:    "gzip, deflate"
  1663.      *   Firefox: "gzip,deflate"
  1664.      *   Chrome:  "gzip,deflate,sdch"
  1665.      *   Safari:  "gzip, deflate"
  1666.      *   Opera:   "gzip, deflate"
  1667.      */

  1668.     if (ngx_memcmp(ae->value.data, "gzip,", 5) != 0
  1669.         && ngx_http_gzip_accept_encoding(&ae->value) != NGX_OK)
  1670.     {
  1671.         return NGX_DECLINED;
  1672.     }

  1673.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1674.     if (r->headers_in.msie6 && clcf->gzip_disable_msie6) {
  1675.         return NGX_DECLINED;
  1676.     }

  1677.     if (r->http_version < clcf->gzip_http_version) {
  1678.         return NGX_DECLINED;
  1679.     }

  1680.     if (r->headers_in.via == NULL) {
  1681.         goto ok;
  1682.     }

  1683.     p = clcf->gzip_proxied;

  1684.     if (p & NGX_HTTP_GZIP_PROXIED_OFF) {
  1685.         return NGX_DECLINED;
  1686.     }

  1687.     if (p & NGX_HTTP_GZIP_PROXIED_ANY) {
  1688.         goto ok;
  1689.     }

  1690.     if (r->headers_in.authorization && (p & NGX_HTTP_GZIP_PROXIED_AUTH)) {
  1691.         goto ok;
  1692.     }

  1693.     e = r->headers_out.expires;

  1694.     if (e) {

  1695.         if (!(p & NGX_HTTP_GZIP_PROXIED_EXPIRED)) {
  1696.             return NGX_DECLINED;
  1697.         }

  1698.         expires = ngx_parse_http_time(e->value.data, e->value.len);
  1699.         if (expires == NGX_ERROR) {
  1700.             return NGX_DECLINED;
  1701.         }

  1702.         d = r->headers_out.date;

  1703.         if (d) {
  1704.             date = ngx_parse_http_time(d->value.data, d->value.len);
  1705.             if (date == NGX_ERROR) {
  1706.                 return NGX_DECLINED;
  1707.             }

  1708.         } else {
  1709.             date = ngx_time();
  1710.         }

  1711.         if (expires < date) {
  1712.             goto ok;
  1713.         }

  1714.         return NGX_DECLINED;
  1715.     }

  1716.     cc = r->headers_out.cache_control;

  1717.     if (cc) {

  1718.         if ((p & NGX_HTTP_GZIP_PROXIED_NO_CACHE)
  1719.             && ngx_http_parse_multi_header_lines(r, cc, &ngx_http_gzip_no_cache,
  1720.                                                  NULL)
  1721.                != NULL)
  1722.         {
  1723.             goto ok;
  1724.         }

  1725.         if ((p & NGX_HTTP_GZIP_PROXIED_NO_STORE)
  1726.             && ngx_http_parse_multi_header_lines(r, cc, &ngx_http_gzip_no_store,
  1727.                                                  NULL)
  1728.                != NULL)
  1729.         {
  1730.             goto ok;
  1731.         }

  1732.         if ((p & NGX_HTTP_GZIP_PROXIED_PRIVATE)
  1733.             && ngx_http_parse_multi_header_lines(r, cc, &ngx_http_gzip_private,
  1734.                                                  NULL)
  1735.                != NULL)
  1736.         {
  1737.             goto ok;
  1738.         }

  1739.         return NGX_DECLINED;
  1740.     }

  1741.     if ((p & NGX_HTTP_GZIP_PROXIED_NO_LM) && r->headers_out.last_modified) {
  1742.         return NGX_DECLINED;
  1743.     }

  1744.     if ((p & NGX_HTTP_GZIP_PROXIED_NO_ETAG) && r->headers_out.etag) {
  1745.         return NGX_DECLINED;
  1746.     }

  1747. ok:

  1748. #if (NGX_PCRE)

  1749.     if (clcf->gzip_disable && r->headers_in.user_agent) {

  1750.         if (ngx_regex_exec_array(clcf->gzip_disable,
  1751.                                  &r->headers_in.user_agent->value,
  1752.                                  r->connection->log)
  1753.             != NGX_DECLINED)
  1754.         {
  1755.             return NGX_DECLINED;
  1756.         }
  1757.     }

  1758. #endif

  1759.     r->gzip_ok = 1;

  1760.     return NGX_OK;
  1761. }


  1762. /*
  1763. * gzip is enabled for the following quantities:
  1764. *     "gzip; q=0.001" ... "gzip; q=1.000"
  1765. * gzip is disabled for the following quantities:
  1766. *     "gzip; q=0" ... "gzip; q=0.000", and for any invalid cases
  1767. */

  1768. static ngx_int_t
  1769. ‌ngx_http_gzip_accept_encoding(ngx_str_t *ae)
  1770. {
  1771.     u_char  *p, *start, *last;

  1772.     start = ae->data;
  1773.     last = start + ae->len;

  1774.     for ( ;; ) {
  1775.         p = ngx_strcasestrn(start, "gzip", 4 - 1);
  1776.         if (p == NULL) {
  1777.             return NGX_DECLINED;
  1778.         }

  1779.         if (p == start || (*(p - 1) == ',' || *(p - 1) == ' ')) {
  1780.             break;
  1781.         }

  1782.         start = p + 4;
  1783.     }

  1784.     p += 4;

  1785.     while (p < last) {
  1786.         switch (*p++) {
  1787.         case ',':
  1788.             return NGX_OK;
  1789.         case ';':
  1790.             goto quantity;
  1791.         case ' ':
  1792.             continue;
  1793.         default:
  1794.             return NGX_DECLINED;
  1795.         }
  1796.     }

  1797.     return NGX_OK;

  1798. quantity:

  1799.     while (p < last) {
  1800.         switch (*p++) {
  1801.         case 'q':
  1802.         case 'Q':
  1803.             goto equal;
  1804.         case ' ':
  1805.             continue;
  1806.         default:
  1807.             return NGX_DECLINED;
  1808.         }
  1809.     }

  1810.     return NGX_OK;

  1811. equal:

  1812.     if (p + 2 > last || *p++ != '=') {
  1813.         return NGX_DECLINED;
  1814.     }

  1815.     if (ngx_http_gzip_quantity(p, last) == 0) {
  1816.         return NGX_DECLINED;
  1817.     }

  1818.     return NGX_OK;
  1819. }


  1820. static ngx_uint_t
  1821. ‌ngx_http_gzip_quantity(u_char *p, u_char *last)
  1822. {
  1823.     u_char      c;
  1824.     ngx_uint_t  n, q;

  1825.     c = *p++;

  1826.     if (c != '0' && c != '1') {
  1827.         return 0;
  1828.     }

  1829.     q = (c - '0') * 100;

  1830.     if (p == last) {
  1831.         return q;
  1832.     }

  1833.     c = *p++;

  1834.     if (c == ',' || c == ' ') {
  1835.         return q;
  1836.     }

  1837.     if (c != '.') {
  1838.         return 0;
  1839.     }

  1840.     n = 0;

  1841.     while (p < last) {
  1842.         c = *p++;

  1843.         if (c == ',' || c == ' ') {
  1844.             break;
  1845.         }

  1846.         if (c >= '0' && c <= '9') {
  1847.             q += c - '0';
  1848.             n++;
  1849.             continue;
  1850.         }

  1851.         return 0;
  1852.     }

  1853.     if (q > 100 || n > 3) {
  1854.         return 0;
  1855.     }

  1856.     return q;
  1857. }

  1858. #endif


  1859. ngx_int_t
  1860. ‌ngx_http_subrequest(ngx_http_request_t *r,
  1861.     ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **psr,
  1862.     ngx_http_post_subrequest_t *ps, ngx_uint_t flags)
  1863. {
  1864.     ngx_time_t                    *tp;
  1865.     ngx_connection_t              *c;
  1866.     ngx_http_request_t            *sr;
  1867.     ngx_http_core_srv_conf_t      *cscf;
  1868.     ngx_http_posted_request_t     *posted;
  1869.     ngx_http_postponed_request_t  *pr, *p;

  1870.     if (r->subrequests == 0) {
  1871.         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  1872.                       "subrequests cycle while processing \"%V\"", uri);
  1873.         return NGX_ERROR;
  1874.     }

  1875.     /*
  1876.      * 1000 is reserved for other purposes.
  1877.      */
  1878.     if (r->main->count >= 65535 - 1000) {
  1879.         ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,
  1880.                       "request reference counter overflow "
  1881.                       "while processing \"%V\"", uri);
  1882.         return NGX_ERROR;
  1883.     }

  1884.     if (r->subrequest_in_memory) {
  1885.         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  1886.                       "nested in-memory subrequest \"%V\"", uri);
  1887.         return NGX_ERROR;
  1888.     }

  1889.     sr = ngx_pcalloc(r->pool, sizeof(ngx_http_request_t));
  1890.     if (sr == NULL) {
  1891.         return NGX_ERROR;
  1892.     }

  1893.     sr->signature = NGX_HTTP_MODULE;

  1894.     c = r->connection;
  1895.     sr->connection = c;

  1896.     sr->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
  1897.     if (sr->ctx == NULL) {
  1898.         return NGX_ERROR;
  1899.     }

  1900.     if (ngx_list_init(&sr->headers_out.headers, r->pool, 20,
  1901.                       sizeof(ngx_table_elt_t))
  1902.         != NGX_OK)
  1903.     {
  1904.         return NGX_ERROR;
  1905.     }

  1906.     if (ngx_list_init(&sr->headers_out.trailers, r->pool, 4,
  1907.                       sizeof(ngx_table_elt_t))
  1908.         != NGX_OK)
  1909.     {
  1910.         return NGX_ERROR;
  1911.     }

  1912.     posted = ngx_palloc(r->pool, sizeof(ngx_http_posted_request_t));
  1913.     if (posted == NULL) {
  1914.         return NGX_ERROR;
  1915.     }

  1916.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
  1917.     sr->main_conf = cscf->ctx->main_conf;
  1918.     sr->srv_conf = cscf->ctx->srv_conf;
  1919.     sr->loc_conf = cscf->ctx->loc_conf;

  1920.     sr->pool = r->pool;

  1921.     sr->headers_in = r->headers_in;

  1922.     ngx_http_clear_content_length(sr);
  1923.     ngx_http_clear_accept_ranges(sr);
  1924.     ngx_http_clear_last_modified(sr);

  1925.     sr->request_body = r->request_body;

  1926. #if (NGX_HTTP_V2)
  1927.     sr->stream = r->stream;
  1928. #endif

  1929.     sr->method = NGX_HTTP_GET;
  1930.     sr->http_version = r->http_version;

  1931.     sr->port = r->port;

  1932.     sr->request_line = r->request_line;
  1933.     sr->uri = *uri;

  1934.     if (args) {
  1935.         sr->args = *args;
  1936.     }

  1937.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
  1938.                    "http subrequest \"%V?%V\"", uri, &sr->args);

  1939.     sr->subrequest_in_memory = (flags & NGX_HTTP_SUBREQUEST_IN_MEMORY) != 0;
  1940.     sr->waited = (flags & NGX_HTTP_SUBREQUEST_WAITED) != 0;
  1941.     sr->background = (flags & NGX_HTTP_SUBREQUEST_BACKGROUND) != 0;

  1942.     sr->unparsed_uri = r->unparsed_uri;
  1943.     sr->method_name = ngx_http_core_get_method;
  1944.     sr->http_protocol = r->http_protocol;
  1945.     sr->schema = r->schema;

  1946.     ngx_http_set_exten(sr);

  1947.     sr->main = r->main;
  1948.     sr->parent = r;
  1949.     sr->post_subrequest = ps;
  1950.     sr->read_event_handler = ngx_http_request_empty_handler;
  1951.     sr->write_event_handler = ngx_http_handler;

  1952.     sr->variables = r->variables;

  1953.     sr->log_handler = r->log_handler;

  1954.     if (sr->subrequest_in_memory) {
  1955.         sr->filter_need_in_memory = 1;
  1956.     }

  1957.     if (!sr->background) {
  1958.         pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t));
  1959.         if (pr == NULL) {
  1960.             return NGX_ERROR;
  1961.         }

  1962.         pr->request = sr;
  1963.         pr->out = NULL;
  1964.         pr->next = NULL;

  1965.         if (c->data == r && r->postponed == NULL) {
  1966.             c->data = sr;
  1967.         }

  1968.         if (r->postponed) {
  1969.             for (p = r->postponed; p->next; p = p->next) { /* void */ }
  1970.             p->next = pr;

  1971.         } else {
  1972.             r->postponed = pr;
  1973.         }
  1974.     }

  1975.     sr->internal = 1;

  1976.     sr->discard_body = r->discard_body;
  1977.     sr->expect_tested = 1;
  1978.     sr->main_filter_need_in_memory = r->main_filter_need_in_memory;

  1979.     sr->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1;
  1980.     sr->subrequests = r->subrequests - 1;

  1981.     tp = ngx_timeofday();
  1982.     sr->start_sec = tp->sec;
  1983.     sr->start_msec = tp->msec;

  1984.     r->main->count++;

  1985.     *psr = sr;

  1986.     if (flags & NGX_HTTP_SUBREQUEST_CLONE) {
  1987.         sr->method = r->method;
  1988.         sr->method_name = r->method_name;
  1989.         sr->loc_conf = r->loc_conf;
  1990.         sr->valid_location = r->valid_location;
  1991.         sr->valid_unparsed_uri = r->valid_unparsed_uri;
  1992.         sr->content_handler = r->content_handler;
  1993.         sr->phase_handler = r->phase_handler;
  1994.         sr->write_event_handler = ngx_http_core_run_phases;

  1995. #if (NGX_PCRE)
  1996.         sr->ncaptures = r->ncaptures;
  1997.         sr->captures = r->captures;
  1998.         sr->captures_data = r->captures_data;
  1999.         sr->realloc_captures = 1;
  2000.         r->realloc_captures = 1;
  2001. #endif

  2002.         ngx_http_update_location_config(sr);
  2003.     }

  2004.     return ngx_http_post_request(sr, posted);
  2005. }


  2006. ngx_int_t
  2007. ‌ngx_http_internal_redirect(ngx_http_request_t *r,
  2008.     ngx_str_t *uri, ngx_str_t *args)
  2009. {
  2010.     ngx_http_core_srv_conf_t  *cscf;

  2011.     r->uri_changes--;

  2012.     if (r->uri_changes == 0) {
  2013.         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  2014.                       "rewrite or internal redirection cycle "
  2015.                       "while internally redirecting to \"%V\"", uri);

  2016.         r->main->count++;
  2017.         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  2018.         return NGX_DONE;
  2019.     }

  2020.     r->uri = *uri;

  2021.     if (args) {
  2022.         r->args = *args;

  2023.     } else {
  2024.         ngx_str_null(&r->args);
  2025.     }

  2026.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  2027.                    "internal redirect: \"%V?%V\"", uri, &r->args);

  2028.     ngx_http_set_exten(r);

  2029.     /* clear the modules contexts */
  2030.     ngx_memzero(r->ctx, sizeof(void *) * ngx_http_max_module);

  2031.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
  2032.     r->loc_conf = cscf->ctx->loc_conf;

  2033.     ngx_http_update_location_config(r);

  2034. #if (NGX_HTTP_CACHE)
  2035.     r->cache = NULL;
  2036. #endif

  2037.     r->internal = 1;
  2038.     r->valid_unparsed_uri = 0;
  2039.     r->add_uri_to_alias = 0;
  2040.     r->main->count++;

  2041.     ngx_http_handler(r);

  2042.     return NGX_DONE;
  2043. }


  2044. ngx_int_t
  2045. ‌ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name)
  2046. {
  2047.     ngx_http_core_srv_conf_t    *cscf;
  2048.     ngx_http_core_loc_conf_t   **clcfp;
  2049.     ngx_http_core_main_conf_t   *cmcf;

  2050.     r->main->count++;
  2051.     r->uri_changes--;

  2052.     if (r->uri_changes == 0) {
  2053.         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  2054.                       "rewrite or internal redirection cycle "
  2055.                       "while redirect to named location \"%V\"", name);

  2056.         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  2057.         return NGX_DONE;
  2058.     }

  2059.     if (r->uri.len == 0) {
  2060.         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  2061.                       "empty URI in redirect to named location \"%V\"", name);

  2062.         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  2063.         return NGX_DONE;
  2064.     }

  2065.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

  2066.     if (cscf->named_locations) {

  2067.         for (clcfp = cscf->named_locations; *clcfp; clcfp++) {

  2068.             ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  2069.                            "test location: \"%V\"", &(*clcfp)->name);

  2070.             if (name->len != (*clcfp)->name.len
  2071.                 || ngx_strncmp(name->data, (*clcfp)->name.data, name->len) != 0)
  2072.             {
  2073.                 continue;
  2074.             }

  2075.             ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  2076.                            "using location: %V \"%V?%V\"",
  2077.                            name, &r->uri, &r->args);

  2078.             r->internal = 1;
  2079.             r->content_handler = NULL;
  2080.             r->uri_changed = 0;
  2081.             r->loc_conf = (*clcfp)->loc_conf;

  2082.             /* clear the modules contexts */
  2083.             ngx_memzero(r->ctx, sizeof(void *) * ngx_http_max_module);

  2084.             ngx_http_update_location_config(r);

  2085.             cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

  2086.             r->phase_handler = cmcf->phase_engine.location_rewrite_index;

  2087.             r->write_event_handler = ngx_http_core_run_phases;
  2088.             ngx_http_core_run_phases(r);

  2089.             return NGX_DONE;
  2090.         }
  2091.     }

  2092.     ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  2093.                   "could not find named location \"%V\"", name);

  2094.     ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);

  2095.     return NGX_DONE;
  2096. }


  2097. ngx_http_cleanup_t *
  2098. ‌ngx_http_cleanup_add(ngx_http_request_t *r, size_t size)
  2099. {
  2100.     ngx_http_cleanup_t  *cln;

  2101.     r = r->main;

  2102.     cln = ngx_palloc(r->pool, sizeof(ngx_http_cleanup_t));
  2103.     if (cln == NULL) {
  2104.         return NULL;
  2105.     }

  2106.     if (size) {
  2107.         cln->data = ngx_palloc(r->pool, size);
  2108.         if (cln->data == NULL) {
  2109.             return NULL;
  2110.         }

  2111.     } else {
  2112.         cln->data = NULL;
  2113.     }

  2114.     cln->handler = NULL;
  2115.     cln->next = r->cleanup;

  2116.     r->cleanup = cln;

  2117.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  2118.                    "http cleanup add: %p", cln);

  2119.     return cln;
  2120. }


  2121. ngx_int_t
  2122. ‌ngx_http_set_disable_symlinks(ngx_http_request_t *r,
  2123.     ngx_http_core_loc_conf_t *clcf, ngx_str_t *path, ngx_open_file_info_t *of)
  2124. {
  2125. #if (NGX_HAVE_OPENAT)
  2126.     u_char     *p;
  2127.     ngx_str_t   from;

  2128.     of->disable_symlinks = clcf->disable_symlinks;

  2129.     if (clcf->disable_symlinks_from == NULL) {
  2130.         return NGX_OK;
  2131.     }

  2132.     if (ngx_http_complex_value(r, clcf->disable_symlinks_from, &from)
  2133.         != NGX_OK)
  2134.     {
  2135.         return NGX_ERROR;
  2136.     }

  2137.     if (from.len == 0
  2138.         || from.len > path->len
  2139.         || ngx_memcmp(path->data, from.data, from.len) != 0)
  2140.     {
  2141.         return NGX_OK;
  2142.     }

  2143.     if (from.len == path->len) {
  2144.         of->disable_symlinks = NGX_DISABLE_SYMLINKS_OFF;
  2145.         return NGX_OK;
  2146.     }

  2147.     p = path->data + from.len;

  2148.     if (*p == '/') {
  2149.         of->disable_symlinks_from = from.len;
  2150.         return NGX_OK;
  2151.     }

  2152.     p--;

  2153.     if (*p == '/') {
  2154.         of->disable_symlinks_from = from.len - 1;
  2155.     }
  2156. #endif

  2157.     return NGX_OK;
  2158. }


  2159. ngx_int_t
  2160. ‌ngx_http_get_forwarded_addr(ngx_http_request_t *r, ngx_addr_t *addr,
  2161.     ngx_table_elt_t *headers, ngx_str_t *value, ngx_array_t *proxies,
  2162.     int recursive)
  2163. {
  2164.     ngx_int_t         rc;
  2165.     ngx_uint_t        found;
  2166.     ngx_table_elt_t  *h, *next;

  2167.     if (headers == NULL) {
  2168.         return ngx_http_get_forwarded_addr_internal(r, addr, value->data,
  2169.                                                     value->len, proxies,
  2170.                                                     recursive);
  2171.     }

  2172.     /* revert headers order */

  2173.     for (h = headers, headers = NULL; h; h = next) {
  2174.         next = h->next;
  2175.         h->next = headers;
  2176.         headers = h;
  2177.     }

  2178.     /* iterate over all headers in reverse order */

  2179.     rc = NGX_DECLINED;

  2180.     found = 0;

  2181.     for (h = headers; h; h = h->next) {
  2182.         rc = ngx_http_get_forwarded_addr_internal(r, addr, h->value.data,
  2183.                                                   h->value.len, proxies,
  2184.                                                   recursive);

  2185.         if (!recursive) {
  2186.             break;
  2187.         }

  2188.         if (rc == NGX_DECLINED && found) {
  2189.             rc = NGX_DONE;
  2190.             break;
  2191.         }

  2192.         if (rc != NGX_OK) {
  2193.             break;
  2194.         }

  2195.         found = 1;
  2196.     }

  2197.     /* restore headers order */

  2198.     for (h = headers, headers = NULL; h; h = next) {
  2199.         next = h->next;
  2200.         h->next = headers;
  2201.         headers = h;
  2202.     }

  2203.     return rc;
  2204. }


  2205. static ngx_int_t
  2206. ‌ngx_http_get_forwarded_addr_internal(ngx_http_request_t *r, ngx_addr_t *addr,
  2207.     u_char *xff, size_t xfflen, ngx_array_t *proxies, int recursive)
  2208. {
  2209.     u_char      *p;
  2210.     ngx_addr_t   paddr;
  2211.     ngx_uint_t   found;

  2212.     found = 0;

  2213.     do {

  2214.         if (ngx_cidr_match(addr->sockaddr, proxies) != NGX_OK) {
  2215.             return found ? NGX_DONE : NGX_DECLINED;
  2216.         }

  2217.         for (p = xff + xfflen - 1; p > xff; p--, xfflen--) {
  2218.             if (*p != ' ' && *p != ',') {
  2219.                 break;
  2220.             }
  2221.         }

  2222.         for ( /* void */ ; p > xff; p--) {
  2223.             if (*p == ' ' || *p == ',') {
  2224.                 p++;
  2225.                 break;
  2226.             }
  2227.         }

  2228.         if (ngx_parse_addr_port(r->pool, &paddr, p, xfflen - (p - xff))
  2229.             != NGX_OK)
  2230.         {
  2231.             return found ? NGX_DONE : NGX_DECLINED;
  2232.         }

  2233.         *addr = paddr;
  2234.         found = 1;
  2235.         xfflen = p - 1 - xff;

  2236.     } while (recursive && p > xff);

  2237.     return NGX_OK;
  2238. }


  2239. ngx_int_t
  2240. ‌ngx_http_link_multi_headers(ngx_http_request_t *r)
  2241. {
  2242.     ngx_uint_t        i, j;
  2243.     ngx_list_part_t  *part, *ppart;
  2244.     ngx_table_elt_t  *header, *pheader, **ph;

  2245.     if (r->headers_in.multi_linked) {
  2246.         return NGX_OK;
  2247.     }

  2248.     r->headers_in.multi_linked = 1;

  2249.     part = &r->headers_in.headers.part;
  2250.     header = part->elts;

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

  2252.         if (i >= part->nelts) {
  2253.             if (part->next == NULL) {
  2254.                 break;
  2255.             }

  2256.             part = part->next;
  2257.             header = part->elts;
  2258.             i = 0;
  2259.         }

  2260.         header[i].next = NULL;

  2261.         /*
  2262.          * search for previous headers with the same name;
  2263.          * if there are any, link to them
  2264.          */

  2265.         ppart = &r->headers_in.headers.part;
  2266.         pheader = ppart->elts;

  2267.         for (j = 0; /* void */; j++) {

  2268.             if (j >= ppart->nelts) {
  2269.                 if (ppart->next == NULL) {
  2270.                     break;
  2271.                 }

  2272.                 ppart = ppart->next;
  2273.                 pheader = ppart->elts;
  2274.                 j = 0;
  2275.             }

  2276.             if (part == ppart && i == j) {
  2277.                 break;
  2278.             }

  2279.             if (header[i].key.len == pheader[j].key.len
  2280.                 && ngx_strncasecmp(header[i].key.data, pheader[j].key.data,
  2281.                                    header[i].key.len)
  2282.                    == 0)
  2283.             {
  2284.                 ph = &pheader[j].next;
  2285.                 while (*ph) { ph = &(*ph)->next; }
  2286.                 *ph = &header[i];

  2287.                 r->headers_in.multi = 1;

  2288.                 break;
  2289.             }
  2290.         }
  2291.     }

  2292.     return NGX_OK;
  2293. }


  2294. static char *
  2295. ‌ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
  2296. {
  2297.     char                        *rv;
  2298.     void                        *mconf;
  2299.     size_t                       len;
  2300.     u_char                      *p;
  2301.     ngx_uint_t                   i;
  2302.     ngx_conf_t                   pcf;
  2303.     ngx_http_module_t           *module;
  2304.     struct sockaddr_in          *sin;
  2305.     ngx_http_conf_ctx_t         *ctx, *http_ctx;
  2306.     ngx_http_listen_opt_t        lsopt;
  2307.     ngx_http_core_srv_conf_t    *cscf, **cscfp;
  2308.     ngx_http_core_main_conf_t   *cmcf;

  2309.     ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
  2310.     if (ctx == NULL) {
  2311.         return NGX_CONF_ERROR;
  2312.     }

  2313.     http_ctx = cf->ctx;
  2314.     ctx->main_conf = http_ctx->main_conf;

  2315.     /* the server{}'s srv_conf */

  2316.     ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
  2317.     if (ctx->srv_conf == NULL) {
  2318.         return NGX_CONF_ERROR;
  2319.     }

  2320.     /* the server{}'s loc_conf */

  2321.     ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
  2322.     if (ctx->loc_conf == NULL) {
  2323.         return NGX_CONF_ERROR;
  2324.     }

  2325.     for (i = 0; cf->cycle->modules[i]; i++) {
  2326.         if (cf->cycle->modules[i]->type != NGX_HTTP_MODULE) {
  2327.             continue;
  2328.         }

  2329.         module = cf->cycle->modules[i]->ctx;

  2330.         if (module->create_srv_conf) {
  2331.             mconf = module->create_srv_conf(cf);
  2332.             if (mconf == NULL) {
  2333.                 return NGX_CONF_ERROR;
  2334.             }

  2335.             ctx->srv_conf[cf->cycle->modules[i]->ctx_index] = mconf;
  2336.         }

  2337.         if (module->create_loc_conf) {
  2338.             mconf = module->create_loc_conf(cf);
  2339.             if (mconf == NULL) {
  2340.                 return NGX_CONF_ERROR;
  2341.             }

  2342.             ctx->loc_conf[cf->cycle->modules[i]->ctx_index] = mconf;
  2343.         }
  2344.     }


  2345.     /* the server configuration context */

  2346.     cscf = ctx->srv_conf[ngx_http_core_module.ctx_index];
  2347.     cscf->ctx = ctx;


  2348.     cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];

  2349.     cscfp = ngx_array_push(&cmcf->servers);
  2350.     if (cscfp == NULL) {
  2351.         return NGX_CONF_ERROR;
  2352.     }

  2353.     *cscfp = cscf;


  2354.     /* parse inside server{} */

  2355.     pcf = *cf;
  2356.     cf->ctx = ctx;
  2357.     cf->cmd_type = NGX_HTTP_SRV_CONF;

  2358.     rv = ngx_conf_parse(cf, NULL);

  2359.     *cf = pcf;

  2360.     if (rv == NGX_CONF_OK && !cscf->listen) {
  2361.         ngx_memzero(&lsopt, sizeof(ngx_http_listen_opt_t));

  2362.         p = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in));
  2363.         if (p == NULL) {
  2364.             return NGX_CONF_ERROR;
  2365.         }

  2366.         lsopt.sockaddr = (struct sockaddr *) p;

  2367.         sin = (struct sockaddr_in *) p;

  2368.         sin->sin_family = AF_INET;
  2369. #if (NGX_WIN32)
  2370.         sin->sin_port = htons(80);
  2371. #else
  2372.         sin->sin_port = htons((getuid() == 0) ? 80 : 8000);
  2373. #endif
  2374.         sin->sin_addr.s_addr = INADDR_ANY;

  2375.         lsopt.socklen = sizeof(struct sockaddr_in);

  2376.         lsopt.backlog = NGX_LISTEN_BACKLOG;
  2377.         lsopt.type = SOCK_STREAM;
  2378.         lsopt.rcvbuf = -1;
  2379.         lsopt.sndbuf = -1;
  2380. #if (NGX_HAVE_SETFIB)
  2381.         lsopt.setfib = -1;
  2382. #endif
  2383. #if (NGX_HAVE_TCP_FASTOPEN)
  2384.         lsopt.fastopen = -1;
  2385. #endif
  2386.         lsopt.wildcard = 1;

  2387.         len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;

  2388.         p = ngx_pnalloc(cf->pool, len);
  2389.         if (p == NULL) {
  2390.             return NGX_CONF_ERROR;
  2391.         }

  2392.         lsopt.addr_text.data = p;
  2393.         lsopt.addr_text.len = ngx_sock_ntop(lsopt.sockaddr, lsopt.socklen, p,
  2394.                                             len, 1);

  2395.         if (ngx_http_add_listen(cf, cscf, &lsopt) != NGX_OK) {
  2396.             return NGX_CONF_ERROR;
  2397.         }
  2398.     }

  2399.     return rv;
  2400. }


  2401. static char *
  2402. ‌ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
  2403. {
  2404.     char                      *rv;
  2405.     u_char                    *mod;
  2406.     size_t                     len;
  2407.     ngx_str_t                 *value, *name;
  2408.     ngx_int_t                  index;
  2409.     ngx_uint_t                 i;
  2410.     ngx_conf_t                 save;
  2411.     ngx_http_module_t         *module;
  2412.     ngx_http_conf_ctx_t       *ctx, *pctx;
  2413.     ngx_http_core_loc_conf_t  *clcf, *pclcf;

  2414.     ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
  2415.     if (ctx == NULL) {
  2416.         return NGX_CONF_ERROR;
  2417.     }

  2418.     pctx = cf->ctx;
  2419.     ctx->main_conf = pctx->main_conf;
  2420.     ctx->srv_conf = pctx->srv_conf;

  2421.     ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
  2422.     if (ctx->loc_conf == NULL) {
  2423.         return NGX_CONF_ERROR;
  2424.     }

  2425.     for (i = 0; cf->cycle->modules[i]; i++) {
  2426.         if (cf->cycle->modules[i]->type != NGX_HTTP_MODULE) {
  2427.             continue;
  2428.         }

  2429.         module = cf->cycle->modules[i]->ctx;

  2430.         if (module->create_loc_conf) {
  2431.             ctx->loc_conf[cf->cycle->modules[i]->ctx_index] =
  2432.                                                    module->create_loc_conf(cf);
  2433.             if (ctx->loc_conf[cf->cycle->modules[i]->ctx_index] == NULL) {
  2434.                 return NGX_CONF_ERROR;
  2435.             }
  2436.         }
  2437.     }

  2438.     clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
  2439.     clcf->loc_conf = ctx->loc_conf;

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

  2441.     if (cf->args->nelts == 3) {

  2442.         len = value[1].len;
  2443.         mod = value[1].data;
  2444.         name = &value[2];

  2445.         if (len == 1 && mod[0] == '=') {

  2446.             clcf->name = *name;
  2447.             clcf->exact_match = 1;

  2448.         } else if (len == 2 && mod[0] == '^' && mod[1] == '~') {

  2449.             clcf->name = *name;
  2450.             clcf->noregex = 1;

  2451.         } else if (len == 1 && mod[0] == '~') {

  2452.             if (ngx_http_core_regex_location(cf, clcf, name, 0) != NGX_OK) {
  2453.                 return NGX_CONF_ERROR;
  2454.             }

  2455.         } else if (len == 2 && mod[0] == '~' && mod[1] == '*') {

  2456.             if (ngx_http_core_regex_location(cf, clcf, name, 1) != NGX_OK) {
  2457.                 return NGX_CONF_ERROR;
  2458.             }

  2459.         } else {
  2460.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2461.                                "invalid location modifier \"%V\"", &value[1]);
  2462.             return NGX_CONF_ERROR;
  2463.         }

  2464.     } else {

  2465.         name = &value[1];

  2466.         if (name->data[0] == '=') {

  2467.             clcf->name.len = name->len - 1;
  2468.             clcf->name.data = name->data + 1;
  2469.             clcf->exact_match = 1;

  2470.         } else if (name->data[0] == '^' && name->data[1] == '~') {

  2471.             clcf->name.len = name->len - 2;
  2472.             clcf->name.data = name->data + 2;
  2473.             clcf->noregex = 1;

  2474.         } else if (name->data[0] == '~') {

  2475.             name->len--;
  2476.             name->data++;

  2477.             if (name->data[0] == '*') {

  2478.                 name->len--;
  2479.                 name->data++;

  2480.                 if (ngx_http_core_regex_location(cf, clcf, name, 1) != NGX_OK) {
  2481.                     return NGX_CONF_ERROR;
  2482.                 }

  2483.             } else {
  2484.                 if (ngx_http_core_regex_location(cf, clcf, name, 0) != NGX_OK) {
  2485.                     return NGX_CONF_ERROR;
  2486.                 }
  2487.             }

  2488.         } else if (name->data[0] == '$') {

  2489.             clcf->name = *name;

  2490.             name->len--;
  2491.             name->data++;

  2492.             index = ngx_http_get_variable_index(cf, name);
  2493.             if (index == NGX_ERROR) {
  2494.                 return NGX_CONF_ERROR;
  2495.             }

  2496.             clcf->predicate = index + 1;

  2497.         } else {

  2498.             clcf->name = *name;

  2499.             if (name->data[0] == '@') {
  2500.                 clcf->named = 1;
  2501.             }
  2502.         }
  2503.     }

  2504.     pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index];

  2505.     if (cf->cmd_type == NGX_HTTP_LOC_CONF) {

  2506.         /* nested location */

  2507. #if 0
  2508.         clcf->prev_location = pclcf;
  2509. #endif

  2510.         if (pclcf->exact_match) {
  2511.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2512.                                "location \"%V\" cannot be inside "
  2513.                                "the exact location \"%V\"",
  2514.                                &clcf->name, &pclcf->name);
  2515.             return NGX_CONF_ERROR;
  2516.         }

  2517.         if (pclcf->named) {
  2518.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2519.                                "location \"%V\" cannot be inside "
  2520.                                "the named location \"%V\"",
  2521.                                &clcf->name, &pclcf->name);
  2522.             return NGX_CONF_ERROR;
  2523.         }

  2524.         if (clcf->named) {
  2525.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2526.                                "named location \"%V\" can be "
  2527.                                "on the server level only",
  2528.                                &clcf->name);
  2529.             return NGX_CONF_ERROR;
  2530.         }

  2531.         len = pclcf->name.len;

  2532.         if (!clcf->predicate && !pclcf->predicate
  2533. #if (NGX_PCRE)
  2534.             && clcf->regex == NULL
  2535. #endif
  2536.             && ngx_filename_cmp(clcf->name.data, pclcf->name.data, len) != 0)
  2537.         {
  2538.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2539.                                "location \"%V\" is outside location \"%V\"",
  2540.                                &clcf->name, &pclcf->name);
  2541.             return NGX_CONF_ERROR;
  2542.         }
  2543.     }

  2544.     if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) {
  2545.         return NGX_CONF_ERROR;
  2546.     }

  2547.     save = *cf;
  2548.     cf->ctx = ctx;
  2549.     cf->cmd_type = NGX_HTTP_LOC_CONF;

  2550.     rv = ngx_conf_parse(cf, NULL);

  2551.     *cf = save;

  2552.     return rv;
  2553. }


  2554. static ngx_int_t
  2555. ‌ngx_http_core_regex_location(ngx_conf_t *cf, ngx_http_core_loc_conf_t *clcf,
  2556.     ngx_str_t *regex, ngx_uint_t caseless)
  2557. {
  2558. #if (NGX_PCRE)
  2559.     ngx_regex_compile_t  rc;
  2560.     u_char               errstr[NGX_MAX_CONF_ERRSTR];

  2561.     ngx_memzero(&rc, sizeof(ngx_regex_compile_t));

  2562.     rc.pattern = *regex;
  2563.     rc.err.len = NGX_MAX_CONF_ERRSTR;
  2564.     rc.err.data = errstr;

  2565. #if (NGX_HAVE_CASELESS_FILESYSTEM)
  2566.     rc.options = NGX_REGEX_CASELESS;
  2567. #else
  2568.     rc.options = caseless ? NGX_REGEX_CASELESS : 0;
  2569. #endif

  2570.     clcf->regex = ngx_http_regex_compile(cf, &rc);
  2571.     if (clcf->regex == NULL) {
  2572.         return NGX_ERROR;
  2573.     }

  2574.     clcf->name = *regex;

  2575.     return NGX_OK;

  2576. #else

  2577.     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2578.                        "using regex \"%V\" requires PCRE library",
  2579.                        regex);
  2580.     return NGX_ERROR;

  2581. #endif
  2582. }


  2583. static char *
  2584. ‌ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  2585. {
  2586.     ngx_http_core_loc_conf_t *clcf = conf;

  2587.     char        *rv;
  2588.     ngx_conf_t   save;

  2589.     if (clcf->types == NULL) {
  2590.         clcf->types = ngx_array_create(cf->pool, 64, sizeof(ngx_hash_key_t));
  2591.         if (clcf->types == NULL) {
  2592.             return NGX_CONF_ERROR;
  2593.         }
  2594.     }

  2595.     save = *cf;
  2596.     cf->handler = ngx_http_core_type;
  2597.     cf->handler_conf = conf;

  2598.     rv = ngx_conf_parse(cf, NULL);

  2599.     *cf = save;

  2600.     return rv;
  2601. }


  2602. static char *
  2603. ‌ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
  2604. {
  2605.     ngx_http_core_loc_conf_t *clcf = conf;

  2606.     ngx_str_t       *value, *content_type, *old;
  2607.     ngx_uint_t       i, n, hash;
  2608.     ngx_hash_key_t  *type;

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

  2610.     if (ngx_strcmp(value[0].data, "include") == 0) {
  2611.         if (cf->args->nelts != 2) {
  2612.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2613.                                "invalid number of arguments"
  2614.                                " in \"include\" directive");
  2615.             return NGX_CONF_ERROR;
  2616.         }

  2617.         return ngx_conf_include(cf, dummy, conf);
  2618.     }

  2619.     content_type = ngx_palloc(cf->pool, sizeof(ngx_str_t));
  2620.     if (content_type == NULL) {
  2621.         return NGX_CONF_ERROR;
  2622.     }

  2623.     *content_type = value[0];

  2624.     for (i = 1; i < cf->args->nelts; i++) {

  2625.         hash = ngx_hash_strlow(value[i].data, value[i].data, value[i].len);

  2626.         type = clcf->types->elts;
  2627.         for (n = 0; n < clcf->types->nelts; n++) {
  2628.             if (ngx_strcmp(value[i].data, type[n].key.data) == 0) {
  2629.                 old = type[n].value;
  2630.                 type[n].value = content_type;

  2631.                 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
  2632.                                    "duplicate extension \"%V\", "
  2633.                                    "content type: \"%V\", "
  2634.                                    "previous content type: \"%V\"",
  2635.                                    &value[i], content_type, old);
  2636.                 goto next;
  2637.             }
  2638.         }


  2639.         type = ngx_array_push(clcf->types);
  2640.         if (type == NULL) {
  2641.             return NGX_CONF_ERROR;
  2642.         }

  2643.         type->key = value[i];
  2644.         type->key_hash = hash;
  2645.         type->value = content_type;

  2646.     next:
  2647.         continue;
  2648.     }

  2649.     return NGX_CONF_OK;
  2650. }


  2651. static ngx_int_t
  2652. ‌ngx_http_core_preconfiguration(ngx_conf_t *cf)
  2653. {
  2654.     return ngx_http_variables_add_core_vars(cf);
  2655. }


  2656. static ngx_int_t
  2657. ‌ngx_http_core_postconfiguration(ngx_conf_t *cf)
  2658. {
  2659.     ngx_http_top_request_body_filter = ngx_http_request_body_save_filter;

  2660.     return NGX_OK;
  2661. }


  2662. static void *
  2663. ‌ngx_http_core_create_main_conf(ngx_conf_t *cf)
  2664. {
  2665.     ngx_http_core_main_conf_t  *cmcf;

  2666.     cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_main_conf_t));
  2667.     if (cmcf == NULL) {
  2668.         return NULL;
  2669.     }

  2670.     if (ngx_array_init(&cmcf->servers, cf->pool, 4,
  2671.                        sizeof(ngx_http_core_srv_conf_t *))
  2672.         != NGX_OK)
  2673.     {
  2674.         return NULL;
  2675.     }

  2676.     cmcf->server_names_hash_max_size = NGX_CONF_UNSET_UINT;
  2677.     cmcf->server_names_hash_bucket_size = NGX_CONF_UNSET_UINT;

  2678.     cmcf->variables_hash_max_size = NGX_CONF_UNSET_UINT;
  2679.     cmcf->variables_hash_bucket_size = NGX_CONF_UNSET_UINT;

  2680.     return cmcf;
  2681. }


  2682. static char *
  2683. ‌ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf)
  2684. {
  2685.     ngx_http_core_main_conf_t *cmcf = conf;

  2686.     ngx_conf_init_uint_value(cmcf->server_names_hash_max_size, 512);
  2687.     ngx_conf_init_uint_value(cmcf->server_names_hash_bucket_size,
  2688.                              ngx_cacheline_size);

  2689.     cmcf->server_names_hash_bucket_size =
  2690.             ngx_align(cmcf->server_names_hash_bucket_size, ngx_cacheline_size);


  2691.     ngx_conf_init_uint_value(cmcf->variables_hash_max_size, 1024);
  2692.     ngx_conf_init_uint_value(cmcf->variables_hash_bucket_size, 64);

  2693.     cmcf->variables_hash_bucket_size =
  2694.                ngx_align(cmcf->variables_hash_bucket_size, ngx_cacheline_size);

  2695.     if (cmcf->ncaptures) {
  2696.         cmcf->ncaptures = (cmcf->ncaptures + 1) * 3;
  2697.     }

  2698.     return NGX_CONF_OK;
  2699. }


  2700. static void *
  2701. ‌ngx_http_core_create_srv_conf(ngx_conf_t *cf)
  2702. {
  2703.     ngx_http_core_srv_conf_t  *cscf;

  2704.     cscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_srv_conf_t));
  2705.     if (cscf == NULL) {
  2706.         return NULL;
  2707.     }

  2708.     /*
  2709.      * set by ngx_pcalloc():
  2710.      *
  2711.      *     conf->client_large_buffers.num = 0;
  2712.      */

  2713.     if (ngx_array_init(&cscf->server_names, cf->temp_pool, 4,
  2714.                        sizeof(ngx_http_server_name_t))
  2715.         != NGX_OK)
  2716.     {
  2717.         return NULL;
  2718.     }

  2719.     cscf->connection_pool_size = NGX_CONF_UNSET_SIZE;
  2720.     cscf->request_pool_size = NGX_CONF_UNSET_SIZE;
  2721.     cscf->client_header_timeout = NGX_CONF_UNSET_MSEC;
  2722.     cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE;
  2723.     cscf->max_headers = NGX_CONF_UNSET_UINT;
  2724.     cscf->ignore_invalid_headers = NGX_CONF_UNSET;
  2725.     cscf->merge_slashes = NGX_CONF_UNSET;
  2726.     cscf->underscores_in_headers = NGX_CONF_UNSET;
  2727.     cscf->client_body_early_read = NGX_CONF_UNSET_PTR;

  2728.     cscf->file_name = cf->conf_file->file.name.data;
  2729.     cscf->line = cf->conf_file->line;

  2730.     return cscf;
  2731. }


  2732. static char *
  2733. ‌ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
  2734. {
  2735.     ngx_http_core_srv_conf_t *prev = parent;
  2736.     ngx_http_core_srv_conf_t *conf = child;

  2737.     ngx_str_t                name;
  2738.     ngx_http_server_name_t  *sn;

  2739.     /* TODO: it does not merge, it inits only */

  2740.     ngx_conf_merge_size_value(conf->connection_pool_size,
  2741.                               prev->connection_pool_size, 64 * sizeof(void *));
  2742.     ngx_conf_merge_size_value(conf->request_pool_size,
  2743.                               prev->request_pool_size, 4096);
  2744.     ngx_conf_merge_msec_value(conf->client_header_timeout,
  2745.                               prev->client_header_timeout, 60000);
  2746.     ngx_conf_merge_size_value(conf->client_header_buffer_size,
  2747.                               prev->client_header_buffer_size, 1024);
  2748.     ngx_conf_merge_bufs_value(conf->large_client_header_buffers,
  2749.                               prev->large_client_header_buffers,
  2750.                               4, 8192);

  2751.     if (conf->large_client_header_buffers.size < conf->connection_pool_size) {
  2752.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2753.                            "the \"large_client_header_buffers\" size must be "
  2754.                            "equal to or greater than \"connection_pool_size\"");
  2755.         return NGX_CONF_ERROR;
  2756.     }

  2757.     ngx_conf_merge_uint_value(conf->max_headers, prev->max_headers, 1000);

  2758.     ngx_conf_merge_value(conf->ignore_invalid_headers,
  2759.                               prev->ignore_invalid_headers, 1);

  2760.     ngx_conf_merge_value(conf->merge_slashes, prev->merge_slashes, 1);

  2761.     ngx_conf_merge_value(conf->underscores_in_headers,
  2762.                               prev->underscores_in_headers, 0);

  2763.     ngx_conf_merge_ptr_value(conf->client_body_early_read,
  2764.                               prev->client_body_early_read, NULL);

  2765.     if (conf->server_names.nelts == 0) {
  2766.         /* the array has 4 empty preallocated elements, so push cannot fail */
  2767.         sn = ngx_array_push(&conf->server_names);
  2768. #if (NGX_PCRE)
  2769.         sn->regex = NULL;
  2770. #endif
  2771.         sn->server = conf;
  2772.         ngx_str_set(&sn->name, "");
  2773.     }

  2774.     sn = conf->server_names.elts;
  2775.     name = sn[0].name;

  2776. #if (NGX_PCRE)
  2777.     if (sn->regex) {
  2778.         name.len++;
  2779.         name.data--;
  2780.     } else
  2781. #endif

  2782.     if (name.data[0] == '.') {
  2783.         name.len--;
  2784.         name.data++;
  2785.     }

  2786.     conf->server_name.len = name.len;
  2787.     conf->server_name.data = ngx_pstrdup(cf->pool, &name);
  2788.     if (conf->server_name.data == NULL) {
  2789.         return NGX_CONF_ERROR;
  2790.     }

  2791.     return NGX_CONF_OK;
  2792. }


  2793. static void *
  2794. ‌ngx_http_core_create_loc_conf(ngx_conf_t *cf)
  2795. {
  2796.     ngx_http_core_loc_conf_t  *clcf;

  2797.     clcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_loc_conf_t));
  2798.     if (clcf == NULL) {
  2799.         return NULL;
  2800.     }

  2801.     /*
  2802.      * set by ngx_pcalloc():
  2803.      *
  2804.      *     clcf->escaped_name = { 0, NULL };
  2805.      *     clcf->root = { 0, NULL };
  2806.      *     clcf->limit_except = 0;
  2807.      *     clcf->post_action = { 0, NULL };
  2808.      *     clcf->types = NULL;
  2809.      *     clcf->default_type = { 0, NULL };
  2810.      *     clcf->error_log = NULL;
  2811.      *     clcf->error_pages = NULL;
  2812.      *     clcf->client_body_path = NULL;
  2813.      *     clcf->regex = NULL;
  2814.      *     clcf->predicate = 0;
  2815.      *     clcf->exact_match = 0;
  2816.      *     clcf->auto_redirect = 0;
  2817.      *     clcf->alias = 0;
  2818.      *     clcf->gzip_proxied = 0;
  2819.      *     clcf->keepalive_disable = 0;
  2820.      */

  2821.     clcf->client_max_body_size = NGX_CONF_UNSET;
  2822.     clcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE;
  2823.     clcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
  2824.     clcf->satisfy = NGX_CONF_UNSET_UINT;
  2825.     clcf->auth_delay = NGX_CONF_UNSET_MSEC;
  2826.     clcf->if_modified_since = NGX_CONF_UNSET_UINT;
  2827.     clcf->max_ranges = NGX_CONF_UNSET_UINT;
  2828.     clcf->client_body_in_file_only = NGX_CONF_UNSET_UINT;
  2829.     clcf->client_body_in_single_buffer = NGX_CONF_UNSET;
  2830.     clcf->internal = NGX_CONF_UNSET;
  2831.     clcf->sendfile = NGX_CONF_UNSET;
  2832.     clcf->sendfile_max_chunk = NGX_CONF_UNSET_SIZE;
  2833.     clcf->subrequest_output_buffer_size = NGX_CONF_UNSET_SIZE;
  2834.     clcf->aio = NGX_CONF_UNSET;
  2835.     clcf->aio_write = NGX_CONF_UNSET;
  2836. #if (NGX_THREADS)
  2837.     clcf->thread_pool = NGX_CONF_UNSET_PTR;
  2838.     clcf->thread_pool_value = NGX_CONF_UNSET_PTR;
  2839. #endif
  2840.     clcf->read_ahead = NGX_CONF_UNSET_SIZE;
  2841.     clcf->directio = NGX_CONF_UNSET;
  2842.     clcf->directio_alignment = NGX_CONF_UNSET;
  2843.     clcf->tcp_nopush = NGX_CONF_UNSET;
  2844.     clcf->tcp_nodelay = NGX_CONF_UNSET;
  2845.     clcf->send_timeout = NGX_CONF_UNSET_MSEC;
  2846.     clcf->send_lowat = NGX_CONF_UNSET_SIZE;
  2847.     clcf->postpone_output = NGX_CONF_UNSET_SIZE;
  2848.     clcf->limit_rate = NGX_CONF_UNSET_PTR;
  2849.     clcf->limit_rate_after = NGX_CONF_UNSET_PTR;
  2850.     clcf->keepalive_time = NGX_CONF_UNSET_MSEC;
  2851.     clcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
  2852.     clcf->keepalive_header = NGX_CONF_UNSET;
  2853.     clcf->keepalive_min_timeout = NGX_CONF_UNSET_MSEC;
  2854.     clcf->keepalive_requests = NGX_CONF_UNSET_UINT;
  2855.     clcf->lingering_close = NGX_CONF_UNSET_UINT;
  2856.     clcf->lingering_time = NGX_CONF_UNSET_MSEC;
  2857.     clcf->lingering_timeout = NGX_CONF_UNSET_MSEC;
  2858.     clcf->resolver_timeout = NGX_CONF_UNSET_MSEC;
  2859.     clcf->reset_timedout_connection = NGX_CONF_UNSET;
  2860.     clcf->absolute_redirect = NGX_CONF_UNSET;
  2861.     clcf->server_name_in_redirect = NGX_CONF_UNSET;
  2862.     clcf->port_in_redirect = NGX_CONF_UNSET;
  2863.     clcf->msie_padding = NGX_CONF_UNSET;
  2864.     clcf->msie_refresh = NGX_CONF_UNSET;
  2865.     clcf->log_not_found = NGX_CONF_UNSET;
  2866.     clcf->log_subrequest = NGX_CONF_UNSET;
  2867.     clcf->recursive_error_pages = NGX_CONF_UNSET;
  2868.     clcf->chunked_transfer_encoding = NGX_CONF_UNSET;
  2869.     clcf->etag = NGX_CONF_UNSET;
  2870.     clcf->server_tokens = NGX_CONF_UNSET_UINT;
  2871.     clcf->early_hints = NGX_CONF_UNSET_PTR;
  2872.     clcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
  2873.     clcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;

  2874.     clcf->open_file_cache = NGX_CONF_UNSET_PTR;
  2875.     clcf->open_file_cache_valid = NGX_CONF_UNSET;
  2876.     clcf->open_file_cache_min_uses = NGX_CONF_UNSET_UINT;
  2877.     clcf->open_file_cache_errors = NGX_CONF_UNSET;
  2878.     clcf->open_file_cache_events = NGX_CONF_UNSET;

  2879. #if (NGX_HTTP_GZIP)
  2880.     clcf->gzip_vary = NGX_CONF_UNSET;
  2881.     clcf->gzip_http_version = NGX_CONF_UNSET_UINT;
  2882. #if (NGX_PCRE)
  2883.     clcf->gzip_disable = NGX_CONF_UNSET_PTR;
  2884. #endif
  2885.     clcf->gzip_disable_msie6 = 3;
  2886. #if (NGX_HTTP_DEGRADATION)
  2887.     clcf->gzip_disable_degradation = 3;
  2888. #endif
  2889. #endif

  2890. #if (NGX_HAVE_OPENAT)
  2891.     clcf->disable_symlinks = NGX_CONF_UNSET_UINT;
  2892.     clcf->disable_symlinks_from = NGX_CONF_UNSET_PTR;
  2893. #endif

  2894.     return clcf;
  2895. }


  2896. ‌static ngx_str_t  ngx_http_core_text_html_type = ngx_string("text/html");
  2897. ‌static ngx_str_t  ngx_http_core_image_gif_type = ngx_string("image/gif");
  2898. ‌static ngx_str_t  ngx_http_core_image_jpeg_type = ngx_string("image/jpeg");

  2899. ‌static ngx_hash_key_t  ngx_http_core_default_types[] = {
  2900.     { ngx_string("html"), 0, &ngx_http_core_text_html_type },
  2901.     { ngx_string("gif"), 0, &ngx_http_core_image_gif_type },
  2902.     { ngx_string("jpg"), 0, &ngx_http_core_image_jpeg_type },
  2903.     { ngx_null_string, 0, NULL }
  2904. };


  2905. static char *
  2906. ‌ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
  2907. {
  2908.     ngx_http_core_loc_conf_t *prev = parent;
  2909.     ngx_http_core_loc_conf_t *conf = child;

  2910.     ngx_uint_t        i;
  2911.     ngx_hash_key_t   *type;
  2912.     ngx_hash_init_t   types_hash;

  2913.     if (conf->root.data == NULL) {

  2914.         conf->alias = prev->alias;
  2915.         conf->root = prev->root;
  2916.         conf->root_lengths = prev->root_lengths;
  2917.         conf->root_values = prev->root_values;

  2918.         if (prev->root.data == NULL) {
  2919.             ngx_str_set(&conf->root, "html");

  2920.             if (ngx_conf_full_name(cf->cycle, &conf->root, 0) != NGX_OK) {
  2921.                 return NGX_CONF_ERROR;
  2922.             }
  2923.         }
  2924.     }

  2925.     if (conf->post_action.data == NULL) {
  2926.         conf->post_action = prev->post_action;
  2927.     }

  2928.     ngx_conf_merge_uint_value(conf->types_hash_max_size,
  2929.                               prev->types_hash_max_size, 1024);

  2930.     ngx_conf_merge_uint_value(conf->types_hash_bucket_size,
  2931.                               prev->types_hash_bucket_size, 64);

  2932.     conf->types_hash_bucket_size = ngx_align(conf->types_hash_bucket_size,
  2933.                                              ngx_cacheline_size);

  2934.     /*
  2935.      * the special handling of the "types" directive in the "http" section
  2936.      * to inherit the http's conf->types_hash to all servers
  2937.      */

  2938.     if (prev->types && prev->types_hash.buckets == NULL) {

  2939.         types_hash.hash = &prev->types_hash;
  2940.         types_hash.key = ngx_hash_key_lc;
  2941.         types_hash.max_size = conf->types_hash_max_size;
  2942.         types_hash.bucket_size = conf->types_hash_bucket_size;
  2943.         types_hash.name = "types_hash";
  2944.         types_hash.pool = cf->pool;
  2945.         types_hash.temp_pool = NULL;

  2946.         if (ngx_hash_init(&types_hash, prev->types->elts, prev->types->nelts)
  2947.             != NGX_OK)
  2948.         {
  2949.             return NGX_CONF_ERROR;
  2950.         }
  2951.     }

  2952.     if (conf->types == NULL) {
  2953.         conf->types = prev->types;
  2954.         conf->types_hash = prev->types_hash;
  2955.     }

  2956.     if (conf->types == NULL) {
  2957.         conf->types = ngx_array_create(cf->pool, 3, sizeof(ngx_hash_key_t));
  2958.         if (conf->types == NULL) {
  2959.             return NGX_CONF_ERROR;
  2960.         }

  2961.         for (i = 0; ngx_http_core_default_types[i].key.len; i++) {
  2962.             type = ngx_array_push(conf->types);
  2963.             if (type == NULL) {
  2964.                 return NGX_CONF_ERROR;
  2965.             }

  2966.             type->key = ngx_http_core_default_types[i].key;
  2967.             type->key_hash =
  2968.                        ngx_hash_key_lc(ngx_http_core_default_types[i].key.data,
  2969.                                        ngx_http_core_default_types[i].key.len);
  2970.             type->value = ngx_http_core_default_types[i].value;
  2971.         }
  2972.     }

  2973.     if (conf->types_hash.buckets == NULL) {

  2974.         types_hash.hash = &conf->types_hash;
  2975.         types_hash.key = ngx_hash_key_lc;
  2976.         types_hash.max_size = conf->types_hash_max_size;
  2977.         types_hash.bucket_size = conf->types_hash_bucket_size;
  2978.         types_hash.name = "types_hash";
  2979.         types_hash.pool = cf->pool;
  2980.         types_hash.temp_pool = NULL;

  2981.         if (ngx_hash_init(&types_hash, conf->types->elts, conf->types->nelts)
  2982.             != NGX_OK)
  2983.         {
  2984.             return NGX_CONF_ERROR;
  2985.         }
  2986.     }

  2987.     if (conf->error_log == NULL) {
  2988.         if (prev->error_log) {
  2989.             conf->error_log = prev->error_log;
  2990.         } else {
  2991.             conf->error_log = &cf->cycle->new_log;
  2992.         }
  2993.     }

  2994.     if (conf->error_pages == NULL && prev->error_pages) {
  2995.         conf->error_pages = prev->error_pages;
  2996.     }

  2997.     ngx_conf_merge_str_value(conf->default_type,
  2998.                               prev->default_type, "text/plain");

  2999.     ngx_conf_merge_off_value(conf->client_max_body_size,
  3000.                               prev->client_max_body_size, 1 * 1024 * 1024);
  3001.     ngx_conf_merge_size_value(conf->client_body_buffer_size,
  3002.                               prev->client_body_buffer_size,
  3003.                               (size_t) 2 * ngx_pagesize);
  3004.     ngx_conf_merge_msec_value(conf->client_body_timeout,
  3005.                               prev->client_body_timeout, 60000);

  3006.     ngx_conf_merge_bitmask_value(conf->keepalive_disable,
  3007.                               prev->keepalive_disable,
  3008.                               (NGX_CONF_BITMASK_SET
  3009.                                |NGX_HTTP_KEEPALIVE_DISABLE_MSIE6));
  3010.     ngx_conf_merge_uint_value(conf->satisfy, prev->satisfy,
  3011.                               NGX_HTTP_SATISFY_ALL);
  3012.     ngx_conf_merge_msec_value(conf->auth_delay, prev->auth_delay, 0);
  3013.     ngx_conf_merge_uint_value(conf->if_modified_since, prev->if_modified_since,
  3014.                               NGX_HTTP_IMS_EXACT);
  3015.     ngx_conf_merge_uint_value(conf->max_ranges, prev->max_ranges,
  3016.                               NGX_MAX_INT32_VALUE);
  3017.     ngx_conf_merge_uint_value(conf->client_body_in_file_only,
  3018.                               prev->client_body_in_file_only,
  3019.                               NGX_HTTP_REQUEST_BODY_FILE_OFF);
  3020.     ngx_conf_merge_value(conf->client_body_in_single_buffer,
  3021.                               prev->client_body_in_single_buffer, 0);
  3022.     ngx_conf_merge_value(conf->internal, prev->internal, 0);
  3023.     ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0);
  3024.     ngx_conf_merge_size_value(conf->sendfile_max_chunk,
  3025.                               prev->sendfile_max_chunk, 2 * 1024 * 1024);
  3026.     ngx_conf_merge_size_value(conf->subrequest_output_buffer_size,
  3027.                               prev->subrequest_output_buffer_size,
  3028.                               (size_t) ngx_pagesize);
  3029.     ngx_conf_merge_value(conf->aio, prev->aio, NGX_HTTP_AIO_OFF);
  3030.     ngx_conf_merge_value(conf->aio_write, prev->aio_write, 0);
  3031. #if (NGX_THREADS)
  3032.     ngx_conf_merge_ptr_value(conf->thread_pool, prev->thread_pool, NULL);
  3033.     ngx_conf_merge_ptr_value(conf->thread_pool_value, prev->thread_pool_value,
  3034.                              NULL);
  3035. #endif
  3036.     ngx_conf_merge_size_value(conf->read_ahead, prev->read_ahead, 0);
  3037.     ngx_conf_merge_off_value(conf->directio, prev->directio,
  3038.                               NGX_OPEN_FILE_DIRECTIO_OFF);
  3039.     ngx_conf_merge_off_value(conf->directio_alignment, prev->directio_alignment,
  3040.                               512);
  3041.     ngx_conf_merge_value(conf->tcp_nopush, prev->tcp_nopush, 0);
  3042.     ngx_conf_merge_value(conf->tcp_nodelay, prev->tcp_nodelay, 1);

  3043.     ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 60000);
  3044.     ngx_conf_merge_size_value(conf->send_lowat, prev->send_lowat, 0);
  3045.     ngx_conf_merge_size_value(conf->postpone_output, prev->postpone_output,
  3046.                               1460);

  3047.     ngx_conf_merge_ptr_value(conf->limit_rate, prev->limit_rate, NULL);
  3048.     ngx_conf_merge_ptr_value(conf->limit_rate_after,
  3049.                               prev->limit_rate_after, NULL);

  3050.     ngx_conf_merge_msec_value(conf->keepalive_time,
  3051.                               prev->keepalive_time, 3600000);
  3052.     ngx_conf_merge_msec_value(conf->keepalive_timeout,
  3053.                               prev->keepalive_timeout, 75000);
  3054.     ngx_conf_merge_sec_value(conf->keepalive_header,
  3055.                               prev->keepalive_header, 0);
  3056.     ngx_conf_merge_msec_value(conf->keepalive_min_timeout,
  3057.                               prev->keepalive_min_timeout, 0);
  3058.     ngx_conf_merge_uint_value(conf->keepalive_requests,
  3059.                               prev->keepalive_requests, 1000);
  3060.     ngx_conf_merge_uint_value(conf->lingering_close,
  3061.                               prev->lingering_close, NGX_HTTP_LINGERING_ON);
  3062.     ngx_conf_merge_msec_value(conf->lingering_time,
  3063.                               prev->lingering_time, 30000);
  3064.     ngx_conf_merge_msec_value(conf->lingering_timeout,
  3065.                               prev->lingering_timeout, 5000);
  3066.     ngx_conf_merge_msec_value(conf->resolver_timeout,
  3067.                               prev->resolver_timeout, 30000);

  3068.     if (conf->resolver == NULL) {

  3069.         if (prev->resolver == NULL) {

  3070.             /*
  3071.              * create dummy resolver in http {} context
  3072.              * to inherit it in all servers
  3073.              */

  3074.             prev->resolver = ngx_resolver_create(cf, NULL, 0);
  3075.             if (prev->resolver == NULL) {
  3076.                 return NGX_CONF_ERROR;
  3077.             }
  3078.         }

  3079.         conf->resolver = prev->resolver;
  3080.     }

  3081.     if (ngx_conf_merge_path_value(cf, &conf->client_body_temp_path,
  3082.                               prev->client_body_temp_path,
  3083.                               &ngx_http_client_temp_path)
  3084.         != NGX_CONF_OK)
  3085.     {
  3086.         return NGX_CONF_ERROR;
  3087.     }

  3088.     ngx_conf_merge_value(conf->reset_timedout_connection,
  3089.                               prev->reset_timedout_connection, 0);
  3090.     ngx_conf_merge_value(conf->absolute_redirect,
  3091.                               prev->absolute_redirect, 1);
  3092.     ngx_conf_merge_value(conf->server_name_in_redirect,
  3093.                               prev->server_name_in_redirect, 0);
  3094.     ngx_conf_merge_value(conf->port_in_redirect, prev->port_in_redirect, 1);
  3095.     ngx_conf_merge_value(conf->msie_padding, prev->msie_padding, 1);
  3096.     ngx_conf_merge_value(conf->msie_refresh, prev->msie_refresh, 0);
  3097.     ngx_conf_merge_value(conf->log_not_found, prev->log_not_found, 1);
  3098.     ngx_conf_merge_value(conf->log_subrequest, prev->log_subrequest, 0);
  3099.     ngx_conf_merge_value(conf->recursive_error_pages,
  3100.                               prev->recursive_error_pages, 0);
  3101.     ngx_conf_merge_value(conf->chunked_transfer_encoding,
  3102.                               prev->chunked_transfer_encoding, 1);
  3103.     ngx_conf_merge_value(conf->etag, prev->etag, 1);

  3104.     ngx_conf_merge_uint_value(conf->server_tokens, prev->server_tokens,
  3105.                               NGX_HTTP_SERVER_TOKENS_ON);

  3106.     ngx_conf_merge_ptr_value(conf->early_hints, prev->early_hints, NULL);

  3107.     ngx_conf_merge_ptr_value(conf->open_file_cache,
  3108.                               prev->open_file_cache, NULL);

  3109.     ngx_conf_merge_sec_value(conf->open_file_cache_valid,
  3110.                               prev->open_file_cache_valid, 60);

  3111.     ngx_conf_merge_uint_value(conf->open_file_cache_min_uses,
  3112.                               prev->open_file_cache_min_uses, 1);

  3113.     ngx_conf_merge_sec_value(conf->open_file_cache_errors,
  3114.                               prev->open_file_cache_errors, 0);

  3115.     ngx_conf_merge_sec_value(conf->open_file_cache_events,
  3116.                               prev->open_file_cache_events, 0);
  3117. #if (NGX_HTTP_GZIP)

  3118.     ngx_conf_merge_value(conf->gzip_vary, prev->gzip_vary, 0);
  3119.     ngx_conf_merge_uint_value(conf->gzip_http_version, prev->gzip_http_version,
  3120.                               NGX_HTTP_VERSION_11);
  3121.     ngx_conf_merge_bitmask_value(conf->gzip_proxied, prev->gzip_proxied,
  3122.                               (NGX_CONF_BITMASK_SET|NGX_HTTP_GZIP_PROXIED_OFF));

  3123. #if (NGX_PCRE)
  3124.     ngx_conf_merge_ptr_value(conf->gzip_disable, prev->gzip_disable, NULL);
  3125. #endif

  3126.     if (conf->gzip_disable_msie6 == 3) {
  3127.         conf->gzip_disable_msie6 =
  3128.             (prev->gzip_disable_msie6 == 3) ? 0 : prev->gzip_disable_msie6;
  3129.     }

  3130. #if (NGX_HTTP_DEGRADATION)

  3131.     if (conf->gzip_disable_degradation == 3) {
  3132.         conf->gzip_disable_degradation =
  3133.             (prev->gzip_disable_degradation == 3) ?
  3134.                  0 : prev->gzip_disable_degradation;
  3135.     }

  3136. #endif
  3137. #endif

  3138. #if (NGX_HAVE_OPENAT)
  3139.     ngx_conf_merge_uint_value(conf->disable_symlinks, prev->disable_symlinks,
  3140.                               NGX_DISABLE_SYMLINKS_OFF);
  3141.     ngx_conf_merge_ptr_value(conf->disable_symlinks_from,
  3142.                              prev->disable_symlinks_from, NULL);
  3143. #endif

  3144.     return NGX_CONF_OK;
  3145. }


  3146. static char *
  3147. ‌ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3148. {
  3149.     ngx_http_core_srv_conf_t *cscf = conf;

  3150.     ngx_str_t              *value, size;
  3151.     ngx_url_t               u;
  3152.     ngx_uint_t              n, i, backlog;
  3153.     ngx_http_listen_opt_t   lsopt;

  3154.     cscf->listen = 1;

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

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

  3157.     u.url = value[1];
  3158.     u.listen = 1;
  3159.     u.default_port = 80;

  3160.     if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
  3161.         if (u.err) {
  3162.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3163.                                "%s in \"%V\" of the \"listen\" directive",
  3164.                                u.err, &u.url);
  3165.         }

  3166.         return NGX_CONF_ERROR;
  3167.     }

  3168.     ngx_memzero(&lsopt, sizeof(ngx_http_listen_opt_t));

  3169.     lsopt.backlog = NGX_LISTEN_BACKLOG;
  3170.     lsopt.type = SOCK_STREAM;
  3171.     lsopt.rcvbuf = -1;
  3172.     lsopt.sndbuf = -1;
  3173. #if (NGX_HAVE_SETFIB)
  3174.     lsopt.setfib = -1;
  3175. #endif
  3176. #if (NGX_HAVE_TCP_FASTOPEN)
  3177.     lsopt.fastopen = -1;
  3178. #endif
  3179. #if (NGX_HAVE_INET6)
  3180.     lsopt.ipv6only = 1;
  3181. #endif

  3182.     backlog = 0;

  3183.     for (n = 2; n < cf->args->nelts; n++) {

  3184.         if (ngx_strcmp(value[n].data, "default_server") == 0
  3185.             || ngx_strcmp(value[n].data, "default") == 0)
  3186.         {
  3187.             lsopt.default_server = 1;
  3188.             continue;
  3189.         }

  3190.         if (ngx_strcmp(value[n].data, "bind") == 0) {
  3191.             lsopt.set = 1;
  3192.             lsopt.bind = 1;
  3193.             continue;
  3194.         }

  3195. #if (NGX_HAVE_SETFIB)
  3196.         if (ngx_strncmp(value[n].data, "setfib=", 7) == 0) {
  3197.             lsopt.setfib = ngx_atoi(value[n].data + 7, value[n].len - 7);
  3198.             lsopt.set = 1;
  3199.             lsopt.bind = 1;

  3200.             if (lsopt.setfib == NGX_ERROR) {
  3201.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3202.                                    "invalid setfib \"%V\"", &value[n]);
  3203.                 return NGX_CONF_ERROR;
  3204.             }

  3205.             continue;
  3206.         }
  3207. #endif

  3208. #if (NGX_HAVE_TCP_FASTOPEN)
  3209.         if (ngx_strncmp(value[n].data, "fastopen=", 9) == 0) {
  3210.             lsopt.fastopen = ngx_atoi(value[n].data + 9, value[n].len - 9);
  3211.             lsopt.set = 1;
  3212.             lsopt.bind = 1;

  3213.             if (lsopt.fastopen == NGX_ERROR) {
  3214.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3215.                                    "invalid fastopen \"%V\"", &value[n]);
  3216.                 return NGX_CONF_ERROR;
  3217.             }

  3218.             continue;
  3219.         }
  3220. #endif

  3221.         if (ngx_strncmp(value[n].data, "backlog=", 8) == 0) {
  3222.             lsopt.backlog = ngx_atoi(value[n].data + 8, value[n].len - 8);
  3223.             lsopt.set = 1;
  3224.             lsopt.bind = 1;

  3225.             if (lsopt.backlog == NGX_ERROR || lsopt.backlog == 0) {
  3226.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3227.                                    "invalid backlog \"%V\"", &value[n]);
  3228.                 return NGX_CONF_ERROR;
  3229.             }

  3230.             backlog = 1;

  3231.             continue;
  3232.         }

  3233.         if (ngx_strncmp(value[n].data, "rcvbuf=", 7) == 0) {
  3234.             size.len = value[n].len - 7;
  3235.             size.data = value[n].data + 7;

  3236.             lsopt.rcvbuf = ngx_parse_size(&size);
  3237.             lsopt.set = 1;
  3238.             lsopt.bind = 1;

  3239.             if (lsopt.rcvbuf == NGX_ERROR) {
  3240.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3241.                                    "invalid rcvbuf \"%V\"", &value[n]);
  3242.                 return NGX_CONF_ERROR;
  3243.             }

  3244.             continue;
  3245.         }

  3246.         if (ngx_strncmp(value[n].data, "sndbuf=", 7) == 0) {
  3247.             size.len = value[n].len - 7;
  3248.             size.data = value[n].data + 7;

  3249.             lsopt.sndbuf = ngx_parse_size(&size);
  3250.             lsopt.set = 1;
  3251.             lsopt.bind = 1;

  3252.             if (lsopt.sndbuf == NGX_ERROR) {
  3253.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3254.                                    "invalid sndbuf \"%V\"", &value[n]);
  3255.                 return NGX_CONF_ERROR;
  3256.             }

  3257.             continue;
  3258.         }

  3259.         if (ngx_strncmp(value[n].data, "accept_filter=", 14) == 0) {
  3260. #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
  3261.             lsopt.accept_filter = (char *) &value[n].data[14];
  3262.             lsopt.set = 1;
  3263.             lsopt.bind = 1;
  3264. #else
  3265.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3266.                                "accept filters \"%V\" are not supported "
  3267.                                "on this platform, ignored",
  3268.                                &value[n]);
  3269. #endif
  3270.             continue;
  3271.         }

  3272.         if (ngx_strcmp(value[n].data, "deferred") == 0) {
  3273. #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
  3274.             lsopt.deferred_accept = 1;
  3275.             lsopt.set = 1;
  3276.             lsopt.bind = 1;
  3277. #else
  3278.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3279.                                "the deferred accept is not supported "
  3280.                                "on this platform, ignored");
  3281. #endif
  3282.             continue;
  3283.         }

  3284.         if (ngx_strncmp(value[n].data, "ipv6only=o", 10) == 0) {
  3285. #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
  3286.             if (ngx_strcmp(&value[n].data[10], "n") == 0) {
  3287.                 lsopt.ipv6only = 1;

  3288.             } else if (ngx_strcmp(&value[n].data[10], "ff") == 0) {
  3289.                 lsopt.ipv6only = 0;

  3290.             } else {
  3291.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3292.                                    "invalid ipv6only flags \"%s\"",
  3293.                                    &value[n].data[9]);
  3294.                 return NGX_CONF_ERROR;
  3295.             }

  3296.             lsopt.set = 1;
  3297.             lsopt.bind = 1;

  3298.             continue;
  3299. #else
  3300.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3301.                                "ipv6only is not supported "
  3302.                                "on this platform");
  3303.             return NGX_CONF_ERROR;
  3304. #endif
  3305.         }

  3306.         if (ngx_strcmp(value[n].data, "reuseport") == 0) {
  3307. #if (NGX_HAVE_REUSEPORT)
  3308.             lsopt.reuseport = 1;
  3309.             lsopt.set = 1;
  3310.             lsopt.bind = 1;
  3311. #else
  3312.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3313.                                "reuseport is not supported "
  3314.                                "on this platform, ignored");
  3315. #endif
  3316.             continue;
  3317.         }

  3318.         if (ngx_strcmp(value[n].data, "multipath") == 0) {
  3319. #ifdef IPPROTO_MPTCP
  3320.             lsopt.protocol = IPPROTO_MPTCP;
  3321.             lsopt.set = 1;
  3322.             lsopt.bind = 1;
  3323. #else
  3324.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3325.                                "multipath is not supported "
  3326.                                "on this platform, ignored");
  3327. #endif
  3328.             continue;
  3329.         }

  3330.         if (ngx_strcmp(value[n].data, "ssl") == 0) {
  3331. #if (NGX_HTTP_SSL)
  3332.             lsopt.ssl = 1;
  3333.             continue;
  3334. #else
  3335.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3336.                                "the \"ssl\" parameter requires "
  3337.                                "ngx_http_ssl_module");
  3338.             return NGX_CONF_ERROR;
  3339. #endif
  3340.         }

  3341.         if (ngx_strcmp(value[n].data, "http2") == 0) {
  3342. #if (NGX_HTTP_V2)
  3343.             ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
  3344.                                "the \"listen ... http2\" directive "
  3345.                                "is deprecated, use "
  3346.                                "the \"http2\" directive instead");

  3347.             lsopt.http2 = 1;
  3348.             continue;
  3349. #else
  3350.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3351.                                "the \"http2\" parameter requires "
  3352.                                "ngx_http_v2_module");
  3353.             return NGX_CONF_ERROR;
  3354. #endif
  3355.         }

  3356.         if (ngx_strcmp(value[n].data, "quic") == 0) {
  3357. #if (NGX_HTTP_V3)
  3358.             lsopt.quic = 1;
  3359.             lsopt.type = SOCK_DGRAM;
  3360.             continue;
  3361. #else
  3362.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3363.                                "the \"quic\" parameter requires "
  3364.                                "ngx_http_v3_module");
  3365.             return NGX_CONF_ERROR;
  3366. #endif
  3367.         }

  3368.         if (ngx_strncmp(value[n].data, "so_keepalive=", 13) == 0) {

  3369.             if (ngx_strcmp(&value[n].data[13], "on") == 0) {
  3370.                 lsopt.so_keepalive = 1;

  3371.             } else if (ngx_strcmp(&value[n].data[13], "off") == 0) {
  3372.                 lsopt.so_keepalive = 2;

  3373.             } else {

  3374. #if (NGX_HAVE_KEEPALIVE_TUNABLE)
  3375.                 u_char     *p, *end;
  3376.                 ngx_str_t   s;

  3377.                 end = value[n].data + value[n].len;
  3378.                 s.data = value[n].data + 13;

  3379.                 p = ngx_strlchr(s.data, end, ':');
  3380.                 if (p == NULL) {
  3381.                     p = end;
  3382.                 }

  3383.                 if (p > s.data) {
  3384.                     s.len = p - s.data;

  3385.                     lsopt.tcp_keepidle = ngx_parse_time(&s, 1);
  3386.                     if (lsopt.tcp_keepidle == (time_t) NGX_ERROR) {
  3387.                         goto invalid_so_keepalive;
  3388.                     }
  3389.                 }

  3390.                 s.data = (p < end) ? (p + 1) : end;

  3391.                 p = ngx_strlchr(s.data, end, ':');
  3392.                 if (p == NULL) {
  3393.                     p = end;
  3394.                 }

  3395.                 if (p > s.data) {
  3396.                     s.len = p - s.data;

  3397.                     lsopt.tcp_keepintvl = ngx_parse_time(&s, 1);
  3398.                     if (lsopt.tcp_keepintvl == (time_t) NGX_ERROR) {
  3399.                         goto invalid_so_keepalive;
  3400.                     }
  3401.                 }

  3402.                 s.data = (p < end) ? (p + 1) : end;

  3403.                 if (s.data < end) {
  3404.                     s.len = end - s.data;

  3405.                     lsopt.tcp_keepcnt = ngx_atoi(s.data, s.len);
  3406.                     if (lsopt.tcp_keepcnt == NGX_ERROR) {
  3407.                         goto invalid_so_keepalive;
  3408.                     }
  3409.                 }

  3410.                 if (lsopt.tcp_keepidle == 0 && lsopt.tcp_keepintvl == 0
  3411.                     && lsopt.tcp_keepcnt == 0)
  3412.                 {
  3413.                     goto invalid_so_keepalive;
  3414.                 }

  3415.                 lsopt.so_keepalive = 1;

  3416. #else

  3417.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3418.                                    "the \"so_keepalive\" parameter accepts "
  3419.                                    "only \"on\" or \"off\" on this platform");
  3420.                 return NGX_CONF_ERROR;

  3421. #endif
  3422.             }

  3423.             lsopt.set = 1;
  3424.             lsopt.bind = 1;

  3425.             continue;

  3426. #if (NGX_HAVE_KEEPALIVE_TUNABLE)
  3427.         invalid_so_keepalive:

  3428.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3429.                                "invalid so_keepalive value: \"%s\"",
  3430.                                &value[n].data[13]);
  3431.             return NGX_CONF_ERROR;
  3432. #endif
  3433.         }

  3434.         if (ngx_strcmp(value[n].data, "proxy_protocol") == 0) {
  3435.             lsopt.proxy_protocol = 1;
  3436.             continue;
  3437.         }

  3438.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3439.                            "invalid parameter \"%V\"", &value[n]);
  3440.         return NGX_CONF_ERROR;
  3441.     }

  3442.     if (lsopt.quic) {
  3443. #if (NGX_HAVE_TCP_FASTOPEN)
  3444.         if (lsopt.fastopen != -1) {
  3445.             return "\"fastopen\" parameter is incompatible with \"quic\"";
  3446.         }
  3447. #endif

  3448.         if (backlog) {
  3449.             return "\"backlog\" parameter is incompatible with \"quic\"";
  3450.         }

  3451. #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
  3452.         if (lsopt.accept_filter) {
  3453.             return "\"accept_filter\" parameter is incompatible with \"quic\"";
  3454.         }
  3455. #endif

  3456. #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
  3457.         if (lsopt.deferred_accept) {
  3458.             return "\"deferred\" parameter is incompatible with \"quic\"";
  3459.         }
  3460. #endif

  3461. #ifdef IPPROTO_MPTCP
  3462.         if (lsopt.protocol == IPPROTO_MPTCP) {
  3463.              return "\"multipath\" parameter is incompatible with \"quic\"";
  3464.         }
  3465. #endif

  3466. #if (NGX_HTTP_SSL)
  3467.         if (lsopt.ssl) {
  3468.             return "\"ssl\" parameter is incompatible with \"quic\"";
  3469.         }
  3470. #endif

  3471. #if (NGX_HTTP_V2)
  3472.         if (lsopt.http2) {
  3473.             return "\"http2\" parameter is incompatible with \"quic\"";
  3474.         }
  3475. #endif

  3476.         if (lsopt.so_keepalive) {
  3477.             return "\"so_keepalive\" parameter is incompatible with \"quic\"";
  3478.         }

  3479.         if (lsopt.proxy_protocol) {
  3480.             return "\"proxy_protocol\" parameter is incompatible with \"quic\"";
  3481.         }
  3482.     }

  3483.     for (n = 0; n < u.naddrs; n++) {

  3484.         for (i = 0; i < n; i++) {
  3485.             if (ngx_cmp_sockaddr(u.addrs[n].sockaddr, u.addrs[n].socklen,
  3486.                                  u.addrs[i].sockaddr, u.addrs[i].socklen, 1)
  3487.                 == NGX_OK)
  3488.             {
  3489.                 goto next;
  3490.             }
  3491.         }

  3492.         lsopt.sockaddr = u.addrs[n].sockaddr;
  3493.         lsopt.socklen = u.addrs[n].socklen;
  3494.         lsopt.addr_text = u.addrs[n].name;
  3495.         lsopt.wildcard = ngx_inet_wildcard(lsopt.sockaddr);

  3496.         if (ngx_http_add_listen(cf, cscf, &lsopt) != NGX_OK) {
  3497.             return NGX_CONF_ERROR;
  3498.         }

  3499.     next:
  3500.         continue;
  3501.     }

  3502.     return NGX_CONF_OK;
  3503. }


  3504. static char *
  3505. ‌ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3506. {
  3507.     ngx_http_core_srv_conf_t *cscf = conf;

  3508.     u_char                   ch;
  3509.     ngx_str_t               *value;
  3510.     ngx_uint_t               i;
  3511.     ngx_http_server_name_t  *sn;

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

  3513.     for (i = 1; i < cf->args->nelts; i++) {

  3514.         ch = value[i].data[0];

  3515.         if ((ch == '*' && (value[i].len < 3 || value[i].data[1] != '.'))
  3516.             || (ch == '.' && value[i].len < 2))
  3517.         {
  3518.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3519.                                "server name \"%V\" is invalid", &value[i]);
  3520.             return NGX_CONF_ERROR;
  3521.         }

  3522.         if (ngx_strchr(value[i].data, '/')) {
  3523.             ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
  3524.                                "server name \"%V\" has suspicious symbols",
  3525.                                &value[i]);
  3526.         }

  3527.         sn = ngx_array_push(&cscf->server_names);
  3528.         if (sn == NULL) {
  3529.             return NGX_CONF_ERROR;
  3530.         }

  3531. #if (NGX_PCRE)
  3532.         sn->regex = NULL;
  3533. #endif
  3534.         sn->server = cscf;

  3535.         if (ngx_strcasecmp(value[i].data, (u_char *) "$hostname") == 0) {
  3536.             sn->name = cf->cycle->hostname;

  3537.         } else {
  3538.             sn->name = value[i];
  3539.         }

  3540.         if (value[i].data[0] != '~') {
  3541.             ngx_strlow(sn->name.data, sn->name.data, sn->name.len);
  3542.             continue;
  3543.         }

  3544. #if (NGX_PCRE)
  3545.         {
  3546.         u_char               *p;
  3547.         ngx_regex_compile_t   rc;
  3548.         u_char                errstr[NGX_MAX_CONF_ERRSTR];

  3549.         if (value[i].len == 1) {
  3550.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3551.                                "empty regex in server name \"%V\"", &value[i]);
  3552.             return NGX_CONF_ERROR;
  3553.         }

  3554.         value[i].len--;
  3555.         value[i].data++;

  3556.         ngx_memzero(&rc, sizeof(ngx_regex_compile_t));

  3557.         rc.pattern = value[i];
  3558.         rc.err.len = NGX_MAX_CONF_ERRSTR;
  3559.         rc.err.data = errstr;

  3560.         for (p = value[i].data; p < value[i].data + value[i].len; p++) {
  3561.             if (*p >= 'A' && *p <= 'Z') {
  3562.                 rc.options = NGX_REGEX_CASELESS;
  3563.                 break;
  3564.             }
  3565.         }

  3566.         sn->regex = ngx_http_regex_compile(cf, &rc);
  3567.         if (sn->regex == NULL) {
  3568.             return NGX_CONF_ERROR;
  3569.         }

  3570.         sn->name = value[i];
  3571.         cscf->captures = (rc.captures > 0);
  3572.         }
  3573. #else
  3574.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3575.                            "using regex \"%V\" "
  3576.                            "requires PCRE library", &value[i]);

  3577.         return NGX_CONF_ERROR;
  3578. #endif
  3579.     }

  3580.     return NGX_CONF_OK;
  3581. }


  3582. static char *
  3583. ‌ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3584. {
  3585.     ngx_http_core_loc_conf_t *clcf = conf;

  3586.     ngx_str_t                  *value;
  3587.     ngx_int_t                   alias;
  3588.     ngx_uint_t                  n;
  3589.     ngx_http_script_compile_t   sc;

  3590.     alias = (cmd->name.len == sizeof("alias") - 1) ? 1 : 0;

  3591.     if (clcf->root.data) {

  3592.         if ((clcf->alias != 0) == alias) {
  3593.             return "is duplicate";
  3594.         }

  3595.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3596.                            "\"%V\" directive is duplicate, "
  3597.                            "\"%s\" directive was specified earlier",
  3598.                            &cmd->name, clcf->alias ? "alias" : "root");

  3599.         return NGX_CONF_ERROR;
  3600.     }

  3601.     if (clcf->named && alias) {
  3602.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3603.                            "the \"alias\" directive cannot be used "
  3604.                            "inside the named location");

  3605.         return NGX_CONF_ERROR;
  3606.     }

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

  3608.     if (ngx_strstr(value[1].data, "$document_root")
  3609.         || ngx_strstr(value[1].data, "${document_root}"))
  3610.     {
  3611.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3612.                            "the $document_root variable cannot be used "
  3613.                            "in the \"%V\" directive",
  3614.                            &cmd->name);

  3615.         return NGX_CONF_ERROR;
  3616.     }

  3617.     if (ngx_strstr(value[1].data, "$realpath_root")
  3618.         || ngx_strstr(value[1].data, "${realpath_root}"))
  3619.     {
  3620.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3621.                            "the $realpath_root variable cannot be used "
  3622.                            "in the \"%V\" directive",
  3623.                            &cmd->name);

  3624.         return NGX_CONF_ERROR;
  3625.     }

  3626.     clcf->alias = alias ? clcf->name.len : 0;
  3627.     clcf->root = value[1];

  3628.     if (!alias && clcf->root.len > 0
  3629.         && clcf->root.data[clcf->root.len - 1] == '/')
  3630.     {
  3631.         clcf->root.len--;
  3632.     }

  3633.     if (clcf->root.data[0] != '$') {
  3634.         if (ngx_conf_full_name(cf->cycle, &clcf->root, 0) != NGX_OK) {
  3635.             return NGX_CONF_ERROR;
  3636.         }
  3637.     }

  3638.     n = ngx_http_script_variables_count(&clcf->root);

  3639.     ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
  3640.     sc.variables = n;

  3641.     if (alias
  3642.         && (clcf->predicate
  3643. #if (NGX_PCRE)
  3644.             || clcf->regex
  3645. #endif
  3646.            ))
  3647.     {
  3648.         clcf->alias = NGX_MAX_SIZE_T_VALUE;
  3649.         n = 1;
  3650.     }

  3651.     if (n) {
  3652.         sc.cf = cf;
  3653.         sc.source = &clcf->root;
  3654.         sc.lengths = &clcf->root_lengths;
  3655.         sc.values = &clcf->root_values;
  3656.         sc.complete_lengths = 1;
  3657.         sc.complete_values = 1;

  3658.         if (ngx_http_script_compile(&sc) != NGX_OK) {
  3659.             return NGX_CONF_ERROR;
  3660.         }
  3661.     }

  3662.     return NGX_CONF_OK;
  3663. }


  3664. ‌static ngx_http_method_name_t  ngx_methods_names[] = {
  3665.     { (u_char *) "GET",       (uint32_t) ~NGX_HTTP_GET },
  3666.     { (u_char *) "HEAD",      (uint32_t) ~NGX_HTTP_HEAD },
  3667.     { (u_char *) "POST",      (uint32_t) ~NGX_HTTP_POST },
  3668.     { (u_char *) "PUT",       (uint32_t) ~NGX_HTTP_PUT },
  3669.     { (u_char *) "DELETE",    (uint32_t) ~NGX_HTTP_DELETE },
  3670.     { (u_char *) "MKCOL",     (uint32_t) ~NGX_HTTP_MKCOL },
  3671.     { (u_char *) "COPY",      (uint32_t) ~NGX_HTTP_COPY },
  3672.     { (u_char *) "MOVE",      (uint32_t) ~NGX_HTTP_MOVE },
  3673.     { (u_char *) "OPTIONS",   (uint32_t) ~NGX_HTTP_OPTIONS },
  3674.     { (u_char *) "PROPFIND",  (uint32_t) ~NGX_HTTP_PROPFIND },
  3675.     { (u_char *) "PROPPATCH", (uint32_t) ~NGX_HTTP_PROPPATCH },
  3676.     { (u_char *) "LOCK",      (uint32_t) ~NGX_HTTP_LOCK },
  3677.     { (u_char *) "UNLOCK",    (uint32_t) ~NGX_HTTP_UNLOCK },
  3678.     { (u_char *) "PATCH",     (uint32_t) ~NGX_HTTP_PATCH },
  3679.     { NULL, 0 }
  3680. };


  3681. static char *
  3682. ‌ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3683. {
  3684.     ngx_http_core_loc_conf_t *pclcf = conf;

  3685.     char                      *rv;
  3686.     void                      *mconf;
  3687.     ngx_str_t                 *value;
  3688.     ngx_uint_t                 i;
  3689.     ngx_conf_t                 save;
  3690.     ngx_http_module_t         *module;
  3691.     ngx_http_conf_ctx_t       *ctx, *pctx;
  3692.     ngx_http_method_name_t    *name;
  3693.     ngx_http_core_loc_conf_t  *clcf;

  3694.     if (pclcf->limit_except) {
  3695.         return "is duplicate";
  3696.     }

  3697.     pclcf->limit_except = 0xffffffff;

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

  3699.     for (i = 1; i < cf->args->nelts; i++) {
  3700.         for (name = ngx_methods_names; name->name; name++) {

  3701.             if (ngx_strcasecmp(value[i].data, name->name) == 0) {
  3702.                 pclcf->limit_except &= name->method;
  3703.                 goto next;
  3704.             }
  3705.         }

  3706.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3707.                            "invalid method \"%V\"", &value[i]);
  3708.         return NGX_CONF_ERROR;

  3709.     next:
  3710.         continue;
  3711.     }

  3712.     if (!(pclcf->limit_except & NGX_HTTP_GET)) {
  3713.         pclcf->limit_except &= (uint32_t) ~NGX_HTTP_HEAD;
  3714.     }

  3715.     ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
  3716.     if (ctx == NULL) {
  3717.         return NGX_CONF_ERROR;
  3718.     }

  3719.     pctx = cf->ctx;
  3720.     ctx->main_conf = pctx->main_conf;
  3721.     ctx->srv_conf = pctx->srv_conf;

  3722.     ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
  3723.     if (ctx->loc_conf == NULL) {
  3724.         return NGX_CONF_ERROR;
  3725.     }

  3726.     for (i = 0; cf->cycle->modules[i]; i++) {
  3727.         if (cf->cycle->modules[i]->type != NGX_HTTP_MODULE) {
  3728.             continue;
  3729.         }

  3730.         module = cf->cycle->modules[i]->ctx;

  3731.         if (module->create_loc_conf) {

  3732.             mconf = module->create_loc_conf(cf);
  3733.             if (mconf == NULL) {
  3734.                 return NGX_CONF_ERROR;
  3735.             }

  3736.             ctx->loc_conf[cf->cycle->modules[i]->ctx_index] = mconf;
  3737.         }
  3738.     }


  3739.     clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
  3740.     pclcf->limit_except_loc_conf = ctx->loc_conf;
  3741.     clcf->loc_conf = ctx->loc_conf;
  3742.     clcf->name = pclcf->name;
  3743.     clcf->noname = 1;
  3744.     clcf->lmt_excpt = 1;

  3745.     if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) {
  3746.         return NGX_CONF_ERROR;
  3747.     }

  3748.     save = *cf;
  3749.     cf->ctx = ctx;
  3750.     cf->cmd_type = NGX_HTTP_LMT_CONF;

  3751.     rv = ngx_conf_parse(cf, NULL);

  3752.     *cf = save;

  3753.     return rv;
  3754. }


  3755. static char *
  3756. ‌ngx_http_core_set_aio(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3757. {
  3758.     ngx_http_core_loc_conf_t *clcf = conf;

  3759.     ngx_str_t  *value;

  3760.     if (clcf->aio != NGX_CONF_UNSET) {
  3761.         return "is duplicate";
  3762.     }

  3763. #if (NGX_THREADS)
  3764.     clcf->thread_pool = NULL;
  3765.     clcf->thread_pool_value = NULL;
  3766. #endif

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

  3768.     if (ngx_strcmp(value[1].data, "off") == 0) {
  3769.         clcf->aio = NGX_HTTP_AIO_OFF;
  3770.         return NGX_CONF_OK;
  3771.     }

  3772.     if (ngx_strcmp(value[1].data, "on") == 0) {
  3773. #if (NGX_HAVE_FILE_AIO)
  3774.         clcf->aio = NGX_HTTP_AIO_ON;
  3775.         return NGX_CONF_OK;
  3776. #else
  3777.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3778.                            "\"aio on\" "
  3779.                            "is unsupported on this platform");
  3780.         return NGX_CONF_ERROR;
  3781. #endif
  3782.     }

  3783.     if (ngx_strncmp(value[1].data, "threads", 7) == 0
  3784.         && (value[1].len == 7 || value[1].data[7] == '='))
  3785.     {
  3786. #if (NGX_THREADS)
  3787.         ngx_str_t                          name;
  3788.         ngx_thread_pool_t                 *tp;
  3789.         ngx_http_complex_value_t           cv;
  3790.         ngx_http_compile_complex_value_t   ccv;

  3791.         clcf->aio = NGX_HTTP_AIO_THREADS;

  3792.         if (value[1].len >= 8) {
  3793.             name.len = value[1].len - 8;
  3794.             name.data = value[1].data + 8;

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

  3796.             ccv.cf = cf;
  3797.             ccv.value = &name;
  3798.             ccv.complex_value = &cv;

  3799.             if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
  3800.                 return NGX_CONF_ERROR;
  3801.             }

  3802.             if (cv.lengths != NULL) {
  3803.                 clcf->thread_pool_value = ngx_palloc(cf->pool,
  3804.                                     sizeof(ngx_http_complex_value_t));
  3805.                 if (clcf->thread_pool_value == NULL) {
  3806.                     return NGX_CONF_ERROR;
  3807.                 }

  3808.                 *clcf->thread_pool_value = cv;

  3809.                 return NGX_CONF_OK;
  3810.             }

  3811.             tp = ngx_thread_pool_add(cf, &name);

  3812.         } else {
  3813.             tp = ngx_thread_pool_add(cf, NULL);
  3814.         }

  3815.         if (tp == NULL) {
  3816.             return NGX_CONF_ERROR;
  3817.         }

  3818.         clcf->thread_pool = tp;

  3819.         return NGX_CONF_OK;
  3820. #else
  3821.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3822.                            "\"aio threads\" "
  3823.                            "is unsupported on this platform");
  3824.         return NGX_CONF_ERROR;
  3825. #endif
  3826.     }

  3827.     return "invalid value";
  3828. }


  3829. static char *
  3830. ‌ngx_http_core_directio(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3831. {
  3832.     ngx_http_core_loc_conf_t *clcf = conf;

  3833.     ngx_str_t  *value;

  3834.     if (clcf->directio != NGX_CONF_UNSET) {
  3835.         return "is duplicate";
  3836.     }

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

  3838.     if (ngx_strcmp(value[1].data, "off") == 0) {
  3839.         clcf->directio = NGX_OPEN_FILE_DIRECTIO_OFF;
  3840.         return NGX_CONF_OK;
  3841.     }

  3842.     clcf->directio = ngx_parse_offset(&value[1]);
  3843.     if (clcf->directio == (off_t) NGX_ERROR) {
  3844.         return "invalid value";
  3845.     }

  3846.     return NGX_CONF_OK;
  3847. }


  3848. static char *
  3849. ‌ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3850. {
  3851.     ngx_http_core_loc_conf_t *clcf = conf;

  3852.     u_char                            *p;
  3853.     ngx_int_t                          overwrite;
  3854.     ngx_str_t                         *value, uri, args;
  3855.     ngx_uint_t                         i, n;
  3856.     ngx_http_err_page_t               *err;
  3857.     ngx_http_complex_value_t           cv;
  3858.     ngx_http_compile_complex_value_t   ccv;

  3859.     if (clcf->error_pages == NULL) {
  3860.         clcf->error_pages = ngx_array_create(cf->pool, 4,
  3861.                                              sizeof(ngx_http_err_page_t));
  3862.         if (clcf->error_pages == NULL) {
  3863.             return NGX_CONF_ERROR;
  3864.         }
  3865.     }

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

  3867.     i = cf->args->nelts - 2;

  3868.     if (value[i].data[0] == '=') {
  3869.         if (i == 1) {
  3870.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3871.                                "invalid value \"%V\"", &value[i]);
  3872.             return NGX_CONF_ERROR;
  3873.         }

  3874.         if (value[i].len > 1) {
  3875.             overwrite = ngx_atoi(&value[i].data[1], value[i].len - 1);

  3876.             if (overwrite == NGX_ERROR) {
  3877.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3878.                                    "invalid value \"%V\"", &value[i]);
  3879.                 return NGX_CONF_ERROR;
  3880.             }

  3881.         } else {
  3882.             overwrite = 0;
  3883.         }

  3884.         n = 2;

  3885.     } else {
  3886.         overwrite = -1;
  3887.         n = 1;
  3888.     }

  3889.     uri = value[cf->args->nelts - 1];

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

  3891.     ccv.cf = cf;
  3892.     ccv.value = &uri;
  3893.     ccv.complex_value = &cv;

  3894.     if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
  3895.         return NGX_CONF_ERROR;
  3896.     }

  3897.     ngx_str_null(&args);

  3898.     if (cv.lengths == NULL && uri.len && uri.data[0] == '/') {
  3899.         p = (u_char *) ngx_strchr(uri.data, '?');

  3900.         if (p) {
  3901.             cv.value.len = p - uri.data;
  3902.             cv.value.data = uri.data;
  3903.             p++;
  3904.             args.len = (uri.data + uri.len) - p;
  3905.             args.data = p;
  3906.         }
  3907.     }

  3908.     for (i = 1; i < cf->args->nelts - n; i++) {
  3909.         err = ngx_array_push(clcf->error_pages);
  3910.         if (err == NULL) {
  3911.             return NGX_CONF_ERROR;
  3912.         }

  3913.         err->status = ngx_atoi(value[i].data, value[i].len);

  3914.         if (err->status == NGX_ERROR || err->status == 499) {
  3915.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3916.                                "invalid value \"%V\"", &value[i]);
  3917.             return NGX_CONF_ERROR;
  3918.         }

  3919.         if (err->status < 300 || err->status > 599) {
  3920.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3921.                                "value \"%V\" must be between 300 and 599",
  3922.                                &value[i]);
  3923.             return NGX_CONF_ERROR;
  3924.         }

  3925.         err->overwrite = overwrite;

  3926.         if (overwrite == -1) {
  3927.             switch (err->status) {
  3928.                 case NGX_HTTP_TO_HTTPS:
  3929.                 case NGX_HTTPS_CERT_ERROR:
  3930.                 case NGX_HTTPS_NO_CERT:
  3931.                 case NGX_HTTP_REQUEST_HEADER_TOO_LARGE:
  3932.                     err->overwrite = NGX_HTTP_BAD_REQUEST;
  3933.             }
  3934.         }

  3935.         err->value = cv;
  3936.         err->args = args;
  3937.     }

  3938.     return NGX_CONF_OK;
  3939. }


  3940. static char *
  3941. ‌ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3942. {
  3943.     ngx_http_core_loc_conf_t *clcf = conf;

  3944.     time_t       inactive;
  3945.     ngx_str_t   *value, s;
  3946.     ngx_int_t    max;
  3947.     ngx_uint_t   i;

  3948.     if (clcf->open_file_cache != NGX_CONF_UNSET_PTR) {
  3949.         return "is duplicate";
  3950.     }

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

  3952.     max = 0;
  3953.     inactive = 60;

  3954.     for (i = 1; i < cf->args->nelts; i++) {

  3955.         if (ngx_strncmp(value[i].data, "max=", 4) == 0) {

  3956.             max = ngx_atoi(value[i].data + 4, value[i].len - 4);
  3957.             if (max <= 0) {
  3958.                 goto failed;
  3959.             }

  3960.             continue;
  3961.         }

  3962.         if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) {

  3963.             s.len = value[i].len - 9;
  3964.             s.data = value[i].data + 9;

  3965.             inactive = ngx_parse_time(&s, 1);
  3966.             if (inactive == (time_t) NGX_ERROR) {
  3967.                 goto failed;
  3968.             }

  3969.             continue;
  3970.         }

  3971.         if (ngx_strcmp(value[i].data, "off") == 0) {

  3972.             clcf->open_file_cache = NULL;

  3973.             continue;
  3974.         }

  3975.     failed:

  3976.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3977.                            "invalid \"open_file_cache\" parameter \"%V\"",
  3978.                            &value[i]);
  3979.         return NGX_CONF_ERROR;
  3980.     }

  3981.     if (clcf->open_file_cache == NULL) {
  3982.         return NGX_CONF_OK;
  3983.     }

  3984.     if (max == 0) {
  3985.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3986.                         "\"open_file_cache\" must have the \"max\" parameter");
  3987.         return NGX_CONF_ERROR;
  3988.     }

  3989.     clcf->open_file_cache = ngx_open_file_cache_init(cf->pool, max, inactive);
  3990.     if (clcf->open_file_cache) {
  3991.         return NGX_CONF_OK;
  3992.     }

  3993.     return NGX_CONF_ERROR;
  3994. }


  3995. static char *
  3996. ‌ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3997. {
  3998.     ngx_http_core_loc_conf_t *clcf = conf;

  3999.     return ngx_log_set_log(cf, &clcf->error_log);
  4000. }


  4001. static char *
  4002. ‌ngx_http_core_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  4003. {
  4004.     ngx_http_core_loc_conf_t *clcf = conf;

  4005.     ngx_str_t  *value;

  4006.     if (clcf->keepalive_timeout != NGX_CONF_UNSET_MSEC) {
  4007.         return "is duplicate";
  4008.     }

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

  4010.     clcf->keepalive_timeout = ngx_parse_time(&value[1], 0);

  4011.     if (clcf->keepalive_timeout == (ngx_msec_t) NGX_ERROR) {
  4012.         return "invalid value";
  4013.     }

  4014.     if (cf->args->nelts == 2) {
  4015.         return NGX_CONF_OK;
  4016.     }

  4017.     clcf->keepalive_header = ngx_parse_time(&value[2], 1);

  4018.     if (clcf->keepalive_header == (time_t) NGX_ERROR) {
  4019.         return "invalid value";
  4020.     }

  4021.     return NGX_CONF_OK;
  4022. }


  4023. static char *
  4024. ‌ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  4025. {
  4026.     ngx_http_core_loc_conf_t *clcf = conf;

  4027.     if (clcf->internal != NGX_CONF_UNSET) {
  4028.         return "is duplicate";
  4029.     }

  4030.     clcf->internal = 1;

  4031.     return NGX_CONF_OK;
  4032. }


  4033. static char *
  4034. ‌ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  4035. {
  4036.     ngx_http_core_loc_conf_t  *clcf = conf;

  4037.     ngx_str_t  *value;

  4038.     if (clcf->resolver) {
  4039.         return "is duplicate";
  4040.     }

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

  4042.     clcf->resolver = ngx_resolver_create(cf, &value[1], cf->args->nelts - 1);
  4043.     if (clcf->resolver == NULL) {
  4044.         return NGX_CONF_ERROR;
  4045.     }

  4046.     return NGX_CONF_OK;
  4047. }


  4048. #if (NGX_HTTP_GZIP)

  4049. static char *
  4050. ‌ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  4051. {
  4052.     ngx_http_core_loc_conf_t  *clcf = conf;

  4053. #if (NGX_PCRE)

  4054.     ngx_str_t            *value;
  4055.     ngx_uint_t            i;
  4056.     ngx_regex_elt_t      *re;
  4057.     ngx_regex_compile_t   rc;
  4058.     u_char                errstr[NGX_MAX_CONF_ERRSTR];

  4059.     if (clcf->gzip_disable == NGX_CONF_UNSET_PTR) {
  4060.         clcf->gzip_disable = ngx_array_create(cf->pool, 2,
  4061.                                               sizeof(ngx_regex_elt_t));
  4062.         if (clcf->gzip_disable == NULL) {
  4063.             return NGX_CONF_ERROR;
  4064.         }
  4065.     }

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

  4067.     ngx_memzero(&rc, sizeof(ngx_regex_compile_t));

  4068.     rc.pool = cf->pool;
  4069.     rc.err.len = NGX_MAX_CONF_ERRSTR;
  4070.     rc.err.data = errstr;

  4071.     for (i = 1; i < cf->args->nelts; i++) {

  4072.         if (ngx_strcmp(value[i].data, "msie6") == 0) {
  4073.             clcf->gzip_disable_msie6 = 1;
  4074.             continue;
  4075.         }

  4076. #if (NGX_HTTP_DEGRADATION)

  4077.         if (ngx_strcmp(value[i].data, "degradation") == 0) {
  4078.             clcf->gzip_disable_degradation = 1;
  4079.             continue;
  4080.         }

  4081. #endif

  4082.         re = ngx_array_push(clcf->gzip_disable);
  4083.         if (re == NULL) {
  4084.             return NGX_CONF_ERROR;
  4085.         }

  4086.         rc.pattern = value[i];
  4087.         rc.options = NGX_REGEX_CASELESS;

  4088.         if (ngx_regex_compile(&rc) != NGX_OK) {
  4089.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc.err);
  4090.             return NGX_CONF_ERROR;
  4091.         }

  4092.         re->regex = rc.regex;
  4093.         re->name = value[i].data;
  4094.     }

  4095.     return NGX_CONF_OK;

  4096. #else
  4097.     ngx_str_t   *value;
  4098.     ngx_uint_t   i;

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

  4100.     for (i = 1; i < cf->args->nelts; i++) {
  4101.         if (ngx_strcmp(value[i].data, "msie6") == 0) {
  4102.             clcf->gzip_disable_msie6 = 1;
  4103.             continue;
  4104.         }

  4105. #if (NGX_HTTP_DEGRADATION)

  4106.         if (ngx_strcmp(value[i].data, "degradation") == 0) {
  4107.             clcf->gzip_disable_degradation = 1;
  4108.             continue;
  4109.         }

  4110. #endif

  4111.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  4112.                            "without PCRE library \"gzip_disable\" supports "
  4113.                            "builtin \"msie6\" and \"degradation\" mask only");

  4114.         return NGX_CONF_ERROR;
  4115.     }

  4116.     return NGX_CONF_OK;

  4117. #endif
  4118. }

  4119. #endif


  4120. #if (NGX_HAVE_OPENAT)

  4121. static char *
  4122. ‌ngx_http_disable_symlinks(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  4123. {
  4124.     ngx_http_core_loc_conf_t *clcf = conf;

  4125.     ngx_str_t                         *value;
  4126.     ngx_uint_t                         i;
  4127.     ngx_http_compile_complex_value_t   ccv;

  4128.     if (clcf->disable_symlinks != NGX_CONF_UNSET_UINT) {
  4129.         return "is duplicate";
  4130.     }

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

  4132.     for (i = 1; i < cf->args->nelts; i++) {

  4133.         if (ngx_strcmp(value[i].data, "off") == 0) {
  4134.             clcf->disable_symlinks = NGX_DISABLE_SYMLINKS_OFF;
  4135.             continue;
  4136.         }

  4137.         if (ngx_strcmp(value[i].data, "if_not_owner") == 0) {
  4138.             clcf->disable_symlinks = NGX_DISABLE_SYMLINKS_NOTOWNER;
  4139.             continue;
  4140.         }

  4141.         if (ngx_strcmp(value[i].data, "on") == 0) {
  4142.             clcf->disable_symlinks = NGX_DISABLE_SYMLINKS_ON;
  4143.             continue;
  4144.         }

  4145.         if (ngx_strncmp(value[i].data, "from=", 5) == 0) {
  4146.             value[i].len -= 5;
  4147.             value[i].data += 5;

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

  4149.             ccv.cf = cf;
  4150.             ccv.value = &value[i];
  4151.             ccv.complex_value = ngx_palloc(cf->pool,
  4152.                                            sizeof(ngx_http_complex_value_t));
  4153.             if (ccv.complex_value == NULL) {
  4154.                 return NGX_CONF_ERROR;
  4155.             }

  4156.             if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
  4157.                 return NGX_CONF_ERROR;
  4158.             }

  4159.             clcf->disable_symlinks_from = ccv.complex_value;

  4160.             continue;
  4161.         }

  4162.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  4163.                            "invalid parameter \"%V\"", &value[i]);
  4164.         return NGX_CONF_ERROR;
  4165.     }

  4166.     if (clcf->disable_symlinks == NGX_CONF_UNSET_UINT) {
  4167.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  4168.                            "\"%V\" must have \"off\", \"on\" "
  4169.                            "or \"if_not_owner\" parameter",
  4170.                            &cmd->name);
  4171.         return NGX_CONF_ERROR;
  4172.     }

  4173.     if (cf->args->nelts == 2) {
  4174.         clcf->disable_symlinks_from = NULL;
  4175.         return NGX_CONF_OK;
  4176.     }

  4177.     if (clcf->disable_symlinks_from == NGX_CONF_UNSET_PTR) {
  4178.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  4179.                            "duplicate parameters \"%V %V\"",
  4180.                            &value[1], &value[2]);
  4181.         return NGX_CONF_ERROR;
  4182.     }

  4183.     if (clcf->disable_symlinks == NGX_DISABLE_SYMLINKS_OFF) {
  4184.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  4185.                            "\"from=\" cannot be used with \"off\" parameter");
  4186.         return NGX_CONF_ERROR;
  4187.     }

  4188.     return NGX_CONF_OK;
  4189. }

  4190. #endif


  4191. static char *
  4192. ‌ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data)
  4193. {
  4194. #if (NGX_FREEBSD)
  4195.     ssize_t *np = data;

  4196.     if ((u_long) *np >= ngx_freebsd_net_inet_tcp_sendspace) {
  4197.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  4198.                            "\"send_lowat\" must be less than %d "
  4199.                            "(sysctl net.inet.tcp.sendspace)",
  4200.                            ngx_freebsd_net_inet_tcp_sendspace);

  4201.         return NGX_CONF_ERROR;
  4202.     }

  4203. #elif !(NGX_HAVE_SO_SNDLOWAT)
  4204.     ssize_t *np = data;

  4205.     ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
  4206.                        "\"send_lowat\" is not supported, ignored");

  4207.     *np = 0;

  4208. #endif

  4209.     return NGX_CONF_OK;
  4210. }


  4211. static char *
  4212. ‌ngx_http_core_pool_size(ngx_conf_t *cf, void *post, void *data)
  4213. {
  4214.     size_t *sp = data;

  4215.     if (*sp < NGX_MIN_POOL_SIZE) {
  4216.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  4217.                            "the pool size must be no less than %uz",
  4218.                            NGX_MIN_POOL_SIZE);
  4219.         return NGX_CONF_ERROR;
  4220.     }

  4221.     if (*sp % NGX_POOL_ALIGNMENT) {
  4222.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  4223.                            "the pool size must be a multiple of %d",
  4224.                            NGX_POOL_ALIGNMENT);
  4225.         return NGX_CONF_ERROR;
  4226.     }

  4227.     return NGX_CONF_OK;
  4228. }