src/http/ngx_http_core_module.c - nginx-1.31.4 nginx/ @ 8d9666701

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.       NULL },

  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.       NULL },

  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("sendfile"),
  326.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
  327.                         |NGX_CONF_FLAG,
  328.       ngx_conf_set_flag_slot,
  329.       NGX_HTTP_LOC_CONF_OFFSET,
  330.       offsetof(ngx_http_core_loc_conf_t, sendfile),
  331.       NULL },

  332.     { ngx_string("sendfile_max_chunk"),
  333.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  334.       ngx_conf_set_size_slot,
  335.       NGX_HTTP_LOC_CONF_OFFSET,
  336.       offsetof(ngx_http_core_loc_conf_t, sendfile_max_chunk),
  337.       NULL },

  338.     { ngx_string("subrequest_output_buffer_size"),
  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, subrequest_output_buffer_size),
  343.       NULL },

  344.     { ngx_string("aio"),
  345.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  346.       ngx_http_core_set_aio,
  347.       NGX_HTTP_LOC_CONF_OFFSET,
  348.       0,
  349.       NULL },

  350.     { ngx_string("aio_write"),
  351.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  352.       ngx_conf_set_flag_slot,
  353.       NGX_HTTP_LOC_CONF_OFFSET,
  354.       offsetof(ngx_http_core_loc_conf_t, aio_write),
  355.       NULL },

  356.     { ngx_string("read_ahead"),
  357.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  358.       ngx_conf_set_size_slot,
  359.       NGX_HTTP_LOC_CONF_OFFSET,
  360.       offsetof(ngx_http_core_loc_conf_t, read_ahead),
  361.       NULL },

  362.     { ngx_string("directio"),
  363.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  364.       ngx_http_core_directio,
  365.       NGX_HTTP_LOC_CONF_OFFSET,
  366.       0,
  367.       NULL },

  368.     { ngx_string("directio_alignment"),
  369.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  370.       ngx_conf_set_off_slot,
  371.       NGX_HTTP_LOC_CONF_OFFSET,
  372.       offsetof(ngx_http_core_loc_conf_t, directio_alignment),
  373.       NULL },

  374.     { ngx_string("tcp_nopush"),
  375.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  376.       ngx_conf_set_flag_slot,
  377.       NGX_HTTP_LOC_CONF_OFFSET,
  378.       offsetof(ngx_http_core_loc_conf_t, tcp_nopush),
  379.       NULL },

  380.     { ngx_string("tcp_nodelay"),
  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_nodelay),
  385.       NULL },

  386.     { ngx_string("send_timeout"),
  387.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  388.       ngx_conf_set_msec_slot,
  389.       NGX_HTTP_LOC_CONF_OFFSET,
  390.       offsetof(ngx_http_core_loc_conf_t, send_timeout),
  391.       NULL },

  392.     { ngx_string("send_lowat"),
  393.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  394.       ngx_conf_set_size_slot,
  395.       NGX_HTTP_LOC_CONF_OFFSET,
  396.       offsetof(ngx_http_core_loc_conf_t, send_lowat),
  397.       &ngx_http_core_lowat_post },

  398.     { ngx_string("postpone_output"),
  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, postpone_output),
  403.       NULL },

  404.     { ngx_string("limit_rate"),
  405.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
  406.                         |NGX_CONF_TAKE1,
  407.       ngx_http_set_complex_value_size_slot,
  408.       NGX_HTTP_LOC_CONF_OFFSET,
  409.       offsetof(ngx_http_core_loc_conf_t, limit_rate),
  410.       NULL },

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

  418.     { ngx_string("keepalive_time"),
  419.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  420.       ngx_conf_set_msec_slot,
  421.       NGX_HTTP_LOC_CONF_OFFSET,
  422.       offsetof(ngx_http_core_loc_conf_t, keepalive_time),
  423.       NULL },

  424.     { ngx_string("keepalive_timeout"),
  425.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
  426.       ngx_http_core_keepalive,
  427.       NGX_HTTP_LOC_CONF_OFFSET,
  428.       0,
  429.       NULL },

  430.     { ngx_string("keepalive_min_timeout"),
  431.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  432.       ngx_conf_set_msec_slot,
  433.       NGX_HTTP_LOC_CONF_OFFSET,
  434.       offsetof(ngx_http_core_loc_conf_t, keepalive_min_timeout),
  435.       NULL },

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

  442.     { ngx_string("keepalive_disable"),
  443.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
  444.       ngx_conf_set_bitmask_slot,
  445.       NGX_HTTP_LOC_CONF_OFFSET,
  446.       offsetof(ngx_http_core_loc_conf_t, keepalive_disable),
  447.       &ngx_http_core_keepalive_disable },

  448.     { ngx_string("satisfy"),
  449.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  450.       ngx_conf_set_enum_slot,
  451.       NGX_HTTP_LOC_CONF_OFFSET,
  452.       offsetof(ngx_http_core_loc_conf_t, satisfy),
  453.       &ngx_http_core_satisfy },

  454.     { ngx_string("auth_delay"),
  455.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  456.       ngx_conf_set_msec_slot,
  457.       NGX_HTTP_LOC_CONF_OFFSET,
  458.       offsetof(ngx_http_core_loc_conf_t, auth_delay),
  459.       NULL },

  460.     { ngx_string("internal"),
  461.       NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
  462.       ngx_http_core_internal,
  463.       NGX_HTTP_LOC_CONF_OFFSET,
  464.       0,
  465.       NULL },

  466.     { ngx_string("lingering_close"),
  467.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  468.       ngx_conf_set_enum_slot,
  469.       NGX_HTTP_LOC_CONF_OFFSET,
  470.       offsetof(ngx_http_core_loc_conf_t, lingering_close),
  471.       &ngx_http_core_lingering_close },

  472.     { ngx_string("lingering_time"),
  473.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  474.       ngx_conf_set_msec_slot,
  475.       NGX_HTTP_LOC_CONF_OFFSET,
  476.       offsetof(ngx_http_core_loc_conf_t, lingering_time),
  477.       NULL },

  478.     { ngx_string("lingering_timeout"),
  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_timeout),
  483.       NULL },

  484.     { ngx_string("reset_timedout_connection"),
  485.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  486.       ngx_conf_set_flag_slot,
  487.       NGX_HTTP_LOC_CONF_OFFSET,
  488.       offsetof(ngx_http_core_loc_conf_t, reset_timedout_connection),
  489.       NULL },

  490.     { ngx_string("absolute_redirect"),
  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, absolute_redirect),
  495.       NULL },

  496.     { ngx_string("server_name_in_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, server_name_in_redirect),
  501.       NULL },

  502.     { ngx_string("port_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, port_in_redirect),
  507.       NULL },

  508.     { ngx_string("msie_padding"),
  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, msie_padding),
  513.       NULL },

  514.     { ngx_string("msie_refresh"),
  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_refresh),
  519.       NULL },

  520.     { ngx_string("log_not_found"),
  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, log_not_found),
  525.       NULL },

  526.     { ngx_string("log_subrequest"),
  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_subrequest),
  531.       NULL },

  532.     { ngx_string("recursive_error_pages"),
  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, recursive_error_pages),
  537.       NULL },

  538.     { ngx_string("server_tokens"),
  539.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  540.       ngx_conf_set_enum_slot,
  541.       NGX_HTTP_LOC_CONF_OFFSET,
  542.       offsetof(ngx_http_core_loc_conf_t, server_tokens),
  543.       &ngx_http_core_server_tokens },

  544.     { ngx_string("if_modified_since"),
  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, if_modified_since),
  549.       &ngx_http_core_if_modified_since },

  550.     { ngx_string("max_ranges"),
  551.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  552.       ngx_conf_set_num_slot,
  553.       NGX_HTTP_LOC_CONF_OFFSET,
  554.       offsetof(ngx_http_core_loc_conf_t, max_ranges),
  555.       NULL },

  556.     { ngx_string("chunked_transfer_encoding"),
  557.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  558.       ngx_conf_set_flag_slot,
  559.       NGX_HTTP_LOC_CONF_OFFSET,
  560.       offsetof(ngx_http_core_loc_conf_t, chunked_transfer_encoding),
  561.       NULL },

  562.     { ngx_string("etag"),
  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, etag),
  567.       NULL },

  568.     { ngx_string("early_hints"),
  569.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  570.       ngx_http_set_predicate_slot,
  571.       NGX_HTTP_LOC_CONF_OFFSET,
  572.       offsetof(ngx_http_core_loc_conf_t, early_hints),
  573.       NULL },

  574.     { ngx_string("error_page"),
  575.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
  576.                         |NGX_CONF_2MORE,
  577.       ngx_http_core_error_page,
  578.       NGX_HTTP_LOC_CONF_OFFSET,
  579.       0,
  580.       NULL },

  581.     { ngx_string("post_action"),
  582.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
  583.                         |NGX_CONF_TAKE1,
  584.       ngx_conf_set_str_slot,
  585.       NGX_HTTP_LOC_CONF_OFFSET,
  586.       offsetof(ngx_http_core_loc_conf_t, post_action),
  587.       NULL },

  588.     { ngx_string("error_log"),
  589.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  590.       ngx_http_core_error_log,
  591.       NGX_HTTP_LOC_CONF_OFFSET,
  592.       0,
  593.       NULL },

  594.     { ngx_string("open_file_cache"),
  595.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
  596.       ngx_http_core_open_file_cache,
  597.       NGX_HTTP_LOC_CONF_OFFSET,
  598.       offsetof(ngx_http_core_loc_conf_t, open_file_cache),
  599.       NULL },

  600.     { ngx_string("open_file_cache_valid"),
  601.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  602.       ngx_conf_set_sec_slot,
  603.       NGX_HTTP_LOC_CONF_OFFSET,
  604.       offsetof(ngx_http_core_loc_conf_t, open_file_cache_valid),
  605.       NULL },

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

  612.     { ngx_string("open_file_cache_errors"),
  613.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  614.       ngx_conf_set_flag_slot,
  615.       NGX_HTTP_LOC_CONF_OFFSET,
  616.       offsetof(ngx_http_core_loc_conf_t, open_file_cache_errors),
  617.       NULL },

  618.     { ngx_string("open_file_cache_events"),
  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_events),
  623.       NULL },

  624.     { ngx_string("resolver"),
  625.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  626.       ngx_http_core_resolver,
  627.       NGX_HTTP_LOC_CONF_OFFSET,
  628.       0,
  629.       NULL },

  630.     { ngx_string("resolver_timeout"),
  631.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  632.       ngx_conf_set_msec_slot,
  633.       NGX_HTTP_LOC_CONF_OFFSET,
  634.       offsetof(ngx_http_core_loc_conf_t, resolver_timeout),
  635.       NULL },

  636. #if (NGX_HTTP_GZIP)

  637.     { ngx_string("gzip_vary"),
  638.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  639.       ngx_conf_set_flag_slot,
  640.       NGX_HTTP_LOC_CONF_OFFSET,
  641.       offsetof(ngx_http_core_loc_conf_t, gzip_vary),
  642.       NULL },

  643.     { ngx_string("gzip_http_version"),
  644.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  645.       ngx_conf_set_enum_slot,
  646.       NGX_HTTP_LOC_CONF_OFFSET,
  647.       offsetof(ngx_http_core_loc_conf_t, gzip_http_version),
  648.       &ngx_http_gzip_http_version },

  649.     { ngx_string("gzip_proxied"),
  650.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  651.       ngx_conf_set_bitmask_slot,
  652.       NGX_HTTP_LOC_CONF_OFFSET,
  653.       offsetof(ngx_http_core_loc_conf_t, gzip_proxied),
  654.       &ngx_http_gzip_proxied_mask },

  655.     { ngx_string("gzip_disable"),
  656.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  657.       ngx_http_gzip_disable,
  658.       NGX_HTTP_LOC_CONF_OFFSET,
  659.       0,
  660.       NULL },

  661. #endif

  662. #if (NGX_HAVE_OPENAT)

  663.     { ngx_string("disable_symlinks"),
  664.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
  665.       ngx_http_disable_symlinks,
  666.       NGX_HTTP_LOC_CONF_OFFSET,
  667.       0,
  668.       NULL },

  669. #endif

  670.       ngx_null_command
  671. };


  672. static ngx_http_module_t  ngx_http_core_module_ctx = {
  673.     ngx_http_core_preconfiguration,        /* preconfiguration */
  674.     ngx_http_core_postconfiguration,       /* postconfiguration */

  675.     ngx_http_core_create_main_conf,        /* create main configuration */
  676.     ngx_http_core_init_main_conf,          /* init main configuration */

  677.     ngx_http_core_create_srv_conf,         /* create server configuration */
  678.     ngx_http_core_merge_srv_conf,          /* merge server configuration */

  679.     ngx_http_core_create_loc_conf,         /* create location configuration */
  680.     ngx_http_core_merge_loc_conf           /* merge location configuration */
  681. };


  682. ngx_module_t  ngx_http_core_module = {
  683.     NGX_MODULE_V1,
  684.     &ngx_http_core_module_ctx,             /* module context */
  685.     ngx_http_core_commands,                /* module directives */
  686.     NGX_HTTP_MODULE,                       /* module type */
  687.     NULL,                                  /* init master */
  688.     NULL,                                  /* init module */
  689.     NULL,                                  /* init process */
  690.     NULL,                                  /* init thread */
  691.     NULL,                                  /* exit thread */
  692.     NULL,                                  /* exit process */
  693.     NULL,                                  /* exit master */
  694.     NGX_MODULE_V1_PADDING
  695. };


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


  697. void
  698. ngx_http_handler(ngx_http_request_t *r)
  699. {
  700.     ngx_http_core_main_conf_t  *cmcf;

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

  702.     if (!r->internal) {

  703.         if (r->method != NGX_HTTP_CONNECT) {
  704.             switch (r->headers_in.connection_type) {
  705.             case 0:
  706.                 r->keepalive = (r->http_version > NGX_HTTP_VERSION_10);
  707.                 break;

  708.             case NGX_HTTP_CONNECTION_CLOSE:
  709.                 r->keepalive = 0;
  710.                 break;

  711.             case NGX_HTTP_CONNECTION_KEEP_ALIVE:
  712.                 r->keepalive = 1;
  713.                 break;
  714.             }
  715.         }

  716.         r->lingering_close = (r->headers_in.content_length_n > 0
  717.                               || r->headers_in.chunked);
  718.         r->phase_handler = 0;

  719.     } else {
  720.         cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
  721.         r->phase_handler = cmcf->phase_engine.server_rewrite_index;
  722.     }

  723.     r->valid_location = 1;
  724. #if (NGX_HTTP_GZIP)
  725.     r->gzip_tested = 0;
  726.     r->gzip_ok = 0;
  727.     r->gzip_vary = 0;
  728. #endif

  729.     r->write_event_handler = ngx_http_core_run_phases;
  730.     ngx_http_core_run_phases(r);
  731. }


  732. void
  733. ngx_http_core_run_phases(ngx_http_request_t *r)
  734. {
  735.     ngx_int_t                   rc;
  736.     ngx_http_phase_handler_t   *ph;
  737.     ngx_http_core_main_conf_t  *cmcf;

  738.     cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

  739.     ph = cmcf->phase_engine.handlers;

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

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

  742.         if (rc == NGX_OK) {
  743.             return;
  744.         }
  745.     }
  746. }


  747. ngx_int_t
  748. ngx_http_core_generic_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
  749. {
  750.     ngx_int_t  rc;

  751.     /*
  752.      * generic phase checker,
  753.      * used by the post read and pre-access phases
  754.      */

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

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

  758.     if (rc == NGX_OK) {
  759.         r->phase_handler = ph->next;
  760.         return NGX_AGAIN;
  761.     }

  762.     if (rc == NGX_DECLINED) {
  763.         r->phase_handler++;
  764.         return NGX_AGAIN;
  765.     }

  766.     if (rc == NGX_AGAIN || rc == NGX_DONE) {
  767.         return NGX_OK;
  768.     }

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

  770.     ngx_http_finalize_request(r, rc);

  771.     return NGX_OK;
  772. }


  773. ngx_int_t
  774. ngx_http_core_rewrite_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
  775. {
  776.     ngx_int_t  rc;

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

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

  780.     if (rc == NGX_DECLINED) {
  781.         r->phase_handler++;
  782.         return NGX_AGAIN;
  783.     }

  784.     if (rc == NGX_DONE) {
  785.         return NGX_OK;
  786.     }

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

  788.     ngx_http_finalize_request(r, rc);

  789.     return NGX_OK;
  790. }


  791. ngx_int_t
  792. ngx_http_core_find_config_phase(ngx_http_request_t *r,
  793.     ngx_http_phase_handler_t *ph)
  794. {
  795.     u_char                    *p;
  796.     size_t                     len;
  797.     ngx_int_t                  rc;
  798.     ngx_http_core_loc_conf_t  *clcf;

  799.     r->content_handler = NULL;
  800.     r->uri_changed = 0;

  801.     rc = ngx_http_core_find_location(r);

  802.     if (rc == NGX_ERROR) {
  803.         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  804.         return NGX_OK;
  805.     }

  806.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  807.     if (!r->internal && clcf->internal) {
  808.         ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
  809.         return NGX_OK;
  810.     }

  811.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  812.                    "using configuration \"%s%V\"",
  813.                    (clcf->noname ? "*" : (clcf->exact_match ? "=" : "")),
  814.                    &clcf->name);

  815.     ngx_http_update_location_config(r);

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

  819.     if (r->headers_in.content_length_n != -1
  820.         && !r->discard_body
  821.         && clcf->client_max_body_size
  822.         && clcf->client_max_body_size < r->headers_in.content_length_n)
  823.     {
  824.         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  825.                       "client intended to send too large body: %O bytes",
  826.                       r->headers_in.content_length_n);

  827.         r->expect_tested = 1;
  828.         (void) ngx_http_discard_request_body(r);
  829.         ngx_http_finalize_request(r, NGX_HTTP_REQUEST_ENTITY_TOO_LARGE);
  830.         return NGX_OK;
  831.     }

  832.     if (rc == NGX_DONE) {
  833.         ngx_http_clear_location(r);

  834.         r->headers_out.location = ngx_list_push(&r->headers_out.headers);
  835.         if (r->headers_out.location == NULL) {
  836.             ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  837.             return NGX_OK;
  838.         }

  839.         r->headers_out.location->hash = 1;
  840.         r->headers_out.location->next = NULL;
  841.         ngx_str_set(&r->headers_out.location->key, "Location");

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

  844.         } else {
  845.             len = clcf->escaped_name.len + 1 + r->args.len;
  846.             p = ngx_pnalloc(r->pool, len);

  847.             if (p == NULL) {
  848.                 ngx_http_clear_location(r);
  849.                 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  850.                 return NGX_OK;
  851.             }

  852.             r->headers_out.location->value.len = len;
  853.             r->headers_out.location->value.data = p;

  854.             p = ngx_cpymem(p, clcf->escaped_name.data, clcf->escaped_name.len);
  855.             *p++ = '?';
  856.             ngx_memcpy(p, r->args.data, r->args.len);
  857.         }

  858.         ngx_http_finalize_request(r, NGX_HTTP_MOVED_PERMANENTLY);
  859.         return NGX_OK;
  860.     }

  861.     r->phase_handler++;
  862.     return NGX_AGAIN;
  863. }


  864. ngx_int_t
  865. ngx_http_core_post_rewrite_phase(ngx_http_request_t *r,
  866.     ngx_http_phase_handler_t *ph)
  867. {
  868.     ngx_http_core_srv_conf_t  *cscf;

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

  871.     if (!r->uri_changed) {
  872.         r->phase_handler++;
  873.         return NGX_AGAIN;
  874.     }

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

  877.     /*
  878.      * gcc before 3.3 compiles the broken code for
  879.      *     if (r->uri_changes-- == 0)
  880.      * if the r->uri_changes is defined as
  881.      *     unsigned  uri_changes:4
  882.      */

  883.     r->uri_changes--;

  884.     if (r->uri_changes == 0) {
  885.         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  886.                       "rewrite or internal redirection cycle "
  887.                       "while processing \"%V\"", &r->uri);

  888.         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  889.         return NGX_OK;
  890.     }

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

  892.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
  893.     r->loc_conf = cscf->ctx->loc_conf;

  894.     return NGX_AGAIN;
  895. }


  896. ngx_int_t
  897. ngx_http_core_access_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
  898. {
  899.     ngx_int_t                  rc;
  900.     ngx_table_elt_t           *h;
  901.     ngx_http_core_loc_conf_t  *clcf;

  902.     if (r != r->main) {
  903.         r->phase_handler = ph->next;
  904.         return NGX_AGAIN;
  905.     }

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

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

  909.     if (rc == NGX_DECLINED) {
  910.         r->phase_handler++;
  911.         return NGX_AGAIN;
  912.     }

  913.     if (rc == NGX_AGAIN || rc == NGX_DONE) {
  914.         return NGX_OK;
  915.     }

  916.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

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

  918.         if (rc == NGX_OK) {
  919.             r->phase_handler++;
  920.             return NGX_AGAIN;
  921.         }

  922.     } else {
  923.         if (rc == NGX_OK) {
  924.             r->access_code = 0;

  925.             h = ngx_http_proxy_auth(r) ? r->headers_out.proxy_authenticate
  926.                                        : r->headers_out.www_authenticate;

  927.             for ( /* void */ ; h; h = h->next) {
  928.                 h->hash = 0;
  929.             }

  930.             r->phase_handler = ph->next;
  931.             return NGX_AGAIN;
  932.         }

  933.         if (rc == NGX_HTTP_FORBIDDEN
  934.             || rc == NGX_HTTP_UNAUTHORIZED
  935.             || rc == NGX_HTTP_PROXY_AUTH_REQUIRED)
  936.         {
  937.             if (r->access_code != NGX_HTTP_UNAUTHORIZED
  938.                 && r->access_code != NGX_HTTP_PROXY_AUTH_REQUIRED)
  939.             {
  940.                 r->access_code = rc;
  941.             }

  942.             r->phase_handler++;
  943.             return NGX_AGAIN;
  944.         }
  945.     }

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

  947.     if (rc == NGX_HTTP_UNAUTHORIZED || rc == NGX_HTTP_PROXY_AUTH_REQUIRED) {
  948.         r->access_code = rc;
  949.         return ngx_http_core_auth_delay(r);
  950.     }

  951.     ngx_http_finalize_request(r, rc);
  952.     return NGX_OK;
  953. }


  954. ngx_int_t
  955. ngx_http_core_post_access_phase(ngx_http_request_t *r,
  956.     ngx_http_phase_handler_t *ph)
  957. {
  958.     ngx_int_t  access_code;

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

  961.     access_code = r->access_code;

  962.     if (access_code) {
  963.         if (access_code == NGX_HTTP_FORBIDDEN) {
  964.             ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  965.                           "access forbidden by rule");
  966.         }

  967.         if (access_code == NGX_HTTP_UNAUTHORIZED
  968.             || access_code == NGX_HTTP_PROXY_AUTH_REQUIRED)
  969.         {
  970.             return ngx_http_core_auth_delay(r);
  971.         }

  972.         r->access_code = 0;

  973.         ngx_http_finalize_request(r, access_code);
  974.         return NGX_OK;
  975.     }

  976.     r->phase_handler++;
  977.     return NGX_AGAIN;
  978. }


  979. static ngx_int_t
  980. ngx_http_core_auth_delay(ngx_http_request_t *r)
  981. {
  982.     ngx_int_t                  access_code;
  983.     ngx_http_core_loc_conf_t  *clcf;

  984.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  985.     if (clcf->auth_delay == 0) {
  986.         access_code = r->access_code;
  987.         r->access_code = 0;

  988.         ngx_http_finalize_request(r, access_code);
  989.         return NGX_OK;
  990.     }

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

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

  995.     } else {
  996.         if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
  997.             return NGX_HTTP_INTERNAL_SERVER_ERROR;
  998.         }
  999.     }

  1000.     r->read_event_handler = ngx_http_test_reading;
  1001.     r->write_event_handler = ngx_http_core_auth_delay_handler;

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

  1004.     /*
  1005.      * trigger an additional event loop iteration
  1006.      * to ensure constant-time processing
  1007.      */

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

  1009.     return NGX_OK;
  1010. }


  1011. static void
  1012. ngx_http_core_auth_delay_handler(ngx_http_request_t *r)
  1013. {
  1014.     ngx_int_t     access_code;
  1015.     ngx_event_t  *wev;

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

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

  1019.     if (wev->delayed) {

  1020.         if (ngx_handle_write_event(wev, 0) != NGX_OK) {
  1021.             ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1022.         }

  1023.         return;
  1024.     }

  1025.     access_code = r->access_code;
  1026.     r->access_code = 0;

  1027.     ngx_http_finalize_request(r, access_code);
  1028. }


  1029. ngx_int_t
  1030. ngx_http_core_content_phase(ngx_http_request_t *r,
  1031.     ngx_http_phase_handler_t *ph)
  1032. {
  1033.     size_t     root;
  1034.     ngx_int_t  rc;
  1035.     ngx_str_t  path;

  1036.     if (r->content_handler) {
  1037.         r->write_event_handler = ngx_http_request_empty_handler;
  1038.         ngx_http_finalize_request(r, r->content_handler(r));
  1039.         return NGX_OK;
  1040.     }

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

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

  1044.     if (rc != NGX_DECLINED) {
  1045.         ngx_http_finalize_request(r, rc);
  1046.         return NGX_OK;
  1047.     }

  1048.     /* rc == NGX_DECLINED */

  1049.     ph++;

  1050.     if (ph->checker) {
  1051.         r->phase_handler++;
  1052.         return NGX_AGAIN;
  1053.     }

  1054.     /* no content handler was found */

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

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

  1060.         ngx_http_finalize_request(r, NGX_HTTP_FORBIDDEN);
  1061.         return NGX_OK;
  1062.     }

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

  1064.     ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
  1065.     return NGX_OK;
  1066. }


  1067. void
  1068. ngx_http_update_location_config(ngx_http_request_t *r)
  1069. {
  1070.     ngx_http_core_loc_conf_t  *clcf;

  1071.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1072.     if (r->method & clcf->limit_except) {
  1073.         r->loc_conf = clcf->limit_except_loc_conf;
  1074.         clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
  1075.     }

  1076.     if (r == r->main) {
  1077.         ngx_set_connection_log(r->connection, clcf->error_log);
  1078.     }

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

  1081.     } else {
  1082.         r->connection->sendfile = 0;
  1083.     }

  1084.     if (clcf->client_body_in_file_only) {
  1085.         r->request_body_in_file_only = 1;
  1086.         r->request_body_in_persistent_file = 1;
  1087.         r->request_body_in_clean_file =
  1088.             clcf->client_body_in_file_only == NGX_HTTP_REQUEST_BODY_FILE_CLEAN;
  1089.         r->request_body_file_log_level = NGX_LOG_NOTICE;

  1090.     } else {
  1091.         r->request_body_file_log_level = NGX_LOG_WARN;
  1092.     }

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

  1094.     if (r->keepalive) {
  1095.         if (clcf->keepalive_timeout == 0) {
  1096.             r->keepalive = 0;

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

  1099.         } else if (ngx_current_msec - r->connection->start_time
  1100.                    > clcf->keepalive_time)
  1101.         {
  1102.             r->keepalive = 0;

  1103.         } else if (r->headers_in.msie6
  1104.                    && r->method == NGX_HTTP_POST
  1105.                    && (clcf->keepalive_disable
  1106.                        & NGX_HTTP_KEEPALIVE_DISABLE_MSIE6))
  1107.         {
  1108.             /*
  1109.              * MSIE may wait for some time if an response for
  1110.              * a POST request was sent over a keepalive connection
  1111.              */
  1112.             r->keepalive = 0;

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

  1125.     if (!clcf->tcp_nopush) {
  1126.         /* disable TCP_NOPUSH/TCP_CORK use */
  1127.         r->connection->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
  1128.     }

  1129.     if (clcf->handler) {
  1130.         r->content_handler = clcf->handler;
  1131.     }
  1132. }


  1133. /*
  1134. * NGX_OK       - exact or regex match
  1135. * NGX_DONE     - auto redirect
  1136. * NGX_AGAIN    - inclusive match
  1137. * NGX_ERROR    - regex error
  1138. * NGX_DECLINED - no match
  1139. */

  1140. static ngx_int_t
  1141. ngx_http_core_find_location(ngx_http_request_t *r)
  1142. {
  1143.     ngx_int_t                  rc;
  1144.     ngx_http_core_loc_conf_t  *pclcf;
  1145. #if (NGX_PCRE)
  1146.     ngx_int_t                  n;
  1147.     ngx_uint_t                 noregex;
  1148.     ngx_http_core_loc_conf_t  *clcf, **clcfp;

  1149.     noregex = 0;
  1150. #endif

  1151.     pclcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

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

  1153.     if (rc == NGX_AGAIN) {

  1154. #if (NGX_PCRE)
  1155.         clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1156.         noregex = clcf->noregex;
  1157. #endif

  1158.         /* look up nested locations */

  1159.         rc = ngx_http_core_find_location(r);
  1160.     }

  1161.     if (rc == NGX_OK || rc == NGX_DONE) {
  1162.         return rc;
  1163.     }

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

  1165. #if (NGX_PCRE)

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

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

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

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

  1171.             if (n == NGX_OK) {
  1172.                 r->loc_conf = (*clcfp)->loc_conf;

  1173.                 /* look up nested locations */

  1174.                 rc = ngx_http_core_find_location(r);

  1175.                 return (rc == NGX_ERROR) ? rc : NGX_OK;
  1176.             }

  1177.             if (n == NGX_DECLINED) {
  1178.                 continue;
  1179.             }

  1180.             return NGX_ERROR;
  1181.         }
  1182.     }
  1183. #endif

  1184.     return rc;
  1185. }


  1186. /*
  1187. * NGX_OK       - exact match
  1188. * NGX_DONE     - auto redirect
  1189. * NGX_AGAIN    - inclusive match
  1190. * NGX_DECLINED - no match
  1191. */

  1192. static ngx_int_t
  1193. ngx_http_core_find_static_location(ngx_http_request_t *r,
  1194.     ngx_http_location_tree_node_t *node)
  1195. {
  1196.     u_char     *uri;
  1197.     size_t      len, n;
  1198.     ngx_int_t   rc, rv;

  1199.     len = r->uri.len;
  1200.     uri = r->uri.data;

  1201.     rv = NGX_DECLINED;

  1202.     for ( ;; ) {

  1203.         if (node == NULL) {
  1204.             return rv;
  1205.         }

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

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

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

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

  1213.             continue;
  1214.         }

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

  1216.             if (node->inclusive) {

  1217.                 r->loc_conf = node->inclusive->loc_conf;
  1218.                 rv = NGX_AGAIN;

  1219.                 node = node->tree;
  1220.                 uri += n;
  1221.                 len -= n;

  1222.                 continue;
  1223.             }

  1224.             /* exact only */

  1225.             node = node->right;

  1226.             continue;
  1227.         }

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

  1229.             if (node->exact) {
  1230.                 r->loc_conf = node->exact->loc_conf;
  1231.                 return NGX_OK;

  1232.             } else {
  1233.                 r->loc_conf = node->inclusive->loc_conf;
  1234.                 return NGX_AGAIN;
  1235.             }
  1236.         }

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

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

  1239.             r->loc_conf = (node->exact) ? node->exact->loc_conf:
  1240.                                           node->inclusive->loc_conf;
  1241.             rv = NGX_DONE;
  1242.         }

  1243.         node = node->left;
  1244.     }
  1245. }


  1246. void *
  1247. ngx_http_test_content_type(ngx_http_request_t *r, ngx_hash_t *types_hash)
  1248. {
  1249.     u_char      c, *lowcase;
  1250.     size_t      len;
  1251.     ngx_uint_t  i, hash;

  1252.     if (types_hash->size == 0) {
  1253.         return (void *) 4;
  1254.     }

  1255.     if (r->headers_out.content_type.len == 0) {
  1256.         return NULL;
  1257.     }

  1258.     len = r->headers_out.content_type_len;

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

  1260.         lowcase = ngx_pnalloc(r->pool, len);
  1261.         if (lowcase == NULL) {
  1262.             return NULL;
  1263.         }

  1264.         r->headers_out.content_type_lowcase = lowcase;

  1265.         hash = 0;

  1266.         for (i = 0; i < len; i++) {
  1267.             c = ngx_tolower(r->headers_out.content_type.data[i]);
  1268.             hash = ngx_hash(hash, c);
  1269.             lowcase[i] = c;
  1270.         }

  1271.         r->headers_out.content_type_hash = hash;
  1272.     }

  1273.     return ngx_hash_find(types_hash, r->headers_out.content_type_hash,
  1274.                          r->headers_out.content_type_lowcase, len);
  1275. }


  1276. ngx_int_t
  1277. ngx_http_set_content_type(ngx_http_request_t *r)
  1278. {
  1279.     u_char                     c, *exten;
  1280.     ngx_str_t                 *type;
  1281.     ngx_uint_t                 i, hash;
  1282.     ngx_http_core_loc_conf_t  *clcf;

  1283.     if (r->headers_out.content_type.len) {
  1284.         return NGX_OK;
  1285.     }

  1286.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

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

  1288.         hash = 0;

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

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

  1292.                 exten = ngx_pnalloc(r->pool, r->exten.len);
  1293.                 if (exten == NULL) {
  1294.                     return NGX_ERROR;
  1295.                 }

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

  1297.                 r->exten.data = exten;

  1298.                 break;
  1299.             }

  1300.             hash = ngx_hash(hash, c);
  1301.         }

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

  1304.         if (type) {
  1305.             r->headers_out.content_type_len = type->len;
  1306.             r->headers_out.content_type = *type;

  1307.             return NGX_OK;
  1308.         }
  1309.     }

  1310.     r->headers_out.content_type_len = clcf->default_type.len;
  1311.     r->headers_out.content_type = clcf->default_type;

  1312.     return NGX_OK;
  1313. }


  1314. void
  1315. ngx_http_set_exten(ngx_http_request_t *r)
  1316. {
  1317.     ngx_int_t  i;

  1318.     ngx_str_null(&r->exten);

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

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

  1323.             return;

  1324.         } else if (r->uri.data[i] == '/') {
  1325.             return;
  1326.         }
  1327.     }

  1328.     return;
  1329. }


  1330. ngx_int_t
  1331. ngx_http_set_etag(ngx_http_request_t *r)
  1332. {
  1333.     ngx_table_elt_t           *etag;
  1334.     ngx_http_core_loc_conf_t  *clcf;

  1335.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1336.     if (!clcf->etag) {
  1337.         return NGX_OK;
  1338.     }

  1339.     etag = ngx_list_push(&r->headers_out.headers);
  1340.     if (etag == NULL) {
  1341.         return NGX_ERROR;
  1342.     }

  1343.     etag->hash = 1;
  1344.     etag->next = NULL;
  1345.     ngx_str_set(&etag->key, "ETag");

  1346.     etag->value.data = ngx_pnalloc(r->pool, NGX_OFF_T_LEN + NGX_TIME_T_LEN + 3);
  1347.     if (etag->value.data == NULL) {
  1348.         etag->hash = 0;
  1349.         return NGX_ERROR;
  1350.     }

  1351.     etag->value.len = ngx_sprintf(etag->value.data, "\"%xT-%xO\"",
  1352.                                   r->headers_out.last_modified_time,
  1353.                                   r->headers_out.content_length_n)
  1354.                       - etag->value.data;

  1355.     r->headers_out.etag = etag;

  1356.     return NGX_OK;
  1357. }


  1358. void
  1359. ngx_http_weak_etag(ngx_http_request_t *r)
  1360. {
  1361.     size_t            len;
  1362.     u_char           *p;
  1363.     ngx_table_elt_t  *etag;

  1364.     etag = r->headers_out.etag;

  1365.     if (etag == NULL) {
  1366.         return;
  1367.     }

  1368.     if (etag->value.len > 2
  1369.         && etag->value.data[0] == 'W'
  1370.         && etag->value.data[1] == '/')
  1371.     {
  1372.         return;
  1373.     }

  1374.     if (etag->value.len < 1 || etag->value.data[0] != '"') {
  1375.         r->headers_out.etag->hash = 0;
  1376.         r->headers_out.etag = NULL;
  1377.         return;
  1378.     }

  1379.     p = ngx_pnalloc(r->pool, etag->value.len + 2);
  1380.     if (p == NULL) {
  1381.         r->headers_out.etag->hash = 0;
  1382.         r->headers_out.etag = NULL;
  1383.         return;
  1384.     }

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

  1386.     etag->value.data = p;
  1387.     etag->value.len = len;
  1388. }


  1389. ngx_int_t
  1390. ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
  1391.     ngx_str_t *ct, ngx_http_complex_value_t *cv)
  1392. {
  1393.     ngx_int_t     rc;
  1394.     ngx_str_t     val;
  1395.     ngx_buf_t    *b;
  1396.     ngx_chain_t   out;

  1397.     rc = ngx_http_discard_request_body(r);

  1398.     if (rc != NGX_OK) {
  1399.         return rc;
  1400.     }

  1401.     r->headers_out.status = status;

  1402.     if (ngx_http_complex_value(r, cv, &val) != NGX_OK) {
  1403.         return NGX_HTTP_INTERNAL_SERVER_ERROR;
  1404.     }

  1405.     if (status == NGX_HTTP_MOVED_PERMANENTLY
  1406.         || status == NGX_HTTP_MOVED_TEMPORARILY
  1407.         || status == NGX_HTTP_SEE_OTHER
  1408.         || status == NGX_HTTP_TEMPORARY_REDIRECT
  1409.         || status == NGX_HTTP_PERMANENT_REDIRECT)
  1410.     {
  1411.         ngx_http_clear_location(r);

  1412.         r->headers_out.location = ngx_list_push(&r->headers_out.headers);
  1413.         if (r->headers_out.location == NULL) {
  1414.             return NGX_HTTP_INTERNAL_SERVER_ERROR;
  1415.         }

  1416.         r->headers_out.location->hash = 1;
  1417.         r->headers_out.location->next = NULL;
  1418.         ngx_str_set(&r->headers_out.location->key, "Location");
  1419.         r->headers_out.location->value = val;

  1420.         return status;
  1421.     }

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

  1423.     if (ct) {
  1424.         r->headers_out.content_type_len = ct->len;
  1425.         r->headers_out.content_type = *ct;

  1426.     } else {
  1427.         if (ngx_http_set_content_type(r) != NGX_OK) {
  1428.             return NGX_HTTP_INTERNAL_SERVER_ERROR;
  1429.         }
  1430.     }

  1431.     b = ngx_calloc_buf(r->pool);
  1432.     if (b == NULL) {
  1433.         return NGX_HTTP_INTERNAL_SERVER_ERROR;
  1434.     }

  1435.     b->pos = val.data;
  1436.     b->last = val.data + val.len;
  1437.     b->memory = val.len ? 1 : 0;
  1438.     b->last_buf = (r == r->main) ? 1 : 0;
  1439.     b->last_in_chain = 1;
  1440.     b->sync = (b->last_buf || b->memory) ? 0 : 1;

  1441.     out.buf = b;
  1442.     out.next = NULL;

  1443.     rc = ngx_http_send_header(r);

  1444.     if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
  1445.         return rc;
  1446.     }

  1447.     return ngx_http_output_filter(r, &out);
  1448. }


  1449. ngx_int_t
  1450. ngx_http_send_header(ngx_http_request_t *r)
  1451. {
  1452.     if (r->post_action) {
  1453.         return NGX_OK;
  1454.     }

  1455.     if (r->header_sent) {
  1456.         ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
  1457.                       "header already sent");
  1458.         return NGX_ERROR;
  1459.     }

  1460.     if (r->err_status) {
  1461.         r->headers_out.status = r->err_status;
  1462.         r->headers_out.status_line.len = 0;
  1463.     }

  1464.     return ngx_http_top_header_filter(r);
  1465. }


  1466. ngx_int_t
  1467. ngx_http_send_early_hints(ngx_http_request_t *r)
  1468. {
  1469.     ngx_int_t                  rc;
  1470.     ngx_http_core_loc_conf_t  *clcf;

  1471.     if (r->post_action) {
  1472.         return NGX_OK;
  1473.     }

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

  1479.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

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

  1481.     if (rc != NGX_DECLINED) {
  1482.         return rc;
  1483.     }

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

  1486.     return ngx_http_top_early_hints_filter(r);
  1487. }


  1488. ngx_int_t
  1489. ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in)
  1490. {
  1491.     ngx_int_t          rc;
  1492.     ngx_connection_t  *c;

  1493.     c = r->connection;

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

  1496.     rc = ngx_http_top_body_filter(r, in);

  1497.     if (rc == NGX_ERROR) {
  1498.         /* NGX_ERROR may be returned by any filter */
  1499.         c->error = 1;
  1500.     }

  1501.     return rc;
  1502. }


  1503. u_char *
  1504. ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *path,
  1505.     size_t *root_length, size_t reserved)
  1506. {
  1507.     u_char                    *last;
  1508.     size_t                     alias;
  1509.     ngx_http_core_loc_conf_t  *clcf;

  1510.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1511.     alias = clcf->alias;

  1512.     if (alias && !r->valid_location) {
  1513.         ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
  1514.                       "\"alias\" cannot be used in location \"%V\" "
  1515.                       "where URI was rewritten", &clcf->name);
  1516.         return NULL;
  1517.     }

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

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

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

  1521.         path->data = ngx_pnalloc(r->pool, path->len);
  1522.         if (path->data == NULL) {
  1523.             return NULL;
  1524.         }

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

  1526.     } else {

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

  1529.         } else {
  1530.             reserved += r->uri.len - alias + 1;
  1531.         }

  1532.         if (ngx_http_script_run(r, path, clcf->root_lengths->elts, reserved,
  1533.                                 clcf->root_values->elts)
  1534.             == NULL)
  1535.         {
  1536.             return NULL;
  1537.         }

  1538.         if (ngx_get_full_name(r->pool, (ngx_str_t *) &ngx_cycle->prefix, path)
  1539.             != NGX_OK)
  1540.         {
  1541.             return NULL;
  1542.         }

  1543.         *root_length = path->len - reserved;
  1544.         last = path->data + *root_length;

  1545.         if (alias == NGX_MAX_SIZE_T_VALUE) {
  1546.             if (!r->add_uri_to_alias) {
  1547.                 *last = '\0';
  1548.                 return last;
  1549.             }

  1550.             alias = 0;
  1551.         }
  1552.     }

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

  1555.     return last;
  1556. }


  1557. ngx_int_t
  1558. ngx_http_auth_basic_user(ngx_http_request_t *r)
  1559. {
  1560.     ngx_str_t         auth, encoded;
  1561.     ngx_uint_t        len;
  1562.     ngx_table_elt_t  *h;

  1563.     if (r->headers_in.user.len == 0 && r->headers_in.user.data != NULL) {
  1564.         return NGX_DECLINED;
  1565.     }

  1566.     h = ngx_http_proxy_auth(r) ? r->headers_in.proxy_authorization
  1567.                                : r->headers_in.authorization;

  1568.     if (h == NULL) {
  1569.         r->headers_in.user.data = (u_char *) "";
  1570.         return NGX_DECLINED;
  1571.     }

  1572.     encoded = h->value;

  1573.     if (encoded.len < sizeof("Basic ") - 1
  1574.         || ngx_strncasecmp(encoded.data, (u_char *) "Basic ",
  1575.                            sizeof("Basic ") - 1)
  1576.            != 0)
  1577.     {
  1578.         r->headers_in.user.data = (u_char *) "";
  1579.         return NGX_DECLINED;
  1580.     }

  1581.     encoded.len -= sizeof("Basic ") - 1;
  1582.     encoded.data += sizeof("Basic ") - 1;

  1583.     while (encoded.len && encoded.data[0] == ' ') {
  1584.         encoded.len--;
  1585.         encoded.data++;
  1586.     }

  1587.     if (encoded.len == 0) {
  1588.         r->headers_in.user.data = (u_char *) "";
  1589.         return NGX_DECLINED;
  1590.     }

  1591.     auth.len = ngx_base64_decoded_length(encoded.len);
  1592.     auth.data = ngx_pnalloc(r->pool, auth.len + 1);
  1593.     if (auth.data == NULL) {
  1594.         return NGX_ERROR;
  1595.     }

  1596.     if (ngx_decode_base64(&auth, &encoded) != NGX_OK) {
  1597.         r->headers_in.user.data = (u_char *) "";
  1598.         return NGX_DECLINED;
  1599.     }

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

  1601.     for (len = 0; len < auth.len; len++) {
  1602.         if (auth.data[len] == ':') {
  1603.             break;
  1604.         }
  1605.     }

  1606.     if (len == 0 || len == auth.len) {
  1607.         r->headers_in.user.data = (u_char *) "";
  1608.         return NGX_DECLINED;
  1609.     }

  1610.     r->headers_in.user.len = len;
  1611.     r->headers_in.user.data = auth.data;
  1612.     r->headers_in.passwd.len = auth.len - len - 1;
  1613.     r->headers_in.passwd.data = &auth.data[len + 1];

  1614.     return NGX_OK;
  1615. }


  1616. #if (NGX_HTTP_GZIP)

  1617. ngx_int_t
  1618. ngx_http_gzip_ok(ngx_http_request_t *r)
  1619. {
  1620.     time_t                     date, expires;
  1621.     ngx_uint_t                 p;
  1622.     ngx_table_elt_t           *e, *d, *ae, *cc;
  1623.     ngx_http_core_loc_conf_t  *clcf;

  1624.     r->gzip_tested = 1;

  1625.     if (r != r->main) {
  1626.         return NGX_DECLINED;
  1627.     }

  1628.     ae = r->headers_in.accept_encoding;
  1629.     if (ae == NULL) {
  1630.         return NGX_DECLINED;
  1631.     }

  1632.     if (ae->value.len < sizeof("gzip") - 1) {
  1633.         return NGX_DECLINED;
  1634.     }

  1635.     /*
  1636.      * test first for the most common case "gzip,...":
  1637.      *   MSIE:    "gzip, deflate"
  1638.      *   Firefox: "gzip,deflate"
  1639.      *   Chrome:  "gzip,deflate,sdch"
  1640.      *   Safari:  "gzip, deflate"
  1641.      *   Opera:   "gzip, deflate"
  1642.      */

  1643.     if (ngx_memcmp(ae->value.data, "gzip,", 5) != 0
  1644.         && ngx_http_gzip_accept_encoding(&ae->value) != NGX_OK)
  1645.     {
  1646.         return NGX_DECLINED;
  1647.     }

  1648.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1649.     if (r->headers_in.msie6 && clcf->gzip_disable_msie6) {
  1650.         return NGX_DECLINED;
  1651.     }

  1652.     if (r->http_version < clcf->gzip_http_version) {
  1653.         return NGX_DECLINED;
  1654.     }

  1655.     if (r->headers_in.via == NULL) {
  1656.         goto ok;
  1657.     }

  1658.     p = clcf->gzip_proxied;

  1659.     if (p & NGX_HTTP_GZIP_PROXIED_OFF) {
  1660.         return NGX_DECLINED;
  1661.     }

  1662.     if (p & NGX_HTTP_GZIP_PROXIED_ANY) {
  1663.         goto ok;
  1664.     }

  1665.     if (r->headers_in.authorization && (p & NGX_HTTP_GZIP_PROXIED_AUTH)) {
  1666.         goto ok;
  1667.     }

  1668.     e = r->headers_out.expires;

  1669.     if (e) {

  1670.         if (!(p & NGX_HTTP_GZIP_PROXIED_EXPIRED)) {
  1671.             return NGX_DECLINED;
  1672.         }

  1673.         expires = ngx_parse_http_time(e->value.data, e->value.len);
  1674.         if (expires == NGX_ERROR) {
  1675.             return NGX_DECLINED;
  1676.         }

  1677.         d = r->headers_out.date;

  1678.         if (d) {
  1679.             date = ngx_parse_http_time(d->value.data, d->value.len);
  1680.             if (date == NGX_ERROR) {
  1681.                 return NGX_DECLINED;
  1682.             }

  1683.         } else {
  1684.             date = ngx_time();
  1685.         }

  1686.         if (expires < date) {
  1687.             goto ok;
  1688.         }

  1689.         return NGX_DECLINED;
  1690.     }

  1691.     cc = r->headers_out.cache_control;

  1692.     if (cc) {

  1693.         if ((p & NGX_HTTP_GZIP_PROXIED_NO_CACHE)
  1694.             && ngx_http_parse_multi_header_lines(r, cc, &ngx_http_gzip_no_cache,
  1695.                                                  NULL)
  1696.                != NULL)
  1697.         {
  1698.             goto ok;
  1699.         }

  1700.         if ((p & NGX_HTTP_GZIP_PROXIED_NO_STORE)
  1701.             && ngx_http_parse_multi_header_lines(r, cc, &ngx_http_gzip_no_store,
  1702.                                                  NULL)
  1703.                != NULL)
  1704.         {
  1705.             goto ok;
  1706.         }

  1707.         if ((p & NGX_HTTP_GZIP_PROXIED_PRIVATE)
  1708.             && ngx_http_parse_multi_header_lines(r, cc, &ngx_http_gzip_private,
  1709.                                                  NULL)
  1710.                != NULL)
  1711.         {
  1712.             goto ok;
  1713.         }

  1714.         return NGX_DECLINED;
  1715.     }

  1716.     if ((p & NGX_HTTP_GZIP_PROXIED_NO_LM) && r->headers_out.last_modified) {
  1717.         return NGX_DECLINED;
  1718.     }

  1719.     if ((p & NGX_HTTP_GZIP_PROXIED_NO_ETAG) && r->headers_out.etag) {
  1720.         return NGX_DECLINED;
  1721.     }

  1722. ok:

  1723. #if (NGX_PCRE)

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

  1725.         if (ngx_regex_exec_array(clcf->gzip_disable,
  1726.                                  &r->headers_in.user_agent->value,
  1727.                                  r->connection->log)
  1728.             != NGX_DECLINED)
  1729.         {
  1730.             return NGX_DECLINED;
  1731.         }
  1732.     }

  1733. #endif

  1734.     r->gzip_ok = 1;

  1735.     return NGX_OK;
  1736. }


  1737. /*
  1738. * gzip is enabled for the following quantities:
  1739. *     "gzip; q=0.001" ... "gzip; q=1.000"
  1740. * gzip is disabled for the following quantities:
  1741. *     "gzip; q=0" ... "gzip; q=0.000", and for any invalid cases
  1742. */

  1743. static ngx_int_t
  1744. ngx_http_gzip_accept_encoding(ngx_str_t *ae)
  1745. {
  1746.     u_char  *p, *start, *last;

  1747.     start = ae->data;
  1748.     last = start + ae->len;

  1749.     for ( ;; ) {
  1750.         p = ngx_strcasestrn(start, "gzip", 4 - 1);
  1751.         if (p == NULL) {
  1752.             return NGX_DECLINED;
  1753.         }

  1754.         if (p == start || (*(p - 1) == ',' || *(p - 1) == ' ')) {
  1755.             break;
  1756.         }

  1757.         start = p + 4;
  1758.     }

  1759.     p += 4;

  1760.     while (p < last) {
  1761.         switch (*p++) {
  1762.         case ',':
  1763.             return NGX_OK;
  1764.         case ';':
  1765.             goto quantity;
  1766.         case ' ':
  1767.             continue;
  1768.         default:
  1769.             return NGX_DECLINED;
  1770.         }
  1771.     }

  1772.     return NGX_OK;

  1773. quantity:

  1774.     while (p < last) {
  1775.         switch (*p++) {
  1776.         case 'q':
  1777.         case 'Q':
  1778.             goto equal;
  1779.         case ' ':
  1780.             continue;
  1781.         default:
  1782.             return NGX_DECLINED;
  1783.         }
  1784.     }

  1785.     return NGX_OK;

  1786. equal:

  1787.     if (p + 2 > last || *p++ != '=') {
  1788.         return NGX_DECLINED;
  1789.     }

  1790.     if (ngx_http_gzip_quantity(p, last) == 0) {
  1791.         return NGX_DECLINED;
  1792.     }

  1793.     return NGX_OK;
  1794. }


  1795. static ngx_uint_t
  1796. ngx_http_gzip_quantity(u_char *p, u_char *last)
  1797. {
  1798.     u_char      c;
  1799.     ngx_uint_t  n, q;

  1800.     c = *p++;

  1801.     if (c != '0' && c != '1') {
  1802.         return 0;
  1803.     }

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

  1805.     if (p == last) {
  1806.         return q;
  1807.     }

  1808.     c = *p++;

  1809.     if (c == ',' || c == ' ') {
  1810.         return q;
  1811.     }

  1812.     if (c != '.') {
  1813.         return 0;
  1814.     }

  1815.     n = 0;

  1816.     while (p < last) {
  1817.         c = *p++;

  1818.         if (c == ',' || c == ' ') {
  1819.             break;
  1820.         }

  1821.         if (c >= '0' && c <= '9') {
  1822.             q += c - '0';
  1823.             n++;
  1824.             continue;
  1825.         }

  1826.         return 0;
  1827.     }

  1828.     if (q > 100 || n > 3) {
  1829.         return 0;
  1830.     }

  1831.     return q;
  1832. }

  1833. #endif


  1834. ngx_int_t
  1835. ngx_http_subrequest(ngx_http_request_t *r,
  1836.     ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **psr,
  1837.     ngx_http_post_subrequest_t *ps, ngx_uint_t flags)
  1838. {
  1839.     ngx_time_t                    *tp;
  1840.     ngx_connection_t              *c;
  1841.     ngx_http_request_t            *sr;
  1842.     ngx_http_core_srv_conf_t      *cscf;
  1843.     ngx_http_posted_request_t     *posted;
  1844.     ngx_http_postponed_request_t  *pr, *p;

  1845.     if (r->subrequests == 0) {
  1846.         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  1847.                       "subrequests cycle while processing \"%V\"", uri);
  1848.         return NGX_ERROR;
  1849.     }

  1850.     /*
  1851.      * 1000 is reserved for other purposes.
  1852.      */
  1853.     if (r->main->count >= 65535 - 1000) {
  1854.         ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,
  1855.                       "request reference counter overflow "
  1856.                       "while processing \"%V\"", uri);
  1857.         return NGX_ERROR;
  1858.     }

  1859.     if (r->subrequest_in_memory) {
  1860.         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  1861.                       "nested in-memory subrequest \"%V\"", uri);
  1862.         return NGX_ERROR;
  1863.     }

  1864.     sr = ngx_pcalloc(r->pool, sizeof(ngx_http_request_t));
  1865.     if (sr == NULL) {
  1866.         return NGX_ERROR;
  1867.     }

  1868.     sr->signature = NGX_HTTP_MODULE;

  1869.     c = r->connection;
  1870.     sr->connection = c;

  1871.     sr->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
  1872.     if (sr->ctx == NULL) {
  1873.         return NGX_ERROR;
  1874.     }

  1875.     if (ngx_list_init(&sr->headers_out.headers, r->pool, 20,
  1876.                       sizeof(ngx_table_elt_t))
  1877.         != NGX_OK)
  1878.     {
  1879.         return NGX_ERROR;
  1880.     }

  1881.     if (ngx_list_init(&sr->headers_out.trailers, r->pool, 4,
  1882.                       sizeof(ngx_table_elt_t))
  1883.         != NGX_OK)
  1884.     {
  1885.         return NGX_ERROR;
  1886.     }

  1887.     posted = ngx_palloc(r->pool, sizeof(ngx_http_posted_request_t));
  1888.     if (posted == NULL) {
  1889.         return NGX_ERROR;
  1890.     }

  1891.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
  1892.     sr->main_conf = cscf->ctx->main_conf;
  1893.     sr->srv_conf = cscf->ctx->srv_conf;
  1894.     sr->loc_conf = cscf->ctx->loc_conf;

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

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

  1897.     ngx_http_clear_content_length(sr);
  1898.     ngx_http_clear_accept_ranges(sr);
  1899.     ngx_http_clear_last_modified(sr);

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

  1901. #if (NGX_HTTP_V2)
  1902.     sr->stream = r->stream;
  1903. #endif

  1904.     sr->method = NGX_HTTP_GET;
  1905.     sr->http_version = r->http_version;

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

  1907.     sr->request_line = r->request_line;
  1908.     sr->uri = *uri;

  1909.     if (args) {
  1910.         sr->args = *args;
  1911.     }

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

  1914.     sr->subrequest_in_memory = (flags & NGX_HTTP_SUBREQUEST_IN_MEMORY) != 0;
  1915.     sr->waited = (flags & NGX_HTTP_SUBREQUEST_WAITED) != 0;
  1916.     sr->background = (flags & NGX_HTTP_SUBREQUEST_BACKGROUND) != 0;

  1917.     sr->unparsed_uri = r->unparsed_uri;
  1918.     sr->method_name = ngx_http_core_get_method;
  1919.     sr->http_protocol = r->http_protocol;
  1920.     sr->schema = r->schema;

  1921.     ngx_http_set_exten(sr);

  1922.     sr->main = r->main;
  1923.     sr->parent = r;
  1924.     sr->post_subrequest = ps;
  1925.     sr->read_event_handler = ngx_http_request_empty_handler;
  1926.     sr->write_event_handler = ngx_http_handler;

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

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

  1929.     if (sr->subrequest_in_memory) {
  1930.         sr->filter_need_in_memory = 1;
  1931.     }

  1932.     if (!sr->background) {
  1933.         pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t));
  1934.         if (pr == NULL) {
  1935.             return NGX_ERROR;
  1936.         }

  1937.         pr->request = sr;
  1938.         pr->out = NULL;
  1939.         pr->next = NULL;

  1940.         if (c->data == r && r->postponed == NULL) {
  1941.             c->data = sr;
  1942.         }

  1943.         if (r->postponed) {
  1944.             for (p = r->postponed; p->next; p = p->next) { /* void */ }
  1945.             p->next = pr;

  1946.         } else {
  1947.             r->postponed = pr;
  1948.         }
  1949.     }

  1950.     sr->internal = 1;

  1951.     sr->discard_body = r->discard_body;
  1952.     sr->expect_tested = 1;
  1953.     sr->main_filter_need_in_memory = r->main_filter_need_in_memory;

  1954.     sr->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1;
  1955.     sr->subrequests = r->subrequests - 1;

  1956.     tp = ngx_timeofday();
  1957.     sr->start_sec = tp->sec;
  1958.     sr->start_msec = tp->msec;

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

  1960.     *psr = sr;

  1961.     if (flags & NGX_HTTP_SUBREQUEST_CLONE) {
  1962.         sr->method = r->method;
  1963.         sr->method_name = r->method_name;
  1964.         sr->loc_conf = r->loc_conf;
  1965.         sr->valid_location = r->valid_location;
  1966.         sr->valid_unparsed_uri = r->valid_unparsed_uri;
  1967.         sr->content_handler = r->content_handler;
  1968.         sr->phase_handler = r->phase_handler;
  1969.         sr->write_event_handler = ngx_http_core_run_phases;

  1970. #if (NGX_PCRE)
  1971.         sr->ncaptures = r->ncaptures;
  1972.         sr->captures = r->captures;
  1973.         sr->captures_data = r->captures_data;
  1974.         sr->realloc_captures = 1;
  1975.         r->realloc_captures = 1;
  1976. #endif

  1977.         ngx_http_update_location_config(sr);
  1978.     }

  1979.     return ngx_http_post_request(sr, posted);
  1980. }


  1981. ngx_int_t
  1982. ngx_http_internal_redirect(ngx_http_request_t *r,
  1983.     ngx_str_t *uri, ngx_str_t *args)
  1984. {
  1985.     ngx_http_core_srv_conf_t  *cscf;

  1986.     r->uri_changes--;

  1987.     if (r->uri_changes == 0) {
  1988.         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  1989.                       "rewrite or internal redirection cycle "
  1990.                       "while internally redirecting to \"%V\"", uri);

  1991.         r->main->count++;
  1992.         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1993.         return NGX_DONE;
  1994.     }

  1995.     r->uri = *uri;

  1996.     if (args) {
  1997.         r->args = *args;

  1998.     } else {
  1999.         ngx_str_null(&r->args);
  2000.     }

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

  2003.     ngx_http_set_exten(r);

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

  2006.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
  2007.     r->loc_conf = cscf->ctx->loc_conf;

  2008.     ngx_http_update_location_config(r);

  2009. #if (NGX_HTTP_CACHE)
  2010.     r->cache = NULL;
  2011. #endif

  2012.     r->internal = 1;
  2013.     r->valid_unparsed_uri = 0;
  2014.     r->add_uri_to_alias = 0;
  2015.     r->main->count++;

  2016.     ngx_http_handler(r);

  2017.     return NGX_DONE;
  2018. }


  2019. ngx_int_t
  2020. ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name)
  2021. {
  2022.     ngx_http_core_srv_conf_t    *cscf;
  2023.     ngx_http_core_loc_conf_t   **clcfp;
  2024.     ngx_http_core_main_conf_t   *cmcf;

  2025.     r->main->count++;
  2026.     r->uri_changes--;

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

  2031.         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  2032.         return NGX_DONE;
  2033.     }

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

  2037.         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  2038.         return NGX_DONE;
  2039.     }

  2040.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

  2041.     if (cscf->named_locations) {

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

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

  2045.             if (name->len != (*clcfp)->name.len
  2046.                 || ngx_strncmp(name->data, (*clcfp)->name.data, name->len) != 0)
  2047.             {
  2048.                 continue;
  2049.             }

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

  2053.             r->internal = 1;
  2054.             r->content_handler = NULL;
  2055.             r->uri_changed = 0;
  2056.             r->loc_conf = (*clcfp)->loc_conf;

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

  2059.             ngx_http_update_location_config(r);

  2060.             cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

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

  2062.             r->write_event_handler = ngx_http_core_run_phases;
  2063.             ngx_http_core_run_phases(r);

  2064.             return NGX_DONE;
  2065.         }
  2066.     }

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

  2069.     ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);

  2070.     return NGX_DONE;
  2071. }


  2072. ngx_http_cleanup_t *
  2073. ngx_http_cleanup_add(ngx_http_request_t *r, size_t size)
  2074. {
  2075.     ngx_http_cleanup_t  *cln;

  2076.     r = r->main;

  2077.     cln = ngx_palloc(r->pool, sizeof(ngx_http_cleanup_t));
  2078.     if (cln == NULL) {
  2079.         return NULL;
  2080.     }

  2081.     if (size) {
  2082.         cln->data = ngx_palloc(r->pool, size);
  2083.         if (cln->data == NULL) {
  2084.             return NULL;
  2085.         }

  2086.     } else {
  2087.         cln->data = NULL;
  2088.     }

  2089.     cln->handler = NULL;
  2090.     cln->next = r->cleanup;

  2091.     r->cleanup = cln;

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

  2094.     return cln;
  2095. }


  2096. ngx_int_t
  2097. ngx_http_set_disable_symlinks(ngx_http_request_t *r,
  2098.     ngx_http_core_loc_conf_t *clcf, ngx_str_t *path, ngx_open_file_info_t *of)
  2099. {
  2100. #if (NGX_HAVE_OPENAT)
  2101.     u_char     *p;
  2102.     ngx_str_t   from;

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

  2104.     if (clcf->disable_symlinks_from == NULL) {
  2105.         return NGX_OK;
  2106.     }

  2107.     if (ngx_http_complex_value(r, clcf->disable_symlinks_from, &from)
  2108.         != NGX_OK)
  2109.     {
  2110.         return NGX_ERROR;
  2111.     }

  2112.     if (from.len == 0
  2113.         || from.len > path->len
  2114.         || ngx_memcmp(path->data, from.data, from.len) != 0)
  2115.     {
  2116.         return NGX_OK;
  2117.     }

  2118.     if (from.len == path->len) {
  2119.         of->disable_symlinks = NGX_DISABLE_SYMLINKS_OFF;
  2120.         return NGX_OK;
  2121.     }

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

  2123.     if (*p == '/') {
  2124.         of->disable_symlinks_from = from.len;
  2125.         return NGX_OK;
  2126.     }

  2127.     p--;

  2128.     if (*p == '/') {
  2129.         of->disable_symlinks_from = from.len - 1;
  2130.     }
  2131. #endif

  2132.     return NGX_OK;
  2133. }


  2134. ngx_int_t
  2135. ngx_http_get_forwarded_addr(ngx_http_request_t *r, ngx_addr_t *addr,
  2136.     ngx_table_elt_t *headers, ngx_str_t *value, ngx_array_t *proxies,
  2137.     int recursive)
  2138. {
  2139.     ngx_int_t         rc;
  2140.     ngx_uint_t        found;
  2141.     ngx_table_elt_t  *h, *next;

  2142.     if (headers == NULL) {
  2143.         return ngx_http_get_forwarded_addr_internal(r, addr, value->data,
  2144.                                                     value->len, proxies,
  2145.                                                     recursive);
  2146.     }

  2147.     /* revert headers order */

  2148.     for (h = headers, headers = NULL; h; h = next) {
  2149.         next = h->next;
  2150.         h->next = headers;
  2151.         headers = h;
  2152.     }

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

  2154.     rc = NGX_DECLINED;

  2155.     found = 0;

  2156.     for (h = headers; h; h = h->next) {
  2157.         rc = ngx_http_get_forwarded_addr_internal(r, addr, h->value.data,
  2158.                                                   h->value.len, proxies,
  2159.                                                   recursive);

  2160.         if (!recursive) {
  2161.             break;
  2162.         }

  2163.         if (rc == NGX_DECLINED && found) {
  2164.             rc = NGX_DONE;
  2165.             break;
  2166.         }

  2167.         if (rc != NGX_OK) {
  2168.             break;
  2169.         }

  2170.         found = 1;
  2171.     }

  2172.     /* restore headers order */

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

  2178.     return rc;
  2179. }


  2180. static ngx_int_t
  2181. ngx_http_get_forwarded_addr_internal(ngx_http_request_t *r, ngx_addr_t *addr,
  2182.     u_char *xff, size_t xfflen, ngx_array_t *proxies, int recursive)
  2183. {
  2184.     u_char      *p;
  2185.     ngx_addr_t   paddr;
  2186.     ngx_uint_t   found;

  2187.     found = 0;

  2188.     do {

  2189.         if (ngx_cidr_match(addr->sockaddr, proxies) != NGX_OK) {
  2190.             return found ? NGX_DONE : NGX_DECLINED;
  2191.         }

  2192.         for (p = xff + xfflen - 1; p > xff; p--, xfflen--) {
  2193.             if (*p != ' ' && *p != ',') {
  2194.                 break;
  2195.             }
  2196.         }

  2197.         for ( /* void */ ; p > xff; p--) {
  2198.             if (*p == ' ' || *p == ',') {
  2199.                 p++;
  2200.                 break;
  2201.             }
  2202.         }

  2203.         if (ngx_parse_addr_port(r->pool, &paddr, p, xfflen - (p - xff))
  2204.             != NGX_OK)
  2205.         {
  2206.             return found ? NGX_DONE : NGX_DECLINED;
  2207.         }

  2208.         *addr = paddr;
  2209.         found = 1;
  2210.         xfflen = p - 1 - xff;

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

  2212.     return NGX_OK;
  2213. }


  2214. ngx_int_t
  2215. ngx_http_link_multi_headers(ngx_http_request_t *r)
  2216. {
  2217.     ngx_uint_t        i, j;
  2218.     ngx_list_part_t  *part, *ppart;
  2219.     ngx_table_elt_t  *header, *pheader, **ph;

  2220.     if (r->headers_in.multi_linked) {
  2221.         return NGX_OK;
  2222.     }

  2223.     r->headers_in.multi_linked = 1;

  2224.     part = &r->headers_in.headers.part;
  2225.     header = part->elts;

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

  2227.         if (i >= part->nelts) {
  2228.             if (part->next == NULL) {
  2229.                 break;
  2230.             }

  2231.             part = part->next;
  2232.             header = part->elts;
  2233.             i = 0;
  2234.         }

  2235.         header[i].next = NULL;

  2236.         /*
  2237.          * search for previous headers with the same name;
  2238.          * if there are any, link to them
  2239.          */

  2240.         ppart = &r->headers_in.headers.part;
  2241.         pheader = ppart->elts;

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

  2243.             if (j >= ppart->nelts) {
  2244.                 if (ppart->next == NULL) {
  2245.                     break;
  2246.                 }

  2247.                 ppart = ppart->next;
  2248.                 pheader = ppart->elts;
  2249.                 j = 0;
  2250.             }

  2251.             if (part == ppart && i == j) {
  2252.                 break;
  2253.             }

  2254.             if (header[i].key.len == pheader[j].key.len
  2255.                 && ngx_strncasecmp(header[i].key.data, pheader[j].key.data,
  2256.                                    header[i].key.len)
  2257.                    == 0)
  2258.             {
  2259.                 ph = &pheader[j].next;
  2260.                 while (*ph) { ph = &(*ph)->next; }
  2261.                 *ph = &header[i];

  2262.                 r->headers_in.multi = 1;

  2263.                 break;
  2264.             }
  2265.         }
  2266.     }

  2267.     return NGX_OK;
  2268. }


  2269. static char *
  2270. ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
  2271. {
  2272.     char                        *rv;
  2273.     void                        *mconf;
  2274.     size_t                       len;
  2275.     u_char                      *p;
  2276.     ngx_uint_t                   i;
  2277.     ngx_conf_t                   pcf;
  2278.     ngx_http_module_t           *module;
  2279.     struct sockaddr_in          *sin;
  2280.     ngx_http_conf_ctx_t         *ctx, *http_ctx;
  2281.     ngx_http_listen_opt_t        lsopt;
  2282.     ngx_http_core_srv_conf_t    *cscf, **cscfp;
  2283.     ngx_http_core_main_conf_t   *cmcf;

  2284.     ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
  2285.     if (ctx == NULL) {
  2286.         return NGX_CONF_ERROR;
  2287.     }

  2288.     http_ctx = cf->ctx;
  2289.     ctx->main_conf = http_ctx->main_conf;

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

  2291.     ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
  2292.     if (ctx->srv_conf == NULL) {
  2293.         return NGX_CONF_ERROR;
  2294.     }

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

  2296.     ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
  2297.     if (ctx->loc_conf == NULL) {
  2298.         return NGX_CONF_ERROR;
  2299.     }

  2300.     for (i = 0; cf->cycle->modules[i]; i++) {
  2301.         if (cf->cycle->modules[i]->type != NGX_HTTP_MODULE) {
  2302.             continue;
  2303.         }

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

  2305.         if (module->create_srv_conf) {
  2306.             mconf = module->create_srv_conf(cf);
  2307.             if (mconf == NULL) {
  2308.                 return NGX_CONF_ERROR;
  2309.             }

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

  2312.         if (module->create_loc_conf) {
  2313.             mconf = module->create_loc_conf(cf);
  2314.             if (mconf == NULL) {
  2315.                 return NGX_CONF_ERROR;
  2316.             }

  2317.             ctx->loc_conf[cf->cycle->modules[i]->ctx_index] = mconf;
  2318.         }
  2319.     }


  2320.     /* the server configuration context */

  2321.     cscf = ctx->srv_conf[ngx_http_core_module.ctx_index];
  2322.     cscf->ctx = ctx;


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

  2324.     cscfp = ngx_array_push(&cmcf->servers);
  2325.     if (cscfp == NULL) {
  2326.         return NGX_CONF_ERROR;
  2327.     }

  2328.     *cscfp = cscf;


  2329.     /* parse inside server{} */

  2330.     pcf = *cf;
  2331.     cf->ctx = ctx;
  2332.     cf->cmd_type = NGX_HTTP_SRV_CONF;

  2333.     rv = ngx_conf_parse(cf, NULL);

  2334.     *cf = pcf;

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

  2337.         p = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in));
  2338.         if (p == NULL) {
  2339.             return NGX_CONF_ERROR;
  2340.         }

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

  2342.         sin = (struct sockaddr_in *) p;

  2343.         sin->sin_family = AF_INET;
  2344. #if (NGX_WIN32)
  2345.         sin->sin_port = htons(80);
  2346. #else
  2347.         sin->sin_port = htons((getuid() == 0) ? 80 : 8000);
  2348. #endif
  2349.         sin->sin_addr.s_addr = INADDR_ANY;

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

  2351.         lsopt.backlog = NGX_LISTEN_BACKLOG;
  2352.         lsopt.type = SOCK_STREAM;
  2353.         lsopt.rcvbuf = -1;
  2354.         lsopt.sndbuf = -1;
  2355. #if (NGX_HAVE_SETFIB)
  2356.         lsopt.setfib = -1;
  2357. #endif
  2358. #if (NGX_HAVE_TCP_FASTOPEN)
  2359.         lsopt.fastopen = -1;
  2360. #endif
  2361.         lsopt.wildcard = 1;

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

  2363.         p = ngx_pnalloc(cf->pool, len);
  2364.         if (p == NULL) {
  2365.             return NGX_CONF_ERROR;
  2366.         }

  2367.         lsopt.addr_text.data = p;
  2368.         lsopt.addr_text.len = ngx_sock_ntop(lsopt.sockaddr, lsopt.socklen, p,
  2369.                                             len, 1);

  2370.         if (ngx_http_add_listen(cf, cscf, &lsopt) != NGX_OK) {
  2371.             return NGX_CONF_ERROR;
  2372.         }
  2373.     }

  2374.     return rv;
  2375. }


  2376. static char *
  2377. ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
  2378. {
  2379.     char                      *rv;
  2380.     u_char                    *mod;
  2381.     size_t                     len;
  2382.     ngx_str_t                 *value, *name;
  2383.     ngx_uint_t                 i;
  2384.     ngx_conf_t                 save;
  2385.     ngx_http_module_t         *module;
  2386.     ngx_http_conf_ctx_t       *ctx, *pctx;
  2387.     ngx_http_core_loc_conf_t  *clcf, *pclcf;

  2388.     ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
  2389.     if (ctx == NULL) {
  2390.         return NGX_CONF_ERROR;
  2391.     }

  2392.     pctx = cf->ctx;
  2393.     ctx->main_conf = pctx->main_conf;
  2394.     ctx->srv_conf = pctx->srv_conf;

  2395.     ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
  2396.     if (ctx->loc_conf == NULL) {
  2397.         return NGX_CONF_ERROR;
  2398.     }

  2399.     for (i = 0; cf->cycle->modules[i]; i++) {
  2400.         if (cf->cycle->modules[i]->type != NGX_HTTP_MODULE) {
  2401.             continue;
  2402.         }

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

  2404.         if (module->create_loc_conf) {
  2405.             ctx->loc_conf[cf->cycle->modules[i]->ctx_index] =
  2406.                                                    module->create_loc_conf(cf);
  2407.             if (ctx->loc_conf[cf->cycle->modules[i]->ctx_index] == NULL) {
  2408.                 return NGX_CONF_ERROR;
  2409.             }
  2410.         }
  2411.     }

  2412.     clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
  2413.     clcf->loc_conf = ctx->loc_conf;

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

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

  2416.         len = value[1].len;
  2417.         mod = value[1].data;
  2418.         name = &value[2];

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

  2420.             clcf->name = *name;
  2421.             clcf->exact_match = 1;

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

  2423.             clcf->name = *name;
  2424.             clcf->noregex = 1;

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

  2426.             if (ngx_http_core_regex_location(cf, clcf, name, 0) != NGX_OK) {
  2427.                 return NGX_CONF_ERROR;
  2428.             }

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

  2430.             if (ngx_http_core_regex_location(cf, clcf, name, 1) != NGX_OK) {
  2431.                 return NGX_CONF_ERROR;
  2432.             }

  2433.         } else {
  2434.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2435.                                "invalid location modifier \"%V\"", &value[1]);
  2436.             return NGX_CONF_ERROR;
  2437.         }

  2438.     } else {

  2439.         name = &value[1];

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

  2441.             clcf->name.len = name->len - 1;
  2442.             clcf->name.data = name->data + 1;
  2443.             clcf->exact_match = 1;

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

  2445.             clcf->name.len = name->len - 2;
  2446.             clcf->name.data = name->data + 2;
  2447.             clcf->noregex = 1;

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

  2449.             name->len--;
  2450.             name->data++;

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

  2452.                 name->len--;
  2453.                 name->data++;

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

  2457.             } else {
  2458.                 if (ngx_http_core_regex_location(cf, clcf, name, 0) != NGX_OK) {
  2459.                     return NGX_CONF_ERROR;
  2460.                 }
  2461.             }

  2462.         } else {

  2463.             clcf->name = *name;

  2464.             if (name->data[0] == '@') {
  2465.                 clcf->named = 1;
  2466.             }
  2467.         }
  2468.     }

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

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

  2471.         /* nested location */

  2472. #if 0
  2473.         clcf->prev_location = pclcf;
  2474. #endif

  2475.         if (pclcf->exact_match) {
  2476.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2477.                                "location \"%V\" cannot be inside "
  2478.                                "the exact location \"%V\"",
  2479.                                &clcf->name, &pclcf->name);
  2480.             return NGX_CONF_ERROR;
  2481.         }

  2482.         if (pclcf->named) {
  2483.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2484.                                "location \"%V\" cannot be inside "
  2485.                                "the named location \"%V\"",
  2486.                                &clcf->name, &pclcf->name);
  2487.             return NGX_CONF_ERROR;
  2488.         }

  2489.         if (clcf->named) {
  2490.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2491.                                "named location \"%V\" can be "
  2492.                                "on the server level only",
  2493.                                &clcf->name);
  2494.             return NGX_CONF_ERROR;
  2495.         }

  2496.         len = pclcf->name.len;

  2497. #if (NGX_PCRE)
  2498.         if (clcf->regex == NULL
  2499.             && ngx_filename_cmp(clcf->name.data, pclcf->name.data, len) != 0)
  2500. #else
  2501.         if (ngx_filename_cmp(clcf->name.data, pclcf->name.data, len) != 0)
  2502. #endif
  2503.         {
  2504.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2505.                                "location \"%V\" is outside location \"%V\"",
  2506.                                &clcf->name, &pclcf->name);
  2507.             return NGX_CONF_ERROR;
  2508.         }
  2509.     }

  2510.     if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) {
  2511.         return NGX_CONF_ERROR;
  2512.     }

  2513.     save = *cf;
  2514.     cf->ctx = ctx;
  2515.     cf->cmd_type = NGX_HTTP_LOC_CONF;

  2516.     rv = ngx_conf_parse(cf, NULL);

  2517.     *cf = save;

  2518.     return rv;
  2519. }


  2520. static ngx_int_t
  2521. ngx_http_core_regex_location(ngx_conf_t *cf, ngx_http_core_loc_conf_t *clcf,
  2522.     ngx_str_t *regex, ngx_uint_t caseless)
  2523. {
  2524. #if (NGX_PCRE)
  2525.     ngx_regex_compile_t  rc;
  2526.     u_char               errstr[NGX_MAX_CONF_ERRSTR];

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

  2528.     rc.pattern = *regex;
  2529.     rc.err.len = NGX_MAX_CONF_ERRSTR;
  2530.     rc.err.data = errstr;

  2531. #if (NGX_HAVE_CASELESS_FILESYSTEM)
  2532.     rc.options = NGX_REGEX_CASELESS;
  2533. #else
  2534.     rc.options = caseless ? NGX_REGEX_CASELESS : 0;
  2535. #endif

  2536.     clcf->regex = ngx_http_regex_compile(cf, &rc);
  2537.     if (clcf->regex == NULL) {
  2538.         return NGX_ERROR;
  2539.     }

  2540.     clcf->name = *regex;

  2541.     return NGX_OK;

  2542. #else

  2543.     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2544.                        "using regex \"%V\" requires PCRE library",
  2545.                        regex);
  2546.     return NGX_ERROR;

  2547. #endif
  2548. }


  2549. static char *
  2550. ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  2551. {
  2552.     ngx_http_core_loc_conf_t *clcf = conf;

  2553.     char        *rv;
  2554.     ngx_conf_t   save;

  2555.     if (clcf->types == NULL) {
  2556.         clcf->types = ngx_array_create(cf->pool, 64, sizeof(ngx_hash_key_t));
  2557.         if (clcf->types == NULL) {
  2558.             return NGX_CONF_ERROR;
  2559.         }
  2560.     }

  2561.     save = *cf;
  2562.     cf->handler = ngx_http_core_type;
  2563.     cf->handler_conf = conf;

  2564.     rv = ngx_conf_parse(cf, NULL);

  2565.     *cf = save;

  2566.     return rv;
  2567. }


  2568. static char *
  2569. ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
  2570. {
  2571.     ngx_http_core_loc_conf_t *clcf = conf;

  2572.     ngx_str_t       *value, *content_type, *old;
  2573.     ngx_uint_t       i, n, hash;
  2574.     ngx_hash_key_t  *type;

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

  2576.     if (ngx_strcmp(value[0].data, "include") == 0) {
  2577.         if (cf->args->nelts != 2) {
  2578.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2579.                                "invalid number of arguments"
  2580.                                " in \"include\" directive");
  2581.             return NGX_CONF_ERROR;
  2582.         }

  2583.         return ngx_conf_include(cf, dummy, conf);
  2584.     }

  2585.     content_type = ngx_palloc(cf->pool, sizeof(ngx_str_t));
  2586.     if (content_type == NULL) {
  2587.         return NGX_CONF_ERROR;
  2588.     }

  2589.     *content_type = value[0];

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

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

  2592.         type = clcf->types->elts;
  2593.         for (n = 0; n < clcf->types->nelts; n++) {
  2594.             if (ngx_strcmp(value[i].data, type[n].key.data) == 0) {
  2595.                 old = type[n].value;
  2596.                 type[n].value = content_type;

  2597.                 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
  2598.                                    "duplicate extension \"%V\", "
  2599.                                    "content type: \"%V\", "
  2600.                                    "previous content type: \"%V\"",
  2601.                                    &value[i], content_type, old);
  2602.                 goto next;
  2603.             }
  2604.         }


  2605.         type = ngx_array_push(clcf->types);
  2606.         if (type == NULL) {
  2607.             return NGX_CONF_ERROR;
  2608.         }

  2609.         type->key = value[i];
  2610.         type->key_hash = hash;
  2611.         type->value = content_type;

  2612.     next:
  2613.         continue;
  2614.     }

  2615.     return NGX_CONF_OK;
  2616. }


  2617. static ngx_int_t
  2618. ngx_http_core_preconfiguration(ngx_conf_t *cf)
  2619. {
  2620.     return ngx_http_variables_add_core_vars(cf);
  2621. }


  2622. static ngx_int_t
  2623. ngx_http_core_postconfiguration(ngx_conf_t *cf)
  2624. {
  2625.     ngx_http_top_request_body_filter = ngx_http_request_body_save_filter;

  2626.     return NGX_OK;
  2627. }


  2628. static void *
  2629. ngx_http_core_create_main_conf(ngx_conf_t *cf)
  2630. {
  2631.     ngx_http_core_main_conf_t  *cmcf;

  2632.     cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_main_conf_t));
  2633.     if (cmcf == NULL) {
  2634.         return NULL;
  2635.     }

  2636.     if (ngx_array_init(&cmcf->servers, cf->pool, 4,
  2637.                        sizeof(ngx_http_core_srv_conf_t *))
  2638.         != NGX_OK)
  2639.     {
  2640.         return NULL;
  2641.     }

  2642.     cmcf->server_names_hash_max_size = NGX_CONF_UNSET_UINT;
  2643.     cmcf->server_names_hash_bucket_size = NGX_CONF_UNSET_UINT;

  2644.     cmcf->variables_hash_max_size = NGX_CONF_UNSET_UINT;
  2645.     cmcf->variables_hash_bucket_size = NGX_CONF_UNSET_UINT;

  2646.     return cmcf;
  2647. }


  2648. static char *
  2649. ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf)
  2650. {
  2651.     ngx_http_core_main_conf_t *cmcf = conf;

  2652.     ngx_conf_init_uint_value(cmcf->server_names_hash_max_size, 512);
  2653.     ngx_conf_init_uint_value(cmcf->server_names_hash_bucket_size,
  2654.                              ngx_cacheline_size);

  2655.     cmcf->server_names_hash_bucket_size =
  2656.             ngx_align(cmcf->server_names_hash_bucket_size, ngx_cacheline_size);


  2657.     ngx_conf_init_uint_value(cmcf->variables_hash_max_size, 1024);
  2658.     ngx_conf_init_uint_value(cmcf->variables_hash_bucket_size, 64);

  2659.     cmcf->variables_hash_bucket_size =
  2660.                ngx_align(cmcf->variables_hash_bucket_size, ngx_cacheline_size);

  2661.     if (cmcf->ncaptures) {
  2662.         cmcf->ncaptures = (cmcf->ncaptures + 1) * 3;
  2663.     }

  2664.     return NGX_CONF_OK;
  2665. }


  2666. static void *
  2667. ngx_http_core_create_srv_conf(ngx_conf_t *cf)
  2668. {
  2669.     ngx_http_core_srv_conf_t  *cscf;

  2670.     cscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_srv_conf_t));
  2671.     if (cscf == NULL) {
  2672.         return NULL;
  2673.     }

  2674.     /*
  2675.      * set by ngx_pcalloc():
  2676.      *
  2677.      *     conf->client_large_buffers.num = 0;
  2678.      */

  2679.     if (ngx_array_init(&cscf->server_names, cf->temp_pool, 4,
  2680.                        sizeof(ngx_http_server_name_t))
  2681.         != NGX_OK)
  2682.     {
  2683.         return NULL;
  2684.     }

  2685.     cscf->connection_pool_size = NGX_CONF_UNSET_SIZE;
  2686.     cscf->request_pool_size = NGX_CONF_UNSET_SIZE;
  2687.     cscf->client_header_timeout = NGX_CONF_UNSET_MSEC;
  2688.     cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE;
  2689.     cscf->max_headers = NGX_CONF_UNSET_UINT;
  2690.     cscf->ignore_invalid_headers = NGX_CONF_UNSET;
  2691.     cscf->merge_slashes = NGX_CONF_UNSET;
  2692.     cscf->underscores_in_headers = NGX_CONF_UNSET;

  2693.     cscf->file_name = cf->conf_file->file.name.data;
  2694.     cscf->line = cf->conf_file->line;

  2695.     return cscf;
  2696. }


  2697. static char *
  2698. ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
  2699. {
  2700.     ngx_http_core_srv_conf_t *prev = parent;
  2701.     ngx_http_core_srv_conf_t *conf = child;

  2702.     ngx_str_t                name;
  2703.     ngx_http_server_name_t  *sn;

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

  2705.     ngx_conf_merge_size_value(conf->connection_pool_size,
  2706.                               prev->connection_pool_size, 64 * sizeof(void *));
  2707.     ngx_conf_merge_size_value(conf->request_pool_size,
  2708.                               prev->request_pool_size, 4096);
  2709.     ngx_conf_merge_msec_value(conf->client_header_timeout,
  2710.                               prev->client_header_timeout, 60000);
  2711.     ngx_conf_merge_size_value(conf->client_header_buffer_size,
  2712.                               prev->client_header_buffer_size, 1024);
  2713.     ngx_conf_merge_bufs_value(conf->large_client_header_buffers,
  2714.                               prev->large_client_header_buffers,
  2715.                               4, 8192);

  2716.     if (conf->large_client_header_buffers.size < conf->connection_pool_size) {
  2717.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2718.                            "the \"large_client_header_buffers\" size must be "
  2719.                            "equal to or greater than \"connection_pool_size\"");
  2720.         return NGX_CONF_ERROR;
  2721.     }

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

  2723.     ngx_conf_merge_value(conf->ignore_invalid_headers,
  2724.                               prev->ignore_invalid_headers, 1);

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

  2726.     ngx_conf_merge_value(conf->underscores_in_headers,
  2727.                               prev->underscores_in_headers, 0);

  2728.     if (conf->server_names.nelts == 0) {
  2729.         /* the array has 4 empty preallocated elements, so push cannot fail */
  2730.         sn = ngx_array_push(&conf->server_names);
  2731. #if (NGX_PCRE)
  2732.         sn->regex = NULL;
  2733. #endif
  2734.         sn->server = conf;
  2735.         ngx_str_set(&sn->name, "");
  2736.     }

  2737.     sn = conf->server_names.elts;
  2738.     name = sn[0].name;

  2739. #if (NGX_PCRE)
  2740.     if (sn->regex) {
  2741.         name.len++;
  2742.         name.data--;
  2743.     } else
  2744. #endif

  2745.     if (name.data[0] == '.') {
  2746.         name.len--;
  2747.         name.data++;
  2748.     }

  2749.     conf->server_name.len = name.len;
  2750.     conf->server_name.data = ngx_pstrdup(cf->pool, &name);
  2751.     if (conf->server_name.data == NULL) {
  2752.         return NGX_CONF_ERROR;
  2753.     }

  2754.     return NGX_CONF_OK;
  2755. }


  2756. static void *
  2757. ngx_http_core_create_loc_conf(ngx_conf_t *cf)
  2758. {
  2759.     ngx_http_core_loc_conf_t  *clcf;

  2760.     clcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_loc_conf_t));
  2761.     if (clcf == NULL) {
  2762.         return NULL;
  2763.     }

  2764.     /*
  2765.      * set by ngx_pcalloc():
  2766.      *
  2767.      *     clcf->escaped_name = { 0, NULL };
  2768.      *     clcf->root = { 0, NULL };
  2769.      *     clcf->limit_except = 0;
  2770.      *     clcf->post_action = { 0, NULL };
  2771.      *     clcf->types = NULL;
  2772.      *     clcf->default_type = { 0, NULL };
  2773.      *     clcf->error_log = NULL;
  2774.      *     clcf->error_pages = NULL;
  2775.      *     clcf->client_body_path = NULL;
  2776.      *     clcf->regex = NULL;
  2777.      *     clcf->exact_match = 0;
  2778.      *     clcf->auto_redirect = 0;
  2779.      *     clcf->alias = 0;
  2780.      *     clcf->gzip_proxied = 0;
  2781.      *     clcf->keepalive_disable = 0;
  2782.      */

  2783.     clcf->client_max_body_size = NGX_CONF_UNSET;
  2784.     clcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE;
  2785.     clcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
  2786.     clcf->satisfy = NGX_CONF_UNSET_UINT;
  2787.     clcf->auth_delay = NGX_CONF_UNSET_MSEC;
  2788.     clcf->if_modified_since = NGX_CONF_UNSET_UINT;
  2789.     clcf->max_ranges = NGX_CONF_UNSET_UINT;
  2790.     clcf->client_body_in_file_only = NGX_CONF_UNSET_UINT;
  2791.     clcf->client_body_in_single_buffer = NGX_CONF_UNSET;
  2792.     clcf->internal = NGX_CONF_UNSET;
  2793.     clcf->sendfile = NGX_CONF_UNSET;
  2794.     clcf->sendfile_max_chunk = NGX_CONF_UNSET_SIZE;
  2795.     clcf->subrequest_output_buffer_size = NGX_CONF_UNSET_SIZE;
  2796.     clcf->aio = NGX_CONF_UNSET;
  2797.     clcf->aio_write = NGX_CONF_UNSET;
  2798. #if (NGX_THREADS)
  2799.     clcf->thread_pool = NGX_CONF_UNSET_PTR;
  2800.     clcf->thread_pool_value = NGX_CONF_UNSET_PTR;
  2801. #endif
  2802.     clcf->read_ahead = NGX_CONF_UNSET_SIZE;
  2803.     clcf->directio = NGX_CONF_UNSET;
  2804.     clcf->directio_alignment = NGX_CONF_UNSET;
  2805.     clcf->tcp_nopush = NGX_CONF_UNSET;
  2806.     clcf->tcp_nodelay = NGX_CONF_UNSET;
  2807.     clcf->send_timeout = NGX_CONF_UNSET_MSEC;
  2808.     clcf->send_lowat = NGX_CONF_UNSET_SIZE;
  2809.     clcf->postpone_output = NGX_CONF_UNSET_SIZE;
  2810.     clcf->limit_rate = NGX_CONF_UNSET_PTR;
  2811.     clcf->limit_rate_after = NGX_CONF_UNSET_PTR;
  2812.     clcf->keepalive_time = NGX_CONF_UNSET_MSEC;
  2813.     clcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
  2814.     clcf->keepalive_header = NGX_CONF_UNSET;
  2815.     clcf->keepalive_min_timeout = NGX_CONF_UNSET_MSEC;
  2816.     clcf->keepalive_requests = NGX_CONF_UNSET_UINT;
  2817.     clcf->lingering_close = NGX_CONF_UNSET_UINT;
  2818.     clcf->lingering_time = NGX_CONF_UNSET_MSEC;
  2819.     clcf->lingering_timeout = NGX_CONF_UNSET_MSEC;
  2820.     clcf->resolver_timeout = NGX_CONF_UNSET_MSEC;
  2821.     clcf->reset_timedout_connection = NGX_CONF_UNSET;
  2822.     clcf->absolute_redirect = NGX_CONF_UNSET;
  2823.     clcf->server_name_in_redirect = NGX_CONF_UNSET;
  2824.     clcf->port_in_redirect = NGX_CONF_UNSET;
  2825.     clcf->msie_padding = NGX_CONF_UNSET;
  2826.     clcf->msie_refresh = NGX_CONF_UNSET;
  2827.     clcf->log_not_found = NGX_CONF_UNSET;
  2828.     clcf->log_subrequest = NGX_CONF_UNSET;
  2829.     clcf->recursive_error_pages = NGX_CONF_UNSET;
  2830.     clcf->chunked_transfer_encoding = NGX_CONF_UNSET;
  2831.     clcf->etag = NGX_CONF_UNSET;
  2832.     clcf->server_tokens = NGX_CONF_UNSET_UINT;
  2833.     clcf->early_hints = NGX_CONF_UNSET_PTR;
  2834.     clcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
  2835.     clcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;

  2836.     clcf->open_file_cache = NGX_CONF_UNSET_PTR;
  2837.     clcf->open_file_cache_valid = NGX_CONF_UNSET;
  2838.     clcf->open_file_cache_min_uses = NGX_CONF_UNSET_UINT;
  2839.     clcf->open_file_cache_errors = NGX_CONF_UNSET;
  2840.     clcf->open_file_cache_events = NGX_CONF_UNSET;

  2841. #if (NGX_HTTP_GZIP)
  2842.     clcf->gzip_vary = NGX_CONF_UNSET;
  2843.     clcf->gzip_http_version = NGX_CONF_UNSET_UINT;
  2844. #if (NGX_PCRE)
  2845.     clcf->gzip_disable = NGX_CONF_UNSET_PTR;
  2846. #endif
  2847.     clcf->gzip_disable_msie6 = 3;
  2848. #if (NGX_HTTP_DEGRADATION)
  2849.     clcf->gzip_disable_degradation = 3;
  2850. #endif
  2851. #endif

  2852. #if (NGX_HAVE_OPENAT)
  2853.     clcf->disable_symlinks = NGX_CONF_UNSET_UINT;
  2854.     clcf->disable_symlinks_from = NGX_CONF_UNSET_PTR;
  2855. #endif

  2856.     return clcf;
  2857. }


  2858. static ngx_str_t  ngx_http_core_text_html_type = ngx_string("text/html");
  2859. static ngx_str_t  ngx_http_core_image_gif_type = ngx_string("image/gif");
  2860. static ngx_str_t  ngx_http_core_image_jpeg_type = ngx_string("image/jpeg");

  2861. static ngx_hash_key_t  ngx_http_core_default_types[] = {
  2862.     { ngx_string("html"), 0, &ngx_http_core_text_html_type },
  2863.     { ngx_string("gif"), 0, &ngx_http_core_image_gif_type },
  2864.     { ngx_string("jpg"), 0, &ngx_http_core_image_jpeg_type },
  2865.     { ngx_null_string, 0, NULL }
  2866. };


  2867. static char *
  2868. ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
  2869. {
  2870.     ngx_http_core_loc_conf_t *prev = parent;
  2871.     ngx_http_core_loc_conf_t *conf = child;

  2872.     ngx_uint_t        i;
  2873.     ngx_hash_key_t   *type;
  2874.     ngx_hash_init_t   types_hash;

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

  2876.         conf->alias = prev->alias;
  2877.         conf->root = prev->root;
  2878.         conf->root_lengths = prev->root_lengths;
  2879.         conf->root_values = prev->root_values;

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

  2882.             if (ngx_conf_full_name(cf->cycle, &conf->root, 0) != NGX_OK) {
  2883.                 return NGX_CONF_ERROR;
  2884.             }
  2885.         }
  2886.     }

  2887.     if (conf->post_action.data == NULL) {
  2888.         conf->post_action = prev->post_action;
  2889.     }

  2890.     ngx_conf_merge_uint_value(conf->types_hash_max_size,
  2891.                               prev->types_hash_max_size, 1024);

  2892.     ngx_conf_merge_uint_value(conf->types_hash_bucket_size,
  2893.                               prev->types_hash_bucket_size, 64);

  2894.     conf->types_hash_bucket_size = ngx_align(conf->types_hash_bucket_size,
  2895.                                              ngx_cacheline_size);

  2896.     /*
  2897.      * the special handling of the "types" directive in the "http" section
  2898.      * to inherit the http's conf->types_hash to all servers
  2899.      */

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

  2901.         types_hash.hash = &prev->types_hash;
  2902.         types_hash.key = ngx_hash_key_lc;
  2903.         types_hash.max_size = conf->types_hash_max_size;
  2904.         types_hash.bucket_size = conf->types_hash_bucket_size;
  2905.         types_hash.name = "types_hash";
  2906.         types_hash.pool = cf->pool;
  2907.         types_hash.temp_pool = NULL;

  2908.         if (ngx_hash_init(&types_hash, prev->types->elts, prev->types->nelts)
  2909.             != NGX_OK)
  2910.         {
  2911.             return NGX_CONF_ERROR;
  2912.         }
  2913.     }

  2914.     if (conf->types == NULL) {
  2915.         conf->types = prev->types;
  2916.         conf->types_hash = prev->types_hash;
  2917.     }

  2918.     if (conf->types == NULL) {
  2919.         conf->types = ngx_array_create(cf->pool, 3, sizeof(ngx_hash_key_t));
  2920.         if (conf->types == NULL) {
  2921.             return NGX_CONF_ERROR;
  2922.         }

  2923.         for (i = 0; ngx_http_core_default_types[i].key.len; i++) {
  2924.             type = ngx_array_push(conf->types);
  2925.             if (type == NULL) {
  2926.                 return NGX_CONF_ERROR;
  2927.             }

  2928.             type->key = ngx_http_core_default_types[i].key;
  2929.             type->key_hash =
  2930.                        ngx_hash_key_lc(ngx_http_core_default_types[i].key.data,
  2931.                                        ngx_http_core_default_types[i].key.len);
  2932.             type->value = ngx_http_core_default_types[i].value;
  2933.         }
  2934.     }

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

  2936.         types_hash.hash = &conf->types_hash;
  2937.         types_hash.key = ngx_hash_key_lc;
  2938.         types_hash.max_size = conf->types_hash_max_size;
  2939.         types_hash.bucket_size = conf->types_hash_bucket_size;
  2940.         types_hash.name = "types_hash";
  2941.         types_hash.pool = cf->pool;
  2942.         types_hash.temp_pool = NULL;

  2943.         if (ngx_hash_init(&types_hash, conf->types->elts, conf->types->nelts)
  2944.             != NGX_OK)
  2945.         {
  2946.             return NGX_CONF_ERROR;
  2947.         }
  2948.     }

  2949.     if (conf->error_log == NULL) {
  2950.         if (prev->error_log) {
  2951.             conf->error_log = prev->error_log;
  2952.         } else {
  2953.             conf->error_log = &cf->cycle->new_log;
  2954.         }
  2955.     }

  2956.     if (conf->error_pages == NULL && prev->error_pages) {
  2957.         conf->error_pages = prev->error_pages;
  2958.     }

  2959.     ngx_conf_merge_str_value(conf->default_type,
  2960.                               prev->default_type, "text/plain");

  2961.     ngx_conf_merge_off_value(conf->client_max_body_size,
  2962.                               prev->client_max_body_size, 1 * 1024 * 1024);
  2963.     ngx_conf_merge_size_value(conf->client_body_buffer_size,
  2964.                               prev->client_body_buffer_size,
  2965.                               (size_t) 2 * ngx_pagesize);
  2966.     ngx_conf_merge_msec_value(conf->client_body_timeout,
  2967.                               prev->client_body_timeout, 60000);

  2968.     ngx_conf_merge_bitmask_value(conf->keepalive_disable,
  2969.                               prev->keepalive_disable,
  2970.                               (NGX_CONF_BITMASK_SET
  2971.                                |NGX_HTTP_KEEPALIVE_DISABLE_MSIE6));
  2972.     ngx_conf_merge_uint_value(conf->satisfy, prev->satisfy,
  2973.                               NGX_HTTP_SATISFY_ALL);
  2974.     ngx_conf_merge_msec_value(conf->auth_delay, prev->auth_delay, 0);
  2975.     ngx_conf_merge_uint_value(conf->if_modified_since, prev->if_modified_since,
  2976.                               NGX_HTTP_IMS_EXACT);
  2977.     ngx_conf_merge_uint_value(conf->max_ranges, prev->max_ranges,
  2978.                               NGX_MAX_INT32_VALUE);
  2979.     ngx_conf_merge_uint_value(conf->client_body_in_file_only,
  2980.                               prev->client_body_in_file_only,
  2981.                               NGX_HTTP_REQUEST_BODY_FILE_OFF);
  2982.     ngx_conf_merge_value(conf->client_body_in_single_buffer,
  2983.                               prev->client_body_in_single_buffer, 0);
  2984.     ngx_conf_merge_value(conf->internal, prev->internal, 0);
  2985.     ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0);
  2986.     ngx_conf_merge_size_value(conf->sendfile_max_chunk,
  2987.                               prev->sendfile_max_chunk, 2 * 1024 * 1024);
  2988.     ngx_conf_merge_size_value(conf->subrequest_output_buffer_size,
  2989.                               prev->subrequest_output_buffer_size,
  2990.                               (size_t) ngx_pagesize);
  2991.     ngx_conf_merge_value(conf->aio, prev->aio, NGX_HTTP_AIO_OFF);
  2992.     ngx_conf_merge_value(conf->aio_write, prev->aio_write, 0);
  2993. #if (NGX_THREADS)
  2994.     ngx_conf_merge_ptr_value(conf->thread_pool, prev->thread_pool, NULL);
  2995.     ngx_conf_merge_ptr_value(conf->thread_pool_value, prev->thread_pool_value,
  2996.                              NULL);
  2997. #endif
  2998.     ngx_conf_merge_size_value(conf->read_ahead, prev->read_ahead, 0);
  2999.     ngx_conf_merge_off_value(conf->directio, prev->directio,
  3000.                               NGX_OPEN_FILE_DIRECTIO_OFF);
  3001.     ngx_conf_merge_off_value(conf->directio_alignment, prev->directio_alignment,
  3002.                               512);
  3003.     ngx_conf_merge_value(conf->tcp_nopush, prev->tcp_nopush, 0);
  3004.     ngx_conf_merge_value(conf->tcp_nodelay, prev->tcp_nodelay, 1);

  3005.     ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 60000);
  3006.     ngx_conf_merge_size_value(conf->send_lowat, prev->send_lowat, 0);
  3007.     ngx_conf_merge_size_value(conf->postpone_output, prev->postpone_output,
  3008.                               1460);

  3009.     ngx_conf_merge_ptr_value(conf->limit_rate, prev->limit_rate, NULL);
  3010.     ngx_conf_merge_ptr_value(conf->limit_rate_after,
  3011.                               prev->limit_rate_after, NULL);

  3012.     ngx_conf_merge_msec_value(conf->keepalive_time,
  3013.                               prev->keepalive_time, 3600000);
  3014.     ngx_conf_merge_msec_value(conf->keepalive_timeout,
  3015.                               prev->keepalive_timeout, 75000);
  3016.     ngx_conf_merge_sec_value(conf->keepalive_header,
  3017.                               prev->keepalive_header, 0);
  3018.     ngx_conf_merge_msec_value(conf->keepalive_min_timeout,
  3019.                               prev->keepalive_min_timeout, 0);
  3020.     ngx_conf_merge_uint_value(conf->keepalive_requests,
  3021.                               prev->keepalive_requests, 1000);
  3022.     ngx_conf_merge_uint_value(conf->lingering_close,
  3023.                               prev->lingering_close, NGX_HTTP_LINGERING_ON);
  3024.     ngx_conf_merge_msec_value(conf->lingering_time,
  3025.                               prev->lingering_time, 30000);
  3026.     ngx_conf_merge_msec_value(conf->lingering_timeout,
  3027.                               prev->lingering_timeout, 5000);
  3028.     ngx_conf_merge_msec_value(conf->resolver_timeout,
  3029.                               prev->resolver_timeout, 30000);

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

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

  3032.             /*
  3033.              * create dummy resolver in http {} context
  3034.              * to inherit it in all servers
  3035.              */

  3036.             prev->resolver = ngx_resolver_create(cf, NULL, 0);
  3037.             if (prev->resolver == NULL) {
  3038.                 return NGX_CONF_ERROR;
  3039.             }
  3040.         }

  3041.         conf->resolver = prev->resolver;
  3042.     }

  3043.     if (ngx_conf_merge_path_value(cf, &conf->client_body_temp_path,
  3044.                               prev->client_body_temp_path,
  3045.                               &ngx_http_client_temp_path)
  3046.         != NGX_CONF_OK)
  3047.     {
  3048.         return NGX_CONF_ERROR;
  3049.     }

  3050.     ngx_conf_merge_value(conf->reset_timedout_connection,
  3051.                               prev->reset_timedout_connection, 0);
  3052.     ngx_conf_merge_value(conf->absolute_redirect,
  3053.                               prev->absolute_redirect, 1);
  3054.     ngx_conf_merge_value(conf->server_name_in_redirect,
  3055.                               prev->server_name_in_redirect, 0);
  3056.     ngx_conf_merge_value(conf->port_in_redirect, prev->port_in_redirect, 1);
  3057.     ngx_conf_merge_value(conf->msie_padding, prev->msie_padding, 1);
  3058.     ngx_conf_merge_value(conf->msie_refresh, prev->msie_refresh, 0);
  3059.     ngx_conf_merge_value(conf->log_not_found, prev->log_not_found, 1);
  3060.     ngx_conf_merge_value(conf->log_subrequest, prev->log_subrequest, 0);
  3061.     ngx_conf_merge_value(conf->recursive_error_pages,
  3062.                               prev->recursive_error_pages, 0);
  3063.     ngx_conf_merge_value(conf->chunked_transfer_encoding,
  3064.                               prev->chunked_transfer_encoding, 1);
  3065.     ngx_conf_merge_value(conf->etag, prev->etag, 1);

  3066.     ngx_conf_merge_uint_value(conf->server_tokens, prev->server_tokens,
  3067.                               NGX_HTTP_SERVER_TOKENS_ON);

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

  3069.     ngx_conf_merge_ptr_value(conf->open_file_cache,
  3070.                               prev->open_file_cache, NULL);

  3071.     ngx_conf_merge_sec_value(conf->open_file_cache_valid,
  3072.                               prev->open_file_cache_valid, 60);

  3073.     ngx_conf_merge_uint_value(conf->open_file_cache_min_uses,
  3074.                               prev->open_file_cache_min_uses, 1);

  3075.     ngx_conf_merge_sec_value(conf->open_file_cache_errors,
  3076.                               prev->open_file_cache_errors, 0);

  3077.     ngx_conf_merge_sec_value(conf->open_file_cache_events,
  3078.                               prev->open_file_cache_events, 0);
  3079. #if (NGX_HTTP_GZIP)

  3080.     ngx_conf_merge_value(conf->gzip_vary, prev->gzip_vary, 0);
  3081.     ngx_conf_merge_uint_value(conf->gzip_http_version, prev->gzip_http_version,
  3082.                               NGX_HTTP_VERSION_11);
  3083.     ngx_conf_merge_bitmask_value(conf->gzip_proxied, prev->gzip_proxied,
  3084.                               (NGX_CONF_BITMASK_SET|NGX_HTTP_GZIP_PROXIED_OFF));

  3085. #if (NGX_PCRE)
  3086.     ngx_conf_merge_ptr_value(conf->gzip_disable, prev->gzip_disable, NULL);
  3087. #endif

  3088.     if (conf->gzip_disable_msie6 == 3) {
  3089.         conf->gzip_disable_msie6 =
  3090.             (prev->gzip_disable_msie6 == 3) ? 0 : prev->gzip_disable_msie6;
  3091.     }

  3092. #if (NGX_HTTP_DEGRADATION)

  3093.     if (conf->gzip_disable_degradation == 3) {
  3094.         conf->gzip_disable_degradation =
  3095.             (prev->gzip_disable_degradation == 3) ?
  3096.                  0 : prev->gzip_disable_degradation;
  3097.     }

  3098. #endif
  3099. #endif

  3100. #if (NGX_HAVE_OPENAT)
  3101.     ngx_conf_merge_uint_value(conf->disable_symlinks, prev->disable_symlinks,
  3102.                               NGX_DISABLE_SYMLINKS_OFF);
  3103.     ngx_conf_merge_ptr_value(conf->disable_symlinks_from,
  3104.                              prev->disable_symlinks_from, NULL);
  3105. #endif

  3106.     return NGX_CONF_OK;
  3107. }


  3108. static char *
  3109. ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3110. {
  3111.     ngx_http_core_srv_conf_t *cscf = conf;

  3112.     ngx_str_t              *value, size;
  3113.     ngx_url_t               u;
  3114.     ngx_uint_t              n, i, backlog;
  3115.     ngx_http_listen_opt_t   lsopt;

  3116.     cscf->listen = 1;

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

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

  3119.     u.url = value[1];
  3120.     u.listen = 1;
  3121.     u.default_port = 80;

  3122.     if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
  3123.         if (u.err) {
  3124.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3125.                                "%s in \"%V\" of the \"listen\" directive",
  3126.                                u.err, &u.url);
  3127.         }

  3128.         return NGX_CONF_ERROR;
  3129.     }

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

  3131.     lsopt.backlog = NGX_LISTEN_BACKLOG;
  3132.     lsopt.type = SOCK_STREAM;
  3133.     lsopt.rcvbuf = -1;
  3134.     lsopt.sndbuf = -1;
  3135. #if (NGX_HAVE_SETFIB)
  3136.     lsopt.setfib = -1;
  3137. #endif
  3138. #if (NGX_HAVE_TCP_FASTOPEN)
  3139.     lsopt.fastopen = -1;
  3140. #endif
  3141. #if (NGX_HAVE_INET6)
  3142.     lsopt.ipv6only = 1;
  3143. #endif

  3144.     backlog = 0;

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

  3146.         if (ngx_strcmp(value[n].data, "default_server") == 0
  3147.             || ngx_strcmp(value[n].data, "default") == 0)
  3148.         {
  3149.             lsopt.default_server = 1;
  3150.             continue;
  3151.         }

  3152.         if (ngx_strcmp(value[n].data, "bind") == 0) {
  3153.             lsopt.set = 1;
  3154.             lsopt.bind = 1;
  3155.             continue;
  3156.         }

  3157. #if (NGX_HAVE_SETFIB)
  3158.         if (ngx_strncmp(value[n].data, "setfib=", 7) == 0) {
  3159.             lsopt.setfib = ngx_atoi(value[n].data + 7, value[n].len - 7);
  3160.             lsopt.set = 1;
  3161.             lsopt.bind = 1;

  3162.             if (lsopt.setfib == NGX_ERROR) {
  3163.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3164.                                    "invalid setfib \"%V\"", &value[n]);
  3165.                 return NGX_CONF_ERROR;
  3166.             }

  3167.             continue;
  3168.         }
  3169. #endif

  3170. #if (NGX_HAVE_TCP_FASTOPEN)
  3171.         if (ngx_strncmp(value[n].data, "fastopen=", 9) == 0) {
  3172.             lsopt.fastopen = ngx_atoi(value[n].data + 9, value[n].len - 9);
  3173.             lsopt.set = 1;
  3174.             lsopt.bind = 1;

  3175.             if (lsopt.fastopen == NGX_ERROR) {
  3176.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3177.                                    "invalid fastopen \"%V\"", &value[n]);
  3178.                 return NGX_CONF_ERROR;
  3179.             }

  3180.             continue;
  3181.         }
  3182. #endif

  3183.         if (ngx_strncmp(value[n].data, "backlog=", 8) == 0) {
  3184.             lsopt.backlog = ngx_atoi(value[n].data + 8, value[n].len - 8);
  3185.             lsopt.set = 1;
  3186.             lsopt.bind = 1;

  3187.             if (lsopt.backlog == NGX_ERROR || lsopt.backlog == 0) {
  3188.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3189.                                    "invalid backlog \"%V\"", &value[n]);
  3190.                 return NGX_CONF_ERROR;
  3191.             }

  3192.             backlog = 1;

  3193.             continue;
  3194.         }

  3195.         if (ngx_strncmp(value[n].data, "rcvbuf=", 7) == 0) {
  3196.             size.len = value[n].len - 7;
  3197.             size.data = value[n].data + 7;

  3198.             lsopt.rcvbuf = ngx_parse_size(&size);
  3199.             lsopt.set = 1;
  3200.             lsopt.bind = 1;

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

  3206.             continue;
  3207.         }

  3208.         if (ngx_strncmp(value[n].data, "sndbuf=", 7) == 0) {
  3209.             size.len = value[n].len - 7;
  3210.             size.data = value[n].data + 7;

  3211.             lsopt.sndbuf = ngx_parse_size(&size);
  3212.             lsopt.set = 1;
  3213.             lsopt.bind = 1;

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

  3219.             continue;
  3220.         }

  3221.         if (ngx_strncmp(value[n].data, "accept_filter=", 14) == 0) {
  3222. #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
  3223.             lsopt.accept_filter = (char *) &value[n].data[14];
  3224.             lsopt.set = 1;
  3225.             lsopt.bind = 1;
  3226. #else
  3227.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3228.                                "accept filters \"%V\" are not supported "
  3229.                                "on this platform, ignored",
  3230.                                &value[n]);
  3231. #endif
  3232.             continue;
  3233.         }

  3234.         if (ngx_strcmp(value[n].data, "deferred") == 0) {
  3235. #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
  3236.             lsopt.deferred_accept = 1;
  3237.             lsopt.set = 1;
  3238.             lsopt.bind = 1;
  3239. #else
  3240.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3241.                                "the deferred accept is not supported "
  3242.                                "on this platform, ignored");
  3243. #endif
  3244.             continue;
  3245.         }

  3246.         if (ngx_strncmp(value[n].data, "ipv6only=o", 10) == 0) {
  3247. #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
  3248.             if (ngx_strcmp(&value[n].data[10], "n") == 0) {
  3249.                 lsopt.ipv6only = 1;

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

  3252.             } else {
  3253.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3254.                                    "invalid ipv6only flags \"%s\"",
  3255.                                    &value[n].data[9]);
  3256.                 return NGX_CONF_ERROR;
  3257.             }

  3258.             lsopt.set = 1;
  3259.             lsopt.bind = 1;

  3260.             continue;
  3261. #else
  3262.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3263.                                "ipv6only is not supported "
  3264.                                "on this platform");
  3265.             return NGX_CONF_ERROR;
  3266. #endif
  3267.         }

  3268.         if (ngx_strcmp(value[n].data, "reuseport") == 0) {
  3269. #if (NGX_HAVE_REUSEPORT)
  3270.             lsopt.reuseport = 1;
  3271.             lsopt.set = 1;
  3272.             lsopt.bind = 1;
  3273. #else
  3274.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3275.                                "reuseport is not supported "
  3276.                                "on this platform, ignored");
  3277. #endif
  3278.             continue;
  3279.         }

  3280.         if (ngx_strcmp(value[n].data, "multipath") == 0) {
  3281. #ifdef IPPROTO_MPTCP
  3282.             lsopt.protocol = IPPROTO_MPTCP;
  3283.             lsopt.set = 1;
  3284.             lsopt.bind = 1;
  3285. #else
  3286.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3287.                                "multipath is not supported "
  3288.                                "on this platform, ignored");
  3289. #endif
  3290.             continue;
  3291.         }

  3292.         if (ngx_strcmp(value[n].data, "ssl") == 0) {
  3293. #if (NGX_HTTP_SSL)
  3294.             lsopt.ssl = 1;
  3295.             continue;
  3296. #else
  3297.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3298.                                "the \"ssl\" parameter requires "
  3299.                                "ngx_http_ssl_module");
  3300.             return NGX_CONF_ERROR;
  3301. #endif
  3302.         }

  3303.         if (ngx_strcmp(value[n].data, "http2") == 0) {
  3304. #if (NGX_HTTP_V2)
  3305.             ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
  3306.                                "the \"listen ... http2\" directive "
  3307.                                "is deprecated, use "
  3308.                                "the \"http2\" directive instead");

  3309.             lsopt.http2 = 1;
  3310.             continue;
  3311. #else
  3312.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3313.                                "the \"http2\" parameter requires "
  3314.                                "ngx_http_v2_module");
  3315.             return NGX_CONF_ERROR;
  3316. #endif
  3317.         }

  3318.         if (ngx_strcmp(value[n].data, "quic") == 0) {
  3319. #if (NGX_HTTP_V3)
  3320.             lsopt.quic = 1;
  3321.             lsopt.type = SOCK_DGRAM;
  3322.             continue;
  3323. #else
  3324.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3325.                                "the \"quic\" parameter requires "
  3326.                                "ngx_http_v3_module");
  3327.             return NGX_CONF_ERROR;
  3328. #endif
  3329.         }

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

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

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

  3335.             } else {

  3336. #if (NGX_HAVE_KEEPALIVE_TUNABLE)
  3337.                 u_char     *p, *end;
  3338.                 ngx_str_t   s;

  3339.                 end = value[n].data + value[n].len;
  3340.                 s.data = value[n].data + 13;

  3341.                 p = ngx_strlchr(s.data, end, ':');
  3342.                 if (p == NULL) {
  3343.                     p = end;
  3344.                 }

  3345.                 if (p > s.data) {
  3346.                     s.len = p - s.data;

  3347.                     lsopt.tcp_keepidle = ngx_parse_time(&s, 1);
  3348.                     if (lsopt.tcp_keepidle == (time_t) NGX_ERROR) {
  3349.                         goto invalid_so_keepalive;
  3350.                     }
  3351.                 }

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

  3353.                 p = ngx_strlchr(s.data, end, ':');
  3354.                 if (p == NULL) {
  3355.                     p = end;
  3356.                 }

  3357.                 if (p > s.data) {
  3358.                     s.len = p - s.data;

  3359.                     lsopt.tcp_keepintvl = ngx_parse_time(&s, 1);
  3360.                     if (lsopt.tcp_keepintvl == (time_t) NGX_ERROR) {
  3361.                         goto invalid_so_keepalive;
  3362.                     }
  3363.                 }

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

  3365.                 if (s.data < end) {
  3366.                     s.len = end - s.data;

  3367.                     lsopt.tcp_keepcnt = ngx_atoi(s.data, s.len);
  3368.                     if (lsopt.tcp_keepcnt == NGX_ERROR) {
  3369.                         goto invalid_so_keepalive;
  3370.                     }
  3371.                 }

  3372.                 if (lsopt.tcp_keepidle == 0 && lsopt.tcp_keepintvl == 0
  3373.                     && lsopt.tcp_keepcnt == 0)
  3374.                 {
  3375.                     goto invalid_so_keepalive;
  3376.                 }

  3377.                 lsopt.so_keepalive = 1;

  3378. #else

  3379.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3380.                                    "the \"so_keepalive\" parameter accepts "
  3381.                                    "only \"on\" or \"off\" on this platform");
  3382.                 return NGX_CONF_ERROR;

  3383. #endif
  3384.             }

  3385.             lsopt.set = 1;
  3386.             lsopt.bind = 1;

  3387.             continue;

  3388. #if (NGX_HAVE_KEEPALIVE_TUNABLE)
  3389.         invalid_so_keepalive:

  3390.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3391.                                "invalid so_keepalive value: \"%s\"",
  3392.                                &value[n].data[13]);
  3393.             return NGX_CONF_ERROR;
  3394. #endif
  3395.         }

  3396.         if (ngx_strcmp(value[n].data, "proxy_protocol") == 0) {
  3397.             lsopt.proxy_protocol = 1;
  3398.             continue;
  3399.         }

  3400.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3401.                            "invalid parameter \"%V\"", &value[n]);
  3402.         return NGX_CONF_ERROR;
  3403.     }

  3404.     if (lsopt.quic) {
  3405. #if (NGX_HAVE_TCP_FASTOPEN)
  3406.         if (lsopt.fastopen != -1) {
  3407.             return "\"fastopen\" parameter is incompatible with \"quic\"";
  3408.         }
  3409. #endif

  3410.         if (backlog) {
  3411.             return "\"backlog\" parameter is incompatible with \"quic\"";
  3412.         }

  3413. #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
  3414.         if (lsopt.accept_filter) {
  3415.             return "\"accept_filter\" parameter is incompatible with \"quic\"";
  3416.         }
  3417. #endif

  3418. #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
  3419.         if (lsopt.deferred_accept) {
  3420.             return "\"deferred\" parameter is incompatible with \"quic\"";
  3421.         }
  3422. #endif

  3423. #ifdef IPPROTO_MPTCP
  3424.         if (lsopt.protocol == IPPROTO_MPTCP) {
  3425.              return "\"multipath\" parameter is incompatible with \"quic\"";
  3426.         }
  3427. #endif

  3428. #if (NGX_HTTP_SSL)
  3429.         if (lsopt.ssl) {
  3430.             return "\"ssl\" parameter is incompatible with \"quic\"";
  3431.         }
  3432. #endif

  3433. #if (NGX_HTTP_V2)
  3434.         if (lsopt.http2) {
  3435.             return "\"http2\" parameter is incompatible with \"quic\"";
  3436.         }
  3437. #endif

  3438.         if (lsopt.so_keepalive) {
  3439.             return "\"so_keepalive\" parameter is incompatible with \"quic\"";
  3440.         }

  3441.         if (lsopt.proxy_protocol) {
  3442.             return "\"proxy_protocol\" parameter is incompatible with \"quic\"";
  3443.         }
  3444.     }

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

  3446.         for (i = 0; i < n; i++) {
  3447.             if (ngx_cmp_sockaddr(u.addrs[n].sockaddr, u.addrs[n].socklen,
  3448.                                  u.addrs[i].sockaddr, u.addrs[i].socklen, 1)
  3449.                 == NGX_OK)
  3450.             {
  3451.                 goto next;
  3452.             }
  3453.         }

  3454.         lsopt.sockaddr = u.addrs[n].sockaddr;
  3455.         lsopt.socklen = u.addrs[n].socklen;
  3456.         lsopt.addr_text = u.addrs[n].name;
  3457.         lsopt.wildcard = ngx_inet_wildcard(lsopt.sockaddr);

  3458.         if (ngx_http_add_listen(cf, cscf, &lsopt) != NGX_OK) {
  3459.             return NGX_CONF_ERROR;
  3460.         }

  3461.     next:
  3462.         continue;
  3463.     }

  3464.     return NGX_CONF_OK;
  3465. }


  3466. static char *
  3467. ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3468. {
  3469.     ngx_http_core_srv_conf_t *cscf = conf;

  3470.     u_char                   ch;
  3471.     ngx_str_t               *value;
  3472.     ngx_uint_t               i;
  3473.     ngx_http_server_name_t  *sn;

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

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

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

  3477.         if ((ch == '*' && (value[i].len < 3 || value[i].data[1] != '.'))
  3478.             || (ch == '.' && value[i].len < 2))
  3479.         {
  3480.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3481.                                "server name \"%V\" is invalid", &value[i]);
  3482.             return NGX_CONF_ERROR;
  3483.         }

  3484.         if (ngx_strchr(value[i].data, '/')) {
  3485.             ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
  3486.                                "server name \"%V\" has suspicious symbols",
  3487.                                &value[i]);
  3488.         }

  3489.         sn = ngx_array_push(&cscf->server_names);
  3490.         if (sn == NULL) {
  3491.             return NGX_CONF_ERROR;
  3492.         }

  3493. #if (NGX_PCRE)
  3494.         sn->regex = NULL;
  3495. #endif
  3496.         sn->server = cscf;

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

  3499.         } else {
  3500.             sn->name = value[i];
  3501.         }

  3502.         if (value[i].data[0] != '~') {
  3503.             ngx_strlow(sn->name.data, sn->name.data, sn->name.len);
  3504.             continue;
  3505.         }

  3506. #if (NGX_PCRE)
  3507.         {
  3508.         u_char               *p;
  3509.         ngx_regex_compile_t   rc;
  3510.         u_char                errstr[NGX_MAX_CONF_ERRSTR];

  3511.         if (value[i].len == 1) {
  3512.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3513.                                "empty regex in server name \"%V\"", &value[i]);
  3514.             return NGX_CONF_ERROR;
  3515.         }

  3516.         value[i].len--;
  3517.         value[i].data++;

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

  3519.         rc.pattern = value[i];
  3520.         rc.err.len = NGX_MAX_CONF_ERRSTR;
  3521.         rc.err.data = errstr;

  3522.         for (p = value[i].data; p < value[i].data + value[i].len; p++) {
  3523.             if (*p >= 'A' && *p <= 'Z') {
  3524.                 rc.options = NGX_REGEX_CASELESS;
  3525.                 break;
  3526.             }
  3527.         }

  3528.         sn->regex = ngx_http_regex_compile(cf, &rc);
  3529.         if (sn->regex == NULL) {
  3530.             return NGX_CONF_ERROR;
  3531.         }

  3532.         sn->name = value[i];
  3533.         cscf->captures = (rc.captures > 0);
  3534.         }
  3535. #else
  3536.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3537.                            "using regex \"%V\" "
  3538.                            "requires PCRE library", &value[i]);

  3539.         return NGX_CONF_ERROR;
  3540. #endif
  3541.     }

  3542.     return NGX_CONF_OK;
  3543. }


  3544. static char *
  3545. ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3546. {
  3547.     ngx_http_core_loc_conf_t *clcf = conf;

  3548.     ngx_str_t                  *value;
  3549.     ngx_int_t                   alias;
  3550.     ngx_uint_t                  n;
  3551.     ngx_http_script_compile_t   sc;

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

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

  3554.         if ((clcf->alias != 0) == alias) {
  3555.             return "is duplicate";
  3556.         }

  3557.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3558.                            "\"%V\" directive is duplicate, "
  3559.                            "\"%s\" directive was specified earlier",
  3560.                            &cmd->name, clcf->alias ? "alias" : "root");

  3561.         return NGX_CONF_ERROR;
  3562.     }

  3563.     if (clcf->named && alias) {
  3564.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3565.                            "the \"alias\" directive cannot be used "
  3566.                            "inside the named location");

  3567.         return NGX_CONF_ERROR;
  3568.     }

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

  3570.     if (ngx_strstr(value[1].data, "$document_root")
  3571.         || ngx_strstr(value[1].data, "${document_root}"))
  3572.     {
  3573.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3574.                            "the $document_root variable cannot be used "
  3575.                            "in the \"%V\" directive",
  3576.                            &cmd->name);

  3577.         return NGX_CONF_ERROR;
  3578.     }

  3579.     if (ngx_strstr(value[1].data, "$realpath_root")
  3580.         || ngx_strstr(value[1].data, "${realpath_root}"))
  3581.     {
  3582.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3583.                            "the $realpath_root variable cannot be used "
  3584.                            "in the \"%V\" directive",
  3585.                            &cmd->name);

  3586.         return NGX_CONF_ERROR;
  3587.     }

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

  3590.     if (!alias && clcf->root.len > 0
  3591.         && clcf->root.data[clcf->root.len - 1] == '/')
  3592.     {
  3593.         clcf->root.len--;
  3594.     }

  3595.     if (clcf->root.data[0] != '$') {
  3596.         if (ngx_conf_full_name(cf->cycle, &clcf->root, 0) != NGX_OK) {
  3597.             return NGX_CONF_ERROR;
  3598.         }
  3599.     }

  3600.     n = ngx_http_script_variables_count(&clcf->root);

  3601.     ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
  3602.     sc.variables = n;

  3603. #if (NGX_PCRE)
  3604.     if (alias && clcf->regex) {
  3605.         clcf->alias = NGX_MAX_SIZE_T_VALUE;
  3606.         n = 1;
  3607.     }
  3608. #endif

  3609.     if (n) {
  3610.         sc.cf = cf;
  3611.         sc.source = &clcf->root;
  3612.         sc.lengths = &clcf->root_lengths;
  3613.         sc.values = &clcf->root_values;
  3614.         sc.complete_lengths = 1;
  3615.         sc.complete_values = 1;

  3616.         if (ngx_http_script_compile(&sc) != NGX_OK) {
  3617.             return NGX_CONF_ERROR;
  3618.         }
  3619.     }

  3620.     return NGX_CONF_OK;
  3621. }


  3622. static ngx_http_method_name_t  ngx_methods_names[] = {
  3623.     { (u_char *) "GET",       (uint32_t) ~NGX_HTTP_GET },
  3624.     { (u_char *) "HEAD",      (uint32_t) ~NGX_HTTP_HEAD },
  3625.     { (u_char *) "POST",      (uint32_t) ~NGX_HTTP_POST },
  3626.     { (u_char *) "PUT",       (uint32_t) ~NGX_HTTP_PUT },
  3627.     { (u_char *) "DELETE",    (uint32_t) ~NGX_HTTP_DELETE },
  3628.     { (u_char *) "MKCOL",     (uint32_t) ~NGX_HTTP_MKCOL },
  3629.     { (u_char *) "COPY",      (uint32_t) ~NGX_HTTP_COPY },
  3630.     { (u_char *) "MOVE",      (uint32_t) ~NGX_HTTP_MOVE },
  3631.     { (u_char *) "OPTIONS",   (uint32_t) ~NGX_HTTP_OPTIONS },
  3632.     { (u_char *) "PROPFIND",  (uint32_t) ~NGX_HTTP_PROPFIND },
  3633.     { (u_char *) "PROPPATCH", (uint32_t) ~NGX_HTTP_PROPPATCH },
  3634.     { (u_char *) "LOCK",      (uint32_t) ~NGX_HTTP_LOCK },
  3635.     { (u_char *) "UNLOCK",    (uint32_t) ~NGX_HTTP_UNLOCK },
  3636.     { (u_char *) "PATCH",     (uint32_t) ~NGX_HTTP_PATCH },
  3637.     { NULL, 0 }
  3638. };


  3639. static char *
  3640. ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3641. {
  3642.     ngx_http_core_loc_conf_t *pclcf = conf;

  3643.     char                      *rv;
  3644.     void                      *mconf;
  3645.     ngx_str_t                 *value;
  3646.     ngx_uint_t                 i;
  3647.     ngx_conf_t                 save;
  3648.     ngx_http_module_t         *module;
  3649.     ngx_http_conf_ctx_t       *ctx, *pctx;
  3650.     ngx_http_method_name_t    *name;
  3651.     ngx_http_core_loc_conf_t  *clcf;

  3652.     if (pclcf->limit_except) {
  3653.         return "is duplicate";
  3654.     }

  3655.     pclcf->limit_except = 0xffffffff;

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

  3657.     for (i = 1; i < cf->args->nelts; i++) {
  3658.         for (name = ngx_methods_names; name->name; name++) {

  3659.             if (ngx_strcasecmp(value[i].data, name->name) == 0) {
  3660.                 pclcf->limit_except &= name->method;
  3661.                 goto next;
  3662.             }
  3663.         }

  3664.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3665.                            "invalid method \"%V\"", &value[i]);
  3666.         return NGX_CONF_ERROR;

  3667.     next:
  3668.         continue;
  3669.     }

  3670.     if (!(pclcf->limit_except & NGX_HTTP_GET)) {
  3671.         pclcf->limit_except &= (uint32_t) ~NGX_HTTP_HEAD;
  3672.     }

  3673.     ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
  3674.     if (ctx == NULL) {
  3675.         return NGX_CONF_ERROR;
  3676.     }

  3677.     pctx = cf->ctx;
  3678.     ctx->main_conf = pctx->main_conf;
  3679.     ctx->srv_conf = pctx->srv_conf;

  3680.     ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
  3681.     if (ctx->loc_conf == NULL) {
  3682.         return NGX_CONF_ERROR;
  3683.     }

  3684.     for (i = 0; cf->cycle->modules[i]; i++) {
  3685.         if (cf->cycle->modules[i]->type != NGX_HTTP_MODULE) {
  3686.             continue;
  3687.         }

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

  3689.         if (module->create_loc_conf) {

  3690.             mconf = module->create_loc_conf(cf);
  3691.             if (mconf == NULL) {
  3692.                 return NGX_CONF_ERROR;
  3693.             }

  3694.             ctx->loc_conf[cf->cycle->modules[i]->ctx_index] = mconf;
  3695.         }
  3696.     }


  3697.     clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
  3698.     pclcf->limit_except_loc_conf = ctx->loc_conf;
  3699.     clcf->loc_conf = ctx->loc_conf;
  3700.     clcf->name = pclcf->name;
  3701.     clcf->noname = 1;
  3702.     clcf->lmt_excpt = 1;

  3703.     if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) {
  3704.         return NGX_CONF_ERROR;
  3705.     }

  3706.     save = *cf;
  3707.     cf->ctx = ctx;
  3708.     cf->cmd_type = NGX_HTTP_LMT_CONF;

  3709.     rv = ngx_conf_parse(cf, NULL);

  3710.     *cf = save;

  3711.     return rv;
  3712. }


  3713. static char *
  3714. ngx_http_core_set_aio(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3715. {
  3716.     ngx_http_core_loc_conf_t *clcf = conf;

  3717.     ngx_str_t  *value;

  3718.     if (clcf->aio != NGX_CONF_UNSET) {
  3719.         return "is duplicate";
  3720.     }

  3721. #if (NGX_THREADS)
  3722.     clcf->thread_pool = NULL;
  3723.     clcf->thread_pool_value = NULL;
  3724. #endif

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

  3726.     if (ngx_strcmp(value[1].data, "off") == 0) {
  3727.         clcf->aio = NGX_HTTP_AIO_OFF;
  3728.         return NGX_CONF_OK;
  3729.     }

  3730.     if (ngx_strcmp(value[1].data, "on") == 0) {
  3731. #if (NGX_HAVE_FILE_AIO)
  3732.         clcf->aio = NGX_HTTP_AIO_ON;
  3733.         return NGX_CONF_OK;
  3734. #else
  3735.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3736.                            "\"aio on\" "
  3737.                            "is unsupported on this platform");
  3738.         return NGX_CONF_ERROR;
  3739. #endif
  3740.     }

  3741.     if (ngx_strncmp(value[1].data, "threads", 7) == 0
  3742.         && (value[1].len == 7 || value[1].data[7] == '='))
  3743.     {
  3744. #if (NGX_THREADS)
  3745.         ngx_str_t                          name;
  3746.         ngx_thread_pool_t                 *tp;
  3747.         ngx_http_complex_value_t           cv;
  3748.         ngx_http_compile_complex_value_t   ccv;

  3749.         clcf->aio = NGX_HTTP_AIO_THREADS;

  3750.         if (value[1].len >= 8) {
  3751.             name.len = value[1].len - 8;
  3752.             name.data = value[1].data + 8;

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

  3754.             ccv.cf = cf;
  3755.             ccv.value = &name;
  3756.             ccv.complex_value = &cv;

  3757.             if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
  3758.                 return NGX_CONF_ERROR;
  3759.             }

  3760.             if (cv.lengths != NULL) {
  3761.                 clcf->thread_pool_value = ngx_palloc(cf->pool,
  3762.                                     sizeof(ngx_http_complex_value_t));
  3763.                 if (clcf->thread_pool_value == NULL) {
  3764.                     return NGX_CONF_ERROR;
  3765.                 }

  3766.                 *clcf->thread_pool_value = cv;

  3767.                 return NGX_CONF_OK;
  3768.             }

  3769.             tp = ngx_thread_pool_add(cf, &name);

  3770.         } else {
  3771.             tp = ngx_thread_pool_add(cf, NULL);
  3772.         }

  3773.         if (tp == NULL) {
  3774.             return NGX_CONF_ERROR;
  3775.         }

  3776.         clcf->thread_pool = tp;

  3777.         return NGX_CONF_OK;
  3778. #else
  3779.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3780.                            "\"aio threads\" "
  3781.                            "is unsupported on this platform");
  3782.         return NGX_CONF_ERROR;
  3783. #endif
  3784.     }

  3785.     return "invalid value";
  3786. }


  3787. static char *
  3788. ngx_http_core_directio(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3789. {
  3790.     ngx_http_core_loc_conf_t *clcf = conf;

  3791.     ngx_str_t  *value;

  3792.     if (clcf->directio != NGX_CONF_UNSET) {
  3793.         return "is duplicate";
  3794.     }

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

  3796.     if (ngx_strcmp(value[1].data, "off") == 0) {
  3797.         clcf->directio = NGX_OPEN_FILE_DIRECTIO_OFF;
  3798.         return NGX_CONF_OK;
  3799.     }

  3800.     clcf->directio = ngx_parse_offset(&value[1]);
  3801.     if (clcf->directio == (off_t) NGX_ERROR) {
  3802.         return "invalid value";
  3803.     }

  3804.     return NGX_CONF_OK;
  3805. }


  3806. static char *
  3807. ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3808. {
  3809.     ngx_http_core_loc_conf_t *clcf = conf;

  3810.     u_char                            *p;
  3811.     ngx_int_t                          overwrite;
  3812.     ngx_str_t                         *value, uri, args;
  3813.     ngx_uint_t                         i, n;
  3814.     ngx_http_err_page_t               *err;
  3815.     ngx_http_complex_value_t           cv;
  3816.     ngx_http_compile_complex_value_t   ccv;

  3817.     if (clcf->error_pages == NULL) {
  3818.         clcf->error_pages = ngx_array_create(cf->pool, 4,
  3819.                                              sizeof(ngx_http_err_page_t));
  3820.         if (clcf->error_pages == NULL) {
  3821.             return NGX_CONF_ERROR;
  3822.         }
  3823.     }

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

  3825.     i = cf->args->nelts - 2;

  3826.     if (value[i].data[0] == '=') {
  3827.         if (i == 1) {
  3828.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3829.                                "invalid value \"%V\"", &value[i]);
  3830.             return NGX_CONF_ERROR;
  3831.         }

  3832.         if (value[i].len > 1) {
  3833.             overwrite = ngx_atoi(&value[i].data[1], value[i].len - 1);

  3834.             if (overwrite == NGX_ERROR) {
  3835.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3836.                                    "invalid value \"%V\"", &value[i]);
  3837.                 return NGX_CONF_ERROR;
  3838.             }

  3839.         } else {
  3840.             overwrite = 0;
  3841.         }

  3842.         n = 2;

  3843.     } else {
  3844.         overwrite = -1;
  3845.         n = 1;
  3846.     }

  3847.     uri = value[cf->args->nelts - 1];

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

  3849.     ccv.cf = cf;
  3850.     ccv.value = &uri;
  3851.     ccv.complex_value = &cv;

  3852.     if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
  3853.         return NGX_CONF_ERROR;
  3854.     }

  3855.     ngx_str_null(&args);

  3856.     if (cv.lengths == NULL && uri.len && uri.data[0] == '/') {
  3857.         p = (u_char *) ngx_strchr(uri.data, '?');

  3858.         if (p) {
  3859.             cv.value.len = p - uri.data;
  3860.             cv.value.data = uri.data;
  3861.             p++;
  3862.             args.len = (uri.data + uri.len) - p;
  3863.             args.data = p;
  3864.         }
  3865.     }

  3866.     for (i = 1; i < cf->args->nelts - n; i++) {
  3867.         err = ngx_array_push(clcf->error_pages);
  3868.         if (err == NULL) {
  3869.             return NGX_CONF_ERROR;
  3870.         }

  3871.         err->status = ngx_atoi(value[i].data, value[i].len);

  3872.         if (err->status == NGX_ERROR || err->status == 499) {
  3873.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3874.                                "invalid value \"%V\"", &value[i]);
  3875.             return NGX_CONF_ERROR;
  3876.         }

  3877.         if (err->status < 300 || err->status > 599) {
  3878.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3879.                                "value \"%V\" must be between 300 and 599",
  3880.                                &value[i]);
  3881.             return NGX_CONF_ERROR;
  3882.         }

  3883.         err->overwrite = overwrite;

  3884.         if (overwrite == -1) {
  3885.             switch (err->status) {
  3886.                 case NGX_HTTP_TO_HTTPS:
  3887.                 case NGX_HTTPS_CERT_ERROR:
  3888.                 case NGX_HTTPS_NO_CERT:
  3889.                 case NGX_HTTP_REQUEST_HEADER_TOO_LARGE:
  3890.                     err->overwrite = NGX_HTTP_BAD_REQUEST;
  3891.             }
  3892.         }

  3893.         err->value = cv;
  3894.         err->args = args;
  3895.     }

  3896.     return NGX_CONF_OK;
  3897. }


  3898. static char *
  3899. ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3900. {
  3901.     ngx_http_core_loc_conf_t *clcf = conf;

  3902.     time_t       inactive;
  3903.     ngx_str_t   *value, s;
  3904.     ngx_int_t    max;
  3905.     ngx_uint_t   i;

  3906.     if (clcf->open_file_cache != NGX_CONF_UNSET_PTR) {
  3907.         return "is duplicate";
  3908.     }

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

  3910.     max = 0;
  3911.     inactive = 60;

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

  3913.         if (ngx_strncmp(value[i].data, "max=", 4) == 0) {

  3914.             max = ngx_atoi(value[i].data + 4, value[i].len - 4);
  3915.             if (max <= 0) {
  3916.                 goto failed;
  3917.             }

  3918.             continue;
  3919.         }

  3920.         if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) {

  3921.             s.len = value[i].len - 9;
  3922.             s.data = value[i].data + 9;

  3923.             inactive = ngx_parse_time(&s, 1);
  3924.             if (inactive == (time_t) NGX_ERROR) {
  3925.                 goto failed;
  3926.             }

  3927.             continue;
  3928.         }

  3929.         if (ngx_strcmp(value[i].data, "off") == 0) {

  3930.             clcf->open_file_cache = NULL;

  3931.             continue;
  3932.         }

  3933.     failed:

  3934.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3935.                            "invalid \"open_file_cache\" parameter \"%V\"",
  3936.                            &value[i]);
  3937.         return NGX_CONF_ERROR;
  3938.     }

  3939.     if (clcf->open_file_cache == NULL) {
  3940.         return NGX_CONF_OK;
  3941.     }

  3942.     if (max == 0) {
  3943.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3944.                         "\"open_file_cache\" must have the \"max\" parameter");
  3945.         return NGX_CONF_ERROR;
  3946.     }

  3947.     clcf->open_file_cache = ngx_open_file_cache_init(cf->pool, max, inactive);
  3948.     if (clcf->open_file_cache) {
  3949.         return NGX_CONF_OK;
  3950.     }

  3951.     return NGX_CONF_ERROR;
  3952. }


  3953. static char *
  3954. ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3955. {
  3956.     ngx_http_core_loc_conf_t *clcf = conf;

  3957.     return ngx_log_set_log(cf, &clcf->error_log);
  3958. }


  3959. static char *
  3960. ngx_http_core_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3961. {
  3962.     ngx_http_core_loc_conf_t *clcf = conf;

  3963.     ngx_str_t  *value;

  3964.     if (clcf->keepalive_timeout != NGX_CONF_UNSET_MSEC) {
  3965.         return "is duplicate";
  3966.     }

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

  3968.     clcf->keepalive_timeout = ngx_parse_time(&value[1], 0);

  3969.     if (clcf->keepalive_timeout == (ngx_msec_t) NGX_ERROR) {
  3970.         return "invalid value";
  3971.     }

  3972.     if (cf->args->nelts == 2) {
  3973.         return NGX_CONF_OK;
  3974.     }

  3975.     clcf->keepalive_header = ngx_parse_time(&value[2], 1);

  3976.     if (clcf->keepalive_header == (time_t) NGX_ERROR) {
  3977.         return "invalid value";
  3978.     }

  3979.     return NGX_CONF_OK;
  3980. }


  3981. static char *
  3982. ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3983. {
  3984.     ngx_http_core_loc_conf_t *clcf = conf;

  3985.     if (clcf->internal != NGX_CONF_UNSET) {
  3986.         return "is duplicate";
  3987.     }

  3988.     clcf->internal = 1;

  3989.     return NGX_CONF_OK;
  3990. }


  3991. static char *
  3992. ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3993. {
  3994.     ngx_http_core_loc_conf_t  *clcf = conf;

  3995.     ngx_str_t  *value;

  3996.     if (clcf->resolver) {
  3997.         return "is duplicate";
  3998.     }

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

  4000.     clcf->resolver = ngx_resolver_create(cf, &value[1], cf->args->nelts - 1);
  4001.     if (clcf->resolver == NULL) {
  4002.         return NGX_CONF_ERROR;
  4003.     }

  4004.     return NGX_CONF_OK;
  4005. }


  4006. #if (NGX_HTTP_GZIP)

  4007. static char *
  4008. ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  4009. {
  4010.     ngx_http_core_loc_conf_t  *clcf = conf;

  4011. #if (NGX_PCRE)

  4012.     ngx_str_t            *value;
  4013.     ngx_uint_t            i;
  4014.     ngx_regex_elt_t      *re;
  4015.     ngx_regex_compile_t   rc;
  4016.     u_char                errstr[NGX_MAX_CONF_ERRSTR];

  4017.     if (clcf->gzip_disable == NGX_CONF_UNSET_PTR) {
  4018.         clcf->gzip_disable = ngx_array_create(cf->pool, 2,
  4019.                                               sizeof(ngx_regex_elt_t));
  4020.         if (clcf->gzip_disable == NULL) {
  4021.             return NGX_CONF_ERROR;
  4022.         }
  4023.     }

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

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

  4026.     rc.pool = cf->pool;
  4027.     rc.err.len = NGX_MAX_CONF_ERRSTR;
  4028.     rc.err.data = errstr;

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

  4030.         if (ngx_strcmp(value[i].data, "msie6") == 0) {
  4031.             clcf->gzip_disable_msie6 = 1;
  4032.             continue;
  4033.         }

  4034. #if (NGX_HTTP_DEGRADATION)

  4035.         if (ngx_strcmp(value[i].data, "degradation") == 0) {
  4036.             clcf->gzip_disable_degradation = 1;
  4037.             continue;
  4038.         }

  4039. #endif

  4040.         re = ngx_array_push(clcf->gzip_disable);
  4041.         if (re == NULL) {
  4042.             return NGX_CONF_ERROR;
  4043.         }

  4044.         rc.pattern = value[i];
  4045.         rc.options = NGX_REGEX_CASELESS;

  4046.         if (ngx_regex_compile(&rc) != NGX_OK) {
  4047.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc.err);
  4048.             return NGX_CONF_ERROR;
  4049.         }

  4050.         re->regex = rc.regex;
  4051.         re->name = value[i].data;
  4052.     }

  4053.     return NGX_CONF_OK;

  4054. #else
  4055.     ngx_str_t   *value;
  4056.     ngx_uint_t   i;

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

  4058.     for (i = 1; i < cf->args->nelts; i++) {
  4059.         if (ngx_strcmp(value[i].data, "msie6") == 0) {
  4060.             clcf->gzip_disable_msie6 = 1;
  4061.             continue;
  4062.         }

  4063. #if (NGX_HTTP_DEGRADATION)

  4064.         if (ngx_strcmp(value[i].data, "degradation") == 0) {
  4065.             clcf->gzip_disable_degradation = 1;
  4066.             continue;
  4067.         }

  4068. #endif

  4069.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  4070.                            "without PCRE library \"gzip_disable\" supports "
  4071.                            "builtin \"msie6\" and \"degradation\" mask only");

  4072.         return NGX_CONF_ERROR;
  4073.     }

  4074.     return NGX_CONF_OK;

  4075. #endif
  4076. }

  4077. #endif


  4078. #if (NGX_HAVE_OPENAT)

  4079. static char *
  4080. ngx_http_disable_symlinks(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  4081. {
  4082.     ngx_http_core_loc_conf_t *clcf = conf;

  4083.     ngx_str_t                         *value;
  4084.     ngx_uint_t                         i;
  4085.     ngx_http_compile_complex_value_t   ccv;

  4086.     if (clcf->disable_symlinks != NGX_CONF_UNSET_UINT) {
  4087.         return "is duplicate";
  4088.     }

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

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

  4091.         if (ngx_strcmp(value[i].data, "off") == 0) {
  4092.             clcf->disable_symlinks = NGX_DISABLE_SYMLINKS_OFF;
  4093.             continue;
  4094.         }

  4095.         if (ngx_strcmp(value[i].data, "if_not_owner") == 0) {
  4096.             clcf->disable_symlinks = NGX_DISABLE_SYMLINKS_NOTOWNER;
  4097.             continue;
  4098.         }

  4099.         if (ngx_strcmp(value[i].data, "on") == 0) {
  4100.             clcf->disable_symlinks = NGX_DISABLE_SYMLINKS_ON;
  4101.             continue;
  4102.         }

  4103.         if (ngx_strncmp(value[i].data, "from=", 5) == 0) {
  4104.             value[i].len -= 5;
  4105.             value[i].data += 5;

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

  4107.             ccv.cf = cf;
  4108.             ccv.value = &value[i];
  4109.             ccv.complex_value = ngx_palloc(cf->pool,
  4110.                                            sizeof(ngx_http_complex_value_t));
  4111.             if (ccv.complex_value == NULL) {
  4112.                 return NGX_CONF_ERROR;
  4113.             }

  4114.             if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
  4115.                 return NGX_CONF_ERROR;
  4116.             }

  4117.             clcf->disable_symlinks_from = ccv.complex_value;

  4118.             continue;
  4119.         }

  4120.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  4121.                            "invalid parameter \"%V\"", &value[i]);
  4122.         return NGX_CONF_ERROR;
  4123.     }

  4124.     if (clcf->disable_symlinks == NGX_CONF_UNSET_UINT) {
  4125.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  4126.                            "\"%V\" must have \"off\", \"on\" "
  4127.                            "or \"if_not_owner\" parameter",
  4128.                            &cmd->name);
  4129.         return NGX_CONF_ERROR;
  4130.     }

  4131.     if (cf->args->nelts == 2) {
  4132.         clcf->disable_symlinks_from = NULL;
  4133.         return NGX_CONF_OK;
  4134.     }

  4135.     if (clcf->disable_symlinks_from == NGX_CONF_UNSET_PTR) {
  4136.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  4137.                            "duplicate parameters \"%V %V\"",
  4138.                            &value[1], &value[2]);
  4139.         return NGX_CONF_ERROR;
  4140.     }

  4141.     if (clcf->disable_symlinks == NGX_DISABLE_SYMLINKS_OFF) {
  4142.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  4143.                            "\"from=\" cannot be used with \"off\" parameter");
  4144.         return NGX_CONF_ERROR;
  4145.     }

  4146.     return NGX_CONF_OK;
  4147. }

  4148. #endif


  4149. static char *
  4150. ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data)
  4151. {
  4152. #if (NGX_FREEBSD)
  4153.     ssize_t *np = data;

  4154.     if ((u_long) *np >= ngx_freebsd_net_inet_tcp_sendspace) {
  4155.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  4156.                            "\"send_lowat\" must be less than %d "
  4157.                            "(sysctl net.inet.tcp.sendspace)",
  4158.                            ngx_freebsd_net_inet_tcp_sendspace);

  4159.         return NGX_CONF_ERROR;
  4160.     }

  4161. #elif !(NGX_HAVE_SO_SNDLOWAT)
  4162.     ssize_t *np = data;

  4163.     ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
  4164.                        "\"send_lowat\" is not supported, ignored");

  4165.     *np = 0;

  4166. #endif

  4167.     return NGX_CONF_OK;
  4168. }


  4169. static char *
  4170. ngx_http_core_pool_size(ngx_conf_t *cf, void *post, void *data)
  4171. {
  4172.     size_t *sp = data;

  4173.     if (*sp < NGX_MIN_POOL_SIZE) {
  4174.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  4175.                            "the pool size must be no less than %uz",
  4176.                            NGX_MIN_POOL_SIZE);
  4177.         return NGX_CONF_ERROR;
  4178.     }

  4179.     if (*sp % NGX_POOL_ALIGNMENT) {
  4180.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  4181.                            "the pool size must be a multiple of %d",
  4182.                            NGX_POOL_ALIGNMENT);
  4183.         return NGX_CONF_ERROR;
  4184.     }

  4185.     return NGX_CONF_OK;
  4186. }