src/http/ngx_http_core_module.c - nginx-1.7.10

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_find_location(ngx_http_request_t *r);
  16. static ngx_int_t ngx_http_core_find_static_location(ngx_http_request_t *r,
  17.     ngx_http_location_tree_node_t *node);

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

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

  33. static char *ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd,
  34.     void *conf);
  35. static char *ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy,
  36.     void *conf);

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

  73. static char *ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data);
  74. static char *ngx_http_core_pool_size(ngx_conf_t *cf, void *post, void *data);

  75. static ngx_conf_post_t  ngx_http_core_lowat_post =
  76.     { ngx_http_core_lowat_check };

  77. static ngx_conf_post_handler_pt  ngx_http_core_pool_size_p =
  78.     ngx_http_core_pool_size;

  79. static ngx_conf_deprecated_t  ngx_conf_deprecated_optimize_server_names = {
  80.     ngx_conf_deprecated, "optimize_server_names", "server_name_in_redirect"
  81. };

  82. static ngx_conf_deprecated_t  ngx_conf_deprecated_open_file_cache_retest = {
  83.     ngx_conf_deprecated, "open_file_cache_retest", "open_file_cache_valid"
  84. };

  85. static ngx_conf_deprecated_t  ngx_conf_deprecated_satisfy_any = {
  86.     ngx_conf_deprecated, "satisfy_any", "satisfy"
  87. };


  88. static ngx_conf_enum_t  ngx_http_core_request_body_in_file[] = {
  89.     { ngx_string("off"), NGX_HTTP_REQUEST_BODY_FILE_OFF },
  90.     { ngx_string("on"), NGX_HTTP_REQUEST_BODY_FILE_ON },
  91.     { ngx_string("clean"), NGX_HTTP_REQUEST_BODY_FILE_CLEAN },
  92.     { ngx_null_string, 0 }
  93. };


  94. #if (NGX_HAVE_FILE_AIO)

  95. static ngx_conf_enum_t  ngx_http_core_aio[] = {
  96.     { ngx_string("off"), NGX_HTTP_AIO_OFF  },
  97.     { ngx_string("on"), NGX_HTTP_AIO_ON },
  98. #if (NGX_HAVE_AIO_SENDFILE)
  99.     { ngx_string("sendfile"), NGX_HTTP_AIO_SENDFILE },
  100. #endif
  101.     { ngx_null_string, 0 }
  102. };

  103. #endif


  104. static ngx_conf_enum_t  ngx_http_core_satisfy[] = {
  105.     { ngx_string("all"), NGX_HTTP_SATISFY_ALL },
  106.     { ngx_string("any"), NGX_HTTP_SATISFY_ANY },
  107.     { ngx_null_string, 0 }
  108. };


  109. static ngx_conf_enum_t  ngx_http_core_lingering_close[] = {
  110.     { ngx_string("off"), NGX_HTTP_LINGERING_OFF },
  111.     { ngx_string("on"), NGX_HTTP_LINGERING_ON },
  112.     { ngx_string("always"), NGX_HTTP_LINGERING_ALWAYS },
  113.     { ngx_null_string, 0 }
  114. };


  115. static ngx_conf_enum_t  ngx_http_core_if_modified_since[] = {
  116.     { ngx_string("off"), NGX_HTTP_IMS_OFF },
  117.     { ngx_string("exact"), NGX_HTTP_IMS_EXACT },
  118.     { ngx_string("before"), NGX_HTTP_IMS_BEFORE },
  119.     { ngx_null_string, 0 }
  120. };


  121. static ngx_conf_bitmask_t  ngx_http_core_keepalive_disable[] = {
  122.     { ngx_string("none"), NGX_HTTP_KEEPALIVE_DISABLE_NONE },
  123.     { ngx_string("msie6"), NGX_HTTP_KEEPALIVE_DISABLE_MSIE6 },
  124.     { ngx_string("safari"), NGX_HTTP_KEEPALIVE_DISABLE_SAFARI },
  125.     { ngx_null_string, 0 }
  126. };


  127. static ngx_path_init_t  ngx_http_client_temp_path = {
  128.     ngx_string(NGX_HTTP_CLIENT_TEMP_PATH), { 0, 0, 0 }
  129. };


  130. #if (NGX_HTTP_GZIP)

  131. static ngx_conf_enum_t  ngx_http_gzip_http_version[] = {
  132.     { ngx_string("1.0"), NGX_HTTP_VERSION_10 },
  133.     { ngx_string("1.1"), NGX_HTTP_VERSION_11 },
  134.     { ngx_null_string, 0 }
  135. };


  136. static ngx_conf_bitmask_t  ngx_http_gzip_proxied_mask[] = {
  137.     { ngx_string("off"), NGX_HTTP_GZIP_PROXIED_OFF },
  138.     { ngx_string("expired"), NGX_HTTP_GZIP_PROXIED_EXPIRED },
  139.     { ngx_string("no-cache"), NGX_HTTP_GZIP_PROXIED_NO_CACHE },
  140.     { ngx_string("no-store"), NGX_HTTP_GZIP_PROXIED_NO_STORE },
  141.     { ngx_string("private"), NGX_HTTP_GZIP_PROXIED_PRIVATE },
  142.     { ngx_string("no_last_modified"), NGX_HTTP_GZIP_PROXIED_NO_LM },
  143.     { ngx_string("no_etag"), NGX_HTTP_GZIP_PROXIED_NO_ETAG },
  144.     { ngx_string("auth"), NGX_HTTP_GZIP_PROXIED_AUTH },
  145.     { ngx_string("any"), NGX_HTTP_GZIP_PROXIED_ANY },
  146.     { ngx_null_string, 0 }
  147. };


  148. static ngx_str_t  ngx_http_gzip_no_cache = ngx_string("no-cache");
  149. static ngx_str_t  ngx_http_gzip_no_store = ngx_string("no-store");
  150. static ngx_str_t  ngx_http_gzip_private = ngx_string("private");

  151. #endif


  152. static ngx_command_t  ngx_http_core_commands[] = {

  153.     { ngx_string("variables_hash_max_size"),
  154.       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
  155.       ngx_conf_set_num_slot,
  156.       NGX_HTTP_MAIN_CONF_OFFSET,
  157.       offsetof(ngx_http_core_main_conf_t, variables_hash_max_size),
  158.       NULL },

  159.     { ngx_string("variables_hash_bucket_size"),
  160.       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
  161.       ngx_conf_set_num_slot,
  162.       NGX_HTTP_MAIN_CONF_OFFSET,
  163.       offsetof(ngx_http_core_main_conf_t, variables_hash_bucket_size),
  164.       NULL },

  165.     { ngx_string("server_names_hash_max_size"),
  166.       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
  167.       ngx_conf_set_num_slot,
  168.       NGX_HTTP_MAIN_CONF_OFFSET,
  169.       offsetof(ngx_http_core_main_conf_t, server_names_hash_max_size),
  170.       NULL },

  171.     { ngx_string("server_names_hash_bucket_size"),
  172.       NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
  173.       ngx_conf_set_num_slot,
  174.       NGX_HTTP_MAIN_CONF_OFFSET,
  175.       offsetof(ngx_http_core_main_conf_t, server_names_hash_bucket_size),
  176.       NULL },

  177.     { ngx_string("server"),
  178.       NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
  179.       ngx_http_core_server,
  180.       0,
  181.       0,
  182.       NULL },

  183.     { ngx_string("connection_pool_size"),
  184.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
  185.       ngx_conf_set_size_slot,
  186.       NGX_HTTP_SRV_CONF_OFFSET,
  187.       offsetof(ngx_http_core_srv_conf_t, connection_pool_size),
  188.       &ngx_http_core_pool_size_p },

  189.     { ngx_string("request_pool_size"),
  190.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
  191.       ngx_conf_set_size_slot,
  192.       NGX_HTTP_SRV_CONF_OFFSET,
  193.       offsetof(ngx_http_core_srv_conf_t, request_pool_size),
  194.       &ngx_http_core_pool_size_p },

  195.     { ngx_string("client_header_timeout"),
  196.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
  197.       ngx_conf_set_msec_slot,
  198.       NGX_HTTP_SRV_CONF_OFFSET,
  199.       offsetof(ngx_http_core_srv_conf_t, client_header_timeout),
  200.       NULL },

  201.     { ngx_string("client_header_buffer_size"),
  202.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
  203.       ngx_conf_set_size_slot,
  204.       NGX_HTTP_SRV_CONF_OFFSET,
  205.       offsetof(ngx_http_core_srv_conf_t, client_header_buffer_size),
  206.       NULL },

  207.     { ngx_string("large_client_header_buffers"),
  208.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE2,
  209.       ngx_conf_set_bufs_slot,
  210.       NGX_HTTP_SRV_CONF_OFFSET,
  211.       offsetof(ngx_http_core_srv_conf_t, large_client_header_buffers),
  212.       NULL },

  213.     { ngx_string("optimize_server_names"),
  214.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
  215.       ngx_conf_set_flag_slot,
  216.       NGX_HTTP_LOC_CONF_OFFSET,
  217.       offsetof(ngx_http_core_loc_conf_t, server_name_in_redirect),
  218.       &ngx_conf_deprecated_optimize_server_names },

  219.     { ngx_string("ignore_invalid_headers"),
  220.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
  221.       ngx_conf_set_flag_slot,
  222.       NGX_HTTP_SRV_CONF_OFFSET,
  223.       offsetof(ngx_http_core_srv_conf_t, ignore_invalid_headers),
  224.       NULL },

  225.     { ngx_string("merge_slashes"),
  226.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
  227.       ngx_conf_set_flag_slot,
  228.       NGX_HTTP_SRV_CONF_OFFSET,
  229.       offsetof(ngx_http_core_srv_conf_t, merge_slashes),
  230.       NULL },

  231.     { ngx_string("underscores_in_headers"),
  232.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
  233.       ngx_conf_set_flag_slot,
  234.       NGX_HTTP_SRV_CONF_OFFSET,
  235.       offsetof(ngx_http_core_srv_conf_t, underscores_in_headers),
  236.       NULL },

  237.     { ngx_string("location"),
  238.       NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12,
  239.       ngx_http_core_location,
  240.       NGX_HTTP_SRV_CONF_OFFSET,
  241.       0,
  242.       NULL },

  243.     { ngx_string("listen"),
  244.       NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
  245.       ngx_http_core_listen,
  246.       NGX_HTTP_SRV_CONF_OFFSET,
  247.       0,
  248.       NULL },

  249.     { ngx_string("server_name"),
  250.       NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
  251.       ngx_http_core_server_name,
  252.       NGX_HTTP_SRV_CONF_OFFSET,
  253.       0,
  254.       NULL },

  255.     { ngx_string("types_hash_max_size"),
  256.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  257.       ngx_conf_set_num_slot,
  258.       NGX_HTTP_LOC_CONF_OFFSET,
  259.       offsetof(ngx_http_core_loc_conf_t, types_hash_max_size),
  260.       NULL },

  261.     { ngx_string("types_hash_bucket_size"),
  262.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  263.       ngx_conf_set_num_slot,
  264.       NGX_HTTP_LOC_CONF_OFFSET,
  265.       offsetof(ngx_http_core_loc_conf_t, types_hash_bucket_size),
  266.       NULL },

  267.     { ngx_string("types"),
  268.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
  269.                                           |NGX_CONF_BLOCK|NGX_CONF_NOARGS,
  270.       ngx_http_core_types,
  271.       NGX_HTTP_LOC_CONF_OFFSET,
  272.       0,
  273.       NULL },

  274.     { ngx_string("default_type"),
  275.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  276.       ngx_conf_set_str_slot,
  277.       NGX_HTTP_LOC_CONF_OFFSET,
  278.       offsetof(ngx_http_core_loc_conf_t, default_type),
  279.       NULL },

  280.     { ngx_string("root"),
  281.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
  282.                         |NGX_CONF_TAKE1,
  283.       ngx_http_core_root,
  284.       NGX_HTTP_LOC_CONF_OFFSET,
  285.       0,
  286.       NULL },

  287.     { ngx_string("alias"),
  288.       NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  289.       ngx_http_core_root,
  290.       NGX_HTTP_LOC_CONF_OFFSET,
  291.       0,
  292.       NULL },

  293.     { ngx_string("limit_except"),
  294.       NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_1MORE,
  295.       ngx_http_core_limit_except,
  296.       NGX_HTTP_LOC_CONF_OFFSET,
  297.       0,
  298.       NULL },

  299.     { ngx_string("client_max_body_size"),
  300.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  301.       ngx_conf_set_off_slot,
  302.       NGX_HTTP_LOC_CONF_OFFSET,
  303.       offsetof(ngx_http_core_loc_conf_t, client_max_body_size),
  304.       NULL },

  305.     { ngx_string("client_body_buffer_size"),
  306.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  307.       ngx_conf_set_size_slot,
  308.       NGX_HTTP_LOC_CONF_OFFSET,
  309.       offsetof(ngx_http_core_loc_conf_t, client_body_buffer_size),
  310.       NULL },

  311.     { ngx_string("client_body_timeout"),
  312.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  313.       ngx_conf_set_msec_slot,
  314.       NGX_HTTP_LOC_CONF_OFFSET,
  315.       offsetof(ngx_http_core_loc_conf_t, client_body_timeout),
  316.       NULL },

  317.     { ngx_string("client_body_temp_path"),
  318.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
  319.       ngx_conf_set_path_slot,
  320.       NGX_HTTP_LOC_CONF_OFFSET,
  321.       offsetof(ngx_http_core_loc_conf_t, client_body_temp_path),
  322.       NULL },

  323.     { ngx_string("client_body_in_file_only"),
  324.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  325.       ngx_conf_set_enum_slot,
  326.       NGX_HTTP_LOC_CONF_OFFSET,
  327.       offsetof(ngx_http_core_loc_conf_t, client_body_in_file_only),
  328.       &ngx_http_core_request_body_in_file },

  329.     { ngx_string("client_body_in_single_buffer"),
  330.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  331.       ngx_conf_set_flag_slot,
  332.       NGX_HTTP_LOC_CONF_OFFSET,
  333.       offsetof(ngx_http_core_loc_conf_t, client_body_in_single_buffer),
  334.       NULL },

  335.     { ngx_string("sendfile"),
  336.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
  337.                         |NGX_CONF_FLAG,
  338.       ngx_conf_set_flag_slot,
  339.       NGX_HTTP_LOC_CONF_OFFSET,
  340.       offsetof(ngx_http_core_loc_conf_t, sendfile),
  341.       NULL },

  342.     { ngx_string("sendfile_max_chunk"),
  343.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  344.       ngx_conf_set_size_slot,
  345.       NGX_HTTP_LOC_CONF_OFFSET,
  346.       offsetof(ngx_http_core_loc_conf_t, sendfile_max_chunk),
  347.       NULL },

  348. #if (NGX_HAVE_FILE_AIO)

  349.     { ngx_string("aio"),
  350.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  351.       ngx_conf_set_enum_slot,
  352.       NGX_HTTP_LOC_CONF_OFFSET,
  353.       offsetof(ngx_http_core_loc_conf_t, aio),
  354.       &ngx_http_core_aio },

  355. #endif

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

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

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

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

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

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

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

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

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

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

  418.     { ngx_string("keepalive_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("satisfy_any"),
  443.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  444.       ngx_conf_set_flag_slot,
  445.       NGX_HTTP_LOC_CONF_OFFSET,
  446.       offsetof(ngx_http_core_loc_conf_t, satisfy),
  447.       &ngx_conf_deprecated_satisfy_any },

  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("server_name_in_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, server_name_in_redirect),
  483.       NULL },

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

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

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

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

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

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

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

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

  532.     { ngx_string("max_ranges"),
  533.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  534.       ngx_conf_set_num_slot,
  535.       NGX_HTTP_LOC_CONF_OFFSET,
  536.       offsetof(ngx_http_core_loc_conf_t, max_ranges),
  537.       NULL },

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

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

  550.     { ngx_string("error_page"),
  551.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
  552.                         |NGX_CONF_2MORE,
  553.       ngx_http_core_error_page,
  554.       NGX_HTTP_LOC_CONF_OFFSET,
  555.       0,
  556.       NULL },

  557.     { ngx_string("try_files"),
  558.       NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_2MORE,
  559.       ngx_http_core_try_files,
  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_retest"),
  589.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  590.       ngx_conf_set_sec_slot,
  591.       NGX_HTTP_LOC_CONF_OFFSET,
  592.       offsetof(ngx_http_core_loc_conf_t, open_file_cache_valid),
  593.       &ngx_conf_deprecated_open_file_cache_retest },

  594.     { ngx_string("open_file_cache_min_uses"),
  595.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  596.       ngx_conf_set_num_slot,
  597.       NGX_HTTP_LOC_CONF_OFFSET,
  598.       offsetof(ngx_http_core_loc_conf_t, open_file_cache_min_uses),
  599.       NULL },

  600.     { ngx_string("open_file_cache_errors"),
  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_errors),
  605.       NULL },

  606.     { ngx_string("open_file_cache_events"),
  607.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  608.       ngx_conf_set_flag_slot,
  609.       NGX_HTTP_LOC_CONF_OFFSET,
  610.       offsetof(ngx_http_core_loc_conf_t, open_file_cache_events),
  611.       NULL },

  612.     { ngx_string("resolver"),
  613.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  614.       ngx_http_core_resolver,
  615.       NGX_HTTP_LOC_CONF_OFFSET,
  616.       0,
  617.       NULL },

  618.     { ngx_string("resolver_timeout"),
  619.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  620.       ngx_conf_set_msec_slot,
  621.       NGX_HTTP_LOC_CONF_OFFSET,
  622.       offsetof(ngx_http_core_loc_conf_t, resolver_timeout),
  623.       NULL },

  624. #if (NGX_HTTP_GZIP)

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

  631.     { ngx_string("gzip_http_version"),
  632.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  633.       ngx_conf_set_enum_slot,
  634.       NGX_HTTP_LOC_CONF_OFFSET,
  635.       offsetof(ngx_http_core_loc_conf_t, gzip_http_version),
  636.       &ngx_http_gzip_http_version },

  637.     { ngx_string("gzip_proxied"),
  638.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  639.       ngx_conf_set_bitmask_slot,
  640.       NGX_HTTP_LOC_CONF_OFFSET,
  641.       offsetof(ngx_http_core_loc_conf_t, gzip_proxied),
  642.       &ngx_http_gzip_proxied_mask },

  643.     { ngx_string("gzip_disable"),
  644.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  645.       ngx_http_gzip_disable,
  646.       NGX_HTTP_LOC_CONF_OFFSET,
  647.       0,
  648.       NULL },

  649. #endif

  650. #if (NGX_HAVE_OPENAT)

  651.     { ngx_string("disable_symlinks"),
  652.       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
  653.       ngx_http_disable_symlinks,
  654.       NGX_HTTP_LOC_CONF_OFFSET,
  655.       0,
  656.       NULL },

  657. #endif

  658.       ngx_null_command
  659. };


  660. static ngx_http_module_t  ngx_http_core_module_ctx = {
  661.     ngx_http_core_preconfiguration,        /* preconfiguration */
  662.     NULL,                                  /* postconfiguration */

  663.     ngx_http_core_create_main_conf,        /* create main configuration */
  664.     ngx_http_core_init_main_conf,          /* init main configuration */

  665.     ngx_http_core_create_srv_conf,         /* create server configuration */
  666.     ngx_http_core_merge_srv_conf,          /* merge server configuration */

  667.     ngx_http_core_create_loc_conf,         /* create location configuration */
  668.     ngx_http_core_merge_loc_conf           /* merge location configuration */
  669. };


  670. ngx_module_t  ngx_http_core_module = {
  671.     NGX_MODULE_V1,
  672.     &ngx_http_core_module_ctx,             /* module context */
  673.     ngx_http_core_commands,                /* module directives */
  674.     NGX_HTTP_MODULE,                       /* module type */
  675.     NULL,                                  /* init master */
  676.     NULL,                                  /* init module */
  677.     NULL,                                  /* init process */
  678.     NULL,                                  /* init thread */
  679.     NULL,                                  /* exit thread */
  680.     NULL,                                  /* exit process */
  681.     NULL,                                  /* exit master */
  682.     NGX_MODULE_V1_PADDING
  683. };


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


  685. void
  686. ngx_http_handler(ngx_http_request_t *r)
  687. {
  688.     ngx_http_core_main_conf_t  *cmcf;

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

  690.     r->connection->unexpected_eof = 0;

  691.     if (!r->internal) {
  692.         switch (r->headers_in.connection_type) {
  693.         case 0:
  694.             r->keepalive = (r->http_version > NGX_HTTP_VERSION_10);
  695.             break;

  696.         case NGX_HTTP_CONNECTION_CLOSE:
  697.             r->keepalive = 0;
  698.             break;

  699.         case NGX_HTTP_CONNECTION_KEEP_ALIVE:
  700.             r->keepalive = 1;
  701.             break;
  702.         }

  703.         r->lingering_close = (r->headers_in.content_length_n > 0
  704.                               || r->headers_in.chunked);
  705.         r->phase_handler = 0;

  706.     } else {
  707.         cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
  708.         r->phase_handler = cmcf->phase_engine.server_rewrite_index;
  709.     }

  710.     r->valid_location = 1;
  711. #if (NGX_HTTP_GZIP)
  712.     r->gzip_tested = 0;
  713.     r->gzip_ok = 0;
  714.     r->gzip_vary = 0;
  715. #endif

  716.     r->write_event_handler = ngx_http_core_run_phases;
  717.     ngx_http_core_run_phases(r);
  718. }


  719. void
  720. ngx_http_core_run_phases(ngx_http_request_t *r)
  721. {
  722.     ngx_int_t                   rc;
  723.     ngx_http_phase_handler_t   *ph;
  724.     ngx_http_core_main_conf_t  *cmcf;

  725.     cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

  726.     ph = cmcf->phase_engine.handlers;

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

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

  729.         if (rc == NGX_OK) {
  730.             return;
  731.         }
  732.     }
  733. }


  734. ngx_int_t
  735. ngx_http_core_generic_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
  736. {
  737.     ngx_int_t  rc;

  738.     /*
  739.      * generic phase checker,
  740.      * used by the post read and pre-access phases
  741.      */

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

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

  745.     if (rc == NGX_OK) {
  746.         r->phase_handler = ph->next;
  747.         return NGX_AGAIN;
  748.     }

  749.     if (rc == NGX_DECLINED) {
  750.         r->phase_handler++;
  751.         return NGX_AGAIN;
  752.     }

  753.     if (rc == NGX_AGAIN || rc == NGX_DONE) {
  754.         return NGX_OK;
  755.     }

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

  757.     ngx_http_finalize_request(r, rc);

  758.     return NGX_OK;
  759. }


  760. ngx_int_t
  761. ngx_http_core_rewrite_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
  762. {
  763.     ngx_int_t  rc;

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

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

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

  771.     if (rc == NGX_DONE) {
  772.         return NGX_OK;
  773.     }

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

  775.     ngx_http_finalize_request(r, rc);

  776.     return NGX_OK;
  777. }


  778. ngx_int_t
  779. ngx_http_core_find_config_phase(ngx_http_request_t *r,
  780.     ngx_http_phase_handler_t *ph)
  781. {
  782.     u_char                    *p;
  783.     size_t                     len;
  784.     ngx_int_t                  rc;
  785.     ngx_http_core_loc_conf_t  *clcf;

  786.     r->content_handler = NULL;
  787.     r->uri_changed = 0;

  788.     rc = ngx_http_core_find_location(r);

  789.     if (rc == NGX_ERROR) {
  790.         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  791.         return NGX_OK;
  792.     }

  793.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  794.     if (!r->internal && clcf->internal) {
  795.         ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
  796.         return NGX_OK;
  797.     }

  798.     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  799.                    "using configuration \"%s%V\"",
  800.                    (clcf->noname ? "*" : (clcf->exact_match ? "=" : "")),
  801.                    &clcf->name);

  802.     ngx_http_update_location_config(r);

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

  806.     if (r->headers_in.content_length_n != -1
  807.         && !r->discard_body
  808.         && clcf->client_max_body_size
  809.         && clcf->client_max_body_size < r->headers_in.content_length_n)
  810.     {
  811.         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  812.                       "client intended to send too large body: %O bytes",
  813.                       r->headers_in.content_length_n);

  814.         r->expect_tested = 1;
  815.         (void) ngx_http_discard_request_body(r);
  816.         ngx_http_finalize_request(r, NGX_HTTP_REQUEST_ENTITY_TOO_LARGE);
  817.         return NGX_OK;
  818.     }

  819.     if (rc == NGX_DONE) {
  820.         ngx_http_clear_location(r);

  821.         r->headers_out.location = ngx_list_push(&r->headers_out.headers);
  822.         if (r->headers_out.location == NULL) {
  823.             ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  824.             return NGX_OK;
  825.         }

  826.         /*
  827.          * we do not need to set the r->headers_out.location->hash and
  828.          * r->headers_out.location->key fields
  829.          */

  830.         if (r->args.len == 0) {
  831.             r->headers_out.location->value = clcf->name;

  832.         } else {
  833.             len = clcf->name.len + 1 + r->args.len;
  834.             p = ngx_pnalloc(r->pool, len);

  835.             if (p == NULL) {
  836.                 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  837.                 return NGX_OK;
  838.             }

  839.             r->headers_out.location->value.len = len;
  840.             r->headers_out.location->value.data = p;

  841.             p = ngx_cpymem(p, clcf->name.data, clcf->name.len);
  842.             *p++ = '?';
  843.             ngx_memcpy(p, r->args.data, r->args.len);
  844.         }

  845.         ngx_http_finalize_request(r, NGX_HTTP_MOVED_PERMANENTLY);
  846.         return NGX_OK;
  847.     }

  848.     r->phase_handler++;
  849.     return NGX_AGAIN;
  850. }


  851. ngx_int_t
  852. ngx_http_core_post_rewrite_phase(ngx_http_request_t *r,
  853.     ngx_http_phase_handler_t *ph)
  854. {
  855.     ngx_http_core_srv_conf_t  *cscf;

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

  858.     if (!r->uri_changed) {
  859.         r->phase_handler++;
  860.         return NGX_AGAIN;
  861.     }

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

  864.     /*
  865.      * gcc before 3.3 compiles the broken code for
  866.      *     if (r->uri_changes-- == 0)
  867.      * if the r->uri_changes is defined as
  868.      *     unsigned  uri_changes:4
  869.      */

  870.     r->uri_changes--;

  871.     if (r->uri_changes == 0) {
  872.         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  873.                       "rewrite or internal redirection cycle "
  874.                       "while processing \"%V\"", &r->uri);

  875.         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  876.         return NGX_OK;
  877.     }

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

  879.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
  880.     r->loc_conf = cscf->ctx->loc_conf;

  881.     return NGX_AGAIN;
  882. }


  883. ngx_int_t
  884. ngx_http_core_access_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
  885. {
  886.     ngx_int_t                  rc;
  887.     ngx_http_core_loc_conf_t  *clcf;

  888.     if (r != r->main) {
  889.         r->phase_handler = ph->next;
  890.         return NGX_AGAIN;
  891.     }

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

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

  895.     if (rc == NGX_DECLINED) {
  896.         r->phase_handler++;
  897.         return NGX_AGAIN;
  898.     }

  899.     if (rc == NGX_AGAIN || rc == NGX_DONE) {
  900.         return NGX_OK;
  901.     }

  902.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

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

  904.         if (rc == NGX_OK) {
  905.             r->phase_handler++;
  906.             return NGX_AGAIN;
  907.         }

  908.     } else {
  909.         if (rc == NGX_OK) {
  910.             r->access_code = 0;

  911.             if (r->headers_out.www_authenticate) {
  912.                 r->headers_out.www_authenticate->hash = 0;
  913.             }

  914.             r->phase_handler = ph->next;
  915.             return NGX_AGAIN;
  916.         }

  917.         if (rc == NGX_HTTP_FORBIDDEN || rc == NGX_HTTP_UNAUTHORIZED) {
  918.             if (r->access_code != NGX_HTTP_UNAUTHORIZED) {
  919.                 r->access_code = rc;
  920.             }

  921.             r->phase_handler++;
  922.             return NGX_AGAIN;
  923.         }
  924.     }

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

  926.     ngx_http_finalize_request(r, rc);
  927.     return NGX_OK;
  928. }


  929. ngx_int_t
  930. ngx_http_core_post_access_phase(ngx_http_request_t *r,
  931.     ngx_http_phase_handler_t *ph)
  932. {
  933.     ngx_int_t  access_code;

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

  936.     access_code = r->access_code;

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

  942.         r->access_code = 0;
  943.         ngx_http_finalize_request(r, access_code);
  944.         return NGX_OK;
  945.     }

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


  949. ngx_int_t
  950. ngx_http_core_try_files_phase(ngx_http_request_t *r,
  951.     ngx_http_phase_handler_t *ph)
  952. {
  953.     size_t                        len, root, alias, reserve, allocated;
  954.     u_char                       *p, *name;
  955.     ngx_str_t                     path, args;
  956.     ngx_uint_t                    test_dir;
  957.     ngx_http_try_file_t          *tf;
  958.     ngx_open_file_info_t          of;
  959.     ngx_http_script_code_pt       code;
  960.     ngx_http_script_engine_t      e;
  961.     ngx_http_core_loc_conf_t     *clcf;
  962.     ngx_http_script_len_code_pt   lcode;

  963.     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  964.                    "try files phase: %ui", r->phase_handler);

  965.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  966.     if (clcf->try_files == NULL) {
  967.         r->phase_handler++;
  968.         return NGX_AGAIN;
  969.     }

  970.     allocated = 0;
  971.     root = 0;
  972.     name = NULL;
  973.     /* suppress MSVC warning */
  974.     path.data = NULL;

  975.     tf = clcf->try_files;

  976.     alias = clcf->alias;

  977.     for ( ;; ) {

  978.         if (tf->lengths) {
  979.             ngx_memzero(&e, sizeof(ngx_http_script_engine_t));

  980.             e.ip = tf->lengths->elts;
  981.             e.request = r;

  982.             /* 1 is for terminating '\0' as in static names */
  983.             len = 1;

  984.             while (*(uintptr_t *) e.ip) {
  985.                 lcode = *(ngx_http_script_len_code_pt *) e.ip;
  986.                 len += lcode(&e);
  987.             }

  988.         } else {
  989.             len = tf->name.len;
  990.         }

  991.         if (!alias) {
  992.             reserve = len > r->uri.len ? len - r->uri.len : 0;

  993.         } else if (alias == NGX_MAX_SIZE_T_VALUE) {
  994.             reserve = len;

  995.         } else {
  996.             reserve = len > r->uri.len - alias ? len - (r->uri.len - alias) : 0;
  997.         }

  998.         if (reserve > allocated || !allocated) {

  999.             /* 16 bytes are preallocation */
  1000.             allocated = reserve + 16;

  1001.             if (ngx_http_map_uri_to_path(r, &path, &root, allocated) == NULL) {
  1002.                 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1003.                 return NGX_OK;
  1004.             }

  1005.             name = path.data + root;
  1006.          }

  1007.         if (tf->values == NULL) {

  1008.             /* tf->name.len includes the terminating '\0' */

  1009.             ngx_memcpy(name, tf->name.data, tf->name.len);

  1010.             path.len = (name + tf->name.len - 1) - path.data;

  1011.         } else {
  1012.             e.ip = tf->values->elts;
  1013.             e.pos = name;
  1014.             e.flushed = 1;

  1015.             while (*(uintptr_t *) e.ip) {
  1016.                 code = *(ngx_http_script_code_pt *) e.ip;
  1017.                 code((ngx_http_script_engine_t *) &e);
  1018.             }

  1019.             path.len = e.pos - path.data;

  1020.             *e.pos = '\0';

  1021.             if (alias && ngx_strncmp(name, clcf->name.data, alias) == 0) {
  1022.                 ngx_memmove(name, name + alias, len - alias);
  1023.                 path.len -= alias;
  1024.             }
  1025.         }

  1026.         test_dir = tf->test_dir;

  1027.         tf++;

  1028.         ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  1029.                        "trying to use %s: \"%s\" \"%s\"",
  1030.                        test_dir ? "dir" : "file", name, path.data);

  1031.         if (tf->lengths == NULL && tf->name.len == 0) {

  1032.             if (tf->code) {
  1033.                 ngx_http_finalize_request(r, tf->code);
  1034.                 return NGX_OK;
  1035.             }

  1036.             path.len -= root;
  1037.             path.data += root;

  1038.             if (path.data[0] == '@') {
  1039.                 (void) ngx_http_named_location(r, &path);

  1040.             } else {
  1041.                 ngx_http_split_args(r, &path, &args);

  1042.                 (void) ngx_http_internal_redirect(r, &path, &args);
  1043.             }

  1044.             ngx_http_finalize_request(r, NGX_DONE);
  1045.             return NGX_OK;
  1046.         }

  1047.         ngx_memzero(&of, sizeof(ngx_open_file_info_t));

  1048.         of.read_ahead = clcf->read_ahead;
  1049.         of.directio = clcf->directio;
  1050.         of.valid = clcf->open_file_cache_valid;
  1051.         of.min_uses = clcf->open_file_cache_min_uses;
  1052.         of.test_only = 1;
  1053.         of.errors = clcf->open_file_cache_errors;
  1054.         of.events = clcf->open_file_cache_events;

  1055.         if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) {
  1056.             ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1057.             return NGX_OK;
  1058.         }

  1059.         if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
  1060.             != NGX_OK)
  1061.         {
  1062.             if (of.err != NGX_ENOENT
  1063.                 && of.err != NGX_ENOTDIR
  1064.                 && of.err != NGX_ENAMETOOLONG)
  1065.             {
  1066.                 ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err,
  1067.                               "%s \"%s\" failed", of.failed, path.data);
  1068.             }

  1069.             continue;
  1070.         }

  1071.         if (of.is_dir != test_dir) {
  1072.             continue;
  1073.         }

  1074.         path.len -= root;
  1075.         path.data += root;

  1076.         if (!alias) {
  1077.             r->uri = path;

  1078.         } else if (alias == NGX_MAX_SIZE_T_VALUE) {
  1079.             if (!test_dir) {
  1080.                 r->uri = path;
  1081.                 r->add_uri_to_alias = 1;
  1082.             }

  1083.         } else {
  1084.             r->uri.len = alias + path.len;
  1085.             r->uri.data = ngx_pnalloc(r->pool, r->uri.len);
  1086.             if (r->uri.data == NULL) {
  1087.                 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
  1088.                 return NGX_OK;
  1089.             }

  1090.             p = ngx_copy(r->uri.data, clcf->name.data, alias);
  1091.             ngx_memcpy(p, name, path.len);
  1092.         }

  1093.         ngx_http_set_exten(r);

  1094.         ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
  1095.                        "try file uri: \"%V\"", &r->uri);

  1096.         r->phase_handler++;
  1097.         return NGX_AGAIN;
  1098.     }

  1099.     /* not reached */
  1100. }


  1101. ngx_int_t
  1102. ngx_http_core_content_phase(ngx_http_request_t *r,
  1103.     ngx_http_phase_handler_t *ph)
  1104. {
  1105.     size_t     root;
  1106.     ngx_int_t  rc;
  1107.     ngx_str_t  path;

  1108.     if (r->content_handler) {
  1109.         r->write_event_handler = ngx_http_request_empty_handler;
  1110.         ngx_http_finalize_request(r, r->content_handler(r));
  1111.         return NGX_OK;
  1112.     }

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

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

  1116.     if (rc != NGX_DECLINED) {
  1117.         ngx_http_finalize_request(r, rc);
  1118.         return NGX_OK;
  1119.     }

  1120.     /* rc == NGX_DECLINED */

  1121.     ph++;

  1122.     if (ph->checker) {
  1123.         r->phase_handler++;
  1124.         return NGX_AGAIN;
  1125.     }

  1126.     /* no content handler was found */

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

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

  1132.         ngx_http_finalize_request(r, NGX_HTTP_FORBIDDEN);
  1133.         return NGX_OK;
  1134.     }

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

  1136.     ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
  1137.     return NGX_OK;
  1138. }


  1139. void
  1140. ngx_http_update_location_config(ngx_http_request_t *r)
  1141. {
  1142.     ngx_http_core_loc_conf_t  *clcf;

  1143.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1144.     if (r->method & clcf->limit_except) {
  1145.         r->loc_conf = clcf->limit_except_loc_conf;
  1146.         clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
  1147.     }

  1148.     if (r == r->main) {
  1149.         ngx_http_set_connection_log(r->connection, clcf->error_log);
  1150.     }

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

  1153.     } else {
  1154.         r->connection->sendfile = 0;
  1155.     }

  1156.     if (clcf->client_body_in_file_only) {
  1157.         r->request_body_in_file_only = 1;
  1158.         r->request_body_in_persistent_file = 1;
  1159.         r->request_body_in_clean_file =
  1160.             clcf->client_body_in_file_only == NGX_HTTP_REQUEST_BODY_FILE_CLEAN;
  1161.         r->request_body_file_log_level = NGX_LOG_NOTICE;

  1162.     } else {
  1163.         r->request_body_file_log_level = NGX_LOG_WARN;
  1164.     }

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

  1166.     if (r->keepalive) {
  1167.         if (clcf->keepalive_timeout == 0) {
  1168.             r->keepalive = 0;

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

  1171.         } else if (r->headers_in.msie6
  1172.                    && r->method == NGX_HTTP_POST
  1173.                    && (clcf->keepalive_disable
  1174.                        & NGX_HTTP_KEEPALIVE_DISABLE_MSIE6))
  1175.         {
  1176.             /*
  1177.              * MSIE may wait for some time if an response for
  1178.              * a POST request was sent over a keepalive connection
  1179.              */
  1180.             r->keepalive = 0;

  1181.         } else if (r->headers_in.safari
  1182.                    && (clcf->keepalive_disable
  1183.                        & NGX_HTTP_KEEPALIVE_DISABLE_SAFARI))
  1184.         {
  1185.             /*
  1186.              * Safari may send a POST request to a closed keepalive
  1187.              * connection and may stall for some time, see
  1188.              *     https://bugs.webkit.org/show_bug.cgi?id=5760
  1189.              */
  1190.             r->keepalive = 0;
  1191.         }
  1192.     }

  1193.     if (!clcf->tcp_nopush) {
  1194.         /* disable TCP_NOPUSH/TCP_CORK use */
  1195.         r->connection->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
  1196.     }

  1197.     if (r->limit_rate == 0) {
  1198.         r->limit_rate = clcf->limit_rate;
  1199.     }

  1200.     if (clcf->handler) {
  1201.         r->content_handler = clcf->handler;
  1202.     }
  1203. }


  1204. /*
  1205. * NGX_OK       - exact or regex match
  1206. * NGX_DONE     - auto redirect
  1207. * NGX_AGAIN    - inclusive match
  1208. * NGX_ERROR    - regex error
  1209. * NGX_DECLINED - no match
  1210. */

  1211. static ngx_int_t
  1212. ngx_http_core_find_location(ngx_http_request_t *r)
  1213. {
  1214.     ngx_int_t                  rc;
  1215.     ngx_http_core_loc_conf_t  *pclcf;
  1216. #if (NGX_PCRE)
  1217.     ngx_int_t                  n;
  1218.     ngx_uint_t                 noregex;
  1219.     ngx_http_core_loc_conf_t  *clcf, **clcfp;

  1220.     noregex = 0;
  1221. #endif

  1222.     pclcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

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

  1224.     if (rc == NGX_AGAIN) {

  1225. #if (NGX_PCRE)
  1226.         clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1227.         noregex = clcf->noregex;
  1228. #endif

  1229.         /* look up nested locations */

  1230.         rc = ngx_http_core_find_location(r);
  1231.     }

  1232.     if (rc == NGX_OK || rc == NGX_DONE) {
  1233.         return rc;
  1234.     }

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

  1236. #if (NGX_PCRE)

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

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

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

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

  1242.             if (n == NGX_OK) {
  1243.                 r->loc_conf = (*clcfp)->loc_conf;

  1244.                 /* look up nested locations */

  1245.                 rc = ngx_http_core_find_location(r);

  1246.                 return (rc == NGX_ERROR) ? rc : NGX_OK;
  1247.             }

  1248.             if (n == NGX_DECLINED) {
  1249.                 continue;
  1250.             }

  1251.             return NGX_ERROR;
  1252.         }
  1253.     }
  1254. #endif

  1255.     return rc;
  1256. }


  1257. /*
  1258. * NGX_OK       - exact match
  1259. * NGX_DONE     - auto redirect
  1260. * NGX_AGAIN    - inclusive match
  1261. * NGX_DECLINED - no match
  1262. */

  1263. static ngx_int_t
  1264. ngx_http_core_find_static_location(ngx_http_request_t *r,
  1265.     ngx_http_location_tree_node_t *node)
  1266. {
  1267.     u_char     *uri;
  1268.     size_t      len, n;
  1269.     ngx_int_t   rc, rv;

  1270.     len = r->uri.len;
  1271.     uri = r->uri.data;

  1272.     rv = NGX_DECLINED;

  1273.     for ( ;; ) {

  1274.         if (node == NULL) {
  1275.             return rv;
  1276.         }

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

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

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

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

  1283.             continue;
  1284.         }

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

  1286.             if (node->inclusive) {

  1287.                 r->loc_conf = node->inclusive->loc_conf;
  1288.                 rv = NGX_AGAIN;

  1289.                 node = node->tree;
  1290.                 uri += n;
  1291.                 len -= n;

  1292.                 continue;
  1293.             }

  1294.             /* exact only */

  1295.             node = node->right;

  1296.             continue;
  1297.         }

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

  1299.             if (node->exact) {
  1300.                 r->loc_conf = node->exact->loc_conf;
  1301.                 return NGX_OK;

  1302.             } else {
  1303.                 r->loc_conf = node->inclusive->loc_conf;
  1304.                 return NGX_AGAIN;
  1305.             }
  1306.         }

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

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

  1309.             r->loc_conf = (node->exact) ? node->exact->loc_conf:
  1310.                                           node->inclusive->loc_conf;
  1311.             rv = NGX_DONE;
  1312.         }

  1313.         node = node->left;
  1314.     }
  1315. }


  1316. void *
  1317. ngx_http_test_content_type(ngx_http_request_t *r, ngx_hash_t *types_hash)
  1318. {
  1319.     u_char      c, *lowcase;
  1320.     size_t      len;
  1321.     ngx_uint_t  i, hash;

  1322.     if (types_hash->size == 0) {
  1323.         return (void *) 4;
  1324.     }

  1325.     if (r->headers_out.content_type.len == 0) {
  1326.         return NULL;
  1327.     }

  1328.     len = r->headers_out.content_type_len;

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

  1330.         lowcase = ngx_pnalloc(r->pool, len);
  1331.         if (lowcase == NULL) {
  1332.             return NULL;
  1333.         }

  1334.         r->headers_out.content_type_lowcase = lowcase;

  1335.         hash = 0;

  1336.         for (i = 0; i < len; i++) {
  1337.             c = ngx_tolower(r->headers_out.content_type.data[i]);
  1338.             hash = ngx_hash(hash, c);
  1339.             lowcase[i] = c;
  1340.         }

  1341.         r->headers_out.content_type_hash = hash;
  1342.     }

  1343.     return ngx_hash_find(types_hash, r->headers_out.content_type_hash,
  1344.                          r->headers_out.content_type_lowcase, len);
  1345. }


  1346. ngx_int_t
  1347. ngx_http_set_content_type(ngx_http_request_t *r)
  1348. {
  1349.     u_char                     c, *exten;
  1350.     ngx_str_t                 *type;
  1351.     ngx_uint_t                 i, hash;
  1352.     ngx_http_core_loc_conf_t  *clcf;

  1353.     if (r->headers_out.content_type.len) {
  1354.         return NGX_OK;
  1355.     }

  1356.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

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

  1358.         hash = 0;

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

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

  1362.                 exten = ngx_pnalloc(r->pool, r->exten.len);
  1363.                 if (exten == NULL) {
  1364.                     return NGX_ERROR;
  1365.                 }

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

  1367.                 r->exten.data = exten;

  1368.                 break;
  1369.             }

  1370.             hash = ngx_hash(hash, c);
  1371.         }

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

  1374.         if (type) {
  1375.             r->headers_out.content_type_len = type->len;
  1376.             r->headers_out.content_type = *type;

  1377.             return NGX_OK;
  1378.         }
  1379.     }

  1380.     r->headers_out.content_type_len = clcf->default_type.len;
  1381.     r->headers_out.content_type = clcf->default_type;

  1382.     return NGX_OK;
  1383. }


  1384. void
  1385. ngx_http_set_exten(ngx_http_request_t *r)
  1386. {
  1387.     ngx_int_t  i;

  1388.     ngx_str_null(&r->exten);

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

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

  1393.             return;

  1394.         } else if (r->uri.data[i] == '/') {
  1395.             return;
  1396.         }
  1397.     }

  1398.     return;
  1399. }


  1400. ngx_int_t
  1401. ngx_http_set_etag(ngx_http_request_t *r)
  1402. {
  1403.     ngx_table_elt_t           *etag;
  1404.     ngx_http_core_loc_conf_t  *clcf;

  1405.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1406.     if (!clcf->etag) {
  1407.         return NGX_OK;
  1408.     }

  1409.     etag = ngx_list_push(&r->headers_out.headers);
  1410.     if (etag == NULL) {
  1411.         return NGX_ERROR;
  1412.     }

  1413.     etag->hash = 1;
  1414.     ngx_str_set(&etag->key, "ETag");

  1415.     etag->value.data = ngx_pnalloc(r->pool, NGX_OFF_T_LEN + NGX_TIME_T_LEN + 3);
  1416.     if (etag->value.data == NULL) {
  1417.         etag->hash = 0;
  1418.         return NGX_ERROR;
  1419.     }

  1420.     etag->value.len = ngx_sprintf(etag->value.data, "\"%xT-%xO\"",
  1421.                                   r->headers_out.last_modified_time,
  1422.                                   r->headers_out.content_length_n)
  1423.                       - etag->value.data;

  1424.     r->headers_out.etag = etag;

  1425.     return NGX_OK;
  1426. }


  1427. void
  1428. ngx_http_weak_etag(ngx_http_request_t *r)
  1429. {
  1430.     size_t            len;
  1431.     u_char           *p;
  1432.     ngx_table_elt_t  *etag;

  1433.     etag = r->headers_out.etag;

  1434.     if (etag == NULL) {
  1435.         return;
  1436.     }

  1437.     if (etag->value.len > 2
  1438.         && etag->value.data[0] == 'W'
  1439.         && etag->value.data[1] == '/')
  1440.     {
  1441.         return;
  1442.     }

  1443.     if (etag->value.len < 1 || etag->value.data[0] != '"') {
  1444.         r->headers_out.etag->hash = 0;
  1445.         r->headers_out.etag = NULL;
  1446.         return;
  1447.     }

  1448.     p = ngx_pnalloc(r->pool, etag->value.len + 2);
  1449.     if (p == NULL) {
  1450.         r->headers_out.etag->hash = 0;
  1451.         r->headers_out.etag = NULL;
  1452.         return;
  1453.     }

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

  1455.     etag->value.data = p;
  1456.     etag->value.len = len;
  1457. }


  1458. ngx_int_t
  1459. ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
  1460.     ngx_str_t *ct, ngx_http_complex_value_t *cv)
  1461. {
  1462.     ngx_int_t     rc;
  1463.     ngx_str_t     val;
  1464.     ngx_buf_t    *b;
  1465.     ngx_chain_t   out;

  1466.     if (ngx_http_discard_request_body(r) != NGX_OK) {
  1467.         return NGX_HTTP_INTERNAL_SERVER_ERROR;
  1468.     }

  1469.     r->headers_out.status = status;

  1470.     if (ngx_http_complex_value(r, cv, &val) != NGX_OK) {
  1471.         return NGX_HTTP_INTERNAL_SERVER_ERROR;
  1472.     }

  1473.     if (status == NGX_HTTP_MOVED_PERMANENTLY
  1474.         || status == NGX_HTTP_MOVED_TEMPORARILY
  1475.         || status == NGX_HTTP_SEE_OTHER
  1476.         || status == NGX_HTTP_TEMPORARY_REDIRECT)
  1477.     {
  1478.         ngx_http_clear_location(r);

  1479.         r->headers_out.location = ngx_list_push(&r->headers_out.headers);
  1480.         if (r->headers_out.location == NULL) {
  1481.             return NGX_HTTP_INTERNAL_SERVER_ERROR;
  1482.         }

  1483.         r->headers_out.location->hash = 1;
  1484.         ngx_str_set(&r->headers_out.location->key, "Location");
  1485.         r->headers_out.location->value = val;

  1486.         return status;
  1487.     }

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

  1489.     if (ct) {
  1490.         r->headers_out.content_type_len = ct->len;
  1491.         r->headers_out.content_type = *ct;

  1492.     } else {
  1493.         if (ngx_http_set_content_type(r) != NGX_OK) {
  1494.             return NGX_HTTP_INTERNAL_SERVER_ERROR;
  1495.         }
  1496.     }

  1497.     if (r->method == NGX_HTTP_HEAD || (r != r->main && val.len == 0)) {
  1498.         return ngx_http_send_header(r);
  1499.     }

  1500.     b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
  1501.     if (b == NULL) {
  1502.         return NGX_HTTP_INTERNAL_SERVER_ERROR;
  1503.     }

  1504.     b->pos = val.data;
  1505.     b->last = val.data + val.len;
  1506.     b->memory = val.len ? 1 : 0;
  1507.     b->last_buf = (r == r->main) ? 1 : 0;
  1508.     b->last_in_chain = 1;

  1509.     out.buf = b;
  1510.     out.next = NULL;

  1511.     rc = ngx_http_send_header(r);

  1512.     if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
  1513.         return rc;
  1514.     }

  1515.     return ngx_http_output_filter(r, &out);
  1516. }


  1517. ngx_int_t
  1518. ngx_http_send_header(ngx_http_request_t *r)
  1519. {
  1520.     if (r->post_action) {
  1521.         return NGX_OK;
  1522.     }

  1523.     if (r->header_sent) {
  1524.         ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
  1525.                       "header already sent");
  1526.         return NGX_ERROR;
  1527.     }

  1528.     if (r->err_status) {
  1529.         r->headers_out.status = r->err_status;
  1530.         r->headers_out.status_line.len = 0;
  1531.     }

  1532.     return ngx_http_top_header_filter(r);
  1533. }


  1534. ngx_int_t
  1535. ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in)
  1536. {
  1537.     ngx_int_t          rc;
  1538.     ngx_connection_t  *c;

  1539.     c = r->connection;

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

  1542.     rc = ngx_http_top_body_filter(r, in);

  1543.     if (rc == NGX_ERROR) {
  1544.         /* NGX_ERROR may be returned by any filter */
  1545.         c->error = 1;
  1546.     }

  1547.     return rc;
  1548. }


  1549. u_char *
  1550. ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *path,
  1551.     size_t *root_length, size_t reserved)
  1552. {
  1553.     u_char                    *last;
  1554.     size_t                     alias;
  1555.     ngx_http_core_loc_conf_t  *clcf;

  1556.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1557.     alias = clcf->alias;

  1558.     if (alias && !r->valid_location) {
  1559.         ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
  1560.                       "\"alias\" cannot be used in location \"%V\" "
  1561.                       "where URI was rewritten", &clcf->name);
  1562.         return NULL;
  1563.     }

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

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

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

  1567.         path->data = ngx_pnalloc(r->pool, path->len);
  1568.         if (path->data == NULL) {
  1569.             return NULL;
  1570.         }

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

  1572.     } else {

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

  1575.         } else {
  1576.             reserved += r->uri.len - alias + 1;
  1577.         }

  1578.         if (ngx_http_script_run(r, path, clcf->root_lengths->elts, reserved,
  1579.                                 clcf->root_values->elts)
  1580.             == NULL)
  1581.         {
  1582.             return NULL;
  1583.         }

  1584.         if (ngx_get_full_name(r->pool, (ngx_str_t *) &ngx_cycle->prefix, path)
  1585.             != NGX_OK)
  1586.         {
  1587.             return NULL;
  1588.         }

  1589.         *root_length = path->len - reserved;
  1590.         last = path->data + *root_length;

  1591.         if (alias == NGX_MAX_SIZE_T_VALUE) {
  1592.             if (!r->add_uri_to_alias) {
  1593.                 *last = '\0';
  1594.                 return last;
  1595.             }

  1596.             alias = 0;
  1597.         }
  1598.     }

  1599.     last = ngx_cpystrn(last, r->uri.data + alias, r->uri.len - alias + 1);

  1600.     return last;
  1601. }


  1602. ngx_int_t
  1603. ngx_http_auth_basic_user(ngx_http_request_t *r)
  1604. {
  1605.     ngx_str_t   auth, encoded;
  1606.     ngx_uint_t  len;

  1607.     if (r->headers_in.user.len == 0 && r->headers_in.user.data != NULL) {
  1608.         return NGX_DECLINED;
  1609.     }

  1610.     if (r->headers_in.authorization == NULL) {
  1611.         r->headers_in.user.data = (u_char *) "";
  1612.         return NGX_DECLINED;
  1613.     }

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

  1615.     if (encoded.len < sizeof("Basic ") - 1
  1616.         || ngx_strncasecmp(encoded.data, (u_char *) "Basic ",
  1617.                            sizeof("Basic ") - 1)
  1618.            != 0)
  1619.     {
  1620.         r->headers_in.user.data = (u_char *) "";
  1621.         return NGX_DECLINED;
  1622.     }

  1623.     encoded.len -= sizeof("Basic ") - 1;
  1624.     encoded.data += sizeof("Basic ") - 1;

  1625.     while (encoded.len && encoded.data[0] == ' ') {
  1626.         encoded.len--;
  1627.         encoded.data++;
  1628.     }

  1629.     if (encoded.len == 0) {
  1630.         r->headers_in.user.data = (u_char *) "";
  1631.         return NGX_DECLINED;
  1632.     }

  1633.     auth.len = ngx_base64_decoded_length(encoded.len);
  1634.     auth.data = ngx_pnalloc(r->pool, auth.len + 1);
  1635.     if (auth.data == NULL) {
  1636.         return NGX_ERROR;
  1637.     }

  1638.     if (ngx_decode_base64(&auth, &encoded) != NGX_OK) {
  1639.         r->headers_in.user.data = (u_char *) "";
  1640.         return NGX_DECLINED;
  1641.     }

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

  1643.     for (len = 0; len < auth.len; len++) {
  1644.         if (auth.data[len] == ':') {
  1645.             break;
  1646.         }
  1647.     }

  1648.     if (len == 0 || len == auth.len) {
  1649.         r->headers_in.user.data = (u_char *) "";
  1650.         return NGX_DECLINED;
  1651.     }

  1652.     r->headers_in.user.len = len;
  1653.     r->headers_in.user.data = auth.data;
  1654.     r->headers_in.passwd.len = auth.len - len - 1;
  1655.     r->headers_in.passwd.data = &auth.data[len + 1];

  1656.     return NGX_OK;
  1657. }


  1658. #if (NGX_HTTP_GZIP)

  1659. ngx_int_t
  1660. ngx_http_gzip_ok(ngx_http_request_t *r)
  1661. {
  1662.     time_t                     date, expires;
  1663.     ngx_uint_t                 p;
  1664.     ngx_array_t               *cc;
  1665.     ngx_table_elt_t           *e, *d, *ae;
  1666.     ngx_http_core_loc_conf_t  *clcf;

  1667.     r->gzip_tested = 1;

  1668.     if (r != r->main) {
  1669.         return NGX_DECLINED;
  1670.     }

  1671. #if (NGX_HTTP_SPDY)
  1672.     if (r->spdy_stream) {
  1673.         r->gzip_ok = 1;
  1674.         return NGX_OK;
  1675.     }
  1676. #endif

  1677.     ae = r->headers_in.accept_encoding;
  1678.     if (ae == NULL) {
  1679.         return NGX_DECLINED;
  1680.     }

  1681.     if (ae->value.len < sizeof("gzip") - 1) {
  1682.         return NGX_DECLINED;
  1683.     }

  1684.     /*
  1685.      * test first for the most common case "gzip,...":
  1686.      *   MSIE:    "gzip, deflate"
  1687.      *   Firefox: "gzip,deflate"
  1688.      *   Chrome:  "gzip,deflate,sdch"
  1689.      *   Safari:  "gzip, deflate"
  1690.      *   Opera:   "gzip, deflate"
  1691.      */

  1692.     if (ngx_memcmp(ae->value.data, "gzip,", 5) != 0
  1693.         && ngx_http_gzip_accept_encoding(&ae->value) != NGX_OK)
  1694.     {
  1695.         return NGX_DECLINED;
  1696.     }

  1697.     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

  1698.     if (r->headers_in.msie6 && clcf->gzip_disable_msie6) {
  1699.         return NGX_DECLINED;
  1700.     }

  1701.     if (r->http_version < clcf->gzip_http_version) {
  1702.         return NGX_DECLINED;
  1703.     }

  1704.     if (r->headers_in.via == NULL) {
  1705.         goto ok;
  1706.     }

  1707.     p = clcf->gzip_proxied;

  1708.     if (p & NGX_HTTP_GZIP_PROXIED_OFF) {
  1709.         return NGX_DECLINED;
  1710.     }

  1711.     if (p & NGX_HTTP_GZIP_PROXIED_ANY) {
  1712.         goto ok;
  1713.     }

  1714.     if (r->headers_in.authorization && (p & NGX_HTTP_GZIP_PROXIED_AUTH)) {
  1715.         goto ok;
  1716.     }

  1717.     e = r->headers_out.expires;

  1718.     if (e) {

  1719.         if (!(p & NGX_HTTP_GZIP_PROXIED_EXPIRED)) {
  1720.             return NGX_DECLINED;
  1721.         }

  1722.         expires = ngx_http_parse_time(e->value.data, e->value.len);
  1723.         if (expires == NGX_ERROR) {
  1724.             return NGX_DECLINED;
  1725.         }

  1726.         d = r->headers_out.date;

  1727.         if (d) {
  1728.             date = ngx_http_parse_time(d->value.data, d->value.len);
  1729.             if (date == NGX_ERROR) {
  1730.                 return NGX_DECLINED;
  1731.             }

  1732.         } else {
  1733.             date = ngx_time();
  1734.         }

  1735.         if (expires < date) {
  1736.             goto ok;
  1737.         }

  1738.         return NGX_DECLINED;
  1739.     }

  1740.     cc = &r->headers_out.cache_control;

  1741.     if (cc->elts) {

  1742.         if ((p & NGX_HTTP_GZIP_PROXIED_NO_CACHE)
  1743.             && ngx_http_parse_multi_header_lines(cc, &ngx_http_gzip_no_cache,
  1744.                                                  NULL)
  1745.                >= 0)
  1746.         {
  1747.             goto ok;
  1748.         }

  1749.         if ((p & NGX_HTTP_GZIP_PROXIED_NO_STORE)
  1750.             && ngx_http_parse_multi_header_lines(cc, &ngx_http_gzip_no_store,
  1751.                                                  NULL)
  1752.                >= 0)
  1753.         {
  1754.             goto ok;
  1755.         }

  1756.         if ((p & NGX_HTTP_GZIP_PROXIED_PRIVATE)
  1757.             && ngx_http_parse_multi_header_lines(cc, &ngx_http_gzip_private,
  1758.                                                  NULL)
  1759.                >= 0)
  1760.         {
  1761.             goto ok;
  1762.         }

  1763.         return NGX_DECLINED;
  1764.     }

  1765.     if ((p & NGX_HTTP_GZIP_PROXIED_NO_LM) && r->headers_out.last_modified) {
  1766.         return NGX_DECLINED;
  1767.     }

  1768.     if ((p & NGX_HTTP_GZIP_PROXIED_NO_ETAG) && r->headers_out.etag) {
  1769.         return NGX_DECLINED;
  1770.     }

  1771. ok:

  1772. #if (NGX_PCRE)

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

  1774.         if (ngx_regex_exec_array(clcf->gzip_disable,
  1775.                                  &r->headers_in.user_agent->value,
  1776.                                  r->connection->log)
  1777.             != NGX_DECLINED)
  1778.         {
  1779.             return NGX_DECLINED;
  1780.         }
  1781.     }

  1782. #endif

  1783.     r->gzip_ok = 1;

  1784.     return NGX_OK;
  1785. }


  1786. /*
  1787. * gzip is enabled for the following quantities:
  1788. *     "gzip; q=0.001" ... "gzip; q=1.000"
  1789. * gzip is disabled for the following quantities:
  1790. *     "gzip; q=0" ... "gzip; q=0.000", and for any invalid cases
  1791. */

  1792. static ngx_int_t
  1793. ngx_http_gzip_accept_encoding(ngx_str_t *ae)
  1794. {
  1795.     u_char  *p, *start, *last;

  1796.     start = ae->data;
  1797.     last = start + ae->len;

  1798.     for ( ;; ) {
  1799.         p = ngx_strcasestrn(start, "gzip", 4 - 1);
  1800.         if (p == NULL) {
  1801.             return NGX_DECLINED;
  1802.         }

  1803.         if (p == start || (*(p - 1) == ',' || *(p - 1) == ' ')) {
  1804.             break;
  1805.         }

  1806.         start = p + 4;
  1807.     }

  1808.     p += 4;

  1809.     while (p < last) {
  1810.         switch (*p++) {
  1811.         case ',':
  1812.             return NGX_OK;
  1813.         case ';':
  1814.             goto quantity;
  1815.         case ' ':
  1816.             continue;
  1817.         default:
  1818.             return NGX_DECLINED;
  1819.         }
  1820.     }

  1821.     return NGX_OK;

  1822. quantity:

  1823.     while (p < last) {
  1824.         switch (*p++) {
  1825.         case 'q':
  1826.         case 'Q':
  1827.             goto equal;
  1828.         case ' ':
  1829.             continue;
  1830.         default:
  1831.             return NGX_DECLINED;
  1832.         }
  1833.     }

  1834.     return NGX_OK;

  1835. equal:

  1836.     if (p + 2 > last || *p++ != '=') {
  1837.         return NGX_DECLINED;
  1838.     }

  1839.     if (ngx_http_gzip_quantity(p, last) == 0) {
  1840.         return NGX_DECLINED;
  1841.     }

  1842.     return NGX_OK;
  1843. }


  1844. static ngx_uint_t
  1845. ngx_http_gzip_quantity(u_char *p, u_char *last)
  1846. {
  1847.     u_char      c;
  1848.     ngx_uint_t  n, q;

  1849.     c = *p++;

  1850.     if (c != '0' && c != '1') {
  1851.         return 0;
  1852.     }

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

  1854.     if (p == last) {
  1855.         return q;
  1856.     }

  1857.     c = *p++;

  1858.     if (c == ',' || c == ' ') {
  1859.         return q;
  1860.     }

  1861.     if (c != '.') {
  1862.         return 0;
  1863.     }

  1864.     n = 0;

  1865.     while (p < last) {
  1866.         c = *p++;

  1867.         if (c == ',' || c == ' ') {
  1868.             break;
  1869.         }

  1870.         if (c >= '0' && c <= '9') {
  1871.             q += c - '0';
  1872.             n++;
  1873.             continue;
  1874.         }

  1875.         return 0;
  1876.     }

  1877.     if (q > 100 || n > 3) {
  1878.         return 0;
  1879.     }

  1880.     return q;
  1881. }

  1882. #endif


  1883. ngx_int_t
  1884. ngx_http_subrequest(ngx_http_request_t *r,
  1885.     ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **psr,
  1886.     ngx_http_post_subrequest_t *ps, ngx_uint_t flags)
  1887. {
  1888.     ngx_time_t                    *tp;
  1889.     ngx_connection_t              *c;
  1890.     ngx_http_request_t            *sr;
  1891.     ngx_http_core_srv_conf_t      *cscf;
  1892.     ngx_http_postponed_request_t  *pr, *p;

  1893.     r->main->subrequests--;

  1894.     if (r->main->subrequests == 0) {
  1895.         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
  1896.                       "subrequests cycle while processing \"%V\"", uri);
  1897.         r->main->subrequests = 1;
  1898.         return NGX_ERROR;
  1899.     }

  1900.     sr = ngx_pcalloc(r->pool, sizeof(ngx_http_request_t));
  1901.     if (sr == NULL) {
  1902.         return NGX_ERROR;
  1903.     }

  1904.     sr->signature = NGX_HTTP_MODULE;

  1905.     c = r->connection;
  1906.     sr->connection = c;

  1907.     sr->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
  1908.     if (sr->ctx == NULL) {
  1909.         return NGX_ERROR;
  1910.     }

  1911.     if (ngx_list_init(&sr->headers_out.headers, r->pool, 20,
  1912.                       sizeof(ngx_table_elt_t))
  1913.         != NGX_OK)
  1914.     {
  1915.         return NGX_ERROR;
  1916.     }

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

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

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

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

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

  1927. #if (NGX_HTTP_SPDY)
  1928.     sr->spdy_stream = r->spdy_stream;
  1929. #endif

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

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

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

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

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

  1941.     sr->unparsed_uri = r->unparsed_uri;
  1942.     sr->method_name = ngx_http_core_get_method;
  1943.     sr->http_protocol = r->http_protocol;

  1944.     ngx_http_set_exten(sr);

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

  1950.     if (c->data == r && r->postponed == NULL) {
  1951.         c->data = sr;
  1952.     }

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

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

  1955.     pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t));
  1956.     if (pr == NULL) {
  1957.         return NGX_ERROR;
  1958.     }

  1959.     pr->request = sr;
  1960.     pr->out = NULL;
  1961.     pr->next = NULL;

  1962.     if (r->postponed) {
  1963.         for (p = r->postponed; p->next; p = p->next) { /* void */ }
  1964.         p->next = pr;

  1965.     } else {
  1966.         r->postponed = pr;
  1967.     }

  1968.     sr->internal = 1;

  1969.     sr->discard_body = r->discard_body;
  1970.     sr->expect_tested = 1;
  1971.     sr->main_filter_need_in_memory = r->main_filter_need_in_memory;

  1972.     sr->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1;

  1973.     tp = ngx_timeofday();
  1974.     sr->start_sec = tp->sec;
  1975.     sr->start_msec = tp->msec;

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

  1977.     *psr = sr;

  1978.     return ngx_http_post_request(sr, NULL);
  1979. }


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

  1985.     r->uri_changes--;

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

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

  1994.     r->uri = *uri;

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

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

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

  2002.     ngx_http_set_exten(r);

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

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

  2007.     ngx_http_update_location_config(r);

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

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

  2015.     ngx_http_handler(r);

  2016.     return NGX_DONE;
  2017. }


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

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

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

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

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

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

  2039.     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);

  2040.     if (cscf->named_locations) {

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

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

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

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

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

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

  2058.             ngx_http_update_location_config(r);

  2059.             cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

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

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

  2063.             return NGX_DONE;
  2064.         }
  2065.     }

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

  2068.     ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);

  2069.     return NGX_DONE;
  2070. }


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

  2075.     r = r->main;

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

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

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

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

  2090.     r->cleanup = cln;

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

  2093.     return cln;
  2094. }


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

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

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

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

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

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

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

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

  2126.     p--;

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

  2131.     return NGX_OK;
  2132. }


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

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

  2146.     i = headers->nelts;
  2147.     h = headers->elts;

  2148.     rc = NGX_DECLINED;

  2149.     found = 0;

  2150.     while (i-- > 0) {
  2151.         rc = ngx_http_get_forwarded_addr_internal(r, addr, h[i]->value.data,
  2152.                                                   h[i]->value.len, proxies,
  2153.                                                   recursive);

  2154.         if (!recursive) {
  2155.             break;
  2156.         }

  2157.         if (rc == NGX_DECLINED && found) {
  2158.             rc = NGX_DONE;
  2159.             break;
  2160.         }

  2161.         if (rc != NGX_OK) {
  2162.             break;
  2163.         }

  2164.         found = 1;
  2165.     }

  2166.     return rc;
  2167. }


  2168. static ngx_int_t
  2169. ngx_http_get_forwarded_addr_internal(ngx_http_request_t *r, ngx_addr_t *addr,
  2170.     u_char *xff, size_t xfflen, ngx_array_t *proxies, int recursive)
  2171. {
  2172.     u_char           *p;
  2173.     in_addr_t         inaddr;
  2174.     ngx_int_t         rc;
  2175.     ngx_addr_t        paddr;
  2176.     ngx_cidr_t       *cidr;
  2177.     ngx_uint_t        family, i;
  2178. #if (NGX_HAVE_INET6)
  2179.     ngx_uint_t        n;
  2180.     struct in6_addr  *inaddr6;
  2181. #endif

  2182. #if (NGX_SUPPRESS_WARN)
  2183.     inaddr = 0;
  2184. #if (NGX_HAVE_INET6)
  2185.     inaddr6 = NULL;
  2186. #endif
  2187. #endif

  2188.     family = addr->sockaddr->sa_family;

  2189.     if (family == AF_INET) {
  2190.         inaddr = ((struct sockaddr_in *) addr->sockaddr)->sin_addr.s_addr;
  2191.     }

  2192. #if (NGX_HAVE_INET6)
  2193.     else if (family == AF_INET6) {
  2194.         inaddr6 = &((struct sockaddr_in6 *) addr->sockaddr)->sin6_addr;

  2195.         if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
  2196.             family = AF_INET;

  2197.             p = inaddr6->s6_addr;

  2198.             inaddr = p[12] << 24;
  2199.             inaddr += p[13] << 16;
  2200.             inaddr += p[14] << 8;
  2201.             inaddr += p[15];

  2202.             inaddr = htonl(inaddr);
  2203.         }
  2204.     }
  2205. #endif

  2206.     for (cidr = proxies->elts, i = 0; i < proxies->nelts; i++) {
  2207.         if (cidr[i].family != family) {
  2208.             goto next;
  2209.         }

  2210.         switch (family) {

  2211. #if (NGX_HAVE_INET6)
  2212.         case AF_INET6:
  2213.             for (n = 0; n < 16; n++) {
  2214.                 if ((inaddr6->s6_addr[n] & cidr[i].u.in6.mask.s6_addr[n])
  2215.                     != cidr[i].u.in6.addr.s6_addr[n])
  2216.                 {
  2217.                     goto next;
  2218.                 }
  2219.             }
  2220.             break;
  2221. #endif

  2222. #if (NGX_HAVE_UNIX_DOMAIN)
  2223.         case AF_UNIX:
  2224.             break;
  2225. #endif

  2226.         default: /* AF_INET */
  2227.             if ((inaddr & cidr[i].u.in.mask) != cidr[i].u.in.addr) {
  2228.                 goto next;
  2229.             }
  2230.             break;
  2231.         }

  2232.         for (p = xff + xfflen - 1; p > xff; p--, xfflen--) {
  2233.             if (*p != ' ' && *p != ',') {
  2234.                 break;
  2235.             }
  2236.         }

  2237.         for ( /* void */ ; p > xff; p--) {
  2238.             if (*p == ' ' || *p == ',') {
  2239.                 p++;
  2240.                 break;
  2241.             }
  2242.         }

  2243.         if (ngx_parse_addr(r->pool, &paddr, p, xfflen - (p - xff)) != NGX_OK) {
  2244.             return NGX_DECLINED;
  2245.         }

  2246.         *addr = paddr;

  2247.         if (recursive && p > xff) {
  2248.             rc = ngx_http_get_forwarded_addr_internal(r, addr, xff, p - 1 - xff,
  2249.                                                       proxies, 1);

  2250.             if (rc == NGX_DECLINED) {
  2251.                 return NGX_DONE;
  2252.             }

  2253.             /* rc == NGX_OK || rc == NGX_DONE  */
  2254.             return rc;
  2255.         }

  2256.         return NGX_OK;

  2257.     next:
  2258.         continue;
  2259.     }

  2260.     return NGX_DECLINED;
  2261. }


  2262. static char *
  2263. ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
  2264. {
  2265.     char                        *rv;
  2266.     void                        *mconf;
  2267.     ngx_uint_t                   i;
  2268.     ngx_conf_t                   pcf;
  2269.     ngx_http_module_t           *module;
  2270.     struct sockaddr_in          *sin;
  2271.     ngx_http_conf_ctx_t         *ctx, *http_ctx;
  2272.     ngx_http_listen_opt_t        lsopt;
  2273.     ngx_http_core_srv_conf_t    *cscf, **cscfp;
  2274.     ngx_http_core_main_conf_t   *cmcf;

  2275.     ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
  2276.     if (ctx == NULL) {
  2277.         return NGX_CONF_ERROR;
  2278.     }

  2279.     http_ctx = cf->ctx;
  2280.     ctx->main_conf = http_ctx->main_conf;

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

  2282.     ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
  2283.     if (ctx->srv_conf == NULL) {
  2284.         return NGX_CONF_ERROR;
  2285.     }

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

  2287.     ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
  2288.     if (ctx->loc_conf == NULL) {
  2289.         return NGX_CONF_ERROR;
  2290.     }

  2291.     for (i = 0; ngx_modules[i]; i++) {
  2292.         if (ngx_modules[i]->type != NGX_HTTP_MODULE) {
  2293.             continue;
  2294.         }

  2295.         module = ngx_modules[i]->ctx;

  2296.         if (module->create_srv_conf) {
  2297.             mconf = module->create_srv_conf(cf);
  2298.             if (mconf == NULL) {
  2299.                 return NGX_CONF_ERROR;
  2300.             }

  2301.             ctx->srv_conf[ngx_modules[i]->ctx_index] = mconf;
  2302.         }

  2303.         if (module->create_loc_conf) {
  2304.             mconf = module->create_loc_conf(cf);
  2305.             if (mconf == NULL) {
  2306.                 return NGX_CONF_ERROR;
  2307.             }

  2308.             ctx->loc_conf[ngx_modules[i]->ctx_index] = mconf;
  2309.         }
  2310.     }


  2311.     /* the server configuration context */

  2312.     cscf = ctx->srv_conf[ngx_http_core_module.ctx_index];
  2313.     cscf->ctx = ctx;


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

  2315.     cscfp = ngx_array_push(&cmcf->servers);
  2316.     if (cscfp == NULL) {
  2317.         return NGX_CONF_ERROR;
  2318.     }

  2319.     *cscfp = cscf;


  2320.     /* parse inside server{} */

  2321.     pcf = *cf;
  2322.     cf->ctx = ctx;
  2323.     cf->cmd_type = NGX_HTTP_SRV_CONF;

  2324.     rv = ngx_conf_parse(cf, NULL);

  2325.     *cf = pcf;

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

  2328.         sin = &lsopt.u.sockaddr_in;

  2329.         sin->sin_family = AF_INET;
  2330. #if (NGX_WIN32)
  2331.         sin->sin_port = htons(80);
  2332. #else
  2333.         sin->sin_port = htons((getuid() == 0) ? 80 : 8000);
  2334. #endif
  2335.         sin->sin_addr.s_addr = INADDR_ANY;

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

  2337.         lsopt.backlog = NGX_LISTEN_BACKLOG;
  2338.         lsopt.rcvbuf = -1;
  2339.         lsopt.sndbuf = -1;
  2340. #if (NGX_HAVE_SETFIB)
  2341.         lsopt.setfib = -1;
  2342. #endif
  2343. #if (NGX_HAVE_TCP_FASTOPEN)
  2344.         lsopt.fastopen = -1;
  2345. #endif
  2346.         lsopt.wildcard = 1;

  2347.         (void) ngx_sock_ntop(&lsopt.u.sockaddr, lsopt.socklen, lsopt.addr,
  2348.                              NGX_SOCKADDR_STRLEN, 1);

  2349.         if (ngx_http_add_listen(cf, cscf, &lsopt) != NGX_OK) {
  2350.             return NGX_CONF_ERROR;
  2351.         }
  2352.     }

  2353.     return rv;
  2354. }


  2355. static char *
  2356. ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
  2357. {
  2358.     char                      *rv;
  2359.     u_char                    *mod;
  2360.     size_t                     len;
  2361.     ngx_str_t                 *value, *name;
  2362.     ngx_uint_t                 i;
  2363.     ngx_conf_t                 save;
  2364.     ngx_http_module_t         *module;
  2365.     ngx_http_conf_ctx_t       *ctx, *pctx;
  2366.     ngx_http_core_loc_conf_t  *clcf, *pclcf;

  2367.     ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
  2368.     if (ctx == NULL) {
  2369.         return NGX_CONF_ERROR;
  2370.     }

  2371.     pctx = cf->ctx;
  2372.     ctx->main_conf = pctx->main_conf;
  2373.     ctx->srv_conf = pctx->srv_conf;

  2374.     ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
  2375.     if (ctx->loc_conf == NULL) {
  2376.         return NGX_CONF_ERROR;
  2377.     }

  2378.     for (i = 0; ngx_modules[i]; i++) {
  2379.         if (ngx_modules[i]->type != NGX_HTTP_MODULE) {
  2380.             continue;
  2381.         }

  2382.         module = ngx_modules[i]->ctx;

  2383.         if (module->create_loc_conf) {
  2384.             ctx->loc_conf[ngx_modules[i]->ctx_index] =
  2385.                                                    module->create_loc_conf(cf);
  2386.             if (ctx->loc_conf[ngx_modules[i]->ctx_index] == NULL) {
  2387.                  return NGX_CONF_ERROR;
  2388.             }
  2389.         }
  2390.     }

  2391.     clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
  2392.     clcf->loc_conf = ctx->loc_conf;

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

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

  2395.         len = value[1].len;
  2396.         mod = value[1].data;
  2397.         name = &value[2];

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

  2399.             clcf->name = *name;
  2400.             clcf->exact_match = 1;

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

  2402.             clcf->name = *name;
  2403.             clcf->noregex = 1;

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

  2405.             if (ngx_http_core_regex_location(cf, clcf, name, 0) != NGX_OK) {
  2406.                 return NGX_CONF_ERROR;
  2407.             }

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

  2409.             if (ngx_http_core_regex_location(cf, clcf, name, 1) != NGX_OK) {
  2410.                 return NGX_CONF_ERROR;
  2411.             }

  2412.         } else {
  2413.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2414.                                "invalid location modifier \"%V\"", &value[1]);
  2415.             return NGX_CONF_ERROR;
  2416.         }

  2417.     } else {

  2418.         name = &value[1];

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

  2420.             clcf->name.len = name->len - 1;
  2421.             clcf->name.data = name->data + 1;
  2422.             clcf->exact_match = 1;

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

  2424.             clcf->name.len = name->len - 2;
  2425.             clcf->name.data = name->data + 2;
  2426.             clcf->noregex = 1;

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

  2428.             name->len--;
  2429.             name->data++;

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

  2431.                 name->len--;
  2432.                 name->data++;

  2433.                 if (ngx_http_core_regex_location(cf, clcf, name, 1) != NGX_OK) {
  2434.                     return NGX_CONF_ERROR;
  2435.                 }

  2436.             } else {
  2437.                 if (ngx_http_core_regex_location(cf, clcf, name, 0) != NGX_OK) {
  2438.                     return NGX_CONF_ERROR;
  2439.                 }
  2440.             }

  2441.         } else {

  2442.             clcf->name = *name;

  2443.             if (name->data[0] == '@') {
  2444.                 clcf->named = 1;
  2445.             }
  2446.         }
  2447.     }

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

  2449.     if (pclcf->name.len) {

  2450.         /* nested location */

  2451. #if 0
  2452.         clcf->prev_location = pclcf;
  2453. #endif

  2454.         if (pclcf->exact_match) {
  2455.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2456.                                "location \"%V\" cannot be inside "
  2457.                                "the exact location \"%V\"",
  2458.                                &clcf->name, &pclcf->name);
  2459.             return NGX_CONF_ERROR;
  2460.         }

  2461.         if (pclcf->named) {
  2462.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2463.                                "location \"%V\" cannot be inside "
  2464.                                "the named location \"%V\"",
  2465.                                &clcf->name, &pclcf->name);
  2466.             return NGX_CONF_ERROR;
  2467.         }

  2468.         if (clcf->named) {
  2469.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2470.                                "named location \"%V\" can be "
  2471.                                "on the server level only",
  2472.                                &clcf->name);
  2473.             return NGX_CONF_ERROR;
  2474.         }

  2475.         len = pclcf->name.len;

  2476. #if (NGX_PCRE)
  2477.         if (clcf->regex == NULL
  2478.             && ngx_filename_cmp(clcf->name.data, pclcf->name.data, len) != 0)
  2479. #else
  2480.         if (ngx_filename_cmp(clcf->name.data, pclcf->name.data, len) != 0)
  2481. #endif
  2482.         {
  2483.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2484.                                "location \"%V\" is outside location \"%V\"",
  2485.                                &clcf->name, &pclcf->name);
  2486.             return NGX_CONF_ERROR;
  2487.         }
  2488.     }

  2489.     if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) {
  2490.         return NGX_CONF_ERROR;
  2491.     }

  2492.     save = *cf;
  2493.     cf->ctx = ctx;
  2494.     cf->cmd_type = NGX_HTTP_LOC_CONF;

  2495.     rv = ngx_conf_parse(cf, NULL);

  2496.     *cf = save;

  2497.     return rv;
  2498. }


  2499. static ngx_int_t
  2500. ngx_http_core_regex_location(ngx_conf_t *cf, ngx_http_core_loc_conf_t *clcf,
  2501.     ngx_str_t *regex, ngx_uint_t caseless)
  2502. {
  2503. #if (NGX_PCRE)
  2504.     ngx_regex_compile_t  rc;
  2505.     u_char               errstr[NGX_MAX_CONF_ERRSTR];

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

  2507.     rc.pattern = *regex;
  2508.     rc.err.len = NGX_MAX_CONF_ERRSTR;
  2509.     rc.err.data = errstr;

  2510. #if (NGX_HAVE_CASELESS_FILESYSTEM)
  2511.     rc.options = NGX_REGEX_CASELESS;
  2512. #else
  2513.     rc.options = caseless ? NGX_REGEX_CASELESS : 0;
  2514. #endif

  2515.     clcf->regex = ngx_http_regex_compile(cf, &rc);
  2516.     if (clcf->regex == NULL) {
  2517.         return NGX_ERROR;
  2518.     }

  2519.     clcf->name = *regex;

  2520.     return NGX_OK;

  2521. #else

  2522.     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2523.                        "using regex \"%V\" requires PCRE library",
  2524.                        regex);
  2525.     return NGX_ERROR;

  2526. #endif
  2527. }


  2528. static char *
  2529. ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  2530. {
  2531.     ngx_http_core_loc_conf_t *clcf = conf;

  2532.     char        *rv;
  2533.     ngx_conf_t   save;

  2534.     if (clcf->types == NULL) {
  2535.         clcf->types = ngx_array_create(cf->pool, 64, sizeof(ngx_hash_key_t));
  2536.         if (clcf->types == NULL) {
  2537.             return NGX_CONF_ERROR;
  2538.         }
  2539.     }

  2540.     save = *cf;
  2541.     cf->handler = ngx_http_core_type;
  2542.     cf->handler_conf = conf;

  2543.     rv = ngx_conf_parse(cf, NULL);

  2544.     *cf = save;

  2545.     return rv;
  2546. }


  2547. static char *
  2548. ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
  2549. {
  2550.     ngx_http_core_loc_conf_t *clcf = conf;

  2551.     ngx_str_t       *value, *content_type, *old;
  2552.     ngx_uint_t       i, n, hash;
  2553.     ngx_hash_key_t  *type;

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

  2555.     if (ngx_strcmp(value[0].data, "include") == 0) {
  2556.         if (cf->args->nelts != 2) {
  2557.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2558.                                "invalid number of arguments"
  2559.                                " in \"include\" directive");
  2560.             return NGX_CONF_ERROR;
  2561.         }

  2562.         return ngx_conf_include(cf, dummy, conf);
  2563.     }

  2564.     content_type = ngx_palloc(cf->pool, sizeof(ngx_str_t));
  2565.     if (content_type == NULL) {
  2566.         return NGX_CONF_ERROR;
  2567.     }

  2568.     *content_type = value[0];

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

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

  2571.         type = clcf->types->elts;
  2572.         for (n = 0; n < clcf->types->nelts; n++) {
  2573.             if (ngx_strcmp(value[i].data, type[n].key.data) == 0) {
  2574.                 old = type[n].value;
  2575.                 type[n].value = content_type;

  2576.                 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
  2577.                                    "duplicate extension \"%V\", "
  2578.                                    "content type: \"%V\", "
  2579.                                    "previous content type: \"%V\"",
  2580.                                    &value[i], content_type, old);
  2581.                 goto next;
  2582.             }
  2583.         }


  2584.         type = ngx_array_push(clcf->types);
  2585.         if (type == NULL) {
  2586.             return NGX_CONF_ERROR;
  2587.         }

  2588.         type->key = value[i];
  2589.         type->key_hash = hash;
  2590.         type->value = content_type;

  2591.     next:
  2592.         continue;
  2593.     }

  2594.     return NGX_CONF_OK;
  2595. }


  2596. static ngx_int_t
  2597. ngx_http_core_preconfiguration(ngx_conf_t *cf)
  2598. {
  2599.     return ngx_http_variables_add_core_vars(cf);
  2600. }


  2601. static void *
  2602. ngx_http_core_create_main_conf(ngx_conf_t *cf)
  2603. {
  2604.     ngx_http_core_main_conf_t  *cmcf;

  2605.     cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_main_conf_t));
  2606.     if (cmcf == NULL) {
  2607.         return NULL;
  2608.     }

  2609.     if (ngx_array_init(&cmcf->servers, cf->pool, 4,
  2610.                        sizeof(ngx_http_core_srv_conf_t *))
  2611.         != NGX_OK)
  2612.     {
  2613.         return NULL;
  2614.     }

  2615.     cmcf->server_names_hash_max_size = NGX_CONF_UNSET_UINT;
  2616.     cmcf->server_names_hash_bucket_size = NGX_CONF_UNSET_UINT;

  2617.     cmcf->variables_hash_max_size = NGX_CONF_UNSET_UINT;
  2618.     cmcf->variables_hash_bucket_size = NGX_CONF_UNSET_UINT;

  2619.     return cmcf;
  2620. }


  2621. static char *
  2622. ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf)
  2623. {
  2624.     ngx_http_core_main_conf_t *cmcf = conf;

  2625.     ngx_conf_init_uint_value(cmcf->server_names_hash_max_size, 512);
  2626.     ngx_conf_init_uint_value(cmcf->server_names_hash_bucket_size,
  2627.                              ngx_cacheline_size);

  2628.     cmcf->server_names_hash_bucket_size =
  2629.             ngx_align(cmcf->server_names_hash_bucket_size, ngx_cacheline_size);


  2630.     ngx_conf_init_uint_value(cmcf->variables_hash_max_size, 1024);
  2631.     ngx_conf_init_uint_value(cmcf->variables_hash_bucket_size, 64);

  2632.     cmcf->variables_hash_bucket_size =
  2633.                ngx_align(cmcf->variables_hash_bucket_size, ngx_cacheline_size);

  2634.     if (cmcf->ncaptures) {
  2635.         cmcf->ncaptures = (cmcf->ncaptures + 1) * 3;
  2636.     }

  2637.     return NGX_CONF_OK;
  2638. }


  2639. static void *
  2640. ngx_http_core_create_srv_conf(ngx_conf_t *cf)
  2641. {
  2642.     ngx_http_core_srv_conf_t  *cscf;

  2643.     cscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_srv_conf_t));
  2644.     if (cscf == NULL) {
  2645.         return NULL;
  2646.     }

  2647.     /*
  2648.      * set by ngx_pcalloc():
  2649.      *
  2650.      *     conf->client_large_buffers.num = 0;
  2651.      */

  2652.     if (ngx_array_init(&cscf->server_names, cf->temp_pool, 4,
  2653.                        sizeof(ngx_http_server_name_t))
  2654.         != NGX_OK)
  2655.     {
  2656.         return NULL;
  2657.     }

  2658.     cscf->connection_pool_size = NGX_CONF_UNSET_SIZE;
  2659.     cscf->request_pool_size = NGX_CONF_UNSET_SIZE;
  2660.     cscf->client_header_timeout = NGX_CONF_UNSET_MSEC;
  2661.     cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE;
  2662.     cscf->ignore_invalid_headers = NGX_CONF_UNSET;
  2663.     cscf->merge_slashes = NGX_CONF_UNSET;
  2664.     cscf->underscores_in_headers = NGX_CONF_UNSET;

  2665.     return cscf;
  2666. }


  2667. static char *
  2668. ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
  2669. {
  2670.     ngx_http_core_srv_conf_t *prev = parent;
  2671.     ngx_http_core_srv_conf_t *conf = child;

  2672.     ngx_str_t                name;
  2673.     ngx_http_server_name_t  *sn;

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

  2675.     ngx_conf_merge_size_value(conf->connection_pool_size,
  2676.                               prev->connection_pool_size, 256);
  2677.     ngx_conf_merge_size_value(conf->request_pool_size,
  2678.                               prev->request_pool_size, 4096);
  2679.     ngx_conf_merge_msec_value(conf->client_header_timeout,
  2680.                               prev->client_header_timeout, 60000);
  2681.     ngx_conf_merge_size_value(conf->client_header_buffer_size,
  2682.                               prev->client_header_buffer_size, 1024);
  2683.     ngx_conf_merge_bufs_value(conf->large_client_header_buffers,
  2684.                               prev->large_client_header_buffers,
  2685.                               4, 8192);

  2686.     if (conf->large_client_header_buffers.size < conf->connection_pool_size) {
  2687.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  2688.                            "the \"large_client_header_buffers\" size must be "
  2689.                            "equal to or greater than \"connection_pool_size\"");
  2690.         return NGX_CONF_ERROR;
  2691.     }

  2692.     ngx_conf_merge_value(conf->ignore_invalid_headers,
  2693.                               prev->ignore_invalid_headers, 1);

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

  2695.     ngx_conf_merge_value(conf->underscores_in_headers,
  2696.                               prev->underscores_in_headers, 0);

  2697.     if (conf->server_names.nelts == 0) {
  2698.         /* the array has 4 empty preallocated elements, so push cannot fail */
  2699.         sn = ngx_array_push(&conf->server_names);
  2700. #if (NGX_PCRE)
  2701.         sn->regex = NULL;
  2702. #endif
  2703.         sn->server = conf;
  2704.         ngx_str_set(&sn->name, "");
  2705.     }

  2706.     sn = conf->server_names.elts;
  2707.     name = sn[0].name;

  2708. #if (NGX_PCRE)
  2709.     if (sn->regex) {
  2710.         name.len++;
  2711.         name.data--;
  2712.     } else
  2713. #endif

  2714.     if (name.data[0] == '.') {
  2715.         name.len--;
  2716.         name.data++;
  2717.     }

  2718.     conf->server_name.len = name.len;
  2719.     conf->server_name.data = ngx_pstrdup(cf->pool, &name);
  2720.     if (conf->server_name.data == NULL) {
  2721.         return NGX_CONF_ERROR;
  2722.     }

  2723.     return NGX_CONF_OK;
  2724. }


  2725. static void *
  2726. ngx_http_core_create_loc_conf(ngx_conf_t *cf)
  2727. {
  2728.     ngx_http_core_loc_conf_t  *clcf;

  2729.     clcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_loc_conf_t));
  2730.     if (clcf == NULL) {
  2731.         return NULL;
  2732.     }

  2733.     /*
  2734.      * set by ngx_pcalloc():
  2735.      *
  2736.      *     clcf->root = { 0, NULL };
  2737.      *     clcf->limit_except = 0;
  2738.      *     clcf->post_action = { 0, NULL };
  2739.      *     clcf->types = NULL;
  2740.      *     clcf->default_type = { 0, NULL };
  2741.      *     clcf->error_log = NULL;
  2742.      *     clcf->error_pages = NULL;
  2743.      *     clcf->try_files = NULL;
  2744.      *     clcf->client_body_path = NULL;
  2745.      *     clcf->regex = NULL;
  2746.      *     clcf->exact_match = 0;
  2747.      *     clcf->auto_redirect = 0;
  2748.      *     clcf->alias = 0;
  2749.      *     clcf->gzip_proxied = 0;
  2750.      *     clcf->keepalive_disable = 0;
  2751.      */

  2752.     clcf->client_max_body_size = NGX_CONF_UNSET;
  2753.     clcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE;
  2754.     clcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
  2755.     clcf->satisfy = NGX_CONF_UNSET_UINT;
  2756.     clcf->if_modified_since = NGX_CONF_UNSET_UINT;
  2757.     clcf->max_ranges = NGX_CONF_UNSET_UINT;
  2758.     clcf->client_body_in_file_only = NGX_CONF_UNSET_UINT;
  2759.     clcf->client_body_in_single_buffer = NGX_CONF_UNSET;
  2760.     clcf->internal = NGX_CONF_UNSET;
  2761.     clcf->sendfile = NGX_CONF_UNSET;
  2762.     clcf->sendfile_max_chunk = NGX_CONF_UNSET_SIZE;
  2763. #if (NGX_HAVE_FILE_AIO)
  2764.     clcf->aio = NGX_CONF_UNSET;
  2765. #endif
  2766.     clcf->read_ahead = NGX_CONF_UNSET_SIZE;
  2767.     clcf->directio = NGX_CONF_UNSET;
  2768.     clcf->directio_alignment = NGX_CONF_UNSET;
  2769.     clcf->tcp_nopush = NGX_CONF_UNSET;
  2770.     clcf->tcp_nodelay = NGX_CONF_UNSET;
  2771.     clcf->send_timeout = NGX_CONF_UNSET_MSEC;
  2772.     clcf->send_lowat = NGX_CONF_UNSET_SIZE;
  2773.     clcf->postpone_output = NGX_CONF_UNSET_SIZE;
  2774.     clcf->limit_rate = NGX_CONF_UNSET_SIZE;
  2775.     clcf->limit_rate_after = NGX_CONF_UNSET_SIZE;
  2776.     clcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
  2777.     clcf->keepalive_header = NGX_CONF_UNSET;
  2778.     clcf->keepalive_requests = NGX_CONF_UNSET_UINT;
  2779.     clcf->lingering_close = NGX_CONF_UNSET_UINT;
  2780.     clcf->lingering_time = NGX_CONF_UNSET_MSEC;
  2781.     clcf->lingering_timeout = NGX_CONF_UNSET_MSEC;
  2782.     clcf->resolver_timeout = NGX_CONF_UNSET_MSEC;
  2783.     clcf->reset_timedout_connection = NGX_CONF_UNSET;
  2784.     clcf->server_name_in_redirect = NGX_CONF_UNSET;
  2785.     clcf->port_in_redirect = NGX_CONF_UNSET;
  2786.     clcf->msie_padding = NGX_CONF_UNSET;
  2787.     clcf->msie_refresh = NGX_CONF_UNSET;
  2788.     clcf->log_not_found = NGX_CONF_UNSET;
  2789.     clcf->log_subrequest = NGX_CONF_UNSET;
  2790.     clcf->recursive_error_pages = NGX_CONF_UNSET;
  2791.     clcf->server_tokens = NGX_CONF_UNSET;
  2792.     clcf->chunked_transfer_encoding = NGX_CONF_UNSET;
  2793.     clcf->etag = NGX_CONF_UNSET;
  2794.     clcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
  2795.     clcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;

  2796.     clcf->open_file_cache = NGX_CONF_UNSET_PTR;
  2797.     clcf->open_file_cache_valid = NGX_CONF_UNSET;
  2798.     clcf->open_file_cache_min_uses = NGX_CONF_UNSET_UINT;
  2799.     clcf->open_file_cache_errors = NGX_CONF_UNSET;
  2800.     clcf->open_file_cache_events = NGX_CONF_UNSET;

  2801. #if (NGX_HTTP_GZIP)
  2802.     clcf->gzip_vary = NGX_CONF_UNSET;
  2803.     clcf->gzip_http_version = NGX_CONF_UNSET_UINT;
  2804. #if (NGX_PCRE)
  2805.     clcf->gzip_disable = NGX_CONF_UNSET_PTR;
  2806. #endif
  2807.     clcf->gzip_disable_msie6 = 3;
  2808. #if (NGX_HTTP_DEGRADATION)
  2809.     clcf->gzip_disable_degradation = 3;
  2810. #endif
  2811. #endif

  2812. #if (NGX_HAVE_OPENAT)
  2813.     clcf->disable_symlinks = NGX_CONF_UNSET_UINT;
  2814.     clcf->disable_symlinks_from = NGX_CONF_UNSET_PTR;
  2815. #endif

  2816.     return clcf;
  2817. }


  2818. static ngx_str_t  ngx_http_core_text_html_type = ngx_string("text/html");
  2819. static ngx_str_t  ngx_http_core_image_gif_type = ngx_string("image/gif");
  2820. static ngx_str_t  ngx_http_core_image_jpeg_type = ngx_string("image/jpeg");

  2821. static ngx_hash_key_t  ngx_http_core_default_types[] = {
  2822.     { ngx_string("html"), 0, &ngx_http_core_text_html_type },
  2823.     { ngx_string("gif"), 0, &ngx_http_core_image_gif_type },
  2824.     { ngx_string("jpg"), 0, &ngx_http_core_image_jpeg_type },
  2825.     { ngx_null_string, 0, NULL }
  2826. };


  2827. static char *
  2828. ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
  2829. {
  2830.     ngx_http_core_loc_conf_t *prev = parent;
  2831.     ngx_http_core_loc_conf_t *conf = child;

  2832.     ngx_uint_t        i;
  2833.     ngx_hash_key_t   *type;
  2834.     ngx_hash_init_t   types_hash;

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

  2836.         conf->alias = prev->alias;
  2837.         conf->root = prev->root;
  2838.         conf->root_lengths = prev->root_lengths;
  2839.         conf->root_values = prev->root_values;

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

  2842.             if (ngx_conf_full_name(cf->cycle, &conf->root, 0) != NGX_OK) {
  2843.                 return NGX_CONF_ERROR;
  2844.             }
  2845.         }
  2846.     }

  2847.     if (conf->post_action.data == NULL) {
  2848.         conf->post_action = prev->post_action;
  2849.     }

  2850.     ngx_conf_merge_uint_value(conf->types_hash_max_size,
  2851.                               prev->types_hash_max_size, 1024);

  2852.     ngx_conf_merge_uint_value(conf->types_hash_bucket_size,
  2853.                               prev->types_hash_bucket_size, 64);

  2854.     conf->types_hash_bucket_size = ngx_align(conf->types_hash_bucket_size,
  2855.                                              ngx_cacheline_size);

  2856.     /*
  2857.      * the special handling of the "types" directive in the "http" section
  2858.      * to inherit the http's conf->types_hash to all servers
  2859.      */

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

  2861.         types_hash.hash = &prev->types_hash;
  2862.         types_hash.key = ngx_hash_key_lc;
  2863.         types_hash.max_size = conf->types_hash_max_size;
  2864.         types_hash.bucket_size = conf->types_hash_bucket_size;
  2865.         types_hash.name = "types_hash";
  2866.         types_hash.pool = cf->pool;
  2867.         types_hash.temp_pool = NULL;

  2868.         if (ngx_hash_init(&types_hash, prev->types->elts, prev->types->nelts)
  2869.             != NGX_OK)
  2870.         {
  2871.             return NGX_CONF_ERROR;
  2872.         }
  2873.     }

  2874.     if (conf->types == NULL) {
  2875.         conf->types = prev->types;
  2876.         conf->types_hash = prev->types_hash;
  2877.     }

  2878.     if (conf->types == NULL) {
  2879.         conf->types = ngx_array_create(cf->pool, 3, sizeof(ngx_hash_key_t));
  2880.         if (conf->types == NULL) {
  2881.             return NGX_CONF_ERROR;
  2882.         }

  2883.         for (i = 0; ngx_http_core_default_types[i].key.len; i++) {
  2884.             type = ngx_array_push(conf->types);
  2885.             if (type == NULL) {
  2886.                 return NGX_CONF_ERROR;
  2887.             }

  2888.             type->key = ngx_http_core_default_types[i].key;
  2889.             type->key_hash =
  2890.                        ngx_hash_key_lc(ngx_http_core_default_types[i].key.data,
  2891.                                        ngx_http_core_default_types[i].key.len);
  2892.             type->value = ngx_http_core_default_types[i].value;
  2893.         }
  2894.     }

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

  2896.         types_hash.hash = &conf->types_hash;
  2897.         types_hash.key = ngx_hash_key_lc;
  2898.         types_hash.max_size = conf->types_hash_max_size;
  2899.         types_hash.bucket_size = conf->types_hash_bucket_size;
  2900.         types_hash.name = "types_hash";
  2901.         types_hash.pool = cf->pool;
  2902.         types_hash.temp_pool = NULL;

  2903.         if (ngx_hash_init(&types_hash, conf->types->elts, conf->types->nelts)
  2904.             != NGX_OK)
  2905.         {
  2906.             return NGX_CONF_ERROR;
  2907.         }
  2908.     }

  2909.     if (conf->error_log == NULL) {
  2910.         if (prev->error_log) {
  2911.             conf->error_log = prev->error_log;
  2912.         } else {
  2913.             conf->error_log = &cf->cycle->new_log;
  2914.         }
  2915.     }

  2916.     if (conf->error_pages == NULL && prev->error_pages) {
  2917.         conf->error_pages = prev->error_pages;
  2918.     }

  2919.     ngx_conf_merge_str_value(conf->default_type,
  2920.                               prev->default_type, "text/plain");

  2921.     ngx_conf_merge_off_value(conf->client_max_body_size,
  2922.                               prev->client_max_body_size, 1 * 1024 * 1024);
  2923.     ngx_conf_merge_size_value(conf->client_body_buffer_size,
  2924.                               prev->client_body_buffer_size,
  2925.                               (size_t) 2 * ngx_pagesize);
  2926.     ngx_conf_merge_msec_value(conf->client_body_timeout,
  2927.                               prev->client_body_timeout, 60000);

  2928.     ngx_conf_merge_bitmask_value(conf->keepalive_disable,
  2929.                               prev->keepalive_disable,
  2930.                               (NGX_CONF_BITMASK_SET
  2931.                                |NGX_HTTP_KEEPALIVE_DISABLE_MSIE6));
  2932.     ngx_conf_merge_uint_value(conf->satisfy, prev->satisfy,
  2933.                               NGX_HTTP_SATISFY_ALL);
  2934.     ngx_conf_merge_uint_value(conf->if_modified_since, prev->if_modified_since,
  2935.                               NGX_HTTP_IMS_EXACT);
  2936.     ngx_conf_merge_uint_value(conf->max_ranges, prev->max_ranges,
  2937.                               NGX_MAX_INT32_VALUE);
  2938.     ngx_conf_merge_uint_value(conf->client_body_in_file_only,
  2939.                               prev->client_body_in_file_only,
  2940.                               NGX_HTTP_REQUEST_BODY_FILE_OFF);
  2941.     ngx_conf_merge_value(conf->client_body_in_single_buffer,
  2942.                               prev->client_body_in_single_buffer, 0);
  2943.     ngx_conf_merge_value(conf->internal, prev->internal, 0);
  2944.     ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0);
  2945.     ngx_conf_merge_size_value(conf->sendfile_max_chunk,
  2946.                               prev->sendfile_max_chunk, 0);
  2947. #if (NGX_HAVE_FILE_AIO)
  2948.     ngx_conf_merge_value(conf->aio, prev->aio, NGX_HTTP_AIO_OFF);
  2949. #endif
  2950.     ngx_conf_merge_size_value(conf->read_ahead, prev->read_ahead, 0);
  2951.     ngx_conf_merge_off_value(conf->directio, prev->directio,
  2952.                               NGX_OPEN_FILE_DIRECTIO_OFF);
  2953.     ngx_conf_merge_off_value(conf->directio_alignment, prev->directio_alignment,
  2954.                               512);
  2955.     ngx_conf_merge_value(conf->tcp_nopush, prev->tcp_nopush, 0);
  2956.     ngx_conf_merge_value(conf->tcp_nodelay, prev->tcp_nodelay, 1);

  2957.     ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 60000);
  2958.     ngx_conf_merge_size_value(conf->send_lowat, prev->send_lowat, 0);
  2959.     ngx_conf_merge_size_value(conf->postpone_output, prev->postpone_output,
  2960.                               1460);
  2961.     ngx_conf_merge_size_value(conf->limit_rate, prev->limit_rate, 0);
  2962.     ngx_conf_merge_size_value(conf->limit_rate_after, prev->limit_rate_after,
  2963.                               0);
  2964.     ngx_conf_merge_msec_value(conf->keepalive_timeout,
  2965.                               prev->keepalive_timeout, 75000);
  2966.     ngx_conf_merge_sec_value(conf->keepalive_header,
  2967.                               prev->keepalive_header, 0);
  2968.     ngx_conf_merge_uint_value(conf->keepalive_requests,
  2969.                               prev->keepalive_requests, 100);
  2970.     ngx_conf_merge_uint_value(conf->lingering_close,
  2971.                               prev->lingering_close, NGX_HTTP_LINGERING_ON);
  2972.     ngx_conf_merge_msec_value(conf->lingering_time,
  2973.                               prev->lingering_time, 30000);
  2974.     ngx_conf_merge_msec_value(conf->lingering_timeout,
  2975.                               prev->lingering_timeout, 5000);
  2976.     ngx_conf_merge_msec_value(conf->resolver_timeout,
  2977.                               prev->resolver_timeout, 30000);

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

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

  2980.             /*
  2981.              * create dummy resolver in http {} context
  2982.              * to inherit it in all servers
  2983.              */

  2984.             prev->resolver = ngx_resolver_create(cf, NULL, 0);
  2985.             if (prev->resolver == NULL) {
  2986.                 return NGX_CONF_ERROR;
  2987.             }
  2988.         }

  2989.         conf->resolver = prev->resolver;
  2990.     }

  2991.     if (ngx_conf_merge_path_value(cf, &conf->client_body_temp_path,
  2992.                               prev->client_body_temp_path,
  2993.                               &ngx_http_client_temp_path)
  2994.         != NGX_OK)
  2995.     {
  2996.         return NGX_CONF_ERROR;
  2997.     }

  2998.     ngx_conf_merge_value(conf->reset_timedout_connection,
  2999.                               prev->reset_timedout_connection, 0);
  3000.     ngx_conf_merge_value(conf->server_name_in_redirect,
  3001.                               prev->server_name_in_redirect, 0);
  3002.     ngx_conf_merge_value(conf->port_in_redirect, prev->port_in_redirect, 1);
  3003.     ngx_conf_merge_value(conf->msie_padding, prev->msie_padding, 1);
  3004.     ngx_conf_merge_value(conf->msie_refresh, prev->msie_refresh, 0);
  3005.     ngx_conf_merge_value(conf->log_not_found, prev->log_not_found, 1);
  3006.     ngx_conf_merge_value(conf->log_subrequest, prev->log_subrequest, 0);
  3007.     ngx_conf_merge_value(conf->recursive_error_pages,
  3008.                               prev->recursive_error_pages, 0);
  3009.     ngx_conf_merge_value(conf->server_tokens, prev->server_tokens, 1);
  3010.     ngx_conf_merge_value(conf->chunked_transfer_encoding,
  3011.                               prev->chunked_transfer_encoding, 1);
  3012.     ngx_conf_merge_value(conf->etag, prev->etag, 1);

  3013.     ngx_conf_merge_ptr_value(conf->open_file_cache,
  3014.                               prev->open_file_cache, NULL);

  3015.     ngx_conf_merge_sec_value(conf->open_file_cache_valid,
  3016.                               prev->open_file_cache_valid, 60);

  3017.     ngx_conf_merge_uint_value(conf->open_file_cache_min_uses,
  3018.                               prev->open_file_cache_min_uses, 1);

  3019.     ngx_conf_merge_sec_value(conf->open_file_cache_errors,
  3020.                               prev->open_file_cache_errors, 0);

  3021.     ngx_conf_merge_sec_value(conf->open_file_cache_events,
  3022.                               prev->open_file_cache_events, 0);
  3023. #if (NGX_HTTP_GZIP)

  3024.     ngx_conf_merge_value(conf->gzip_vary, prev->gzip_vary, 0);
  3025.     ngx_conf_merge_uint_value(conf->gzip_http_version, prev->gzip_http_version,
  3026.                               NGX_HTTP_VERSION_11);
  3027.     ngx_conf_merge_bitmask_value(conf->gzip_proxied, prev->gzip_proxied,
  3028.                               (NGX_CONF_BITMASK_SET|NGX_HTTP_GZIP_PROXIED_OFF));

  3029. #if (NGX_PCRE)
  3030.     ngx_conf_merge_ptr_value(conf->gzip_disable, prev->gzip_disable, NULL);
  3031. #endif

  3032.     if (conf->gzip_disable_msie6 == 3) {
  3033.         conf->gzip_disable_msie6 =
  3034.             (prev->gzip_disable_msie6 == 3) ? 0 : prev->gzip_disable_msie6;
  3035.     }

  3036. #if (NGX_HTTP_DEGRADATION)

  3037.     if (conf->gzip_disable_degradation == 3) {
  3038.         conf->gzip_disable_degradation =
  3039.             (prev->gzip_disable_degradation == 3) ?
  3040.                  0 : prev->gzip_disable_degradation;
  3041.     }

  3042. #endif
  3043. #endif

  3044. #if (NGX_HAVE_OPENAT)
  3045.     ngx_conf_merge_uint_value(conf->disable_symlinks, prev->disable_symlinks,
  3046.                               NGX_DISABLE_SYMLINKS_OFF);
  3047.     ngx_conf_merge_ptr_value(conf->disable_symlinks_from,
  3048.                              prev->disable_symlinks_from, NULL);
  3049. #endif

  3050.     return NGX_CONF_OK;
  3051. }


  3052. static char *
  3053. ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3054. {
  3055.     ngx_http_core_srv_conf_t *cscf = conf;

  3056.     ngx_str_t              *value, size;
  3057.     ngx_url_t               u;
  3058.     ngx_uint_t              n;
  3059.     ngx_http_listen_opt_t   lsopt;

  3060.     cscf->listen = 1;

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

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

  3063.     u.url = value[1];
  3064.     u.listen = 1;
  3065.     u.default_port = 80;

  3066.     if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
  3067.         if (u.err) {
  3068.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3069.                                "%s in \"%V\" of the \"listen\" directive",
  3070.                                u.err, &u.url);
  3071.         }

  3072.         return NGX_CONF_ERROR;
  3073.     }

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

  3075.     ngx_memcpy(&lsopt.u.sockaddr, u.sockaddr, u.socklen);

  3076.     lsopt.socklen = u.socklen;
  3077.     lsopt.backlog = NGX_LISTEN_BACKLOG;
  3078.     lsopt.rcvbuf = -1;
  3079.     lsopt.sndbuf = -1;
  3080. #if (NGX_HAVE_SETFIB)
  3081.     lsopt.setfib = -1;
  3082. #endif
  3083. #if (NGX_HAVE_TCP_FASTOPEN)
  3084.     lsopt.fastopen = -1;
  3085. #endif
  3086.     lsopt.wildcard = u.wildcard;
  3087. #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
  3088.     lsopt.ipv6only = 1;
  3089. #endif

  3090.     (void) ngx_sock_ntop(&lsopt.u.sockaddr, lsopt.socklen, lsopt.addr,
  3091.                          NGX_SOCKADDR_STRLEN, 1);

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

  3093.         if (ngx_strcmp(value[n].data, "default_server") == 0
  3094.             || ngx_strcmp(value[n].data, "default") == 0)
  3095.         {
  3096.             lsopt.default_server = 1;
  3097.             continue;
  3098.         }

  3099.         if (ngx_strcmp(value[n].data, "bind") == 0) {
  3100.             lsopt.set = 1;
  3101.             lsopt.bind = 1;
  3102.             continue;
  3103.         }

  3104. #if (NGX_HAVE_SETFIB)
  3105.         if (ngx_strncmp(value[n].data, "setfib=", 7) == 0) {
  3106.             lsopt.setfib = ngx_atoi(value[n].data + 7, value[n].len - 7);
  3107.             lsopt.set = 1;
  3108.             lsopt.bind = 1;

  3109.             if (lsopt.setfib == NGX_ERROR) {
  3110.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3111.                                    "invalid setfib \"%V\"", &value[n]);
  3112.                 return NGX_CONF_ERROR;
  3113.             }

  3114.             continue;
  3115.         }
  3116. #endif

  3117. #if (NGX_HAVE_TCP_FASTOPEN)
  3118.         if (ngx_strncmp(value[n].data, "fastopen=", 9) == 0) {
  3119.             lsopt.fastopen = ngx_atoi(value[n].data + 9, value[n].len - 9);
  3120.             lsopt.set = 1;
  3121.             lsopt.bind = 1;

  3122.             if (lsopt.fastopen == NGX_ERROR) {
  3123.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3124.                                    "invalid fastopen \"%V\"", &value[n]);
  3125.                 return NGX_CONF_ERROR;
  3126.             }

  3127.             continue;
  3128.         }
  3129. #endif

  3130.         if (ngx_strncmp(value[n].data, "backlog=", 8) == 0) {
  3131.             lsopt.backlog = ngx_atoi(value[n].data + 8, value[n].len - 8);
  3132.             lsopt.set = 1;
  3133.             lsopt.bind = 1;

  3134.             if (lsopt.backlog == NGX_ERROR || lsopt.backlog == 0) {
  3135.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3136.                                    "invalid backlog \"%V\"", &value[n]);
  3137.                 return NGX_CONF_ERROR;
  3138.             }

  3139.             continue;
  3140.         }

  3141.         if (ngx_strncmp(value[n].data, "rcvbuf=", 7) == 0) {
  3142.             size.len = value[n].len - 7;
  3143.             size.data = value[n].data + 7;

  3144.             lsopt.rcvbuf = ngx_parse_size(&size);
  3145.             lsopt.set = 1;
  3146.             lsopt.bind = 1;

  3147.             if (lsopt.rcvbuf == NGX_ERROR) {
  3148.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3149.                                    "invalid rcvbuf \"%V\"", &value[n]);
  3150.                 return NGX_CONF_ERROR;
  3151.             }

  3152.             continue;
  3153.         }

  3154.         if (ngx_strncmp(value[n].data, "sndbuf=", 7) == 0) {
  3155.             size.len = value[n].len - 7;
  3156.             size.data = value[n].data + 7;

  3157.             lsopt.sndbuf = ngx_parse_size(&size);
  3158.             lsopt.set = 1;
  3159.             lsopt.bind = 1;

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

  3165.             continue;
  3166.         }

  3167.         if (ngx_strncmp(value[n].data, "accept_filter=", 14) == 0) {
  3168. #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
  3169.             lsopt.accept_filter = (char *) &value[n].data[14];
  3170.             lsopt.set = 1;
  3171.             lsopt.bind = 1;
  3172. #else
  3173.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3174.                                "accept filters \"%V\" are not supported "
  3175.                                "on this platform, ignored",
  3176.                                &value[n]);
  3177. #endif
  3178.             continue;
  3179.         }

  3180.         if (ngx_strcmp(value[n].data, "deferred") == 0) {
  3181. #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
  3182.             lsopt.deferred_accept = 1;
  3183.             lsopt.set = 1;
  3184.             lsopt.bind = 1;
  3185. #else
  3186.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3187.                                "the deferred accept is not supported "
  3188.                                "on this platform, ignored");
  3189. #endif
  3190.             continue;
  3191.         }

  3192.         if (ngx_strncmp(value[n].data, "ipv6only=o", 10) == 0) {
  3193. #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
  3194.             struct sockaddr  *sa;

  3195.             sa = &lsopt.u.sockaddr;

  3196.             if (sa->sa_family == AF_INET6) {

  3197.                 if (ngx_strcmp(&value[n].data[10], "n") == 0) {
  3198.                     lsopt.ipv6only = 1;

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

  3201.                 } else {
  3202.                     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3203.                                        "invalid ipv6only flags \"%s\"",
  3204.                                        &value[n].data[9]);
  3205.                     return NGX_CONF_ERROR;
  3206.                 }

  3207.                 lsopt.set = 1;
  3208.                 lsopt.bind = 1;

  3209.             } else {
  3210.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3211.                                    "ipv6only is not supported "
  3212.                                    "on addr \"%s\", ignored", lsopt.addr);
  3213.             }

  3214.             continue;
  3215. #else
  3216.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3217.                                "ipv6only is not supported "
  3218.                                "on this platform");
  3219.             return NGX_CONF_ERROR;
  3220. #endif
  3221.         }

  3222.         if (ngx_strcmp(value[n].data, "ssl") == 0) {
  3223. #if (NGX_HTTP_SSL)
  3224.             lsopt.ssl = 1;
  3225.             continue;
  3226. #else
  3227.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3228.                                "the \"ssl\" parameter requires "
  3229.                                "ngx_http_ssl_module");
  3230.             return NGX_CONF_ERROR;
  3231. #endif
  3232.         }

  3233.         if (ngx_strcmp(value[n].data, "spdy") == 0) {
  3234. #if (NGX_HTTP_SPDY)
  3235.             lsopt.spdy = 1;
  3236.             continue;
  3237. #else
  3238.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3239.                                "the \"spdy\" parameter requires "
  3240.                                "ngx_http_spdy_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 (ngx_http_add_listen(cf, cscf, &lsopt) == NGX_OK) {
  3319.         return NGX_CONF_OK;
  3320.     }

  3321.     return NGX_CONF_ERROR;
  3322. }


  3323. static char *
  3324. ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3325. {
  3326.     ngx_http_core_srv_conf_t *cscf = conf;

  3327.     u_char                   ch;
  3328.     ngx_str_t               *value;
  3329.     ngx_uint_t               i;
  3330.     ngx_http_server_name_t  *sn;

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

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

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

  3334.         if ((ch == '*' && (value[i].len < 3 || value[i].data[1] != '.'))
  3335.             || (ch == '.' && value[i].len < 2))
  3336.         {
  3337.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3338.                                "server name \"%V\" is invalid", &value[i]);
  3339.             return NGX_CONF_ERROR;
  3340.         }

  3341.         if (ngx_strchr(value[i].data, '/')) {
  3342.             ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
  3343.                                "server name \"%V\" has suspicious symbols",
  3344.                                &value[i]);
  3345.         }

  3346.         sn = ngx_array_push(&cscf->server_names);
  3347.         if (sn == NULL) {
  3348.             return NGX_CONF_ERROR;
  3349.         }

  3350. #if (NGX_PCRE)
  3351.         sn->regex = NULL;
  3352. #endif
  3353.         sn->server = cscf;

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

  3356.         } else {
  3357.             sn->name = value[i];
  3358.         }

  3359.         if (value[i].data[0] != '~') {
  3360.             ngx_strlow(sn->name.data, sn->name.data, sn->name.len);
  3361.             continue;
  3362.         }

  3363. #if (NGX_PCRE)
  3364.         {
  3365.         u_char               *p;
  3366.         ngx_regex_compile_t   rc;
  3367.         u_char                errstr[NGX_MAX_CONF_ERRSTR];

  3368.         if (value[i].len == 1) {
  3369.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3370.                                "empty regex in server name \"%V\"", &value[i]);
  3371.             return NGX_CONF_ERROR;
  3372.         }

  3373.         value[i].len--;
  3374.         value[i].data++;

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

  3376.         rc.pattern = value[i];
  3377.         rc.err.len = NGX_MAX_CONF_ERRSTR;
  3378.         rc.err.data = errstr;

  3379.         for (p = value[i].data; p < value[i].data + value[i].len; p++) {
  3380.             if (*p >= 'A' && *p <= 'Z') {
  3381.                 rc.options = NGX_REGEX_CASELESS;
  3382.                 break;
  3383.             }
  3384.         }

  3385.         sn->regex = ngx_http_regex_compile(cf, &rc);
  3386.         if (sn->regex == NULL) {
  3387.             return NGX_CONF_ERROR;
  3388.         }

  3389.         sn->name = value[i];
  3390.         cscf->captures = (rc.captures > 0);
  3391.         }
  3392. #else
  3393.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3394.                            "using regex \"%V\" "
  3395.                            "requires PCRE library", &value[i]);

  3396.         return NGX_CONF_ERROR;
  3397. #endif
  3398.     }

  3399.     return NGX_CONF_OK;
  3400. }


  3401. static char *
  3402. ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3403. {
  3404.     ngx_http_core_loc_conf_t *clcf = conf;

  3405.     ngx_str_t                  *value;
  3406.     ngx_int_t                   alias;
  3407.     ngx_uint_t                  n;
  3408.     ngx_http_script_compile_t   sc;

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

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

  3411.         if ((clcf->alias != 0) == alias) {
  3412.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3413.                                "\"%V\" directive is duplicate",
  3414.                                &cmd->name);
  3415.         } else {
  3416.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3417.                                "\"%V\" directive is duplicate, "
  3418.                                "\"%s\" directive was specified earlier",
  3419.                                &cmd->name, clcf->alias ? "alias" : "root");
  3420.         }

  3421.         return NGX_CONF_ERROR;
  3422.     }

  3423.     if (clcf->named && alias) {
  3424.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3425.                            "the \"alias\" directive cannot be used "
  3426.                            "inside the named location");

  3427.         return NGX_CONF_ERROR;
  3428.     }

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

  3430.     if (ngx_strstr(value[1].data, "$document_root")
  3431.         || ngx_strstr(value[1].data, "${document_root}"))
  3432.     {
  3433.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3434.                            "the $document_root variable cannot be used "
  3435.                            "in the \"%V\" directive",
  3436.                            &cmd->name);

  3437.         return NGX_CONF_ERROR;
  3438.     }

  3439.     if (ngx_strstr(value[1].data, "$realpath_root")
  3440.         || ngx_strstr(value[1].data, "${realpath_root}"))
  3441.     {
  3442.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3443.                            "the $realpath_root variable cannot be used "
  3444.                            "in the \"%V\" directive",
  3445.                            &cmd->name);

  3446.         return NGX_CONF_ERROR;
  3447.     }

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

  3450.     if (!alias && clcf->root.data[clcf->root.len - 1] == '/') {
  3451.         clcf->root.len--;
  3452.     }

  3453.     if (clcf->root.data[0] != '$') {
  3454.         if (ngx_conf_full_name(cf->cycle, &clcf->root, 0) != NGX_OK) {
  3455.             return NGX_CONF_ERROR;
  3456.         }
  3457.     }

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

  3459.     ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
  3460.     sc.variables = n;

  3461. #if (NGX_PCRE)
  3462.     if (alias && clcf->regex) {
  3463.         clcf->alias = NGX_MAX_SIZE_T_VALUE;
  3464.         n = 1;
  3465.     }
  3466. #endif

  3467.     if (n) {
  3468.         sc.cf = cf;
  3469.         sc.source = &clcf->root;
  3470.         sc.lengths = &clcf->root_lengths;
  3471.         sc.values = &clcf->root_values;
  3472.         sc.complete_lengths = 1;
  3473.         sc.complete_values = 1;

  3474.         if (ngx_http_script_compile(&sc) != NGX_OK) {
  3475.             return NGX_CONF_ERROR;
  3476.         }
  3477.     }

  3478.     return NGX_CONF_OK;
  3479. }


  3480. static ngx_http_method_name_t  ngx_methods_names[] = {
  3481.    { (u_char *) "GET",       (uint32_t) ~NGX_HTTP_GET },
  3482.    { (u_char *) "HEAD",      (uint32_t) ~NGX_HTTP_HEAD },
  3483.    { (u_char *) "POST",      (uint32_t) ~NGX_HTTP_POST },
  3484.    { (u_char *) "PUT",       (uint32_t) ~NGX_HTTP_PUT },
  3485.    { (u_char *) "DELETE",    (uint32_t) ~NGX_HTTP_DELETE },
  3486.    { (u_char *) "MKCOL",     (uint32_t) ~NGX_HTTP_MKCOL },
  3487.    { (u_char *) "COPY",      (uint32_t) ~NGX_HTTP_COPY },
  3488.    { (u_char *) "MOVE",      (uint32_t) ~NGX_HTTP_MOVE },
  3489.    { (u_char *) "OPTIONS",   (uint32_t) ~NGX_HTTP_OPTIONS },
  3490.    { (u_char *) "PROPFIND",  (uint32_t) ~NGX_HTTP_PROPFIND },
  3491.    { (u_char *) "PROPPATCH", (uint32_t) ~NGX_HTTP_PROPPATCH },
  3492.    { (u_char *) "LOCK",      (uint32_t) ~NGX_HTTP_LOCK },
  3493.    { (u_char *) "UNLOCK",    (uint32_t) ~NGX_HTTP_UNLOCK },
  3494.    { (u_char *) "PATCH",     (uint32_t) ~NGX_HTTP_PATCH },
  3495.    { NULL, 0 }
  3496. };


  3497. static char *
  3498. ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3499. {
  3500.     ngx_http_core_loc_conf_t *pclcf = conf;

  3501.     char                      *rv;
  3502.     void                      *mconf;
  3503.     ngx_str_t                 *value;
  3504.     ngx_uint_t                 i;
  3505.     ngx_conf_t                 save;
  3506.     ngx_http_module_t         *module;
  3507.     ngx_http_conf_ctx_t       *ctx, *pctx;
  3508.     ngx_http_method_name_t    *name;
  3509.     ngx_http_core_loc_conf_t  *clcf;

  3510.     if (pclcf->limit_except) {
  3511.         return "duplicate";
  3512.     }

  3513.     pclcf->limit_except = 0xffffffff;

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

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

  3517.             if (ngx_strcasecmp(value[i].data, name->name) == 0) {
  3518.                 pclcf->limit_except &= name->method;
  3519.                 goto next;
  3520.             }
  3521.         }

  3522.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3523.                            "invalid method \"%V\"", &value[i]);
  3524.         return NGX_CONF_ERROR;

  3525.     next:
  3526.         continue;
  3527.     }

  3528.     if (!(pclcf->limit_except & NGX_HTTP_GET)) {
  3529.         pclcf->limit_except &= (uint32_t) ~NGX_HTTP_HEAD;
  3530.     }

  3531.     ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
  3532.     if (ctx == NULL) {
  3533.         return NGX_CONF_ERROR;
  3534.     }

  3535.     pctx = cf->ctx;
  3536.     ctx->main_conf = pctx->main_conf;
  3537.     ctx->srv_conf = pctx->srv_conf;

  3538.     ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
  3539.     if (ctx->loc_conf == NULL) {
  3540.         return NGX_CONF_ERROR;
  3541.     }

  3542.     for (i = 0; ngx_modules[i]; i++) {
  3543.         if (ngx_modules[i]->type != NGX_HTTP_MODULE) {
  3544.             continue;
  3545.         }

  3546.         module = ngx_modules[i]->ctx;

  3547.         if (module->create_loc_conf) {

  3548.             mconf = module->create_loc_conf(cf);
  3549.             if (mconf == NULL) {
  3550.                  return NGX_CONF_ERROR;
  3551.             }

  3552.             ctx->loc_conf[ngx_modules[i]->ctx_index] = mconf;
  3553.         }
  3554.     }


  3555.     clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
  3556.     pclcf->limit_except_loc_conf = ctx->loc_conf;
  3557.     clcf->loc_conf = ctx->loc_conf;
  3558.     clcf->name = pclcf->name;
  3559.     clcf->noname = 1;
  3560.     clcf->lmt_excpt = 1;

  3561.     if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) {
  3562.         return NGX_CONF_ERROR;
  3563.     }

  3564.     save = *cf;
  3565.     cf->ctx = ctx;
  3566.     cf->cmd_type = NGX_HTTP_LMT_CONF;

  3567.     rv = ngx_conf_parse(cf, NULL);

  3568.     *cf = save;

  3569.     return rv;
  3570. }


  3571. static char *
  3572. ngx_http_core_directio(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3573. {
  3574.     ngx_http_core_loc_conf_t *clcf = conf;

  3575.     ngx_str_t  *value;

  3576.     if (clcf->directio != NGX_CONF_UNSET) {
  3577.         return "is duplicate";
  3578.     }

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

  3580.     if (ngx_strcmp(value[1].data, "off") == 0) {
  3581.         clcf->directio = NGX_OPEN_FILE_DIRECTIO_OFF;
  3582.         return NGX_CONF_OK;
  3583.     }

  3584.     clcf->directio = ngx_parse_offset(&value[1]);
  3585.     if (clcf->directio == (off_t) NGX_ERROR) {
  3586.         return "invalid value";
  3587.     }

  3588.     return NGX_CONF_OK;
  3589. }


  3590. static char *
  3591. ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3592. {
  3593.     ngx_http_core_loc_conf_t *clcf = conf;

  3594.     u_char                            *p;
  3595.     ngx_int_t                          overwrite;
  3596.     ngx_str_t                         *value, uri, args;
  3597.     ngx_uint_t                         i, n;
  3598.     ngx_http_err_page_t               *err;
  3599.     ngx_http_complex_value_t           cv;
  3600.     ngx_http_compile_complex_value_t   ccv;

  3601.     if (clcf->error_pages == NULL) {
  3602.         clcf->error_pages = ngx_array_create(cf->pool, 4,
  3603.                                              sizeof(ngx_http_err_page_t));
  3604.         if (clcf->error_pages == NULL) {
  3605.             return NGX_CONF_ERROR;
  3606.         }
  3607.     }

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

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

  3610.     if (value[i].data[0] == '=') {
  3611.         if (i == 1) {
  3612.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3613.                                "invalid value \"%V\"", &value[i]);
  3614.             return NGX_CONF_ERROR;
  3615.         }

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

  3618.             if (overwrite == NGX_ERROR) {
  3619.                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3620.                                    "invalid value \"%V\"", &value[i]);
  3621.                 return NGX_CONF_ERROR;
  3622.             }

  3623.         } else {
  3624.             overwrite = 0;
  3625.         }

  3626.         n = 2;

  3627.     } else {
  3628.         overwrite = -1;
  3629.         n = 1;
  3630.     }

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

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

  3633.     ccv.cf = cf;
  3634.     ccv.value = &uri;
  3635.     ccv.complex_value = &cv;

  3636.     if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
  3637.         return NGX_CONF_ERROR;
  3638.     }

  3639.     ngx_str_null(&args);

  3640.     if (cv.lengths == NULL && uri.len && uri.data[0] == '/') {
  3641.         p = (u_char *) ngx_strchr(uri.data, '?');

  3642.         if (p) {
  3643.             cv.value.len = p - uri.data;
  3644.             cv.value.data = uri.data;
  3645.             p++;
  3646.             args.len = (uri.data + uri.len) - p;
  3647.             args.data = p;
  3648.         }
  3649.     }

  3650.     for (i = 1; i < cf->args->nelts - n; i++) {
  3651.         err = ngx_array_push(clcf->error_pages);
  3652.         if (err == NULL) {
  3653.             return NGX_CONF_ERROR;
  3654.         }

  3655.         err->status = ngx_atoi(value[i].data, value[i].len);

  3656.         if (err->status == NGX_ERROR || err->status == 499) {
  3657.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3658.                                "invalid value \"%V\"", &value[i]);
  3659.             return NGX_CONF_ERROR;
  3660.         }

  3661.         if (err->status < 300 || err->status > 599) {
  3662.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3663.                                "value \"%V\" must be between 300 and 599",
  3664.                                &value[i]);
  3665.             return NGX_CONF_ERROR;
  3666.         }

  3667.         err->overwrite = overwrite;

  3668.         if (overwrite == -1) {
  3669.             switch (err->status) {
  3670.                 case NGX_HTTP_TO_HTTPS:
  3671.                 case NGX_HTTPS_CERT_ERROR:
  3672.                 case NGX_HTTPS_NO_CERT:
  3673.                     err->overwrite = NGX_HTTP_BAD_REQUEST;
  3674.                 default:
  3675.                     break;
  3676.             }
  3677.         }

  3678.         err->value = cv;
  3679.         err->args = args;
  3680.     }

  3681.     return NGX_CONF_OK;
  3682. }


  3683. static char *
  3684. ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3685. {
  3686.     ngx_http_core_loc_conf_t *clcf = conf;

  3687.     ngx_str_t                  *value;
  3688.     ngx_int_t                   code;
  3689.     ngx_uint_t                  i, n;
  3690.     ngx_http_try_file_t        *tf;
  3691.     ngx_http_script_compile_t   sc;
  3692.     ngx_http_core_main_conf_t  *cmcf;

  3693.     if (clcf->try_files) {
  3694.         return "is duplicate";
  3695.     }

  3696.     cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);

  3697.     cmcf->try_files = 1;

  3698.     tf = ngx_pcalloc(cf->pool, cf->args->nelts * sizeof(ngx_http_try_file_t));
  3699.     if (tf == NULL) {
  3700.         return NGX_CONF_ERROR;
  3701.     }

  3702.     clcf->try_files = tf;

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

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

  3705.         tf[i].name = value[i + 1];

  3706.         if (tf[i].name.len > 0
  3707.             && tf[i].name.data[tf[i].name.len - 1] == '/'
  3708.             && i + 2 < cf->args->nelts)
  3709.         {
  3710.             tf[i].test_dir = 1;
  3711.             tf[i].name.len--;
  3712.             tf[i].name.data[tf[i].name.len] = '\0';
  3713.         }

  3714.         n = ngx_http_script_variables_count(&tf[i].name);

  3715.         if (n) {
  3716.             ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));

  3717.             sc.cf = cf;
  3718.             sc.source = &tf[i].name;
  3719.             sc.lengths = &tf[i].lengths;
  3720.             sc.values = &tf[i].values;
  3721.             sc.variables = n;
  3722.             sc.complete_lengths = 1;
  3723.             sc.complete_values = 1;

  3724.             if (ngx_http_script_compile(&sc) != NGX_OK) {
  3725.                 return NGX_CONF_ERROR;
  3726.             }

  3727.         } else {
  3728.             /* add trailing '\0' to length */
  3729.             tf[i].name.len++;
  3730.         }
  3731.     }

  3732.     if (tf[i - 1].name.data[0] == '=') {

  3733.         code = ngx_atoi(tf[i - 1].name.data + 1, tf[i - 1].name.len - 2);

  3734.         if (code == NGX_ERROR || code > 999) {
  3735.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3736.                                "invalid code \"%*s\"",
  3737.                                tf[i - 1].name.len - 1, tf[i - 1].name.data);
  3738.             return NGX_CONF_ERROR;
  3739.         }

  3740.         tf[i].code = code;
  3741.     }

  3742.     return NGX_CONF_OK;
  3743. }


  3744. static char *
  3745. ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3746. {
  3747.     ngx_http_core_loc_conf_t *clcf = conf;

  3748.     time_t       inactive;
  3749.     ngx_str_t   *value, s;
  3750.     ngx_int_t    max;
  3751.     ngx_uint_t   i;

  3752.     if (clcf->open_file_cache != NGX_CONF_UNSET_PTR) {
  3753.         return "is duplicate";
  3754.     }

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

  3756.     max = 0;
  3757.     inactive = 60;

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

  3759.         if (ngx_strncmp(value[i].data, "max=", 4) == 0) {

  3760.             max = ngx_atoi(value[i].data + 4, value[i].len - 4);
  3761.             if (max <= 0) {
  3762.                 goto failed;
  3763.             }

  3764.             continue;
  3765.         }

  3766.         if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) {

  3767.             s.len = value[i].len - 9;
  3768.             s.data = value[i].data + 9;

  3769.             inactive = ngx_parse_time(&s, 1);
  3770.             if (inactive == (time_t) NGX_ERROR) {
  3771.                 goto failed;
  3772.             }

  3773.             continue;
  3774.         }

  3775.         if (ngx_strcmp(value[i].data, "off") == 0) {

  3776.             clcf->open_file_cache = NULL;

  3777.             continue;
  3778.         }

  3779.     failed:

  3780.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3781.                            "invalid \"open_file_cache\" parameter \"%V\"",
  3782.                            &value[i]);
  3783.         return NGX_CONF_ERROR;
  3784.     }

  3785.     if (clcf->open_file_cache == NULL) {
  3786.         return NGX_CONF_OK;
  3787.     }

  3788.     if (max == 0) {
  3789.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3790.                         "\"open_file_cache\" must have the \"max\" parameter");
  3791.         return NGX_CONF_ERROR;
  3792.     }

  3793.     clcf->open_file_cache = ngx_open_file_cache_init(cf->pool, max, inactive);
  3794.     if (clcf->open_file_cache) {
  3795.         return NGX_CONF_OK;
  3796.     }

  3797.     return NGX_CONF_ERROR;
  3798. }


  3799. static char *
  3800. ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3801. {
  3802.     ngx_http_core_loc_conf_t *clcf = conf;

  3803.     return ngx_log_set_log(cf, &clcf->error_log);
  3804. }


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

  3809.     ngx_str_t  *value;

  3810.     if (clcf->keepalive_timeout != NGX_CONF_UNSET_MSEC) {
  3811.         return "is duplicate";
  3812.     }

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

  3814.     clcf->keepalive_timeout = ngx_parse_time(&value[1], 0);

  3815.     if (clcf->keepalive_timeout == (ngx_msec_t) NGX_ERROR) {
  3816.         return "invalid value";
  3817.     }

  3818.     if (cf->args->nelts == 2) {
  3819.         return NGX_CONF_OK;
  3820.     }

  3821.     clcf->keepalive_header = ngx_parse_time(&value[2], 1);

  3822.     if (clcf->keepalive_header == (time_t) NGX_ERROR) {
  3823.         return "invalid value";
  3824.     }

  3825.     return NGX_CONF_OK;
  3826. }


  3827. static char *
  3828. ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3829. {
  3830.     ngx_http_core_loc_conf_t *clcf = conf;

  3831.     if (clcf->internal != NGX_CONF_UNSET) {
  3832.         return "is duplicate";
  3833.     }

  3834.     clcf->internal = 1;

  3835.     return NGX_CONF_OK;
  3836. }


  3837. static char *
  3838. ngx_http_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3839. {
  3840.     ngx_http_core_loc_conf_t  *clcf = conf;

  3841.     ngx_str_t  *value;

  3842.     if (clcf->resolver) {
  3843.         return "is duplicate";
  3844.     }

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

  3846.     clcf->resolver = ngx_resolver_create(cf, &value[1], cf->args->nelts - 1);
  3847.     if (clcf->resolver == NULL) {
  3848.         return NGX_CONF_ERROR;
  3849.     }

  3850.     return NGX_CONF_OK;
  3851. }


  3852. #if (NGX_HTTP_GZIP)

  3853. static char *
  3854. ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3855. {
  3856.     ngx_http_core_loc_conf_t  *clcf = conf;

  3857. #if (NGX_PCRE)

  3858.     ngx_str_t            *value;
  3859.     ngx_uint_t            i;
  3860.     ngx_regex_elt_t      *re;
  3861.     ngx_regex_compile_t   rc;
  3862.     u_char                errstr[NGX_MAX_CONF_ERRSTR];

  3863.     if (clcf->gzip_disable == NGX_CONF_UNSET_PTR) {
  3864.         clcf->gzip_disable = ngx_array_create(cf->pool, 2,
  3865.                                               sizeof(ngx_regex_elt_t));
  3866.         if (clcf->gzip_disable == NULL) {
  3867.             return NGX_CONF_ERROR;
  3868.         }
  3869.     }

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

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

  3872.     rc.pool = cf->pool;
  3873.     rc.err.len = NGX_MAX_CONF_ERRSTR;
  3874.     rc.err.data = errstr;

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

  3876.         if (ngx_strcmp(value[i].data, "msie6") == 0) {
  3877.             clcf->gzip_disable_msie6 = 1;
  3878.             continue;
  3879.         }

  3880. #if (NGX_HTTP_DEGRADATION)

  3881.         if (ngx_strcmp(value[i].data, "degradation") == 0) {
  3882.             clcf->gzip_disable_degradation = 1;
  3883.             continue;
  3884.         }

  3885. #endif

  3886.         re = ngx_array_push(clcf->gzip_disable);
  3887.         if (re == NULL) {
  3888.             return NGX_CONF_ERROR;
  3889.         }

  3890.         rc.pattern = value[i];
  3891.         rc.options = NGX_REGEX_CASELESS;

  3892.         if (ngx_regex_compile(&rc) != NGX_OK) {
  3893.             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc.err);
  3894.             return NGX_CONF_ERROR;
  3895.         }

  3896.         re->regex = rc.regex;
  3897.         re->name = value[i].data;
  3898.     }

  3899.     return NGX_CONF_OK;

  3900. #else
  3901.     ngx_str_t   *value;
  3902.     ngx_uint_t   i;

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

  3904.     for (i = 1; i < cf->args->nelts; i++) {
  3905.         if (ngx_strcmp(value[i].data, "msie6") == 0) {
  3906.             clcf->gzip_disable_msie6 = 1;
  3907.             continue;
  3908.         }

  3909. #if (NGX_HTTP_DEGRADATION)

  3910.         if (ngx_strcmp(value[i].data, "degradation") == 0) {
  3911.             clcf->gzip_disable_degradation = 1;
  3912.             continue;
  3913.         }

  3914. #endif

  3915.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3916.                            "without PCRE library \"gzip_disable\" supports "
  3917.                            "builtin \"msie6\" and \"degradation\" mask only");

  3918.         return NGX_CONF_ERROR;
  3919.     }

  3920.     return NGX_CONF_OK;

  3921. #endif
  3922. }

  3923. #endif


  3924. #if (NGX_HAVE_OPENAT)

  3925. static char *
  3926. ngx_http_disable_symlinks(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  3927. {
  3928.     ngx_http_core_loc_conf_t *clcf = conf;

  3929.     ngx_str_t                         *value;
  3930.     ngx_uint_t                         i;
  3931.     ngx_http_compile_complex_value_t   ccv;

  3932.     if (clcf->disable_symlinks != NGX_CONF_UNSET_UINT) {
  3933.         return "is duplicate";
  3934.     }

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

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

  3937.         if (ngx_strcmp(value[i].data, "off") == 0) {
  3938.             clcf->disable_symlinks = NGX_DISABLE_SYMLINKS_OFF;
  3939.             continue;
  3940.         }

  3941.         if (ngx_strcmp(value[i].data, "if_not_owner") == 0) {
  3942.             clcf->disable_symlinks = NGX_DISABLE_SYMLINKS_NOTOWNER;
  3943.             continue;
  3944.         }

  3945.         if (ngx_strcmp(value[i].data, "on") == 0) {
  3946.             clcf->disable_symlinks = NGX_DISABLE_SYMLINKS_ON;
  3947.             continue;
  3948.         }

  3949.         if (ngx_strncmp(value[i].data, "from=", 5) == 0) {
  3950.             value[i].len -= 5;
  3951.             value[i].data += 5;

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

  3953.             ccv.cf = cf;
  3954.             ccv.value = &value[i];
  3955.             ccv.complex_value = ngx_palloc(cf->pool,
  3956.                                            sizeof(ngx_http_complex_value_t));
  3957.             if (ccv.complex_value == NULL) {
  3958.                 return NGX_CONF_ERROR;
  3959.             }

  3960.             if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
  3961.                 return NGX_CONF_ERROR;
  3962.             }

  3963.             clcf->disable_symlinks_from = ccv.complex_value;

  3964.             continue;
  3965.         }

  3966.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3967.                            "invalid parameter \"%V\"", &value[i]);
  3968.         return NGX_CONF_ERROR;
  3969.     }

  3970.     if (clcf->disable_symlinks == NGX_CONF_UNSET_UINT) {
  3971.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3972.                            "\"%V\" must have \"off\", \"on\" "
  3973.                            "or \"if_not_owner\" parameter",
  3974.                            &cmd->name);
  3975.         return NGX_CONF_ERROR;
  3976.     }

  3977.     if (cf->args->nelts == 2) {
  3978.         clcf->disable_symlinks_from = NULL;
  3979.         return NGX_CONF_OK;
  3980.     }

  3981.     if (clcf->disable_symlinks_from == NGX_CONF_UNSET_PTR) {
  3982.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3983.                            "duplicate parameters \"%V %V\"",
  3984.                            &value[1], &value[2]);
  3985.         return NGX_CONF_ERROR;
  3986.     }

  3987.     if (clcf->disable_symlinks == NGX_DISABLE_SYMLINKS_OFF) {
  3988.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  3989.                            "\"from=\" cannot be used with \"off\" parameter");
  3990.         return NGX_CONF_ERROR;
  3991.     }

  3992.     return NGX_CONF_OK;
  3993. }

  3994. #endif


  3995. static char *
  3996. ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data)
  3997. {
  3998. #if (NGX_FREEBSD)
  3999.     ssize_t *np = data;

  4000.     if ((u_long) *np >= ngx_freebsd_net_inet_tcp_sendspace) {
  4001.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  4002.                            "\"send_lowat\" must be less than %d "
  4003.                            "(sysctl net.inet.tcp.sendspace)",
  4004.                            ngx_freebsd_net_inet_tcp_sendspace);

  4005.         return NGX_CONF_ERROR;
  4006.     }

  4007. #elif !(NGX_HAVE_SO_SNDLOWAT)
  4008.     ssize_t *np = data;

  4009.     ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
  4010.                        "\"send_lowat\" is not supported, ignored");

  4011.     *np = 0;

  4012. #endif

  4013.     return NGX_CONF_OK;
  4014. }


  4015. static char *
  4016. ngx_http_core_pool_size(ngx_conf_t *cf, void *post, void *data)
  4017. {
  4018.     size_t *sp = data;

  4019.     if (*sp < NGX_MIN_POOL_SIZE) {
  4020.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  4021.                            "the pool size must be no less than %uz",
  4022.                            NGX_MIN_POOL_SIZE);
  4023.         return NGX_CONF_ERROR;
  4024.     }

  4025.     if (*sp % NGX_POOL_ALIGNMENT) {
  4026.         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  4027.                            "the pool size must be a multiple of %uz",
  4028.                            NGX_POOL_ALIGNMENT);
  4029.         return NGX_CONF_ERROR;
  4030.     }

  4031.     return NGX_CONF_OK;
  4032. }