src/http/ngx_http_core_module.c - nginx source code

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("ignore_invalid_headers"),
  204.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
  205.       ngx_conf_set_flag_slot,
  206.       NGX_HTTP_SRV_CONF_OFFSET,
  207.       offsetof(ngx_http_core_srv_conf_t, ignore_invalid_headers),
  208.       NULL },

  209.     { ngx_string("merge_slashes"),
  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, merge_slashes),
  214.       NULL },

  215.     { ngx_string("underscores_in_headers"),
  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, underscores_in_headers),
  220.       NULL },

  221.     { ngx_string("location"),
  222.       NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12,
  223.       ngx_http_core_location,
  224.       NGX_HTTP_SRV_CONF_OFFSET,
  225.       0,
  226.       NULL },

  227.     { ngx_string("listen"),
  228.       NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
  229.       ngx_http_core_listen,
  230.       NGX_HTTP_SRV_CONF_OFFSET,
  231.       0,
  232.       NULL },

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

  239.     { ngx_string("types_hash_max_size"),
  240.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  241.       ngx_conf_set_num_slot,
  242.       NGX_HTTP_LOC_CONF_OFFSET,
  243.       offsetof(ngx_http_core_loc_conf_t, types_hash_max_size),
  244.       NULL },

  245.     { ngx_string("types_hash_bucket_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_bucket_size),
  250.       NULL },

  251.     { ngx_string("types"),
  252.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
  253.                                           |NGX_CONF_BLOCK|NGX_CONF_NOARGS,
  254.       ngx_http_core_types,
  255.       NGX_HTTP_LOC_CONF_OFFSET,
  256.       0,
  257.       NULL },

  258.     { ngx_string("default_type"),
  259.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  260.       ngx_conf_set_str_slot,
  261.       NGX_HTTP_LOC_CONF_OFFSET,
  262.       offsetof(ngx_http_core_loc_conf_t, default_type),
  263.       NULL },

  264.     { ngx_string("root"),
  265.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
  266.                         |NGX_CONF_TAKE1,
  267.       ngx_http_core_root,
  268.       NGX_HTTP_LOC_CONF_OFFSET,
  269.       0,
  270.       NULL },

  271.     { ngx_string("alias"),
  272.       NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  273.       ngx_http_core_root,
  274.       NGX_HTTP_LOC_CONF_OFFSET,
  275.       0,
  276.       NULL },

  277.     { ngx_string("limit_except"),
  278.       NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_1MORE,
  279.       ngx_http_core_limit_except,
  280.       NGX_HTTP_LOC_CONF_OFFSET,
  281.       0,
  282.       NULL },

  283.     { ngx_string("client_max_body_size"),
  284.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  285.       ngx_conf_set_off_slot,
  286.       NGX_HTTP_LOC_CONF_OFFSET,
  287.       offsetof(ngx_http_core_loc_conf_t, client_max_body_size),
  288.       NULL },

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

  295.     { ngx_string("client_body_timeout"),
  296.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  297.       ngx_conf_set_msec_slot,
  298.       NGX_HTTP_LOC_CONF_OFFSET,
  299.       offsetof(ngx_http_core_loc_conf_t, client_body_timeout),
  300.       NULL },

  301.     { ngx_string("client_body_temp_path"),
  302.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
  303.       ngx_conf_set_path_slot,
  304.       NGX_HTTP_LOC_CONF_OFFSET,
  305.       offsetof(ngx_http_core_loc_conf_t, client_body_temp_path),
  306.       NULL },

  307.     { ngx_string("client_body_in_file_only"),
  308.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  309.       ngx_conf_set_enum_slot,
  310.       NGX_HTTP_LOC_CONF_OFFSET,
  311.       offsetof(ngx_http_core_loc_conf_t, client_body_in_file_only),
  312.       &ngx_http_core_request_body_in_file },

  313.     { ngx_string("client_body_in_single_buffer"),
  314.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  315.       ngx_conf_set_flag_slot,
  316.       NGX_HTTP_LOC_CONF_OFFSET,
  317.       offsetof(ngx_http_core_loc_conf_t, client_body_in_single_buffer),
  318.       NULL },

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

  326.     { ngx_string("sendfile_max_chunk"),
  327.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  328.       ngx_conf_set_size_slot,
  329.       NGX_HTTP_LOC_CONF_OFFSET,
  330.       offsetof(ngx_http_core_loc_conf_t, sendfile_max_chunk),
  331.       NULL },

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

  338.     { ngx_string("aio"),
  339.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  340.       ngx_http_core_set_aio,
  341.       NGX_HTTP_LOC_CONF_OFFSET,
  342.       0,
  343.       NULL },

  344.     { ngx_string("aio_write"),
  345.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  346.       ngx_conf_set_flag_slot,
  347.       NGX_HTTP_LOC_CONF_OFFSET,
  348.       offsetof(ngx_http_core_loc_conf_t, aio_write),
  349.       NULL },

  350.     { ngx_string("read_ahead"),
  351.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  352.       ngx_conf_set_size_slot,
  353.       NGX_HTTP_LOC_CONF_OFFSET,
  354.       offsetof(ngx_http_core_loc_conf_t, read_ahead),
  355.       NULL },

  356.     { ngx_string("directio"),
  357.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  358.       ngx_http_core_directio,
  359.       NGX_HTTP_LOC_CONF_OFFSET,
  360.       0,
  361.       NULL },

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

  368.     { ngx_string("tcp_nopush"),
  369.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  370.       ngx_conf_set_flag_slot,
  371.       NGX_HTTP_LOC_CONF_OFFSET,
  372.       offsetof(ngx_http_core_loc_conf_t, tcp_nopush),
  373.       NULL },

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

  380.     { ngx_string("send_timeout"),
  381.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  382.       ngx_conf_set_msec_slot,
  383.       NGX_HTTP_LOC_CONF_OFFSET,
  384.       offsetof(ngx_http_core_loc_conf_t, send_timeout),
  385.       NULL },

  386.     { ngx_string("send_lowat"),
  387.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  388.       ngx_conf_set_size_slot,
  389.       NGX_HTTP_LOC_CONF_OFFSET,
  390.       offsetof(ngx_http_core_loc_conf_t, send_lowat),
  391.       &ngx_http_core_lowat_post },

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

  398.     { ngx_string("limit_rate"),
  399.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
  400.                         |NGX_CONF_TAKE1,
  401.       ngx_http_set_complex_value_size_slot,
  402.       NGX_HTTP_LOC_CONF_OFFSET,
  403.       offsetof(ngx_http_core_loc_conf_t, limit_rate),
  404.       NULL },

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

  412.     { ngx_string("keepalive_time"),
  413.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  414.       ngx_conf_set_msec_slot,
  415.       NGX_HTTP_LOC_CONF_OFFSET,
  416.       offsetof(ngx_http_core_loc_conf_t, keepalive_time),
  417.       NULL },

  418.     { ngx_string("keepalive_timeout"),
  419.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
  420.       ngx_http_core_keepalive,
  421.       NGX_HTTP_LOC_CONF_OFFSET,
  422.       0,
  423.       NULL },

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

  430.     { ngx_string("keepalive_disable"),
  431.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
  432.       ngx_conf_set_bitmask_slot,
  433.       NGX_HTTP_LOC_CONF_OFFSET,
  434.       offsetof(ngx_http_core_loc_conf_t, keepalive_disable),
  435.       &ngx_http_core_keepalive_disable },

  436.     { ngx_string("satisfy"),
  437.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  438.       ngx_conf_set_enum_slot,
  439.       NGX_HTTP_LOC_CONF_OFFSET,
  440.       offsetof(ngx_http_core_loc_conf_t, satisfy),
  441.       &ngx_http_core_satisfy },

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

  448.     { ngx_string("internal"),
  449.       NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
  450.       ngx_http_core_internal,
  451.       NGX_HTTP_LOC_CONF_OFFSET,
  452.       0,
  453.       NULL },

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

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

  466.     { ngx_string("lingering_timeout"),
  467.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  468.       ngx_conf_set_msec_slot,
  469.       NGX_HTTP_LOC_CONF_OFFSET,
  470.       offsetof(ngx_http_core_loc_conf_t, lingering_timeout),
  471.       NULL },

  472.     { ngx_string("reset_timedout_connection"),
  473.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  474.       ngx_conf_set_flag_slot,
  475.       NGX_HTTP_LOC_CONF_OFFSET,
  476.       offsetof(ngx_http_core_loc_conf_t, reset_timedout_connection),
  477.       NULL },

  478.     { ngx_string("absolute_redirect"),
  479.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  480.       ngx_conf_set_flag_slot,
  481.       NGX_HTTP_LOC_CONF_OFFSET,
  482.       offsetof(ngx_http_core_loc_conf_t, absolute_redirect),
  483.       NULL },

  484.     { ngx_string("server_name_in_redirect"),
  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, server_name_in_redirect),
  489.       NULL },

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

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

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

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

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

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

  526.     { ngx_string("server_tokens"),
  527.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  528.       ngx_conf_set_enum_slot,
  529.       NGX_HTTP_LOC_CONF_OFFSET,
  530.       offsetof(ngx_http_core_loc_conf_t, server_tokens),
  531.       &ngx_http_core_server_tokens },

  532.     { ngx_string("if_modified_since"),
  533.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  534.       ngx_conf_set_enum_slot,
  535.       NGX_HTTP_LOC_CONF_OFFSET,
  536.       offsetof(ngx_http_core_loc_conf_t, if_modified_since),
  537.       &ngx_http_core_if_modified_since },

  538.     { ngx_string("max_ranges"),
  539.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  540.       ngx_conf_set_num_slot,
  541.       NGX_HTTP_LOC_CONF_OFFSET,
  542.       offsetof(ngx_http_core_loc_conf_t, max_ranges),
  543.       NULL },

  544.     { ngx_string("chunked_transfer_encoding"),
  545.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  546.       ngx_conf_set_flag_slot,
  547.       NGX_HTTP_LOC_CONF_OFFSET,
  548.       offsetof(ngx_http_core_loc_conf_t, chunked_transfer_encoding),
  549.       NULL },

  550.     { ngx_string("etag"),
  551.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  552.       ngx_conf_set_flag_slot,
  553.       NGX_HTTP_LOC_CONF_OFFSET,
  554.       offsetof(ngx_http_core_loc_conf_t, etag),
  555.       NULL },

  556.     { ngx_string("error_page"),
  557.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
  558.                         |NGX_CONF_2MORE,
  559.       ngx_http_core_error_page,
  560.       NGX_HTTP_LOC_CONF_OFFSET,
  561.       0,
  562.       NULL },

  563.     { ngx_string("post_action"),
  564.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
  565.                         |NGX_CONF_TAKE1,
  566.       ngx_conf_set_str_slot,
  567.       NGX_HTTP_LOC_CONF_OFFSET,
  568.       offsetof(ngx_http_core_loc_conf_t, post_action),
  569.       NULL },

  570.     { ngx_string("error_log"),
  571.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  572.       ngx_http_core_error_log,
  573.       NGX_HTTP_LOC_CONF_OFFSET,
  574.       0,
  575.       NULL },

  576.     { ngx_string("open_file_cache"),
  577.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
  578.       ngx_http_core_open_file_cache,
  579.       NGX_HTTP_LOC_CONF_OFFSET,
  580.       offsetof(ngx_http_core_loc_conf_t, open_file_cache),
  581.       NULL },

  582.     { ngx_string("open_file_cache_valid"),
  583.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  584.       ngx_conf_set_sec_slot,
  585.       NGX_HTTP_LOC_CONF_OFFSET,
  586.       offsetof(ngx_http_core_loc_conf_t, open_file_cache_valid),
  587.       NULL },

  588.     { ngx_string("open_file_cache_min_uses"),
  589.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  590.       ngx_conf_set_num_slot,
  591.       NGX_HTTP_LOC_CONF_OFFSET,
  592.       offsetof(ngx_http_core_loc_conf_t, open_file_cache_min_uses),
  593.       NULL },

  594.     { ngx_string("open_file_cache_errors"),
  595.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  596.       ngx_conf_set_flag_slot,
  597.       NGX_HTTP_LOC_CONF_OFFSET,
  598.       offsetof(ngx_http_core_loc_conf_t, open_file_cache_errors),
  599.       NULL },

  600.     { ngx_string("open_file_cache_events"),
  601.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  602.       ngx_conf_set_flag_slot,
  603.       NGX_HTTP_LOC_CONF_OFFSET,
  604.       offsetof(ngx_http_core_loc_conf_t, open_file_cache_events),
  605.       NULL },

  606.     { ngx_string("resolver"),
  607.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  608.       ngx_http_core_resolver,
  609.       NGX_HTTP_LOC_CONF_OFFSET,
  610.       0,
  611.       NULL },

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

  618. #if (NGX_HTTP_GZIP)

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

  625.     { ngx_string("gzip_http_version"),
  626.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  627.       ngx_conf_set_enum_slot,
  628.       NGX_HTTP_LOC_CONF_OFFSET,
  629.       offsetof(ngx_http_core_loc_conf_t, gzip_http_version),
  630.       &ngx_http_gzip_http_version },

  631.     { ngx_string("gzip_proxied"),
  632.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  633.       ngx_conf_set_bitmask_slot,
  634.       NGX_HTTP_LOC_CONF_OFFSET,
  635.       offsetof(ngx_http_core_loc_conf_t, gzip_proxied),
  636.       &ngx_http_gzip_proxied_mask },

  637.     { ngx_string("gzip_disable"),
  638.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  639.       ngx_http_gzip_disable,
  640.       NGX_HTTP_LOC_CONF_OFFSET,
  641.       0,
  642.       NULL },

  643. #endif

  644. #if (NGX_HAVE_OPENAT)

  645.     { ngx_string("disable_symlinks"),
  646.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
  647.       ngx_http_disable_symlinks,
  648.       NGX_HTTP_LOC_CONF_OFFSET,
  649.       0,
  650.       NULL },

  651. #endif

  652.       ngx_null_command
  653. };


  654. static ngx_http_module_t  ngx_http_core_module_ctx = {
  655.     ngx_http_core_preconfiguration,        /* preconfiguration */
  656.     ngx_http_core_postconfiguration,       /* postconfiguration */

  657.     ngx_http_core_create_main_conf,        /* create main configuration */
  658.     ngx_http_core_init_main_conf,          /* init main configuration */

  659.     ngx_http_core_create_srv_conf,         /* create server configuration */
  660.     ngx_http_core_merge_srv_conf,          /* merge server configuration */

  661.     ngx_http_core_create_loc_conf,         /* create location configuration */
  662.     ngx_http_core_merge_loc_conf           /* merge location configuration */
  663. };


  664. ngx_module_t  ngx_http_core_module = {
  665.     NGX_MODULE_V1,
  666.     &ngx_http_core_module_ctx,             /* module context */
  667.     ngx_http_core_commands,                /* module directives */
  668.     NGX_HTTP_MODULE,                       /* module type */
  669.     NULL,                                  /* init master */
  670.     NULL,                                  /* init module */
  671.     NULL,                                  /* init process */
  672.     NULL,                                  /* init thread */
  673.     NULL,                                  /* exit thread */
  674.     NULL,                                  /* exit process */
  675.     NULL,                                  /* exit master */
  676.     NGX_MODULE_V1_PADDING
  677. };


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


  679. void
  680. ngx_http_handler(ngx_http_request_t *r)
  681. {
  682.     ngx_http_core_main_conf_t  *cmcf;

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

  684.     if (!r->internal) {
  685.         switch (r->headers_in.connection_type) {
  686.         case 0:
  687.             r->keepalive = (r->http_version > NGX_HTTP_VERSION_10);
  688.             break;

  689.         case NGX_HTTP_CONNECTION_CLOSE:
  690.             r->keepalive = 0;
  691.             break;

  692.         case NGX_HTTP_CONNECTION_KEEP_ALIVE:
  693.             r->keepalive = 1;
  694.             break;
  695.         }

  696.         r->lingering_close = (r->headers_in.content_length_n > 0
  697.                               || r->headers_in.chunked);
  698.         r->phase_handler = 0;

  699.     } else {
  700.         cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
  701.         r->phase_handler = cmcf->phase_engine.server_rewrite_index;
  702.     }

  703.     r->valid_location = 1;
  704. #if (NGX_HTTP_GZIP)
  705.     r->gzip_tested = 0;
  706.     r->gzip_ok = 0;
  707.     r->gzip_vary = 0;
  708. #endif

  709.     r->write_event_handler = ngx_http_core_run_phases;
  710.     ngx_http_core_run_phases(r);
  711. }


  712. void
  713. ngx_http_core_run_phases(ngx_http_request_t *r)
  714. {
  715.     ngx_int_t                   rc;
  716.     ngx_http_phase_handler_t   *ph;
  717.     ngx_http_core_main_conf_t  *cmcf;

  718.     cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

  719.     ph = cmcf->phase_engine.handlers;

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

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

  722.         if (rc == NGX_OK) {
  723.             return;
  724.         }
  725.     }
  726. }


  727. ngx_int_t
  728. ngx_http_core_generic_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
  729. {
  730.     ngx_int_t  rc;

  731.     /*
  732.      * generic phase checker,
  733.      * used by the post read and pre-access phases
  734.      */

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

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

  738.     if (rc == NGX_OK) {
  739.         r->phase_handler = ph->next;
  740.         return NGX_AGAIN;
  741.     }

  742.     if (rc == NGX_DECLINED) {
  743.         r->phase_handler++;
  744.         return NGX_AGAIN;
  745.     }

  746.     if (rc == NGX_AGAIN || rc == NGX_DONE) {
  747.         return NGX_OK;
  748.     }

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

  750.     ngx_http_finalize_request(r, rc);

  751.     return NGX_OK;
  752. }


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

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

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

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

  764.     if (rc == NGX_DONE) {
  765.         return NGX_OK;
  766.     }

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

  768.     ngx_http_finalize_request(r, rc);

  769.     return NGX_OK;
  770. }


  771. ngx_int_t
  772. ngx_http_core_find_config_phase(ngx_http_request_t *r,
  773.     ngx_http_phase_handler_t *ph)
  774. {
  775.     u_char                    *p;
  776.     size_t                     len;
  777.     ngx_int_t                  rc;
  778.     ngx_http_core_loc_conf_t  *clcf;

  779.     r->content_handler = NULL;
  780.     r->uri_changed = 0;

  781.     rc = ngx_http_core_find_location(r);

  782.     if (rc == NGX_ERROR) {
  783.         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  784.         return NGX_OK;
  785.     }

  786.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  787.     if (!r->internal && clcf->internal) {
  788.         ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
  789.         return NGX_OK;
  790.     }

  791.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  792.                    "using configuration \"%s%V\"",
  793.                    (clcf->noname ? "*" : (clcf->exact_match ? "=" : "")),
  794.                    &clcf->name);

  795.     ngx_http_update_location_config(r);

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

  799.     if (r->headers_in.content_length_n != -1
  800.         && !r->discard_body
  801.         && clcf->client_max_body_size
  802.         && clcf->client_max_body_size < r->headers_in.content_length_n)
  803.     {
  804.         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  805.                       "client intended to send too large body: %O bytes",
  806.                       r->headers_in.content_length_n);

  807.         r->expect_tested = 1;
  808.         (void) ngx_http_discard_request_body(r);
  809.         ngx_http_finalize_request(r, NGX_HTTP_REQUEST_ENTITY_TOO_LARGE);
  810.         return NGX_OK;
  811.     }

  812.     if (rc == NGX_DONE) {
  813.         ngx_http_clear_location(r);

  814.         r->headers_out.location = ngx_list_push(&r->headers_out.headers);
  815.         if (r->headers_out.location == NULL) {
  816.             ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  817.             return NGX_OK;
  818.         }

  819.         r->headers_out.location->hash = 1;
  820.         r->headers_out.location->next = NULL;
  821.         ngx_str_set(&r->headers_out.location->key, "Location");

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

  824.         } else {
  825.             len = clcf->escaped_name.len + 1 + r->args.len;
  826.             p = ngx_pnalloc(r->pool, len);

  827.             if (p == NULL) {
  828.                 ngx_http_clear_location(r);
  829.                 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  830.                 return NGX_OK;
  831.             }

  832.             r->headers_out.location->value.len = len;
  833.             r->headers_out.location->value.data = p;

  834.             p = ngx_cpymem(p, clcf->escaped_name.data, clcf->escaped_name.len);
  835.             *p++ = '?';
  836.             ngx_memcpy(p, r->args.data, r->args.len);
  837.         }

  838.         ngx_http_finalize_request(r, NGX_HTTP_MOVED_PERMANENTLY);
  839.         return NGX_OK;
  840.     }

  841.     r->phase_handler++;
  842.     return NGX_AGAIN;
  843. }


  844. ngx_int_t
  845. ngx_http_core_post_rewrite_phase(ngx_http_request_t *r,
  846.     ngx_http_phase_handler_t *ph)
  847. {
  848.     ngx_http_core_srv_conf_t  *cscf;

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

  851.     if (!r->uri_changed) {
  852.         r->phase_handler++;
  853.         return NGX_AGAIN;
  854.     }

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

  857.     /*
  858.      * gcc before 3.3 compiles the broken code for
  859.      *     if (r->uri_changes-- == 0)
  860.      * if the r->uri_changes is defined as
  861.      *     unsigned  uri_changes:4
  862.      */

  863.     r->uri_changes--;

  864.     if (r->uri_changes == 0) {
  865.         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  866.                       "rewrite or internal redirection cycle "
  867.                       "while processing \"%V\"", &r->uri);

  868.         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  869.         return NGX_OK;
  870.     }

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

  872.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
  873.     r->loc_conf = cscf->ctx->loc_conf;

  874.     return NGX_AGAIN;
  875. }


  876. ngx_int_t
  877. ngx_http_core_access_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
  878. {
  879.     ngx_int_t                  rc;
  880.     ngx_table_elt_t           *h;
  881.     ngx_http_core_loc_conf_t  *clcf;

  882.     if (r != r->main) {
  883.         r->phase_handler = ph->next;
  884.         return NGX_AGAIN;
  885.     }

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

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

  889.     if (rc == NGX_DECLINED) {
  890.         r->phase_handler++;
  891.         return NGX_AGAIN;
  892.     }

  893.     if (rc == NGX_AGAIN || rc == NGX_DONE) {
  894.         return NGX_OK;
  895.     }

  896.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

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

  898.         if (rc == NGX_OK) {
  899.             r->phase_handler++;
  900.             return NGX_AGAIN;
  901.         }

  902.     } else {
  903.         if (rc == NGX_OK) {
  904.             r->access_code = 0;

  905.             for (h = r->headers_out.www_authenticate; h; h = h->next) {
  906.                 h->hash = 0;
  907.             }

  908.             r->phase_handler = ph->next;
  909.             return NGX_AGAIN;
  910.         }

  911.         if (rc == NGX_HTTP_FORBIDDEN || rc == NGX_HTTP_UNAUTHORIZED) {
  912.             if (r->access_code != NGX_HTTP_UNAUTHORIZED) {
  913.                 r->access_code = rc;
  914.             }

  915.             r->phase_handler++;
  916.             return NGX_AGAIN;
  917.         }
  918.     }

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

  920.     if (rc == NGX_HTTP_UNAUTHORIZED) {
  921.         return ngx_http_core_auth_delay(r);
  922.     }

  923.     ngx_http_finalize_request(r, rc);
  924.     return NGX_OK;
  925. }


  926. ngx_int_t
  927. ngx_http_core_post_access_phase(ngx_http_request_t *r,
  928.     ngx_http_phase_handler_t *ph)
  929. {
  930.     ngx_int_t  access_code;

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

  933.     access_code = r->access_code;

  934.     if (access_code) {
  935.         r->access_code = 0;

  936.         if (access_code == NGX_HTTP_FORBIDDEN) {
  937.             ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  938.                           "access forbidden by rule");
  939.         }

  940.         if (access_code == NGX_HTTP_UNAUTHORIZED) {
  941.             return ngx_http_core_auth_delay(r);
  942.         }

  943.         ngx_http_finalize_request(r, access_code);
  944.         return NGX_OK;
  945.     }

  946.     r->phase_handler++;
  947.     return NGX_AGAIN;
  948. }


  949. static ngx_int_t
  950. ngx_http_core_auth_delay(ngx_http_request_t *r)
  951. {
  952.     ngx_http_core_loc_conf_t  *clcf;

  953.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  954.     if (clcf->auth_delay == 0) {
  955.         ngx_http_finalize_request(r, NGX_HTTP_UNAUTHORIZED);
  956.         return NGX_OK;
  957.     }

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

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

  962.     } else {
  963.         if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
  964.             return NGX_HTTP_INTERNAL_SERVER_ERROR;
  965.         }
  966.     }

  967.     r->read_event_handler = ngx_http_test_reading;
  968.     r->write_event_handler = ngx_http_core_auth_delay_handler;

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

  971.     /*
  972.      * trigger an additional event loop iteration
  973.      * to ensure constant-time processing
  974.      */

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

  976.     return NGX_OK;
  977. }


  978. static void
  979. ngx_http_core_auth_delay_handler(ngx_http_request_t *r)
  980. {
  981.     ngx_event_t  *wev;

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

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

  985.     if (wev->delayed) {

  986.         if (ngx_handle_write_event(wev, 0) != NGX_OK) {
  987.             ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  988.         }

  989.         return;
  990.     }

  991.     ngx_http_finalize_request(r, NGX_HTTP_UNAUTHORIZED);
  992. }


  993. ngx_int_t
  994. ngx_http_core_content_phase(ngx_http_request_t *r,
  995.     ngx_http_phase_handler_t *ph)
  996. {
  997.     size_t     root;
  998.     ngx_int_t  rc;
  999.     ngx_str_t  path;

  1000.     if (r->content_handler) {
  1001.         r->write_event_handler = ngx_http_request_empty_handler;
  1002.         ngx_http_finalize_request(r, r->content_handler(r));
  1003.         return NGX_OK;
  1004.     }

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

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

  1008.     if (rc != NGX_DECLINED) {
  1009.         ngx_http_finalize_request(r, rc);
  1010.         return NGX_OK;
  1011.     }

  1012.     /* rc == NGX_DECLINED */

  1013.     ph++;

  1014.     if (ph->checker) {
  1015.         r->phase_handler++;
  1016.         return NGX_AGAIN;
  1017.     }

  1018.     /* no content handler was found */

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

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

  1024.         ngx_http_finalize_request(r, NGX_HTTP_FORBIDDEN);
  1025.         return NGX_OK;
  1026.     }

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

  1028.     ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
  1029.     return NGX_OK;
  1030. }


  1031. void
  1032. ngx_http_update_location_config(ngx_http_request_t *r)
  1033. {
  1034.     ngx_http_core_loc_conf_t  *clcf;

  1035.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1036.     if (r->method & clcf->limit_except) {
  1037.         r->loc_conf = clcf->limit_except_loc_conf;
  1038.         clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
  1039.     }

  1040.     if (r == r->main) {
  1041.         ngx_set_connection_log(r->connection, clcf->error_log);
  1042.     }

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

  1045.     } else {
  1046.         r->connection->sendfile = 0;
  1047.     }

  1048.     if (clcf->client_body_in_file_only) {
  1049.         r->request_body_in_file_only = 1;
  1050.         r->request_body_in_persistent_file = 1;
  1051.         r->request_body_in_clean_file =
  1052.             clcf->client_body_in_file_only == NGX_HTTP_REQUEST_BODY_FILE_CLEAN;
  1053.         r->request_body_file_log_level = NGX_LOG_NOTICE;

  1054.     } else {
  1055.         r->request_body_file_log_level = NGX_LOG_WARN;
  1056.     }

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

  1058.     if (r->keepalive) {
  1059.         if (clcf->keepalive_timeout == 0) {
  1060.             r->keepalive = 0;

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

  1063.         } else if (ngx_current_msec - r->connection->start_time
  1064.                    > clcf->keepalive_time)
  1065.         {
  1066.             r->keepalive = 0;

  1067.         } else if (r->headers_in.msie6
  1068.                    && r->method == NGX_HTTP_POST
  1069.                    && (clcf->keepalive_disable
  1070.                        & NGX_HTTP_KEEPALIVE_DISABLE_MSIE6))
  1071.         {
  1072.             /*
  1073.              * MSIE may wait for some time if an response for
  1074.              * a POST request was sent over a keepalive connection
  1075.              */
  1076.             r->keepalive = 0;

  1077.         } else if (r->headers_in.safari
  1078.                    && (clcf->keepalive_disable
  1079.                        & NGX_HTTP_KEEPALIVE_DISABLE_SAFARI))
  1080.         {
  1081.             /*
  1082.              * Safari may send a POST request to a closed keepalive
  1083.              * connection and may stall for some time, see
  1084.              *     https://bugs.webkit.org/show_bug.cgi?id=5760
  1085.              */
  1086.             r->keepalive = 0;
  1087.         }
  1088.     }

  1089.     if (!clcf->tcp_nopush) {
  1090.         /* disable TCP_NOPUSH/TCP_CORK use */
  1091.         r->connection->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
  1092.     }

  1093.     if (clcf->handler) {
  1094.         r->content_handler = clcf->handler;
  1095.     }
  1096. }


  1097. /*
  1098. * NGX_OK       - exact or regex match
  1099. * NGX_DONE     - auto redirect
  1100. * NGX_AGAIN    - inclusive match
  1101. * NGX_ERROR    - regex error
  1102. * NGX_DECLINED - no match
  1103. */

  1104. static ngx_int_t
  1105. ngx_http_core_find_location(ngx_http_request_t *r)
  1106. {
  1107.     ngx_int_t                  rc;
  1108.     ngx_http_core_loc_conf_t  *pclcf;
  1109. #if (NGX_PCRE)
  1110.     ngx_int_t                  n;
  1111.     ngx_uint_t                 noregex;
  1112.     ngx_http_core_loc_conf_t  *clcf, **clcfp;

  1113.     noregex = 0;
  1114. #endif

  1115.     pclcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

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

  1117.     if (rc == NGX_AGAIN) {

  1118. #if (NGX_PCRE)
  1119.         clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1120.         noregex = clcf->noregex;
  1121. #endif

  1122.         /* look up nested locations */

  1123.         rc = ngx_http_core_find_location(r);
  1124.     }

  1125.     if (rc == NGX_OK || rc == NGX_DONE) {
  1126.         return rc;
  1127.     }

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

  1129. #if (NGX_PCRE)

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

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

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

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

  1135.             if (n == NGX_OK) {
  1136.                 r->loc_conf = (*clcfp)->loc_conf;

  1137.                 /* look up nested locations */

  1138.                 rc = ngx_http_core_find_location(r);

  1139.                 return (rc == NGX_ERROR) ? rc : NGX_OK;
  1140.             }

  1141.             if (n == NGX_DECLINED) {
  1142.                 continue;
  1143.             }

  1144.             return NGX_ERROR;
  1145.         }
  1146.     }
  1147. #endif

  1148.     return rc;
  1149. }


  1150. /*
  1151. * NGX_OK       - exact match
  1152. * NGX_DONE     - auto redirect
  1153. * NGX_AGAIN    - inclusive match
  1154. * NGX_DECLINED - no match
  1155. */

  1156. static ngx_int_t
  1157. ngx_http_core_find_static_location(ngx_http_request_t *r,
  1158.     ngx_http_location_tree_node_t *node)
  1159. {
  1160.     u_char     *uri;
  1161.     size_t      len, n;
  1162.     ngx_int_t   rc, rv;

  1163.     len = r->uri.len;
  1164.     uri = r->uri.data;

  1165.     rv = NGX_DECLINED;

  1166.     for ( ;; ) {

  1167.         if (node == NULL) {
  1168.             return rv;
  1169.         }

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

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

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

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

  1177.             continue;
  1178.         }

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

  1180.             if (node->inclusive) {

  1181.                 r->loc_conf = node->inclusive->loc_conf;
  1182.                 rv = NGX_AGAIN;

  1183.                 node = node->tree;
  1184.                 uri += n;
  1185.                 len -= n;

  1186.                 continue;
  1187.             }

  1188.             /* exact only */

  1189.             node = node->right;

  1190.             continue;
  1191.         }

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

  1193.             if (node->exact) {
  1194.                 r->loc_conf = node->exact->loc_conf;
  1195.                 return NGX_OK;

  1196.             } else {
  1197.                 r->loc_conf = node->inclusive->loc_conf;
  1198.                 return NGX_AGAIN;
  1199.             }
  1200.         }

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

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

  1203.             r->loc_conf = (node->exact) ? node->exact->loc_conf:
  1204.                                           node->inclusive->loc_conf;
  1205.             rv = NGX_DONE;
  1206.         }

  1207.         node = node->left;
  1208.     }
  1209. }


  1210. void *
  1211. ngx_http_test_content_type(ngx_http_request_t *r, ngx_hash_t *types_hash)
  1212. {
  1213.     u_char      c, *lowcase;
  1214.     size_t      len;
  1215.     ngx_uint_t  i, hash;

  1216.     if (types_hash->size == 0) {
  1217.         return (void *) 4;
  1218.     }

  1219.     if (r->headers_out.content_type.len == 0) {
  1220.         return NULL;
  1221.     }

  1222.     len = r->headers_out.content_type_len;

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

  1224.         lowcase = ngx_pnalloc(r->pool, len);
  1225.         if (lowcase == NULL) {
  1226.             return NULL;
  1227.         }

  1228.         r->headers_out.content_type_lowcase = lowcase;

  1229.         hash = 0;

  1230.         for (i = 0; i < len; i++) {
  1231.             c = ngx_tolower(r->headers_out.content_type.data[i]);
  1232.             hash = ngx_hash(hash, c);
  1233.             lowcase[i] = c;
  1234.         }

  1235.         r->headers_out.content_type_hash = hash;
  1236.     }

  1237.     return ngx_hash_find(types_hash, r->headers_out.content_type_hash,
  1238.                          r->headers_out.content_type_lowcase, len);
  1239. }


  1240. ngx_int_t
  1241. ngx_http_set_content_type(ngx_http_request_t *r)
  1242. {
  1243.     u_char                     c, *exten;
  1244.     ngx_str_t                 *type;
  1245.     ngx_uint_t                 i, hash;
  1246.     ngx_http_core_loc_conf_t  *clcf;

  1247.     if (r->headers_out.content_type.len) {
  1248.         return NGX_OK;
  1249.     }

  1250.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

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

  1252.         hash = 0;

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

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

  1256.                 exten = ngx_pnalloc(r->pool, r->exten.len);
  1257.                 if (exten == NULL) {
  1258.                     return NGX_ERROR;
  1259.                 }

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

  1261.                 r->exten.data = exten;

  1262.                 break;
  1263.             }

  1264.             hash = ngx_hash(hash, c);
  1265.         }

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

  1268.         if (type) {
  1269.             r->headers_out.content_type_len = type->len;
  1270.             r->headers_out.content_type = *type;

  1271.             return NGX_OK;
  1272.         }
  1273.     }

  1274.     r->headers_out.content_type_len = clcf->default_type.len;
  1275.     r->headers_out.content_type = clcf->default_type;

  1276.     return NGX_OK;
  1277. }


  1278. void
  1279. ngx_http_set_exten(ngx_http_request_t *r)
  1280. {
  1281.     ngx_int_t  i;

  1282.     ngx_str_null(&r->exten);

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

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

  1287.             return;

  1288.         } else if (r->uri.data[i] == '/') {
  1289.             return;
  1290.         }
  1291.     }

  1292.     return;
  1293. }


  1294. ngx_int_t
  1295. ngx_http_set_etag(ngx_http_request_t *r)
  1296. {
  1297.     ngx_table_elt_t           *etag;
  1298.     ngx_http_core_loc_conf_t  *clcf;

  1299.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1300.     if (!clcf->etag) {
  1301.         return NGX_OK;
  1302.     }

  1303.     etag = ngx_list_push(&r->headers_out.headers);
  1304.     if (etag == NULL) {
  1305.         return NGX_ERROR;
  1306.     }

  1307.     etag->hash = 1;
  1308.     etag->next = NULL;
  1309.     ngx_str_set(&etag->key, "ETag");

  1310.     etag->value.data = ngx_pnalloc(r->pool, NGX_OFF_T_LEN + NGX_TIME_T_LEN + 3);
  1311.     if (etag->value.data == NULL) {
  1312.         etag->hash = 0;
  1313.         return NGX_ERROR;
  1314.     }

  1315.     etag->value.len = ngx_sprintf(etag->value.data, "\"%xT-%xO\"",
  1316.                                   r->headers_out.last_modified_time,
  1317.                                   r->headers_out.content_length_n)
  1318.                       - etag->value.data;

  1319.     r->headers_out.etag = etag;

  1320.     return NGX_OK;
  1321. }


  1322. void
  1323. ngx_http_weak_etag(ngx_http_request_t *r)
  1324. {
  1325.     size_t            len;
  1326.     u_char           *p;
  1327.     ngx_table_elt_t  *etag;

  1328.     etag = r->headers_out.etag;

  1329.     if (etag == NULL) {
  1330.         return;
  1331.     }

  1332.     if (etag->value.len > 2
  1333.         && etag->value.data[0] == 'W'
  1334.         && etag->value.data[1] == '/')
  1335.     {
  1336.         return;
  1337.     }

  1338.     if (etag->value.len < 1 || etag->value.data[0] != '"') {
  1339.         r->headers_out.etag->hash = 0;
  1340.         r->headers_out.etag = NULL;
  1341.         return;
  1342.     }

  1343.     p = ngx_pnalloc(r->pool, etag->value.len + 2);
  1344.     if (p == NULL) {
  1345.         r->headers_out.etag->hash = 0;
  1346.         r->headers_out.etag = NULL;
  1347.         return;
  1348.     }

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

  1350.     etag->value.data = p;
  1351.     etag->value.len = len;
  1352. }


  1353. ngx_int_t
  1354. ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
  1355.     ngx_str_t *ct, ngx_http_complex_value_t *cv)
  1356. {
  1357.     ngx_int_t     rc;
  1358.     ngx_str_t     val;
  1359.     ngx_buf_t    *b;
  1360.     ngx_chain_t   out;

  1361.     rc = ngx_http_discard_request_body(r);

  1362.     if (rc != NGX_OK) {
  1363.         return rc;
  1364.     }

  1365.     r->headers_out.status = status;

  1366.     if (ngx_http_complex_value(r, cv, &val) != NGX_OK) {
  1367.         return NGX_HTTP_INTERNAL_SERVER_ERROR;
  1368.     }

  1369.     if (status == NGX_HTTP_MOVED_PERMANENTLY
  1370.         || status == NGX_HTTP_MOVED_TEMPORARILY
  1371.         || status == NGX_HTTP_SEE_OTHER
  1372.         || status == NGX_HTTP_TEMPORARY_REDIRECT
  1373.         || status == NGX_HTTP_PERMANENT_REDIRECT)
  1374.     {
  1375.         ngx_http_clear_location(r);

  1376.         r->headers_out.location = ngx_list_push(&r->headers_out.headers);
  1377.         if (r->headers_out.location == NULL) {
  1378.             return NGX_HTTP_INTERNAL_SERVER_ERROR;
  1379.         }

  1380.         r->headers_out.location->hash = 1;
  1381.         r->headers_out.location->next = NULL;
  1382.         ngx_str_set(&r->headers_out.location->key, "Location");
  1383.         r->headers_out.location->value = val;

  1384.         return status;
  1385.     }

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

  1387.     if (ct) {
  1388.         r->headers_out.content_type_len = ct->len;
  1389.         r->headers_out.content_type = *ct;

  1390.     } else {
  1391.         if (ngx_http_set_content_type(r) != NGX_OK) {
  1392.             return NGX_HTTP_INTERNAL_SERVER_ERROR;
  1393.         }
  1394.     }

  1395.     b = ngx_calloc_buf(r->pool);
  1396.     if (b == NULL) {
  1397.         return NGX_HTTP_INTERNAL_SERVER_ERROR;
  1398.     }

  1399.     b->pos = val.data;
  1400.     b->last = val.data + val.len;
  1401.     b->memory = val.len ? 1 : 0;
  1402.     b->last_buf = (r == r->main) ? 1 : 0;
  1403.     b->last_in_chain = 1;
  1404.     b->sync = (b->last_buf || b->memory) ? 0 : 1;

  1405.     out.buf = b;
  1406.     out.next = NULL;

  1407.     rc = ngx_http_send_header(r);

  1408.     if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
  1409.         return rc;
  1410.     }

  1411.     return ngx_http_output_filter(r, &out);
  1412. }


  1413. ngx_int_t
  1414. ngx_http_send_header(ngx_http_request_t *r)
  1415. {
  1416.     if (r->post_action) {
  1417.         return NGX_OK;
  1418.     }

  1419.     if (r->header_sent) {
  1420.         ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
  1421.                       "header already sent");
  1422.         return NGX_ERROR;
  1423.     }

  1424.     if (r->err_status) {
  1425.         r->headers_out.status = r->err_status;
  1426.         r->headers_out.status_line.len = 0;
  1427.     }

  1428.     return ngx_http_top_header_filter(r);
  1429. }


  1430. ngx_int_t
  1431. ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in)
  1432. {
  1433.     ngx_int_t          rc;
  1434.     ngx_connection_t  *c;

  1435.     c = r->connection;

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

  1438.     rc = ngx_http_top_body_filter(r, in);

  1439.     if (rc == NGX_ERROR) {
  1440.         /* NGX_ERROR may be returned by any filter */
  1441.         c->error = 1;
  1442.     }

  1443.     return rc;
  1444. }


  1445. u_char *
  1446. ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *path,
  1447.     size_t *root_length, size_t reserved)
  1448. {
  1449.     u_char                    *last;
  1450.     size_t                     alias;
  1451.     ngx_http_core_loc_conf_t  *clcf;

  1452.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1453.     alias = clcf->alias;

  1454.     if (alias && !r->valid_location) {
  1455.         ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
  1456.                       "\"alias\" cannot be used in location \"%V\" "
  1457.                       "where URI was rewritten", &clcf->name);
  1458.         return NULL;
  1459.     }

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

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

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

  1463.         path->data = ngx_pnalloc(r->pool, path->len);
  1464.         if (path->data == NULL) {
  1465.             return NULL;
  1466.         }

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

  1468.     } else {

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

  1471.         } else {
  1472.             reserved += r->uri.len - alias + 1;
  1473.         }

  1474.         if (ngx_http_script_run(r, path, clcf->root_lengths->elts, reserved,
  1475.                                 clcf->root_values->elts)
  1476.             == NULL)
  1477.         {
  1478.             return NULL;
  1479.         }

  1480.         if (ngx_get_full_name(r->pool, (ngx_str_t *) &ngx_cycle->prefix, path)
  1481.             != NGX_OK)
  1482.         {
  1483.             return NULL;
  1484.         }

  1485.         *root_length = path->len - reserved;
  1486.         last = path->data + *root_length;

  1487.         if (alias == NGX_MAX_SIZE_T_VALUE) {
  1488.             if (!r->add_uri_to_alias) {
  1489.                 *last = '\0';
  1490.                 return last;
  1491.             }

  1492.             alias = 0;
  1493.         }
  1494.     }

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

  1497.     return last;
  1498. }


  1499. ngx_int_t
  1500. ngx_http_auth_basic_user(ngx_http_request_t *r)
  1501. {
  1502.     ngx_str_t   auth, encoded;
  1503.     ngx_uint_t  len;

  1504.     if (r->headers_in.user.len == 0 && r->headers_in.user.data != NULL) {
  1505.         return NGX_DECLINED;
  1506.     }

  1507.     if (r->headers_in.authorization == NULL) {
  1508.         r->headers_in.user.data = (u_char *) "";
  1509.         return NGX_DECLINED;
  1510.     }

  1511.     encoded = r->headers_in.authorization->value;

  1512.     if (encoded.len < sizeof("Basic ") - 1
  1513.         || ngx_strncasecmp(encoded.data, (u_char *) "Basic ",
  1514.                            sizeof("Basic ") - 1)
  1515.            != 0)
  1516.     {
  1517.         r->headers_in.user.data = (u_char *) "";
  1518.         return NGX_DECLINED;
  1519.     }

  1520.     encoded.len -= sizeof("Basic ") - 1;
  1521.     encoded.data += sizeof("Basic ") - 1;

  1522.     while (encoded.len && encoded.data[0] == ' ') {
  1523.         encoded.len--;
  1524.         encoded.data++;
  1525.     }

  1526.     if (encoded.len == 0) {
  1527.         r->headers_in.user.data = (u_char *) "";
  1528.         return NGX_DECLINED;
  1529.     }

  1530.     auth.len = ngx_base64_decoded_length(encoded.len);
  1531.     auth.data = ngx_pnalloc(r->pool, auth.len + 1);
  1532.     if (auth.data == NULL) {
  1533.         return NGX_ERROR;
  1534.     }

  1535.     if (ngx_decode_base64(&auth, &encoded) != NGX_OK) {
  1536.         r->headers_in.user.data = (u_char *) "";
  1537.         return NGX_DECLINED;
  1538.     }

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

  1540.     for (len = 0; len < auth.len; len++) {
  1541.         if (auth.data[len] == ':') {
  1542.             break;
  1543.         }
  1544.     }

  1545.     if (len == 0 || len == auth.len) {
  1546.         r->headers_in.user.data = (u_char *) "";
  1547.         return NGX_DECLINED;
  1548.     }

  1549.     r->headers_in.user.len = len;
  1550.     r->headers_in.user.data = auth.data;
  1551.     r->headers_in.passwd.len = auth.len - len - 1;
  1552.     r->headers_in.passwd.data = &auth.data[len + 1];

  1553.     return NGX_OK;
  1554. }


  1555. #if (NGX_HTTP_GZIP)

  1556. ngx_int_t
  1557. ngx_http_gzip_ok(ngx_http_request_t *r)
  1558. {
  1559.     time_t                     date, expires;
  1560.     ngx_uint_t                 p;
  1561.     ngx_table_elt_t           *e, *d, *ae, *cc;
  1562.     ngx_http_core_loc_conf_t  *clcf;

  1563.     r->gzip_tested = 1;

  1564.     if (r != r->main) {
  1565.         return NGX_DECLINED;
  1566.     }

  1567.     ae = r->headers_in.accept_encoding;
  1568.     if (ae == NULL) {
  1569.         return NGX_DECLINED;
  1570.     }

  1571.     if (ae->value.len < sizeof("gzip") - 1) {
  1572.         return NGX_DECLINED;
  1573.     }

  1574.     /*
  1575.      * test first for the most common case "gzip,...":
  1576.      *   MSIE:    "gzip, deflate"
  1577.      *   Firefox: "gzip,deflate"
  1578.      *   Chrome:  "gzip,deflate,sdch"
  1579.      *   Safari:  "gzip, deflate"
  1580.      *   Opera:   "gzip, deflate"
  1581.      */

  1582.     if (ngx_memcmp(ae->value.data, "gzip,", 5) != 0
  1583.         && ngx_http_gzip_accept_encoding(&ae->value) != NGX_OK)
  1584.     {
  1585.         return NGX_DECLINED;
  1586.     }

  1587.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1588.     if (r->headers_in.msie6 && clcf->gzip_disable_msie6) {
  1589.         return NGX_DECLINED;
  1590.     }

  1591.     if (r->http_version < clcf->gzip_http_version) {
  1592.         return NGX_DECLINED;
  1593.     }

  1594.     if (r->headers_in.via == NULL) {
  1595.         goto ok;
  1596.     }

  1597.     p = clcf->gzip_proxied;

  1598.     if (p & NGX_HTTP_GZIP_PROXIED_OFF) {
  1599.         return NGX_DECLINED;
  1600.     }

  1601.     if (p & NGX_HTTP_GZIP_PROXIED_ANY) {
  1602.         goto ok;
  1603.     }

  1604.     if (r->headers_in.authorization && (p & NGX_HTTP_GZIP_PROXIED_AUTH)) {
  1605.         goto ok;
  1606.     }

  1607.     e = r->headers_out.expires;

  1608.     if (e) {

  1609.         if (!(p & NGX_HTTP_GZIP_PROXIED_EXPIRED)) {
  1610.             return NGX_DECLINED;
  1611.         }

  1612.         expires = ngx_parse_http_time(e->value.data, e->value.len);
  1613.         if (expires == NGX_ERROR) {
  1614.             return NGX_DECLINED;
  1615.         }

  1616.         d = r->headers_out.date;

  1617.         if (d) {
  1618.             date = ngx_parse_http_time(d->value.data, d->value.len);
  1619.             if (date == NGX_ERROR) {
  1620.                 return NGX_DECLINED;
  1621.             }

  1622.         } else {
  1623.             date = ngx_time();
  1624.         }

  1625.         if (expires < date) {
  1626.             goto ok;
  1627.         }

  1628.         return NGX_DECLINED;
  1629.     }

  1630.     cc = r->headers_out.cache_control;

  1631.     if (cc) {

  1632.         if ((p & NGX_HTTP_GZIP_PROXIED_NO_CACHE)
  1633.             && ngx_http_parse_multi_header_lines(r, cc, &ngx_http_gzip_no_cache,
  1634.                                                  NULL)
  1635.                != NULL)
  1636.         {
  1637.             goto ok;
  1638.         }

  1639.         if ((p & NGX_HTTP_GZIP_PROXIED_NO_STORE)
  1640.             && ngx_http_parse_multi_header_lines(r, cc, &ngx_http_gzip_no_store,
  1641.                                                  NULL)
  1642.                != NULL)
  1643.         {
  1644.             goto ok;
  1645.         }

  1646.         if ((p & NGX_HTTP_GZIP_PROXIED_PRIVATE)
  1647.             && ngx_http_parse_multi_header_lines(r, cc, &ngx_http_gzip_private,
  1648.                                                  NULL)
  1649.                != NULL)
  1650.         {
  1651.             goto ok;
  1652.         }

  1653.         return NGX_DECLINED;
  1654.     }

  1655.     if ((p & NGX_HTTP_GZIP_PROXIED_NO_LM) && r->headers_out.last_modified) {
  1656.         return NGX_DECLINED;
  1657.     }

  1658.     if ((p & NGX_HTTP_GZIP_PROXIED_NO_ETAG) && r->headers_out.etag) {
  1659.         return NGX_DECLINED;
  1660.     }

  1661. ok:

  1662. #if (NGX_PCRE)

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

  1664.         if (ngx_regex_exec_array(clcf->gzip_disable,
  1665.                                  &r->headers_in.user_agent->value,
  1666.                                  r->connection->log)
  1667.             != NGX_DECLINED)
  1668.         {
  1669.             return NGX_DECLINED;
  1670.         }
  1671.     }

  1672. #endif

  1673.     r->gzip_ok = 1;

  1674.     return NGX_OK;
  1675. }


  1676. /*
  1677. * gzip is enabled for the following quantities:
  1678. *     "gzip; q=0.001" ... "gzip; q=1.000"
  1679. * gzip is disabled for the following quantities:
  1680. *     "gzip; q=0" ... "gzip; q=0.000", and for any invalid cases
  1681. */

  1682. static ngx_int_t
  1683. ngx_http_gzip_accept_encoding(ngx_str_t *ae)
  1684. {
  1685.     u_char  *p, *start, *last;

  1686.     start = ae->data;
  1687.     last = start + ae->len;

  1688.     for ( ;; ) {
  1689.         p = ngx_strcasestrn(start, "gzip", 4 - 1);
  1690.         if (p == NULL) {
  1691.             return NGX_DECLINED;
  1692.         }

  1693.         if (p == start || (*(p - 1) == ',' || *(p - 1) == ' ')) {
  1694.             break;
  1695.         }

  1696.         start = p + 4;
  1697.     }

  1698.     p += 4;

  1699.     while (p < last) {
  1700.         switch (*p++) {
  1701.         case ',':
  1702.             return NGX_OK;
  1703.         case ';':
  1704.             goto quantity;
  1705.         case ' ':
  1706.             continue;
  1707.         default:
  1708.             return NGX_DECLINED;
  1709.         }
  1710.     }

  1711.     return NGX_OK;

  1712. quantity:

  1713.     while (p < last) {
  1714.         switch (*p++) {
  1715.         case 'q':
  1716.         case 'Q':
  1717.             goto equal;
  1718.         case ' ':
  1719.             continue;
  1720.         default:
  1721.             return NGX_DECLINED;
  1722.         }
  1723.     }

  1724.     return NGX_OK;

  1725. equal:

  1726.     if (p + 2 > last || *p++ != '=') {
  1727.         return NGX_DECLINED;
  1728.     }

  1729.     if (ngx_http_gzip_quantity(p, last) == 0) {
  1730.         return NGX_DECLINED;
  1731.     }

  1732.     return NGX_OK;
  1733. }


  1734. static ngx_uint_t
  1735. ngx_http_gzip_quantity(u_char *p, u_char *last)
  1736. {
  1737.     u_char      c;
  1738.     ngx_uint_t  n, q;

  1739.     c = *p++;

  1740.     if (c != '0' && c != '1') {
  1741.         return 0;
  1742.     }

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

  1744.     if (p == last) {
  1745.         return q;
  1746.     }

  1747.     c = *p++;

  1748.     if (c == ',' || c == ' ') {
  1749.         return q;
  1750.     }

  1751.     if (c != '.') {
  1752.         return 0;
  1753.     }

  1754.     n = 0;

  1755.     while (p < last) {
  1756.         c = *p++;

  1757.         if (c == ',' || c == ' ') {
  1758.             break;
  1759.         }

  1760.         if (c >= '0' && c <= '9') {
  1761.             q += c - '0';
  1762.             n++;
  1763.             continue;
  1764.         }

  1765.         return 0;
  1766.     }

  1767.     if (q > 100 || n > 3) {
  1768.         return 0;
  1769.     }

  1770.     return q;
  1771. }

  1772. #endif


  1773. ngx_int_t
  1774. ngx_http_subrequest(ngx_http_request_t *r,
  1775.     ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **psr,
  1776.     ngx_http_post_subrequest_t *ps, ngx_uint_t flags)
  1777. {
  1778.     ngx_time_t                    *tp;
  1779.     ngx_connection_t              *c;
  1780.     ngx_http_request_t            *sr;
  1781.     ngx_http_core_srv_conf_t      *cscf;
  1782.     ngx_http_postponed_request_t  *pr, *p;

  1783.     if (r->subrequests == 0) {
  1784.         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  1785.                       "subrequests cycle while processing \"%V\"", uri);
  1786.         return NGX_ERROR;
  1787.     }

  1788.     /*
  1789.      * 1000 is reserved for other purposes.
  1790.      */
  1791.     if (r->main->count >= 65535 - 1000) {
  1792.         ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,
  1793.                       "request reference counter overflow "
  1794.                       "while processing \"%V\"", uri);
  1795.         return NGX_ERROR;
  1796.     }

  1797.     if (r->subrequest_in_memory) {
  1798.         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  1799.                       "nested in-memory subrequest \"%V\"", uri);
  1800.         return NGX_ERROR;
  1801.     }

  1802.     sr = ngx_pcalloc(r->pool, sizeof(ngx_http_request_t));
  1803.     if (sr == NULL) {
  1804.         return NGX_ERROR;
  1805.     }

  1806.     sr->signature = NGX_HTTP_MODULE;

  1807.     c = r->connection;
  1808.     sr->connection = c;

  1809.     sr->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
  1810.     if (sr->ctx == NULL) {
  1811.         return NGX_ERROR;
  1812.     }

  1813.     if (ngx_list_init(&sr->headers_out.headers, r->pool, 20,
  1814.                       sizeof(ngx_table_elt_t))
  1815.         != NGX_OK)
  1816.     {
  1817.         return NGX_ERROR;
  1818.     }

  1819.     if (ngx_list_init(&sr->headers_out.trailers, r->pool, 4,
  1820.                       sizeof(ngx_table_elt_t))
  1821.         != NGX_OK)
  1822.     {
  1823.         return NGX_ERROR;
  1824.     }

  1825.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
  1826.     sr->main_conf = cscf->ctx->main_conf;
  1827.     sr->srv_conf = cscf->ctx->srv_conf;
  1828.     sr->loc_conf = cscf->ctx->loc_conf;

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

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

  1831.     ngx_http_clear_content_length(sr);
  1832.     ngx_http_clear_accept_ranges(sr);
  1833.     ngx_http_clear_last_modified(sr);

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

  1835. #if (NGX_HTTP_V2)
  1836.     sr->stream = r->stream;
  1837. #endif

  1838.     sr->method = NGX_HTTP_GET;
  1839.     sr->http_version = r->http_version;

  1840.     sr->request_line = r->request_line;
  1841.     sr->uri = *uri;

  1842.     if (args) {
  1843.         sr->args = *args;
  1844.     }

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

  1847.     sr->subrequest_in_memory = (flags & NGX_HTTP_SUBREQUEST_IN_MEMORY) != 0;
  1848.     sr->waited = (flags & NGX_HTTP_SUBREQUEST_WAITED) != 0;
  1849.     sr->background = (flags & NGX_HTTP_SUBREQUEST_BACKGROUND) != 0;

  1850.     sr->unparsed_uri = r->unparsed_uri;
  1851.     sr->method_name = ngx_http_core_get_method;
  1852.     sr->http_protocol = r->http_protocol;
  1853.     sr->schema = r->schema;

  1854.     ngx_http_set_exten(sr);

  1855.     sr->main = r->main;
  1856.     sr->parent = r;
  1857.     sr->post_subrequest = ps;
  1858.     sr->read_event_handler = ngx_http_request_empty_handler;
  1859.     sr->write_event_handler = ngx_http_handler;

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

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

  1862.     if (sr->subrequest_in_memory) {
  1863.         sr->filter_need_in_memory = 1;
  1864.     }

  1865.     if (!sr->background) {
  1866.         if (c->data == r && r->postponed == NULL) {
  1867.             c->data = sr;
  1868.         }

  1869.         pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t));
  1870.         if (pr == NULL) {
  1871.             return NGX_ERROR;
  1872.         }

  1873.         pr->request = sr;
  1874.         pr->out = NULL;
  1875.         pr->next = NULL;

  1876.         if (r->postponed) {
  1877.             for (p = r->postponed; p->next; p = p->next) { /* void */ }
  1878.             p->next = pr;

  1879.         } else {
  1880.             r->postponed = pr;
  1881.         }
  1882.     }

  1883.     sr->internal = 1;

  1884.     sr->discard_body = r->discard_body;
  1885.     sr->expect_tested = 1;
  1886.     sr->main_filter_need_in_memory = r->main_filter_need_in_memory;

  1887.     sr->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1;
  1888.     sr->subrequests = r->subrequests - 1;

  1889.     tp = ngx_timeofday();
  1890.     sr->start_sec = tp->sec;
  1891.     sr->start_msec = tp->msec;

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

  1893.     *psr = sr;

  1894.     if (flags & NGX_HTTP_SUBREQUEST_CLONE) {
  1895.         sr->method = r->method;
  1896.         sr->method_name = r->method_name;
  1897.         sr->loc_conf = r->loc_conf;
  1898.         sr->valid_location = r->valid_location;
  1899.         sr->valid_unparsed_uri = r->valid_unparsed_uri;
  1900.         sr->content_handler = r->content_handler;
  1901.         sr->phase_handler = r->phase_handler;
  1902.         sr->write_event_handler = ngx_http_core_run_phases;

  1903. #if (NGX_PCRE)
  1904.         sr->ncaptures = r->ncaptures;
  1905.         sr->captures = r->captures;
  1906.         sr->captures_data = r->captures_data;
  1907.         sr->realloc_captures = 1;
  1908.         r->realloc_captures = 1;
  1909. #endif

  1910.         ngx_http_update_location_config(sr);
  1911.     }

  1912.     return ngx_http_post_request(sr, NULL);
  1913. }


  1914. ngx_int_t
  1915. ngx_http_internal_redirect(ngx_http_request_t *r,
  1916.     ngx_str_t *uri, ngx_str_t *args)
  1917. {
  1918.     ngx_http_core_srv_conf_t  *cscf;

  1919.     r->uri_changes--;

  1920.     if (r->uri_changes == 0) {
  1921.         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  1922.                       "rewrite or internal redirection cycle "
  1923.                       "while internally redirecting to \"%V\"", uri);

  1924.         r->main->count++;
  1925.         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1926.         return NGX_DONE;
  1927.     }

  1928.     r->uri = *uri;

  1929.     if (args) {
  1930.         r->args = *args;

  1931.     } else {
  1932.         ngx_str_null(&r->args);
  1933.     }

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

  1936.     ngx_http_set_exten(r);

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

  1939.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
  1940.     r->loc_conf = cscf->ctx->loc_conf;

  1941.     ngx_http_update_location_config(r);

  1942. #if (NGX_HTTP_CACHE)
  1943.     r->cache = NULL;
  1944. #endif

  1945.     r->internal = 1;
  1946.     r->valid_unparsed_uri = 0;
  1947.     r->add_uri_to_alias = 0;
  1948.     r->main->count++;

  1949.     ngx_http_handler(r);

  1950.     return NGX_DONE;
  1951. }


  1952. ngx_int_t
  1953. ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name)
  1954. {
  1955.     ngx_http_core_srv_conf_t    *cscf;
  1956.     ngx_http_core_loc_conf_t   **clcfp;
  1957.     ngx_http_core_main_conf_t   *cmcf;

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

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

  1964.         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1965.         return NGX_DONE;
  1966.     }

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

  1970.         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1971.         return NGX_DONE;
  1972.     }

  1973.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

  1974.     if (cscf->named_locations) {

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

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

  1978.             if (name->len != (*clcfp)->name.len
  1979.                 || ngx_strncmp(name->data, (*clcfp)->name.data, name->len) != 0)
  1980.             {
  1981.                 continue;
  1982.             }

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

  1986.             r->internal = 1;
  1987.             r->content_handler = NULL;
  1988.             r->uri_changed = 0;
  1989.             r->loc_conf = (*clcfp)->loc_conf;

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

  1992.             ngx_http_update_location_config(r);

  1993.             cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

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

  1995.             r->write_event_handler = ngx_http_core_run_phases;
  1996.             ngx_http_core_run_phases(r);

  1997.             return NGX_DONE;
  1998.         }
  1999.     }

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

  2002.     ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);

  2003.     return NGX_DONE;
  2004. }


  2005. ngx_http_cleanup_t *
  2006. ngx_http_cleanup_add(ngx_http_request_t *r, size_t size)
  2007. {
  2008.     ngx_http_cleanup_t  *cln;

  2009.     r = r->main;

  2010.     cln = ngx_palloc(r->pool, sizeof(ngx_http_cleanup_t));
  2011.     if (cln == NULL) {
  2012.         return NULL;
  2013.     }

  2014.     if (size) {
  2015.         cln->data = ngx_palloc(r->pool, size);
  2016.         if (cln->data == NULL) {
  2017.             return NULL;
  2018.         }

  2019.     } else {
  2020.         cln->data = NULL;
  2021.     }

  2022.     cln->handler = NULL;
  2023.     cln->next = r->cleanup;

  2024.     r->cleanup = cln;

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

  2027.     return cln;
  2028. }


  2029. ngx_int_t
  2030. ngx_http_set_disable_symlinks(ngx_http_request_t *r,
  2031.     ngx_http_core_loc_conf_t *clcf, ngx_str_t *path, ngx_open_file_info_t *of)
  2032. {
  2033. #if (NGX_HAVE_OPENAT)
  2034.     u_char     *p;
  2035.     ngx_str_t   from;

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

  2037.     if (clcf->disable_symlinks_from == NULL) {
  2038.         return NGX_OK;
  2039.     }

  2040.     if (ngx_http_complex_value(r, clcf->disable_symlinks_from, &from)
  2041.         != NGX_OK)
  2042.     {
  2043.         return NGX_ERROR;
  2044.     }

  2045.     if (from.len == 0
  2046.         || from.len > path->len
  2047.         || ngx_memcmp(path->data, from.data, from.len) != 0)
  2048.     {
  2049.         return NGX_OK;
  2050.     }

  2051.     if (from.len == path->len) {
  2052.         of->disable_symlinks = NGX_DISABLE_SYMLINKS_OFF;
  2053.         return NGX_OK;
  2054.     }

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

  2056.     if (*p == '/') {
  2057.         of->disable_symlinks_from = from.len;
  2058.         return NGX_OK;
  2059.     }

  2060.     p--;

  2061.     if (*p == '/') {
  2062.         of->disable_symlinks_from = from.len - 1;
  2063.     }
  2064. #endif

  2065.     return NGX_OK;
  2066. }


  2067. ngx_int_t
  2068. ngx_http_get_forwarded_addr(ngx_http_request_t *r, ngx_addr_t *addr,
  2069.     ngx_table_elt_t *headers, ngx_str_t *value, ngx_array_t *proxies,
  2070.     int recursive)
  2071. {
  2072.     ngx_int_t         rc;
  2073.     ngx_uint_t        found;
  2074.     ngx_table_elt_t  *h, *next;

  2075.     if (headers == NULL) {
  2076.         return ngx_http_get_forwarded_addr_internal(r, addr, value->data,
  2077.                                                     value->len, proxies,
  2078.                                                     recursive);
  2079.     }

  2080.     /* revert headers order */

  2081.     for (h = headers, headers = NULL; h; h = next) {
  2082.         next = h->next;
  2083.         h->next = headers;
  2084.         headers = h;
  2085.     }

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

  2087.     rc = NGX_DECLINED;

  2088.     found = 0;

  2089.     for (h = headers; h; h = h->next) {
  2090.         rc = ngx_http_get_forwarded_addr_internal(r, addr, h->value.data,
  2091.                                                   h->value.len, proxies,
  2092.                                                   recursive);

  2093.         if (!recursive) {
  2094.             break;
  2095.         }

  2096.         if (rc == NGX_DECLINED && found) {
  2097.             rc = NGX_DONE;
  2098.             break;
  2099.         }

  2100.         if (rc != NGX_OK) {
  2101.             break;
  2102.         }

  2103.         found = 1;
  2104.     }

  2105.     /* restore headers order */

  2106.     for (h = headers, headers = NULL; h; h = next) {
  2107.         next = h->next;
  2108.         h->next = headers;
  2109.         headers = h;
  2110.     }

  2111.     return rc;
  2112. }


  2113. static ngx_int_t
  2114. ngx_http_get_forwarded_addr_internal(ngx_http_request_t *r, ngx_addr_t *addr,
  2115.     u_char *xff, size_t xfflen, ngx_array_t *proxies, int recursive)
  2116. {
  2117.     u_char      *p;
  2118.     ngx_addr_t   paddr;
  2119.     ngx_uint_t   found;

  2120.     found = 0;

  2121.     do {

  2122.         if (ngx_cidr_match(addr->sockaddr, proxies) != NGX_OK) {
  2123.             return found ? NGX_DONE : NGX_DECLINED;
  2124.         }

  2125.         for (p = xff + xfflen - 1; p > xff; p--, xfflen--) {
  2126.             if (*p != ' ' && *p != ',') {
  2127.                 break;
  2128.             }
  2129.         }

  2130.         for ( /* void */ ; p > xff; p--) {
  2131.             if (*p == ' ' || *p == ',') {
  2132.                 p++;
  2133.                 break;
  2134.             }
  2135.         }

  2136.         if (ngx_parse_addr_port(r->pool, &paddr, p, xfflen - (p - xff))
  2137.             != NGX_OK)
  2138.         {
  2139.             return found ? NGX_DONE : NGX_DECLINED;
  2140.         }

  2141.         *addr = paddr;
  2142.         found = 1;
  2143.         xfflen = p - 1 - xff;

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

  2145.     return NGX_OK;
  2146. }


  2147. ngx_int_t
  2148. ngx_http_link_multi_headers(ngx_http_request_t *r)
  2149. {
  2150.     ngx_uint_t        i, j;
  2151.     ngx_list_part_t  *part, *ppart;
  2152.     ngx_table_elt_t  *header, *pheader, **ph;

  2153.     if (r->headers_in.multi_linked) {
  2154.         return NGX_OK;
  2155.     }

  2156.     r->headers_in.multi_linked = 1;

  2157.     part = &r->headers_in.headers.part;
  2158.     header = part->elts;

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

  2160.         if (i >= part->nelts) {
  2161.             if (part->next == NULL) {
  2162.                 break;
  2163.             }

  2164.             part = part->next;
  2165.             header = part->elts;
  2166.             i = 0;
  2167.         }

  2168.         header[i].next = NULL;

  2169.         /*
  2170.          * search for previous headers with the same name;
  2171.          * if there are any, link to them
  2172.          */

  2173.         ppart = &r->headers_in.headers.part;
  2174.         pheader = ppart->elts;

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

  2176.             if (j >= ppart->nelts) {
  2177.                 if (ppart->next == NULL) {
  2178.                     break;
  2179.                 }

  2180.                 ppart = ppart->next;
  2181.                 pheader = ppart->elts;
  2182.                 j = 0;
  2183.             }

  2184.             if (part == ppart && i == j) {
  2185.                 break;
  2186.             }

  2187.             if (header[i].key.len == pheader[j].key.len
  2188.                 && ngx_strncasecmp(header[i].key.data, pheader[j].key.data,
  2189.                                    header[i].key.len)
  2190.                    == 0)
  2191.             {
  2192.                 ph = &pheader[j].next;
  2193.                 while (*ph) { ph = &(*ph)->next; }
  2194.                 *ph = &header[i];

  2195.                 r->headers_in.multi = 1;

  2196.                 break;
  2197.             }
  2198.         }
  2199.     }

  2200.     return NGX_OK;
  2201. }


  2202. static char *
  2203. ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
  2204. {
  2205.     char                        *rv;
  2206.     void                        *mconf;
  2207.     size_t                       len;
  2208.     u_char                      *p;
  2209.     ngx_uint_t                   i;
  2210.     ngx_conf_t                   pcf;
  2211.     ngx_http_module_t           *module;
  2212.     struct sockaddr_in          *sin;
  2213.     ngx_http_conf_ctx_t         *ctx, *http_ctx;
  2214.     ngx_http_listen_opt_t        lsopt;
  2215.     ngx_http_core_srv_conf_t    *cscf, **cscfp;
  2216.     ngx_http_core_main_conf_t   *cmcf;

  2217.     ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
  2218.     if (ctx == NULL) {
  2219.         return NGX_CONF_ERROR;
  2220.     }

  2221.     http_ctx = cf->ctx;
  2222.     ctx->main_conf = http_ctx->main_conf;

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

  2224.     ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
  2225.     if (ctx->srv_conf == NULL) {
  2226.         return NGX_CONF_ERROR;
  2227.     }

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

  2229.     ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
  2230.     if (ctx->loc_conf == NULL) {
  2231.         return NGX_CONF_ERROR;
  2232.     }

  2233.     for (i = 0; cf->cycle->modules[i]; i++) {
  2234.         if (cf->cycle->modules[i]->type != NGX_HTTP_MODULE) {
  2235.             continue;
  2236.         }

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

  2238.         if (module->create_srv_conf) {
  2239.             mconf = module->create_srv_conf(cf);
  2240.             if (mconf == NULL) {
  2241.                 return NGX_CONF_ERROR;
  2242.             }

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

  2245.         if (module->create_loc_conf) {
  2246.             mconf = module->create_loc_conf(cf);
  2247.             if (mconf == NULL) {
  2248.                 return NGX_CONF_ERROR;
  2249.             }

  2250.             ctx->loc_conf[cf->cycle->modules[i]->ctx_index] = mconf;
  2251.         }
  2252.     }


  2253.     /* the server configuration context */

  2254.     cscf = ctx->srv_conf[ngx_http_core_module.ctx_index];
  2255.     cscf->ctx = ctx;


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

  2257.     cscfp = ngx_array_push(&cmcf->servers);
  2258.     if (cscfp == NULL) {
  2259.         return NGX_CONF_ERROR;
  2260.     }

  2261.     *cscfp = cscf;


  2262.     /* parse inside server{} */

  2263.     pcf = *cf;
  2264.     cf->ctx = ctx;
  2265.     cf->cmd_type = NGX_HTTP_SRV_CONF;

  2266.     rv = ngx_conf_parse(cf, NULL);

  2267.     *cf = pcf;

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

  2270.         p = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in));
  2271.         if (p == NULL) {
  2272.             return NGX_CONF_ERROR;
  2273.         }

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

  2275.         sin = (struct sockaddr_in *) p;

  2276.         sin->sin_family = AF_INET;
  2277. #if (NGX_WIN32)
  2278.         sin->sin_port = htons(80);
  2279. #else
  2280.         sin->sin_port = htons((getuid() == 0) ? 80 : 8000);
  2281. #endif
  2282.         sin->sin_addr.s_addr = INADDR_ANY;

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

  2284.         lsopt.backlog = NGX_LISTEN_BACKLOG;
  2285.         lsopt.type = SOCK_STREAM;
  2286.         lsopt.rcvbuf = -1;
  2287.         lsopt.sndbuf = -1;
  2288. #if (NGX_HAVE_SETFIB)
  2289.         lsopt.setfib = -1;
  2290. #endif
  2291. #if (NGX_HAVE_TCP_FASTOPEN)
  2292.         lsopt.fastopen = -1;
  2293. #endif
  2294.         lsopt.wildcard = 1;

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

  2296.         p = ngx_pnalloc(cf->pool, len);
  2297.         if (p == NULL) {
  2298.             return NGX_CONF_ERROR;
  2299.         }

  2300.         lsopt.addr_text.data = p;
  2301.         lsopt.addr_text.len = ngx_sock_ntop(lsopt.sockaddr, lsopt.socklen, p,
  2302.                                             len, 1);

  2303.         if (ngx_http_add_listen(cf, cscf, &lsopt) != NGX_OK) {
  2304.             return NGX_CONF_ERROR;
  2305.         }
  2306.     }

  2307.     return rv;
  2308. }


  2309. static char *
  2310. ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
  2311. {
  2312.     char                      *rv;
  2313.     u_char                    *mod;
  2314.     size_t                     len;
  2315.     ngx_str_t                 *value, *name;
  2316.     ngx_uint_t                 i;
  2317.     ngx_conf_t                 save;
  2318.     ngx_http_module_t         *module;
  2319.     ngx_http_conf_ctx_t       *ctx, *pctx;
  2320.     ngx_http_core_loc_conf_t  *clcf, *pclcf;

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

  2325.     pctx = cf->ctx;
  2326.     ctx->main_conf = pctx->main_conf;
  2327.     ctx->srv_conf = pctx->srv_conf;

  2328.     ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
  2329.     if (ctx->loc_conf == NULL) {
  2330.         return NGX_CONF_ERROR;
  2331.     }

  2332.     for (i = 0; cf->cycle->modules[i]; i++) {
  2333.         if (cf->cycle->modules[i]->type != NGX_HTTP_MODULE) {
  2334.             continue;
  2335.         }

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

  2337.         if (module->create_loc_conf) {
  2338.             ctx->loc_conf[cf->cycle->modules[i]->ctx_index] =
  2339.                                                    module->create_loc_conf(cf);
  2340.             if (ctx->loc_conf[cf->cycle->modules[i]->ctx_index] == NULL) {
  2341.                 return NGX_CONF_ERROR;
  2342.             }
  2343.         }
  2344.     }

  2345.     clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
  2346.     clcf->loc_conf = ctx->loc_conf;

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

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

  2349.         len = value[1].len;
  2350.         mod = value[1].data;
  2351.         name = &value[2];

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

  2353.             clcf->name = *name;
  2354.             clcf->exact_match = 1;

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

  2356.             clcf->name = *name;
  2357.             clcf->noregex = 1;

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

  2359.             if (ngx_http_core_regex_location(cf, clcf, name, 0) != NGX_OK) {
  2360.                 return NGX_CONF_ERROR;
  2361.             }

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

  2363.             if (ngx_http_core_regex_location(cf, clcf, name, 1) != NGX_OK) {
  2364.                 return NGX_CONF_ERROR;
  2365.             }

  2366.         } else {
  2367.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2368.                                "invalid location modifier \"%V\"", &value[1]);
  2369.             return NGX_CONF_ERROR;
  2370.         }

  2371.     } else {

  2372.         name = &value[1];

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

  2374.             clcf->name.len = name->len - 1;
  2375.             clcf->name.data = name->data + 1;
  2376.             clcf->exact_match = 1;

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

  2378.             clcf->name.len = name->len - 2;
  2379.             clcf->name.data = name->data + 2;
  2380.             clcf->noregex = 1;

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

  2382.             name->len--;
  2383.             name->data++;

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

  2385.                 name->len--;
  2386.                 name->data++;

  2387.                 if (ngx_http_core_regex_location(cf, clcf, name, 1) != NGX_OK) {
  2388.                     return NGX_CONF_ERROR;
  2389.                 }

  2390.             } else {
  2391.                 if (ngx_http_core_regex_location(cf, clcf, name, 0) != NGX_OK) {
  2392.                     return NGX_CONF_ERROR;
  2393.                 }
  2394.             }

  2395.         } else {

  2396.             clcf->name = *name;

  2397.             if (name->data[0] == '@') {
  2398.                 clcf->named = 1;
  2399.             }
  2400.         }
  2401.     }

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

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

  2404.         /* nested location */

  2405. #if 0
  2406.         clcf->prev_location = pclcf;
  2407. #endif

  2408.         if (pclcf->exact_match) {
  2409.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2410.                                "location \"%V\" cannot be inside "
  2411.                                "the exact location \"%V\"",
  2412.                                &clcf->name, &pclcf->name);
  2413.             return NGX_CONF_ERROR;
  2414.         }

  2415.         if (pclcf->named) {
  2416.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2417.                                "location \"%V\" cannot be inside "
  2418.                                "the named location \"%V\"",
  2419.                                &clcf->name, &pclcf->name);
  2420.             return NGX_CONF_ERROR;
  2421.         }

  2422.         if (clcf->named) {
  2423.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2424.                                "named location \"%V\" can be "
  2425.                                "on the server level only",
  2426.                                &clcf->name);
  2427.             return NGX_CONF_ERROR;
  2428.         }

  2429.         len = pclcf->name.len;

  2430. #if (NGX_PCRE)
  2431.         if (clcf->regex == NULL
  2432.             && ngx_filename_cmp(clcf->name.data, pclcf->name.data, len) != 0)
  2433. #else
  2434.         if (ngx_filename_cmp(clcf->name.data, pclcf->name.data, len) != 0)
  2435. #endif
  2436.         {
  2437.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2438.                                "location \"%V\" is outside location \"%V\"",
  2439.                                &clcf->name, &pclcf->name);
  2440.             return NGX_CONF_ERROR;
  2441.         }
  2442.     }

  2443.     if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) {
  2444.         return NGX_CONF_ERROR;
  2445.     }

  2446.     save = *cf;
  2447.     cf->ctx = ctx;
  2448.     cf->cmd_type = NGX_HTTP_LOC_CONF;

  2449.     rv = ngx_conf_parse(cf, NULL);

  2450.     *cf = save;

  2451.     return rv;
  2452. }


  2453. static ngx_int_t
  2454. ngx_http_core_regex_location(ngx_conf_t *cf, ngx_http_core_loc_conf_t *clcf,
  2455.     ngx_str_t *regex, ngx_uint_t caseless)
  2456. {
  2457. #if (NGX_PCRE)
  2458.     ngx_regex_compile_t  rc;
  2459.     u_char               errstr[NGX_MAX_CONF_ERRSTR];

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

  2461.     rc.pattern = *regex;
  2462.     rc.err.len = NGX_MAX_CONF_ERRSTR;
  2463.     rc.err.data = errstr;

  2464. #if (NGX_HAVE_CASELESS_FILESYSTEM)
  2465.     rc.options = NGX_REGEX_CASELESS;
  2466. #else
  2467.     rc.options = caseless ? NGX_REGEX_CASELESS : 0;
  2468. #endif

  2469.     clcf->regex = ngx_http_regex_compile(cf, &rc);
  2470.     if (clcf->regex == NULL) {
  2471.         return NGX_ERROR;
  2472.     }

  2473.     clcf->name = *regex;

  2474.     return NGX_OK;

  2475. #else

  2476.     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2477.                        "using regex \"%V\" requires PCRE library",
  2478.                        regex);
  2479.     return NGX_ERROR;

  2480. #endif
  2481. }


  2482. static char *
  2483. ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  2484. {
  2485.     ngx_http_core_loc_conf_t *clcf = conf;

  2486.     char        *rv;
  2487.     ngx_conf_t   save;

  2488.     if (clcf->types == NULL) {
  2489.         clcf->types = ngx_array_create(cf->pool, 64, sizeof(ngx_hash_key_t));
  2490.         if (clcf->types == NULL) {
  2491.             return NGX_CONF_ERROR;
  2492.         }
  2493.     }

  2494.     save = *cf;
  2495.     cf->handler = ngx_http_core_type;
  2496.     cf->handler_conf = conf;

  2497.     rv = ngx_conf_parse(cf, NULL);

  2498.     *cf = save;

  2499.     return rv;
  2500. }


  2501. static char *
  2502. ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
  2503. {
  2504.     ngx_http_core_loc_conf_t *clcf = conf;

  2505.     ngx_str_t       *value, *content_type, *old;
  2506.     ngx_uint_t       i, n, hash;
  2507.     ngx_hash_key_t  *type;

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

  2509.     if (ngx_strcmp(value[0].data, "include") == 0) {
  2510.         if (cf->args->nelts != 2) {
  2511.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2512.                                "invalid number of arguments"
  2513.                                " in \"include\" directive");
  2514.             return NGX_CONF_ERROR;
  2515.         }

  2516.         return ngx_conf_include(cf, dummy, conf);
  2517.     }

  2518.     content_type = ngx_palloc(cf->pool, sizeof(ngx_str_t));
  2519.     if (content_type == NULL) {
  2520.         return NGX_CONF_ERROR;
  2521.     }

  2522.     *content_type = value[0];

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

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

  2525.         type = clcf->types->elts;
  2526.         for (n = 0; n < clcf->types->nelts; n++) {
  2527.             if (ngx_strcmp(value[i].data, type[n].key.data) == 0) {
  2528.                 old = type[n].value;
  2529.                 type[n].value = content_type;

  2530.                 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
  2531.                                    "duplicate extension \"%V\", "
  2532.                                    "content type: \"%V\", "
  2533.                                    "previous content type: \"%V\"",
  2534.                                    &value[i], content_type, old);
  2535.                 goto next;
  2536.             }
  2537.         }


  2538.         type = ngx_array_push(clcf->types);
  2539.         if (type == NULL) {
  2540.             return NGX_CONF_ERROR;
  2541.         }

  2542.         type->key = value[i];
  2543.         type->key_hash = hash;
  2544.         type->value = content_type;

  2545.     next:
  2546.         continue;
  2547.     }

  2548.     return NGX_CONF_OK;
  2549. }


  2550. static ngx_int_t
  2551. ngx_http_core_preconfiguration(ngx_conf_t *cf)
  2552. {
  2553.     return ngx_http_variables_add_core_vars(cf);
  2554. }


  2555. static ngx_int_t
  2556. ngx_http_core_postconfiguration(ngx_conf_t *cf)
  2557. {
  2558.     ngx_http_top_request_body_filter = ngx_http_request_body_save_filter;

  2559.     return NGX_OK;
  2560. }


  2561. static void *
  2562. ngx_http_core_create_main_conf(ngx_conf_t *cf)
  2563. {
  2564.     ngx_http_core_main_conf_t  *cmcf;

  2565.     cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_main_conf_t));
  2566.     if (cmcf == NULL) {
  2567.         return NULL;
  2568.     }

  2569.     if (ngx_array_init(&cmcf->servers, cf->pool, 4,
  2570.                        sizeof(ngx_http_core_srv_conf_t *))
  2571.         != NGX_OK)
  2572.     {
  2573.         return NULL;
  2574.     }

  2575.     cmcf->server_names_hash_max_size = NGX_CONF_UNSET_UINT;
  2576.     cmcf->server_names_hash_bucket_size = NGX_CONF_UNSET_UINT;

  2577.     cmcf->variables_hash_max_size = NGX_CONF_UNSET_UINT;
  2578.     cmcf->variables_hash_bucket_size = NGX_CONF_UNSET_UINT;

  2579.     return cmcf;
  2580. }


  2581. static char *
  2582. ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf)
  2583. {
  2584.     ngx_http_core_main_conf_t *cmcf = conf;

  2585.     ngx_conf_init_uint_value(cmcf->server_names_hash_max_size, 512);
  2586.     ngx_conf_init_uint_value(cmcf->server_names_hash_bucket_size,
  2587.                              ngx_cacheline_size);

  2588.     cmcf->server_names_hash_bucket_size =
  2589.             ngx_align(cmcf->server_names_hash_bucket_size, ngx_cacheline_size);


  2590.     ngx_conf_init_uint_value(cmcf->variables_hash_max_size, 1024);
  2591.     ngx_conf_init_uint_value(cmcf->variables_hash_bucket_size, 64);

  2592.     cmcf->variables_hash_bucket_size =
  2593.                ngx_align(cmcf->variables_hash_bucket_size, ngx_cacheline_size);

  2594.     if (cmcf->ncaptures) {
  2595.         cmcf->ncaptures = (cmcf->ncaptures + 1) * 3;
  2596.     }

  2597.     return NGX_CONF_OK;
  2598. }


  2599. static void *
  2600. ngx_http_core_create_srv_conf(ngx_conf_t *cf)
  2601. {
  2602.     ngx_http_core_srv_conf_t  *cscf;

  2603.     cscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_srv_conf_t));
  2604.     if (cscf == NULL) {
  2605.         return NULL;
  2606.     }

  2607.     /*
  2608.      * set by ngx_pcalloc():
  2609.      *
  2610.      *     conf->client_large_buffers.num = 0;
  2611.      */

  2612.     if (ngx_array_init(&cscf->server_names, cf->temp_pool, 4,
  2613.                        sizeof(ngx_http_server_name_t))
  2614.         != NGX_OK)
  2615.     {
  2616.         return NULL;
  2617.     }

  2618.     cscf->connection_pool_size = NGX_CONF_UNSET_SIZE;
  2619.     cscf->request_pool_size = NGX_CONF_UNSET_SIZE;
  2620.     cscf->client_header_timeout = NGX_CONF_UNSET_MSEC;
  2621.     cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE;
  2622.     cscf->ignore_invalid_headers = NGX_CONF_UNSET;
  2623.     cscf->merge_slashes = NGX_CONF_UNSET;
  2624.     cscf->underscores_in_headers = NGX_CONF_UNSET;

  2625.     cscf->file_name = cf->conf_file->file.name.data;
  2626.     cscf->line = cf->conf_file->line;

  2627.     return cscf;
  2628. }


  2629. static char *
  2630. ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
  2631. {
  2632.     ngx_http_core_srv_conf_t *prev = parent;
  2633.     ngx_http_core_srv_conf_t *conf = child;

  2634.     ngx_str_t                name;
  2635.     ngx_http_server_name_t  *sn;

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

  2637.     ngx_conf_merge_size_value(conf->connection_pool_size,
  2638.                               prev->connection_pool_size, 64 * sizeof(void *));
  2639.     ngx_conf_merge_size_value(conf->request_pool_size,
  2640.                               prev->request_pool_size, 4096);
  2641.     ngx_conf_merge_msec_value(conf->client_header_timeout,
  2642.                               prev->client_header_timeout, 60000);
  2643.     ngx_conf_merge_size_value(conf->client_header_buffer_size,
  2644.                               prev->client_header_buffer_size, 1024);
  2645.     ngx_conf_merge_bufs_value(conf->large_client_header_buffers,
  2646.                               prev->large_client_header_buffers,
  2647.                               4, 8192);

  2648.     if (conf->large_client_header_buffers.size < conf->connection_pool_size) {
  2649.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2650.                            "the \"large_client_header_buffers\" size must be "
  2651.                            "equal to or greater than \"connection_pool_size\"");
  2652.         return NGX_CONF_ERROR;
  2653.     }

  2654.     ngx_conf_merge_value(conf->ignore_invalid_headers,
  2655.                               prev->ignore_invalid_headers, 1);

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

  2657.     ngx_conf_merge_value(conf->underscores_in_headers,
  2658.                               prev->underscores_in_headers, 0);

  2659.     if (conf->server_names.nelts == 0) {
  2660.         /* the array has 4 empty preallocated elements, so push cannot fail */
  2661.         sn = ngx_array_push(&conf->server_names);
  2662. #if (NGX_PCRE)
  2663.         sn->regex = NULL;
  2664. #endif
  2665.         sn->server = conf;
  2666.         ngx_str_set(&sn->name, "");
  2667.     }

  2668.     sn = conf->server_names.elts;
  2669.     name = sn[0].name;

  2670. #if (NGX_PCRE)
  2671.     if (sn->regex) {
  2672.         name.len++;
  2673.         name.data--;
  2674.     } else
  2675. #endif

  2676.     if (name.data[0] == '.') {
  2677.         name.len--;
  2678.         name.data++;
  2679.     }

  2680.     conf->server_name.len = name.len;
  2681.     conf->server_name.data = ngx_pstrdup(cf->pool, &name);
  2682.     if (conf->server_name.data == NULL) {
  2683.         return NGX_CONF_ERROR;
  2684.     }

  2685.     return NGX_CONF_OK;
  2686. }


  2687. static void *
  2688. ngx_http_core_create_loc_conf(ngx_conf_t *cf)
  2689. {
  2690.     ngx_http_core_loc_conf_t  *clcf;

  2691.     clcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_loc_conf_t));
  2692.     if (clcf == NULL) {
  2693.         return NULL;
  2694.     }

  2695.     /*
  2696.      * set by ngx_pcalloc():
  2697.      *
  2698.      *     clcf->escaped_name = { 0, NULL };
  2699.      *     clcf->root = { 0, NULL };
  2700.      *     clcf->limit_except = 0;
  2701.      *     clcf->post_action = { 0, NULL };
  2702.      *     clcf->types = NULL;
  2703.      *     clcf->default_type = { 0, NULL };
  2704.      *     clcf->error_log = NULL;
  2705.      *     clcf->error_pages = NULL;
  2706.      *     clcf->client_body_path = NULL;
  2707.      *     clcf->regex = NULL;
  2708.      *     clcf->exact_match = 0;
  2709.      *     clcf->auto_redirect = 0;
  2710.      *     clcf->alias = 0;
  2711.      *     clcf->gzip_proxied = 0;
  2712.      *     clcf->keepalive_disable = 0;
  2713.      */

  2714.     clcf->client_max_body_size = NGX_CONF_UNSET;
  2715.     clcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE;
  2716.     clcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
  2717.     clcf->satisfy = NGX_CONF_UNSET_UINT;
  2718.     clcf->auth_delay = NGX_CONF_UNSET_MSEC;
  2719.     clcf->if_modified_since = NGX_CONF_UNSET_UINT;
  2720.     clcf->max_ranges = NGX_CONF_UNSET_UINT;
  2721.     clcf->client_body_in_file_only = NGX_CONF_UNSET_UINT;
  2722.     clcf->client_body_in_single_buffer = NGX_CONF_UNSET;
  2723.     clcf->internal = NGX_CONF_UNSET;
  2724.     clcf->sendfile = NGX_CONF_UNSET;
  2725.     clcf->sendfile_max_chunk = NGX_CONF_UNSET_SIZE;
  2726.     clcf->subrequest_output_buffer_size = NGX_CONF_UNSET_SIZE;
  2727.     clcf->aio = NGX_CONF_UNSET;
  2728.     clcf->aio_write = NGX_CONF_UNSET;
  2729. #if (NGX_THREADS)
  2730.     clcf->thread_pool = NGX_CONF_UNSET_PTR;
  2731.     clcf->thread_pool_value = NGX_CONF_UNSET_PTR;
  2732. #endif
  2733.     clcf->read_ahead = NGX_CONF_UNSET_SIZE;
  2734.     clcf->directio = NGX_CONF_UNSET;
  2735.     clcf->directio_alignment = NGX_CONF_UNSET;
  2736.     clcf->tcp_nopush = NGX_CONF_UNSET;
  2737.     clcf->tcp_nodelay = NGX_CONF_UNSET;
  2738.     clcf->send_timeout = NGX_CONF_UNSET_MSEC;
  2739.     clcf->send_lowat = NGX_CONF_UNSET_SIZE;
  2740.     clcf->postpone_output = NGX_CONF_UNSET_SIZE;
  2741.     clcf->limit_rate = NGX_CONF_UNSET_PTR;
  2742.     clcf->limit_rate_after = NGX_CONF_UNSET_PTR;
  2743.     clcf->keepalive_time = NGX_CONF_UNSET_MSEC;
  2744.     clcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
  2745.     clcf->keepalive_header = NGX_CONF_UNSET;
  2746.     clcf->keepalive_requests = NGX_CONF_UNSET_UINT;
  2747.     clcf->lingering_close = NGX_CONF_UNSET_UINT;
  2748.     clcf->lingering_time = NGX_CONF_UNSET_MSEC;
  2749.     clcf->lingering_timeout = NGX_CONF_UNSET_MSEC;
  2750.     clcf->resolver_timeout = NGX_CONF_UNSET_MSEC;
  2751.     clcf->reset_timedout_connection = NGX_CONF_UNSET;
  2752.     clcf->absolute_redirect = NGX_CONF_UNSET;
  2753.     clcf->server_name_in_redirect = NGX_CONF_UNSET;
  2754.     clcf->port_in_redirect = NGX_CONF_UNSET;
  2755.     clcf->msie_padding = NGX_CONF_UNSET;
  2756.     clcf->msie_refresh = NGX_CONF_UNSET;
  2757.     clcf->log_not_found = NGX_CONF_UNSET;
  2758.     clcf->log_subrequest = NGX_CONF_UNSET;
  2759.     clcf->recursive_error_pages = NGX_CONF_UNSET;
  2760.     clcf->chunked_transfer_encoding = NGX_CONF_UNSET;
  2761.     clcf->etag = NGX_CONF_UNSET;
  2762.     clcf->server_tokens = NGX_CONF_UNSET_UINT;
  2763.     clcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
  2764.     clcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;

  2765.     clcf->open_file_cache = NGX_CONF_UNSET_PTR;
  2766.     clcf->open_file_cache_valid = NGX_CONF_UNSET;
  2767.     clcf->open_file_cache_min_uses = NGX_CONF_UNSET_UINT;
  2768.     clcf->open_file_cache_errors = NGX_CONF_UNSET;
  2769.     clcf->open_file_cache_events = NGX_CONF_UNSET;

  2770. #if (NGX_HTTP_GZIP)
  2771.     clcf->gzip_vary = NGX_CONF_UNSET;
  2772.     clcf->gzip_http_version = NGX_CONF_UNSET_UINT;
  2773. #if (NGX_PCRE)
  2774.     clcf->gzip_disable = NGX_CONF_UNSET_PTR;
  2775. #endif
  2776.     clcf->gzip_disable_msie6 = 3;
  2777. #if (NGX_HTTP_DEGRADATION)
  2778.     clcf->gzip_disable_degradation = 3;
  2779. #endif
  2780. #endif

  2781. #if (NGX_HAVE_OPENAT)
  2782.     clcf->disable_symlinks = NGX_CONF_UNSET_UINT;
  2783.     clcf->disable_symlinks_from = NGX_CONF_UNSET_PTR;
  2784. #endif

  2785.     return clcf;
  2786. }


  2787. static ngx_str_t  ngx_http_core_text_html_type = ngx_string("text/html");
  2788. static ngx_str_t  ngx_http_core_image_gif_type = ngx_string("image/gif");
  2789. static ngx_str_t  ngx_http_core_image_jpeg_type = ngx_string("image/jpeg");

  2790. static ngx_hash_key_t  ngx_http_core_default_types[] = {
  2791.     { ngx_string("html"), 0, &ngx_http_core_text_html_type },
  2792.     { ngx_string("gif"), 0, &ngx_http_core_image_gif_type },
  2793.     { ngx_string("jpg"), 0, &ngx_http_core_image_jpeg_type },
  2794.     { ngx_null_string, 0, NULL }
  2795. };


  2796. static char *
  2797. ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
  2798. {
  2799.     ngx_http_core_loc_conf_t *prev = parent;
  2800.     ngx_http_core_loc_conf_t *conf = child;

  2801.     ngx_uint_t        i;
  2802.     ngx_hash_key_t   *type;
  2803.     ngx_hash_init_t   types_hash;

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

  2805.         conf->alias = prev->alias;
  2806.         conf->root = prev->root;
  2807.         conf->root_lengths = prev->root_lengths;
  2808.         conf->root_values = prev->root_values;

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

  2811.             if (ngx_conf_full_name(cf->cycle, &conf->root, 0) != NGX_OK) {
  2812.                 return NGX_CONF_ERROR;
  2813.             }
  2814.         }
  2815.     }

  2816.     if (conf->post_action.data == NULL) {
  2817.         conf->post_action = prev->post_action;
  2818.     }

  2819.     ngx_conf_merge_uint_value(conf->types_hash_max_size,
  2820.                               prev->types_hash_max_size, 1024);

  2821.     ngx_conf_merge_uint_value(conf->types_hash_bucket_size,
  2822.                               prev->types_hash_bucket_size, 64);

  2823.     conf->types_hash_bucket_size = ngx_align(conf->types_hash_bucket_size,
  2824.                                              ngx_cacheline_size);

  2825.     /*
  2826.      * the special handling of the "types" directive in the "http" section
  2827.      * to inherit the http's conf->types_hash to all servers
  2828.      */

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

  2830.         types_hash.hash = &prev->types_hash;
  2831.         types_hash.key = ngx_hash_key_lc;
  2832.         types_hash.max_size = conf->types_hash_max_size;
  2833.         types_hash.bucket_size = conf->types_hash_bucket_size;
  2834.         types_hash.name = "types_hash";
  2835.         types_hash.pool = cf->pool;
  2836.         types_hash.temp_pool = NULL;

  2837.         if (ngx_hash_init(&types_hash, prev->types->elts, prev->types->nelts)
  2838.             != NGX_OK)
  2839.         {
  2840.             return NGX_CONF_ERROR;
  2841.         }
  2842.     }

  2843.     if (conf->types == NULL) {
  2844.         conf->types = prev->types;
  2845.         conf->types_hash = prev->types_hash;
  2846.     }

  2847.     if (conf->types == NULL) {
  2848.         conf->types = ngx_array_create(cf->pool, 3, sizeof(ngx_hash_key_t));
  2849.         if (conf->types == NULL) {
  2850.             return NGX_CONF_ERROR;
  2851.         }

  2852.         for (i = 0; ngx_http_core_default_types[i].key.len; i++) {
  2853.             type = ngx_array_push(conf->types);
  2854.             if (type == NULL) {
  2855.                 return NGX_CONF_ERROR;
  2856.             }

  2857.             type->key = ngx_http_core_default_types[i].key;
  2858.             type->key_hash =
  2859.                        ngx_hash_key_lc(ngx_http_core_default_types[i].key.data,
  2860.                                        ngx_http_core_default_types[i].key.len);
  2861.             type->value = ngx_http_core_default_types[i].value;
  2862.         }
  2863.     }

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

  2865.         types_hash.hash = &conf->types_hash;
  2866.         types_hash.key = ngx_hash_key_lc;
  2867.         types_hash.max_size = conf->types_hash_max_size;
  2868.         types_hash.bucket_size = conf->types_hash_bucket_size;
  2869.         types_hash.name = "types_hash";
  2870.         types_hash.pool = cf->pool;
  2871.         types_hash.temp_pool = NULL;

  2872.         if (ngx_hash_init(&types_hash, conf->types->elts, conf->types->nelts)
  2873.             != NGX_OK)
  2874.         {
  2875.             return NGX_CONF_ERROR;
  2876.         }
  2877.     }

  2878.     if (conf->error_log == NULL) {
  2879.         if (prev->error_log) {
  2880.             conf->error_log = prev->error_log;
  2881.         } else {
  2882.             conf->error_log = &cf->cycle->new_log;
  2883.         }
  2884.     }

  2885.     if (conf->error_pages == NULL && prev->error_pages) {
  2886.         conf->error_pages = prev->error_pages;
  2887.     }

  2888.     ngx_conf_merge_str_value(conf->default_type,
  2889.                               prev->default_type, "text/plain");

  2890.     ngx_conf_merge_off_value(conf->client_max_body_size,
  2891.                               prev->client_max_body_size, 1 * 1024 * 1024);
  2892.     ngx_conf_merge_size_value(conf->client_body_buffer_size,
  2893.                               prev->client_body_buffer_size,
  2894.                               (size_t) 2 * ngx_pagesize);
  2895.     ngx_conf_merge_msec_value(conf->client_body_timeout,
  2896.                               prev->client_body_timeout, 60000);

  2897.     ngx_conf_merge_bitmask_value(conf->keepalive_disable,
  2898.                               prev->keepalive_disable,
  2899.                               (NGX_CONF_BITMASK_SET
  2900.                                |NGX_HTTP_KEEPALIVE_DISABLE_MSIE6));
  2901.     ngx_conf_merge_uint_value(conf->satisfy, prev->satisfy,
  2902.                               NGX_HTTP_SATISFY_ALL);
  2903.     ngx_conf_merge_msec_value(conf->auth_delay, prev->auth_delay, 0);
  2904.     ngx_conf_merge_uint_value(conf->if_modified_since, prev->if_modified_since,
  2905.                               NGX_HTTP_IMS_EXACT);
  2906.     ngx_conf_merge_uint_value(conf->max_ranges, prev->max_ranges,
  2907.                               NGX_MAX_INT32_VALUE);
  2908.     ngx_conf_merge_uint_value(conf->client_body_in_file_only,
  2909.                               prev->client_body_in_file_only,
  2910.                               NGX_HTTP_REQUEST_BODY_FILE_OFF);
  2911.     ngx_conf_merge_value(conf->client_body_in_single_buffer,
  2912.                               prev->client_body_in_single_buffer, 0);
  2913.     ngx_conf_merge_value(conf->internal, prev->internal, 0);
  2914.     ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0);
  2915.     ngx_conf_merge_size_value(conf->sendfile_max_chunk,
  2916.                               prev->sendfile_max_chunk, 2 * 1024 * 1024);
  2917.     ngx_conf_merge_size_value(conf->subrequest_output_buffer_size,
  2918.                               prev->subrequest_output_buffer_size,
  2919.                               (size_t) ngx_pagesize);
  2920.     ngx_conf_merge_value(conf->aio, prev->aio, NGX_HTTP_AIO_OFF);
  2921.     ngx_conf_merge_value(conf->aio_write, prev->aio_write, 0);
  2922. #if (NGX_THREADS)
  2923.     ngx_conf_merge_ptr_value(conf->thread_pool, prev->thread_pool, NULL);
  2924.     ngx_conf_merge_ptr_value(conf->thread_pool_value, prev->thread_pool_value,
  2925.                              NULL);
  2926. #endif
  2927.     ngx_conf_merge_size_value(conf->read_ahead, prev->read_ahead, 0);
  2928.     ngx_conf_merge_off_value(conf->directio, prev->directio,
  2929.                               NGX_OPEN_FILE_DIRECTIO_OFF);
  2930.     ngx_conf_merge_off_value(conf->directio_alignment, prev->directio_alignment,
  2931.                               512);
  2932.     ngx_conf_merge_value(conf->tcp_nopush, prev->tcp_nopush, 0);
  2933.     ngx_conf_merge_value(conf->tcp_nodelay, prev->tcp_nodelay, 1);

  2934.     ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 60000);
  2935.     ngx_conf_merge_size_value(conf->send_lowat, prev->send_lowat, 0);
  2936.     ngx_conf_merge_size_value(conf->postpone_output, prev->postpone_output,
  2937.                               1460);

  2938.     ngx_conf_merge_ptr_value(conf->limit_rate, prev->limit_rate, NULL);
  2939.     ngx_conf_merge_ptr_value(conf->limit_rate_after,
  2940.                               prev->limit_rate_after, NULL);

  2941.     ngx_conf_merge_msec_value(conf->keepalive_time,
  2942.                               prev->keepalive_time, 3600000);
  2943.     ngx_conf_merge_msec_value(conf->keepalive_timeout,
  2944.                               prev->keepalive_timeout, 75000);
  2945.     ngx_conf_merge_sec_value(conf->keepalive_header,
  2946.                               prev->keepalive_header, 0);
  2947.     ngx_conf_merge_uint_value(conf->keepalive_requests,
  2948.                               prev->keepalive_requests, 1000);
  2949.     ngx_conf_merge_uint_value(conf->lingering_close,
  2950.                               prev->lingering_close, NGX_HTTP_LINGERING_ON);
  2951.     ngx_conf_merge_msec_value(conf->lingering_time,
  2952.                               prev->lingering_time, 30000);
  2953.     ngx_conf_merge_msec_value(conf->lingering_timeout,
  2954.                               prev->lingering_timeout, 5000);
  2955.     ngx_conf_merge_msec_value(conf->resolver_timeout,
  2956.                               prev->resolver_timeout, 30000);

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

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

  2959.             /*
  2960.              * create dummy resolver in http {} context
  2961.              * to inherit it in all servers
  2962.              */

  2963.             prev->resolver = ngx_resolver_create(cf, NULL, 0);
  2964.             if (prev->resolver == NULL) {
  2965.                 return NGX_CONF_ERROR;
  2966.             }
  2967.         }

  2968.         conf->resolver = prev->resolver;
  2969.     }

  2970.     if (ngx_conf_merge_path_value(cf, &conf->client_body_temp_path,
  2971.                               prev->client_body_temp_path,
  2972.                               &ngx_http_client_temp_path)
  2973.         != NGX_OK)
  2974.     {
  2975.         return NGX_CONF_ERROR;
  2976.     }

  2977.     ngx_conf_merge_value(conf->reset_timedout_connection,
  2978.                               prev->reset_timedout_connection, 0);
  2979.     ngx_conf_merge_value(conf->absolute_redirect,
  2980.                               prev->absolute_redirect, 1);
  2981.     ngx_conf_merge_value(conf->server_name_in_redirect,
  2982.                               prev->server_name_in_redirect, 0);
  2983.     ngx_conf_merge_value(conf->port_in_redirect, prev->port_in_redirect, 1);
  2984.     ngx_conf_merge_value(conf->msie_padding, prev->msie_padding, 1);
  2985.     ngx_conf_merge_value(conf->msie_refresh, prev->msie_refresh, 0);
  2986.     ngx_conf_merge_value(conf->log_not_found, prev->log_not_found, 1);
  2987.     ngx_conf_merge_value(conf->log_subrequest, prev->log_subrequest, 0);
  2988.     ngx_conf_merge_value(conf->recursive_error_pages,
  2989.                               prev->recursive_error_pages, 0);
  2990.     ngx_conf_merge_value(conf->chunked_transfer_encoding,
  2991.                               prev->chunked_transfer_encoding, 1);
  2992.     ngx_conf_merge_value(conf->etag, prev->etag, 1);

  2993.     ngx_conf_merge_uint_value(conf->server_tokens, prev->server_tokens,
  2994.                               NGX_HTTP_SERVER_TOKENS_ON);

  2995.     ngx_conf_merge_ptr_value(conf->open_file_cache,
  2996.                               prev->open_file_cache, NULL);

  2997.     ngx_conf_merge_sec_value(conf->open_file_cache_valid,
  2998.                               prev->open_file_cache_valid, 60);

  2999.     ngx_conf_merge_uint_value(conf->open_file_cache_min_uses,
  3000.                               prev->open_file_cache_min_uses, 1);

  3001.     ngx_conf_merge_sec_value(conf->open_file_cache_errors,
  3002.                               prev->open_file_cache_errors, 0);

  3003.     ngx_conf_merge_sec_value(conf->open_file_cache_events,
  3004.                               prev->open_file_cache_events, 0);
  3005. #if (NGX_HTTP_GZIP)

  3006.     ngx_conf_merge_value(conf->gzip_vary, prev->gzip_vary, 0);
  3007.     ngx_conf_merge_uint_value(conf->gzip_http_version, prev->gzip_http_version,
  3008.                               NGX_HTTP_VERSION_11);
  3009.     ngx_conf_merge_bitmask_value(conf->gzip_proxied, prev->gzip_proxied,
  3010.                               (NGX_CONF_BITMASK_SET|NGX_HTTP_GZIP_PROXIED_OFF));

  3011. #if (NGX_PCRE)
  3012.     ngx_conf_merge_ptr_value(conf->gzip_disable, prev->gzip_disable, NULL);
  3013. #endif

  3014.     if (conf->gzip_disable_msie6 == 3) {
  3015.         conf->gzip_disable_msie6 =
  3016.             (prev->gzip_disable_msie6 == 3) ? 0 : prev->gzip_disable_msie6;
  3017.     }

  3018. #if (NGX_HTTP_DEGRADATION)

  3019.     if (conf->gzip_disable_degradation == 3) {
  3020.         conf->gzip_disable_degradation =
  3021.             (prev->gzip_disable_degradation == 3) ?
  3022.                  0 : prev->gzip_disable_degradation;
  3023.     }

  3024. #endif
  3025. #endif

  3026. #if (NGX_HAVE_OPENAT)
  3027.     ngx_conf_merge_uint_value(conf->disable_symlinks, prev->disable_symlinks,
  3028.                               NGX_DISABLE_SYMLINKS_OFF);
  3029.     ngx_conf_merge_ptr_value(conf->disable_symlinks_from,
  3030.                              prev->disable_symlinks_from, NULL);
  3031. #endif

  3032.     return NGX_CONF_OK;
  3033. }


  3034. static char *
  3035. ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3036. {
  3037.     ngx_http_core_srv_conf_t *cscf = conf;

  3038.     ngx_str_t              *value, size;
  3039.     ngx_url_t               u;
  3040.     ngx_uint_t              n, i, backlog;
  3041.     ngx_http_listen_opt_t   lsopt;

  3042.     cscf->listen = 1;

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

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

  3045.     u.url = value[1];
  3046.     u.listen = 1;
  3047.     u.default_port = 80;

  3048.     if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
  3049.         if (u.err) {
  3050.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3051.                                "%s in \"%V\" of the \"listen\" directive",
  3052.                                u.err, &u.url);
  3053.         }

  3054.         return NGX_CONF_ERROR;
  3055.     }

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

  3057.     lsopt.backlog = NGX_LISTEN_BACKLOG;
  3058.     lsopt.type = SOCK_STREAM;
  3059.     lsopt.rcvbuf = -1;
  3060.     lsopt.sndbuf = -1;
  3061. #if (NGX_HAVE_SETFIB)
  3062.     lsopt.setfib = -1;
  3063. #endif
  3064. #if (NGX_HAVE_TCP_FASTOPEN)
  3065.     lsopt.fastopen = -1;
  3066. #endif
  3067. #if (NGX_HAVE_INET6)
  3068.     lsopt.ipv6only = 1;
  3069. #endif

  3070.     backlog = 0;

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

  3072.         if (ngx_strcmp(value[n].data, "default_server") == 0
  3073.             || ngx_strcmp(value[n].data, "default") == 0)
  3074.         {
  3075.             lsopt.default_server = 1;
  3076.             continue;
  3077.         }

  3078.         if (ngx_strcmp(value[n].data, "bind") == 0) {
  3079.             lsopt.set = 1;
  3080.             lsopt.bind = 1;
  3081.             continue;
  3082.         }

  3083. #if (NGX_HAVE_SETFIB)
  3084.         if (ngx_strncmp(value[n].data, "setfib=", 7) == 0) {
  3085.             lsopt.setfib = ngx_atoi(value[n].data + 7, value[n].len - 7);
  3086.             lsopt.set = 1;
  3087.             lsopt.bind = 1;

  3088.             if (lsopt.setfib == NGX_ERROR) {
  3089.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3090.                                    "invalid setfib \"%V\"", &value[n]);
  3091.                 return NGX_CONF_ERROR;
  3092.             }

  3093.             continue;
  3094.         }
  3095. #endif

  3096. #if (NGX_HAVE_TCP_FASTOPEN)
  3097.         if (ngx_strncmp(value[n].data, "fastopen=", 9) == 0) {
  3098.             lsopt.fastopen = ngx_atoi(value[n].data + 9, value[n].len - 9);
  3099.             lsopt.set = 1;
  3100.             lsopt.bind = 1;

  3101.             if (lsopt.fastopen == NGX_ERROR) {
  3102.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3103.                                    "invalid fastopen \"%V\"", &value[n]);
  3104.                 return NGX_CONF_ERROR;
  3105.             }

  3106.             continue;
  3107.         }
  3108. #endif

  3109.         if (ngx_strncmp(value[n].data, "backlog=", 8) == 0) {
  3110.             lsopt.backlog = ngx_atoi(value[n].data + 8, value[n].len - 8);
  3111.             lsopt.set = 1;
  3112.             lsopt.bind = 1;

  3113.             if (lsopt.backlog == NGX_ERROR || lsopt.backlog == 0) {
  3114.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3115.                                    "invalid backlog \"%V\"", &value[n]);
  3116.                 return NGX_CONF_ERROR;
  3117.             }

  3118.             backlog = 1;

  3119.             continue;
  3120.         }

  3121.         if (ngx_strncmp(value[n].data, "rcvbuf=", 7) == 0) {
  3122.             size.len = value[n].len - 7;
  3123.             size.data = value[n].data + 7;

  3124.             lsopt.rcvbuf = ngx_parse_size(&size);
  3125.             lsopt.set = 1;
  3126.             lsopt.bind = 1;

  3127.             if (lsopt.rcvbuf == NGX_ERROR) {
  3128.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3129.                                    "invalid rcvbuf \"%V\"", &value[n]);
  3130.                 return NGX_CONF_ERROR;
  3131.             }

  3132.             continue;
  3133.         }

  3134.         if (ngx_strncmp(value[n].data, "sndbuf=", 7) == 0) {
  3135.             size.len = value[n].len - 7;
  3136.             size.data = value[n].data + 7;

  3137.             lsopt.sndbuf = ngx_parse_size(&size);
  3138.             lsopt.set = 1;
  3139.             lsopt.bind = 1;

  3140.             if (lsopt.sndbuf == NGX_ERROR) {
  3141.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3142.                                    "invalid sndbuf \"%V\"", &value[n]);
  3143.                 return NGX_CONF_ERROR;
  3144.             }

  3145.             continue;
  3146.         }

  3147.         if (ngx_strncmp(value[n].data, "accept_filter=", 14) == 0) {
  3148. #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
  3149.             lsopt.accept_filter = (char *) &value[n].data[14];
  3150.             lsopt.set = 1;
  3151.             lsopt.bind = 1;
  3152. #else
  3153.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3154.                                "accept filters \"%V\" are not supported "
  3155.                                "on this platform, ignored",
  3156.                                &value[n]);
  3157. #endif
  3158.             continue;
  3159.         }

  3160.         if (ngx_strcmp(value[n].data, "deferred") == 0) {
  3161. #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
  3162.             lsopt.deferred_accept = 1;
  3163.             lsopt.set = 1;
  3164.             lsopt.bind = 1;
  3165. #else
  3166.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3167.                                "the deferred accept is not supported "
  3168.                                "on this platform, ignored");
  3169. #endif
  3170.             continue;
  3171.         }

  3172.         if (ngx_strncmp(value[n].data, "ipv6only=o", 10) == 0) {
  3173. #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
  3174.             if (ngx_strcmp(&value[n].data[10], "n") == 0) {
  3175.                 lsopt.ipv6only = 1;

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

  3178.             } else {
  3179.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3180.                                    "invalid ipv6only flags \"%s\"",
  3181.                                    &value[n].data[9]);
  3182.                 return NGX_CONF_ERROR;
  3183.             }

  3184.             lsopt.set = 1;
  3185.             lsopt.bind = 1;

  3186.             continue;
  3187. #else
  3188.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3189.                                "ipv6only is not supported "
  3190.                                "on this platform");
  3191.             return NGX_CONF_ERROR;
  3192. #endif
  3193.         }

  3194.         if (ngx_strcmp(value[n].data, "reuseport") == 0) {
  3195. #if (NGX_HAVE_REUSEPORT)
  3196.             lsopt.reuseport = 1;
  3197.             lsopt.set = 1;
  3198.             lsopt.bind = 1;
  3199. #else
  3200.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3201.                                "reuseport is not supported "
  3202.                                "on this platform, ignored");
  3203. #endif
  3204.             continue;
  3205.         }

  3206.         if (ngx_strcmp(value[n].data, "ssl") == 0) {
  3207. #if (NGX_HTTP_SSL)
  3208.             lsopt.ssl = 1;
  3209.             continue;
  3210. #else
  3211.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3212.                                "the \"ssl\" parameter requires "
  3213.                                "ngx_http_ssl_module");
  3214.             return NGX_CONF_ERROR;
  3215. #endif
  3216.         }

  3217.         if (ngx_strcmp(value[n].data, "http2") == 0) {
  3218. #if (NGX_HTTP_V2)
  3219.             ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
  3220.                                "the \"listen ... http2\" directive "
  3221.                                "is deprecated, use "
  3222.                                "the \"http2\" directive instead");

  3223.             lsopt.http2 = 1;
  3224.             continue;
  3225. #else
  3226.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3227.                                "the \"http2\" parameter requires "
  3228.                                "ngx_http_v2_module");
  3229.             return NGX_CONF_ERROR;
  3230. #endif
  3231.         }

  3232.         if (ngx_strcmp(value[n].data, "quic") == 0) {
  3233. #if (NGX_HTTP_V3)
  3234.             lsopt.quic = 1;
  3235.             lsopt.type = SOCK_DGRAM;
  3236.             continue;
  3237. #else
  3238.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3239.                                "the \"quic\" parameter requires "
  3240.                                "ngx_http_v3_module");
  3241.             return NGX_CONF_ERROR;
  3242. #endif
  3243.         }

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

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

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

  3249.             } else {

  3250. #if (NGX_HAVE_KEEPALIVE_TUNABLE)
  3251.                 u_char     *p, *end;
  3252.                 ngx_str_t   s;

  3253.                 end = value[n].data + value[n].len;
  3254.                 s.data = value[n].data + 13;

  3255.                 p = ngx_strlchr(s.data, end, ':');
  3256.                 if (p == NULL) {
  3257.                     p = end;
  3258.                 }

  3259.                 if (p > s.data) {
  3260.                     s.len = p - s.data;

  3261.                     lsopt.tcp_keepidle = ngx_parse_time(&s, 1);
  3262.                     if (lsopt.tcp_keepidle == (time_t) NGX_ERROR) {
  3263.                         goto invalid_so_keepalive;
  3264.                     }
  3265.                 }

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

  3267.                 p = ngx_strlchr(s.data, end, ':');
  3268.                 if (p == NULL) {
  3269.                     p = end;
  3270.                 }

  3271.                 if (p > s.data) {
  3272.                     s.len = p - s.data;

  3273.                     lsopt.tcp_keepintvl = ngx_parse_time(&s, 1);
  3274.                     if (lsopt.tcp_keepintvl == (time_t) NGX_ERROR) {
  3275.                         goto invalid_so_keepalive;
  3276.                     }
  3277.                 }

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

  3279.                 if (s.data < end) {
  3280.                     s.len = end - s.data;

  3281.                     lsopt.tcp_keepcnt = ngx_atoi(s.data, s.len);
  3282.                     if (lsopt.tcp_keepcnt == NGX_ERROR) {
  3283.                         goto invalid_so_keepalive;
  3284.                     }
  3285.                 }

  3286.                 if (lsopt.tcp_keepidle == 0 && lsopt.tcp_keepintvl == 0
  3287.                     && lsopt.tcp_keepcnt == 0)
  3288.                 {
  3289.                     goto invalid_so_keepalive;
  3290.                 }

  3291.                 lsopt.so_keepalive = 1;

  3292. #else

  3293.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3294.                                    "the \"so_keepalive\" parameter accepts "
  3295.                                    "only \"on\" or \"off\" on this platform");
  3296.                 return NGX_CONF_ERROR;

  3297. #endif
  3298.             }

  3299.             lsopt.set = 1;
  3300.             lsopt.bind = 1;

  3301.             continue;

  3302. #if (NGX_HAVE_KEEPALIVE_TUNABLE)
  3303.         invalid_so_keepalive:

  3304.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3305.                                "invalid so_keepalive value: \"%s\"",
  3306.                                &value[n].data[13]);
  3307.             return NGX_CONF_ERROR;
  3308. #endif
  3309.         }

  3310.         if (ngx_strcmp(value[n].data, "proxy_protocol") == 0) {
  3311.             lsopt.proxy_protocol = 1;
  3312.             continue;
  3313.         }

  3314.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3315.                            "invalid parameter \"%V\"", &value[n]);
  3316.         return NGX_CONF_ERROR;
  3317.     }

  3318.     if (lsopt.quic) {
  3319. #if (NGX_HAVE_TCP_FASTOPEN)
  3320.         if (lsopt.fastopen != -1) {
  3321.             return "\"fastopen\" parameter is incompatible with \"quic\"";
  3322.         }
  3323. #endif

  3324.         if (backlog) {
  3325.             return "\"backlog\" parameter is incompatible with \"quic\"";
  3326.         }

  3327. #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
  3328.         if (lsopt.accept_filter) {
  3329.             return "\"accept_filter\" parameter is incompatible with \"quic\"";
  3330.         }
  3331. #endif

  3332. #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
  3333.         if (lsopt.deferred_accept) {
  3334.             return "\"deferred\" parameter is incompatible with \"quic\"";
  3335.         }
  3336. #endif

  3337. #if (NGX_HTTP_SSL)
  3338.         if (lsopt.ssl) {
  3339.             return "\"ssl\" parameter is incompatible with \"quic\"";
  3340.         }
  3341. #endif

  3342. #if (NGX_HTTP_V2)
  3343.         if (lsopt.http2) {
  3344.             return "\"http2\" parameter is incompatible with \"quic\"";
  3345.         }
  3346. #endif

  3347.         if (lsopt.so_keepalive) {
  3348.             return "\"so_keepalive\" parameter is incompatible with \"quic\"";
  3349.         }

  3350.         if (lsopt.proxy_protocol) {
  3351.             return "\"proxy_protocol\" parameter is incompatible with \"quic\"";
  3352.         }
  3353.     }

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

  3355.         for (i = 0; i < n; i++) {
  3356.             if (ngx_cmp_sockaddr(u.addrs[n].sockaddr, u.addrs[n].socklen,
  3357.                                  u.addrs[i].sockaddr, u.addrs[i].socklen, 1)
  3358.                 == NGX_OK)
  3359.             {
  3360.                 goto next;
  3361.             }
  3362.         }

  3363.         lsopt.sockaddr = u.addrs[n].sockaddr;
  3364.         lsopt.socklen = u.addrs[n].socklen;
  3365.         lsopt.addr_text = u.addrs[n].name;
  3366.         lsopt.wildcard = ngx_inet_wildcard(lsopt.sockaddr);

  3367.         if (ngx_http_add_listen(cf, cscf, &lsopt) != NGX_OK) {
  3368.             return NGX_CONF_ERROR;
  3369.         }

  3370.     next:
  3371.         continue;
  3372.     }

  3373.     return NGX_CONF_OK;
  3374. }


  3375. static char *
  3376. ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3377. {
  3378.     ngx_http_core_srv_conf_t *cscf = conf;

  3379.     u_char                   ch;
  3380.     ngx_str_t               *value;
  3381.     ngx_uint_t               i;
  3382.     ngx_http_server_name_t  *sn;

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

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

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

  3386.         if ((ch == '*' && (value[i].len < 3 || value[i].data[1] != '.'))
  3387.             || (ch == '.' && value[i].len < 2))
  3388.         {
  3389.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3390.                                "server name \"%V\" is invalid", &value[i]);
  3391.             return NGX_CONF_ERROR;
  3392.         }

  3393.         if (ngx_strchr(value[i].data, '/')) {
  3394.             ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
  3395.                                "server name \"%V\" has suspicious symbols",
  3396.                                &value[i]);
  3397.         }

  3398.         sn = ngx_array_push(&cscf->server_names);
  3399.         if (sn == NULL) {
  3400.             return NGX_CONF_ERROR;
  3401.         }

  3402. #if (NGX_PCRE)
  3403.         sn->regex = NULL;
  3404. #endif
  3405.         sn->server = cscf;

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

  3408.         } else {
  3409.             sn->name = value[i];
  3410.         }

  3411.         if (value[i].data[0] != '~') {
  3412.             ngx_strlow(sn->name.data, sn->name.data, sn->name.len);
  3413.             continue;
  3414.         }

  3415. #if (NGX_PCRE)
  3416.         {
  3417.         u_char               *p;
  3418.         ngx_regex_compile_t   rc;
  3419.         u_char                errstr[NGX_MAX_CONF_ERRSTR];

  3420.         if (value[i].len == 1) {
  3421.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3422.                                "empty regex in server name \"%V\"", &value[i]);
  3423.             return NGX_CONF_ERROR;
  3424.         }

  3425.         value[i].len--;
  3426.         value[i].data++;

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

  3428.         rc.pattern = value[i];
  3429.         rc.err.len = NGX_MAX_CONF_ERRSTR;
  3430.         rc.err.data = errstr;

  3431.         for (p = value[i].data; p < value[i].data + value[i].len; p++) {
  3432.             if (*p >= 'A' && *p <= 'Z') {
  3433.                 rc.options = NGX_REGEX_CASELESS;
  3434.                 break;
  3435.             }
  3436.         }

  3437.         sn->regex = ngx_http_regex_compile(cf, &rc);
  3438.         if (sn->regex == NULL) {
  3439.             return NGX_CONF_ERROR;
  3440.         }

  3441.         sn->name = value[i];
  3442.         cscf->captures = (rc.captures > 0);
  3443.         }
  3444. #else
  3445.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3446.                            "using regex \"%V\" "
  3447.                            "requires PCRE library", &value[i]);

  3448.         return NGX_CONF_ERROR;
  3449. #endif
  3450.     }

  3451.     return NGX_CONF_OK;
  3452. }


  3453. static char *
  3454. ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3455. {
  3456.     ngx_http_core_loc_conf_t *clcf = conf;

  3457.     ngx_str_t                  *value;
  3458.     ngx_int_t                   alias;
  3459.     ngx_uint_t                  n;
  3460.     ngx_http_script_compile_t   sc;

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

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

  3463.         if ((clcf->alias != 0) == alias) {
  3464.             return "is duplicate";
  3465.         }

  3466.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3467.                            "\"%V\" directive is duplicate, "
  3468.                            "\"%s\" directive was specified earlier",
  3469.                            &cmd->name, clcf->alias ? "alias" : "root");

  3470.         return NGX_CONF_ERROR;
  3471.     }

  3472.     if (clcf->named && alias) {
  3473.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3474.                            "the \"alias\" directive cannot be used "
  3475.                            "inside the named location");

  3476.         return NGX_CONF_ERROR;
  3477.     }

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

  3479.     if (ngx_strstr(value[1].data, "$document_root")
  3480.         || ngx_strstr(value[1].data, "${document_root}"))
  3481.     {
  3482.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3483.                            "the $document_root variable cannot be used "
  3484.                            "in the \"%V\" directive",
  3485.                            &cmd->name);

  3486.         return NGX_CONF_ERROR;
  3487.     }

  3488.     if (ngx_strstr(value[1].data, "$realpath_root")
  3489.         || ngx_strstr(value[1].data, "${realpath_root}"))
  3490.     {
  3491.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3492.                            "the $realpath_root variable cannot be used "
  3493.                            "in the \"%V\" directive",
  3494.                            &cmd->name);

  3495.         return NGX_CONF_ERROR;
  3496.     }

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

  3499.     if (!alias && clcf->root.len > 0
  3500.         && clcf->root.data[clcf->root.len - 1] == '/')
  3501.     {
  3502.         clcf->root.len--;
  3503.     }

  3504.     if (clcf->root.data[0] != '$') {
  3505.         if (ngx_conf_full_name(cf->cycle, &clcf->root, 0) != NGX_OK) {
  3506.             return NGX_CONF_ERROR;
  3507.         }
  3508.     }

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

  3510.     ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
  3511.     sc.variables = n;

  3512. #if (NGX_PCRE)
  3513.     if (alias && clcf->regex) {
  3514.         clcf->alias = NGX_MAX_SIZE_T_VALUE;
  3515.         n = 1;
  3516.     }
  3517. #endif

  3518.     if (n) {
  3519.         sc.cf = cf;
  3520.         sc.source = &clcf->root;
  3521.         sc.lengths = &clcf->root_lengths;
  3522.         sc.values = &clcf->root_values;
  3523.         sc.complete_lengths = 1;
  3524.         sc.complete_values = 1;

  3525.         if (ngx_http_script_compile(&sc) != NGX_OK) {
  3526.             return NGX_CONF_ERROR;
  3527.         }
  3528.     }

  3529.     return NGX_CONF_OK;
  3530. }


  3531. static ngx_http_method_name_t  ngx_methods_names[] = {
  3532.     { (u_char *) "GET",       (uint32_t) ~NGX_HTTP_GET },
  3533.     { (u_char *) "HEAD",      (uint32_t) ~NGX_HTTP_HEAD },
  3534.     { (u_char *) "POST",      (uint32_t) ~NGX_HTTP_POST },
  3535.     { (u_char *) "PUT",       (uint32_t) ~NGX_HTTP_PUT },
  3536.     { (u_char *) "DELETE",    (uint32_t) ~NGX_HTTP_DELETE },
  3537.     { (u_char *) "MKCOL",     (uint32_t) ~NGX_HTTP_MKCOL },
  3538.     { (u_char *) "COPY",      (uint32_t) ~NGX_HTTP_COPY },
  3539.     { (u_char *) "MOVE",      (uint32_t) ~NGX_HTTP_MOVE },
  3540.     { (u_char *) "OPTIONS",   (uint32_t) ~NGX_HTTP_OPTIONS },
  3541.     { (u_char *) "PROPFIND",  (uint32_t) ~NGX_HTTP_PROPFIND },
  3542.     { (u_char *) "PROPPATCH", (uint32_t) ~NGX_HTTP_PROPPATCH },
  3543.     { (u_char *) "LOCK",      (uint32_t) ~NGX_HTTP_LOCK },
  3544.     { (u_char *) "UNLOCK",    (uint32_t) ~NGX_HTTP_UNLOCK },
  3545.     { (u_char *) "PATCH",     (uint32_t) ~NGX_HTTP_PATCH },
  3546.     { NULL, 0 }
  3547. };


  3548. static char *
  3549. ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3550. {
  3551.     ngx_http_core_loc_conf_t *pclcf = conf;

  3552.     char                      *rv;
  3553.     void                      *mconf;
  3554.     ngx_str_t                 *value;
  3555.     ngx_uint_t                 i;
  3556.     ngx_conf_t                 save;
  3557.     ngx_http_module_t         *module;
  3558.     ngx_http_conf_ctx_t       *ctx, *pctx;
  3559.     ngx_http_method_name_t    *name;
  3560.     ngx_http_core_loc_conf_t  *clcf;

  3561.     if (pclcf->limit_except) {
  3562.         return "is duplicate";
  3563.     }

  3564.     pclcf->limit_except = 0xffffffff;

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

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

  3568.             if (ngx_strcasecmp(value[i].data, name->name) == 0) {
  3569.                 pclcf->limit_except &= name->method;
  3570.                 goto next;
  3571.             }
  3572.         }

  3573.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3574.                            "invalid method \"%V\"", &value[i]);
  3575.         return NGX_CONF_ERROR;

  3576.     next:
  3577.         continue;
  3578.     }

  3579.     if (!(pclcf->limit_except & NGX_HTTP_GET)) {
  3580.         pclcf->limit_except &= (uint32_t) ~NGX_HTTP_HEAD;
  3581.     }

  3582.     ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
  3583.     if (ctx == NULL) {
  3584.         return NGX_CONF_ERROR;
  3585.     }

  3586.     pctx = cf->ctx;
  3587.     ctx->main_conf = pctx->main_conf;
  3588.     ctx->srv_conf = pctx->srv_conf;

  3589.     ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
  3590.     if (ctx->loc_conf == NULL) {
  3591.         return NGX_CONF_ERROR;
  3592.     }

  3593.     for (i = 0; cf->cycle->modules[i]; i++) {
  3594.         if (cf->cycle->modules[i]->type != NGX_HTTP_MODULE) {
  3595.             continue;
  3596.         }

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

  3598.         if (module->create_loc_conf) {

  3599.             mconf = module->create_loc_conf(cf);
  3600.             if (mconf == NULL) {
  3601.                 return NGX_CONF_ERROR;
  3602.             }

  3603.             ctx->loc_conf[cf->cycle->modules[i]->ctx_index] = mconf;
  3604.         }
  3605.     }


  3606.     clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
  3607.     pclcf->limit_except_loc_conf = ctx->loc_conf;
  3608.     clcf->loc_conf = ctx->loc_conf;
  3609.     clcf->name = pclcf->name;
  3610.     clcf->noname = 1;
  3611.     clcf->lmt_excpt = 1;

  3612.     if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) {
  3613.         return NGX_CONF_ERROR;
  3614.     }

  3615.     save = *cf;
  3616.     cf->ctx = ctx;
  3617.     cf->cmd_type = NGX_HTTP_LMT_CONF;

  3618.     rv = ngx_conf_parse(cf, NULL);

  3619.     *cf = save;

  3620.     return rv;
  3621. }


  3622. static char *
  3623. ngx_http_core_set_aio(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3624. {
  3625.     ngx_http_core_loc_conf_t *clcf = conf;

  3626.     ngx_str_t  *value;

  3627.     if (clcf->aio != NGX_CONF_UNSET) {
  3628.         return "is duplicate";
  3629.     }

  3630. #if (NGX_THREADS)
  3631.     clcf->thread_pool = NULL;
  3632.     clcf->thread_pool_value = NULL;
  3633. #endif

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

  3635.     if (ngx_strcmp(value[1].data, "off") == 0) {
  3636.         clcf->aio = NGX_HTTP_AIO_OFF;
  3637.         return NGX_CONF_OK;
  3638.     }

  3639.     if (ngx_strcmp(value[1].data, "on") == 0) {
  3640. #if (NGX_HAVE_FILE_AIO)
  3641.         clcf->aio = NGX_HTTP_AIO_ON;
  3642.         return NGX_CONF_OK;
  3643. #else
  3644.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3645.                            "\"aio on\" "
  3646.                            "is unsupported on this platform");
  3647.         return NGX_CONF_ERROR;
  3648. #endif
  3649.     }

  3650.     if (ngx_strncmp(value[1].data, "threads", 7) == 0
  3651.         && (value[1].len == 7 || value[1].data[7] == '='))
  3652.     {
  3653. #if (NGX_THREADS)
  3654.         ngx_str_t                          name;
  3655.         ngx_thread_pool_t                 *tp;
  3656.         ngx_http_complex_value_t           cv;
  3657.         ngx_http_compile_complex_value_t   ccv;

  3658.         clcf->aio = NGX_HTTP_AIO_THREADS;

  3659.         if (value[1].len >= 8) {
  3660.             name.len = value[1].len - 8;
  3661.             name.data = value[1].data + 8;

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

  3663.             ccv.cf = cf;
  3664.             ccv.value = &name;
  3665.             ccv.complex_value = &cv;

  3666.             if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
  3667.                 return NGX_CONF_ERROR;
  3668.             }

  3669.             if (cv.lengths != NULL) {
  3670.                 clcf->thread_pool_value = ngx_palloc(cf->pool,
  3671.                                     sizeof(ngx_http_complex_value_t));
  3672.                 if (clcf->thread_pool_value == NULL) {
  3673.                     return NGX_CONF_ERROR;
  3674.                 }

  3675.                 *clcf->thread_pool_value = cv;

  3676.                 return NGX_CONF_OK;
  3677.             }

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

  3679.         } else {
  3680.             tp = ngx_thread_pool_add(cf, NULL);
  3681.         }

  3682.         if (tp == NULL) {
  3683.             return NGX_CONF_ERROR;
  3684.         }

  3685.         clcf->thread_pool = tp;

  3686.         return NGX_CONF_OK;
  3687. #else
  3688.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3689.                            "\"aio threads\" "
  3690.                            "is unsupported on this platform");
  3691.         return NGX_CONF_ERROR;
  3692. #endif
  3693.     }

  3694.     return "invalid value";
  3695. }


  3696. static char *
  3697. ngx_http_core_directio(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3698. {
  3699.     ngx_http_core_loc_conf_t *clcf = conf;

  3700.     ngx_str_t  *value;

  3701.     if (clcf->directio != NGX_CONF_UNSET) {
  3702.         return "is duplicate";
  3703.     }

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

  3705.     if (ngx_strcmp(value[1].data, "off") == 0) {
  3706.         clcf->directio = NGX_OPEN_FILE_DIRECTIO_OFF;
  3707.         return NGX_CONF_OK;
  3708.     }

  3709.     clcf->directio = ngx_parse_offset(&value[1]);
  3710.     if (clcf->directio == (off_t) NGX_ERROR) {
  3711.         return "invalid value";
  3712.     }

  3713.     return NGX_CONF_OK;
  3714. }


  3715. static char *
  3716. ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3717. {
  3718.     ngx_http_core_loc_conf_t *clcf = conf;

  3719.     u_char                            *p;
  3720.     ngx_int_t                          overwrite;
  3721.     ngx_str_t                         *value, uri, args;
  3722.     ngx_uint_t                         i, n;
  3723.     ngx_http_err_page_t               *err;
  3724.     ngx_http_complex_value_t           cv;
  3725.     ngx_http_compile_complex_value_t   ccv;

  3726.     if (clcf->error_pages == NULL) {
  3727.         clcf->error_pages = ngx_array_create(cf->pool, 4,
  3728.                                              sizeof(ngx_http_err_page_t));
  3729.         if (clcf->error_pages == NULL) {
  3730.             return NGX_CONF_ERROR;
  3731.         }
  3732.     }

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

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

  3735.     if (value[i].data[0] == '=') {
  3736.         if (i == 1) {
  3737.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3738.                                "invalid value \"%V\"", &value[i]);
  3739.             return NGX_CONF_ERROR;
  3740.         }

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

  3743.             if (overwrite == NGX_ERROR) {
  3744.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3745.                                    "invalid value \"%V\"", &value[i]);
  3746.                 return NGX_CONF_ERROR;
  3747.             }

  3748.         } else {
  3749.             overwrite = 0;
  3750.         }

  3751.         n = 2;

  3752.     } else {
  3753.         overwrite = -1;
  3754.         n = 1;
  3755.     }

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

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

  3758.     ccv.cf = cf;
  3759.     ccv.value = &uri;
  3760.     ccv.complex_value = &cv;

  3761.     if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
  3762.         return NGX_CONF_ERROR;
  3763.     }

  3764.     ngx_str_null(&args);

  3765.     if (cv.lengths == NULL && uri.len && uri.data[0] == '/') {
  3766.         p = (u_char *) ngx_strchr(uri.data, '?');

  3767.         if (p) {
  3768.             cv.value.len = p - uri.data;
  3769.             cv.value.data = uri.data;
  3770.             p++;
  3771.             args.len = (uri.data + uri.len) - p;
  3772.             args.data = p;
  3773.         }
  3774.     }

  3775.     for (i = 1; i < cf->args->nelts - n; i++) {
  3776.         err = ngx_array_push(clcf->error_pages);
  3777.         if (err == NULL) {
  3778.             return NGX_CONF_ERROR;
  3779.         }

  3780.         err->status = ngx_atoi(value[i].data, value[i].len);

  3781.         if (err->status == NGX_ERROR || err->status == 499) {
  3782.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3783.                                "invalid value \"%V\"", &value[i]);
  3784.             return NGX_CONF_ERROR;
  3785.         }

  3786.         if (err->status < 300 || err->status > 599) {
  3787.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3788.                                "value \"%V\" must be between 300 and 599",
  3789.                                &value[i]);
  3790.             return NGX_CONF_ERROR;
  3791.         }

  3792.         err->overwrite = overwrite;

  3793.         if (overwrite == -1) {
  3794.             switch (err->status) {
  3795.                 case NGX_HTTP_TO_HTTPS:
  3796.                 case NGX_HTTPS_CERT_ERROR:
  3797.                 case NGX_HTTPS_NO_CERT:
  3798.                 case NGX_HTTP_REQUEST_HEADER_TOO_LARGE:
  3799.                     err->overwrite = NGX_HTTP_BAD_REQUEST;
  3800.             }
  3801.         }

  3802.         err->value = cv;
  3803.         err->args = args;
  3804.     }

  3805.     return NGX_CONF_OK;
  3806. }


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

  3811.     time_t       inactive;
  3812.     ngx_str_t   *value, s;
  3813.     ngx_int_t    max;
  3814.     ngx_uint_t   i;

  3815.     if (clcf->open_file_cache != NGX_CONF_UNSET_PTR) {
  3816.         return "is duplicate";
  3817.     }

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

  3819.     max = 0;
  3820.     inactive = 60;

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

  3822.         if (ngx_strncmp(value[i].data, "max=", 4) == 0) {

  3823.             max = ngx_atoi(value[i].data + 4, value[i].len - 4);
  3824.             if (max <= 0) {
  3825.                 goto failed;
  3826.             }

  3827.             continue;
  3828.         }

  3829.         if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) {

  3830.             s.len = value[i].len - 9;
  3831.             s.data = value[i].data + 9;

  3832.             inactive = ngx_parse_time(&s, 1);
  3833.             if (inactive == (time_t) NGX_ERROR) {
  3834.                 goto failed;
  3835.             }

  3836.             continue;
  3837.         }

  3838.         if (ngx_strcmp(value[i].data, "off") == 0) {

  3839.             clcf->open_file_cache = NULL;

  3840.             continue;
  3841.         }

  3842.     failed:

  3843.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3844.                            "invalid \"open_file_cache\" parameter \"%V\"",
  3845.                            &value[i]);
  3846.         return NGX_CONF_ERROR;
  3847.     }

  3848.     if (clcf->open_file_cache == NULL) {
  3849.         return NGX_CONF_OK;
  3850.     }

  3851.     if (max == 0) {
  3852.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3853.                         "\"open_file_cache\" must have the \"max\" parameter");
  3854.         return NGX_CONF_ERROR;
  3855.     }

  3856.     clcf->open_file_cache = ngx_open_file_cache_init(cf->pool, max, inactive);
  3857.     if (clcf->open_file_cache) {
  3858.         return NGX_CONF_OK;
  3859.     }

  3860.     return NGX_CONF_ERROR;
  3861. }


  3862. static char *
  3863. ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3864. {
  3865.     ngx_http_core_loc_conf_t *clcf = conf;

  3866.     return ngx_log_set_log(cf, &clcf->error_log);
  3867. }


  3868. static char *
  3869. ngx_http_core_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3870. {
  3871.     ngx_http_core_loc_conf_t *clcf = conf;

  3872.     ngx_str_t  *value;

  3873.     if (clcf->keepalive_timeout != NGX_CONF_UNSET_MSEC) {
  3874.         return "is duplicate";
  3875.     }

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

  3877.     clcf->keepalive_timeout = ngx_parse_time(&value[1], 0);

  3878.     if (clcf->keepalive_timeout == (ngx_msec_t) NGX_ERROR) {
  3879.         return "invalid value";
  3880.     }

  3881.     if (cf->args->nelts == 2) {
  3882.         return NGX_CONF_OK;
  3883.     }

  3884.     clcf->keepalive_header = ngx_parse_time(&value[2], 1);

  3885.     if (clcf->keepalive_header == (time_t) NGX_ERROR) {
  3886.         return "invalid value";
  3887.     }

  3888.     return NGX_CONF_OK;
  3889. }


  3890. static char *
  3891. ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3892. {
  3893.     ngx_http_core_loc_conf_t *clcf = conf;

  3894.     if (clcf->internal != NGX_CONF_UNSET) {
  3895.         return "is duplicate";
  3896.     }

  3897.     clcf->internal = 1;

  3898.     return NGX_CONF_OK;
  3899. }


  3900. static char *
  3901. ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3902. {
  3903.     ngx_http_core_loc_conf_t  *clcf = conf;

  3904.     ngx_str_t  *value;

  3905.     if (clcf->resolver) {
  3906.         return "is duplicate";
  3907.     }

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

  3909.     clcf->resolver = ngx_resolver_create(cf, &value[1], cf->args->nelts - 1);
  3910.     if (clcf->resolver == NULL) {
  3911.         return NGX_CONF_ERROR;
  3912.     }

  3913.     return NGX_CONF_OK;
  3914. }


  3915. #if (NGX_HTTP_GZIP)

  3916. static char *
  3917. ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3918. {
  3919.     ngx_http_core_loc_conf_t  *clcf = conf;

  3920. #if (NGX_PCRE)

  3921.     ngx_str_t            *value;
  3922.     ngx_uint_t            i;
  3923.     ngx_regex_elt_t      *re;
  3924.     ngx_regex_compile_t   rc;
  3925.     u_char                errstr[NGX_MAX_CONF_ERRSTR];

  3926.     if (clcf->gzip_disable == NGX_CONF_UNSET_PTR) {
  3927.         clcf->gzip_disable = ngx_array_create(cf->pool, 2,
  3928.                                               sizeof(ngx_regex_elt_t));
  3929.         if (clcf->gzip_disable == NULL) {
  3930.             return NGX_CONF_ERROR;
  3931.         }
  3932.     }

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

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

  3935.     rc.pool = cf->pool;
  3936.     rc.err.len = NGX_MAX_CONF_ERRSTR;
  3937.     rc.err.data = errstr;

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

  3939.         if (ngx_strcmp(value[i].data, "msie6") == 0) {
  3940.             clcf->gzip_disable_msie6 = 1;
  3941.             continue;
  3942.         }

  3943. #if (NGX_HTTP_DEGRADATION)

  3944.         if (ngx_strcmp(value[i].data, "degradation") == 0) {
  3945.             clcf->gzip_disable_degradation = 1;
  3946.             continue;
  3947.         }

  3948. #endif

  3949.         re = ngx_array_push(clcf->gzip_disable);
  3950.         if (re == NULL) {
  3951.             return NGX_CONF_ERROR;
  3952.         }

  3953.         rc.pattern = value[i];
  3954.         rc.options = NGX_REGEX_CASELESS;

  3955.         if (ngx_regex_compile(&rc) != NGX_OK) {
  3956.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc.err);
  3957.             return NGX_CONF_ERROR;
  3958.         }

  3959.         re->regex = rc.regex;
  3960.         re->name = value[i].data;
  3961.     }

  3962.     return NGX_CONF_OK;

  3963. #else
  3964.     ngx_str_t   *value;
  3965.     ngx_uint_t   i;

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

  3967.     for (i = 1; i < cf->args->nelts; i++) {
  3968.         if (ngx_strcmp(value[i].data, "msie6") == 0) {
  3969.             clcf->gzip_disable_msie6 = 1;
  3970.             continue;
  3971.         }

  3972. #if (NGX_HTTP_DEGRADATION)

  3973.         if (ngx_strcmp(value[i].data, "degradation") == 0) {
  3974.             clcf->gzip_disable_degradation = 1;
  3975.             continue;
  3976.         }

  3977. #endif

  3978.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3979.                            "without PCRE library \"gzip_disable\" supports "
  3980.                            "builtin \"msie6\" and \"degradation\" mask only");

  3981.         return NGX_CONF_ERROR;
  3982.     }

  3983.     return NGX_CONF_OK;

  3984. #endif
  3985. }

  3986. #endif


  3987. #if (NGX_HAVE_OPENAT)

  3988. static char *
  3989. ngx_http_disable_symlinks(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3990. {
  3991.     ngx_http_core_loc_conf_t *clcf = conf;

  3992.     ngx_str_t                         *value;
  3993.     ngx_uint_t                         i;
  3994.     ngx_http_compile_complex_value_t   ccv;

  3995.     if (clcf->disable_symlinks != NGX_CONF_UNSET_UINT) {
  3996.         return "is duplicate";
  3997.     }

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

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

  4000.         if (ngx_strcmp(value[i].data, "off") == 0) {
  4001.             clcf->disable_symlinks = NGX_DISABLE_SYMLINKS_OFF;
  4002.             continue;
  4003.         }

  4004.         if (ngx_strcmp(value[i].data, "if_not_owner") == 0) {
  4005.             clcf->disable_symlinks = NGX_DISABLE_SYMLINKS_NOTOWNER;
  4006.             continue;
  4007.         }

  4008.         if (ngx_strcmp(value[i].data, "on") == 0) {
  4009.             clcf->disable_symlinks = NGX_DISABLE_SYMLINKS_ON;
  4010.             continue;
  4011.         }

  4012.         if (ngx_strncmp(value[i].data, "from=", 5) == 0) {
  4013.             value[i].len -= 5;
  4014.             value[i].data += 5;

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

  4016.             ccv.cf = cf;
  4017.             ccv.value = &value[i];
  4018.             ccv.complex_value = ngx_palloc(cf->pool,
  4019.                                            sizeof(ngx_http_complex_value_t));
  4020.             if (ccv.complex_value == NULL) {
  4021.                 return NGX_CONF_ERROR;
  4022.             }

  4023.             if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
  4024.                 return NGX_CONF_ERROR;
  4025.             }

  4026.             clcf->disable_symlinks_from = ccv.complex_value;

  4027.             continue;
  4028.         }

  4029.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  4030.                            "invalid parameter \"%V\"", &value[i]);
  4031.         return NGX_CONF_ERROR;
  4032.     }

  4033.     if (clcf->disable_symlinks == NGX_CONF_UNSET_UINT) {
  4034.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  4035.                            "\"%V\" must have \"off\", \"on\" "
  4036.                            "or \"if_not_owner\" parameter",
  4037.                            &cmd->name);
  4038.         return NGX_CONF_ERROR;
  4039.     }

  4040.     if (cf->args->nelts == 2) {
  4041.         clcf->disable_symlinks_from = NULL;
  4042.         return NGX_CONF_OK;
  4043.     }

  4044.     if (clcf->disable_symlinks_from == NGX_CONF_UNSET_PTR) {
  4045.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  4046.                            "duplicate parameters \"%V %V\"",
  4047.                            &value[1], &value[2]);
  4048.         return NGX_CONF_ERROR;
  4049.     }

  4050.     if (clcf->disable_symlinks == NGX_DISABLE_SYMLINKS_OFF) {
  4051.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  4052.                            "\"from=\" cannot be used with \"off\" parameter");
  4053.         return NGX_CONF_ERROR;
  4054.     }

  4055.     return NGX_CONF_OK;
  4056. }

  4057. #endif


  4058. static char *
  4059. ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data)
  4060. {
  4061. #if (NGX_FREEBSD)
  4062.     ssize_t *np = data;

  4063.     if ((u_long) *np >= ngx_freebsd_net_inet_tcp_sendspace) {
  4064.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  4065.                            "\"send_lowat\" must be less than %d "
  4066.                            "(sysctl net.inet.tcp.sendspace)",
  4067.                            ngx_freebsd_net_inet_tcp_sendspace);

  4068.         return NGX_CONF_ERROR;
  4069.     }

  4070. #elif !(NGX_HAVE_SO_SNDLOWAT)
  4071.     ssize_t *np = data;

  4072.     ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
  4073.                        "\"send_lowat\" is not supported, ignored");

  4074.     *np = 0;

  4075. #endif

  4076.     return NGX_CONF_OK;
  4077. }


  4078. static char *
  4079. ngx_http_core_pool_size(ngx_conf_t *cf, void *post, void *data)
  4080. {
  4081.     size_t *sp = data;

  4082.     if (*sp < NGX_MIN_POOL_SIZE) {
  4083.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  4084.                            "the pool size must be no less than %uz",
  4085.                            NGX_MIN_POOL_SIZE);
  4086.         return NGX_CONF_ERROR;
  4087.     }

  4088.     if (*sp % NGX_POOL_ALIGNMENT) {
  4089.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  4090.                            "the pool size must be a multiple of %uz",
  4091.                            NGX_POOL_ALIGNMENT);
  4092.         return NGX_CONF_ERROR;
  4093.     }

  4094.     return NGX_CONF_OK;
  4095. }