blob: c35ccacdabca6ff80f7fca4b7247ea57be540f85 [file] [log] [blame]
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001
Igor Sysoevd90282d2004-09-28 08:34:51 +00002/*
Igor Sysoevff8da912004-09-29 16:00:49 +00003 * Copyright (C) Igor Sysoev
Igor Sysoevd90282d2004-09-28 08:34:51 +00004 */
5
6
Igor Sysoev4e9393a2003-01-09 05:36:00 +00007#include <ngx_config.h>
Igor Sysoev4e9393a2003-01-09 05:36:00 +00008#include <ngx_core.h>
Igor Sysoevb3e73d82003-10-10 15:10:50 +00009#include <ngx_event.h>
Igor Sysoev6253ca12003-05-27 12:18:54 +000010#include <ngx_http.h>
Igor Sysoeva9830112003-05-19 16:39:14 +000011#include <nginx.h>
Igor Sysoev4e9393a2003-01-09 05:36:00 +000012
Igor Sysoev1b735832004-11-11 14:07:14 +000013
Igor Sysoev94e32ce2006-04-07 14:08:04 +000014typedef struct {
15 char *name;
16 uint32_t method;
17} ngx_http_method_name_t;
18
19
Igor Sysoev74a5ddb2004-07-18 19:11:20 +000020#define NGX_HTTP_LOCATION_EXACT 1
21#define NGX_HTTP_LOCATION_AUTO_REDIRECT 2
Igor Sysoevd43bee82004-11-20 19:52:20 +000022#define NGX_HTTP_LOCATION_NOREGEX 3
23#define NGX_HTTP_LOCATION_REGEX 4
Igor Sysoev74a5ddb2004-07-18 19:11:20 +000024
Igor Sysoev6253ca12003-05-27 12:18:54 +000025
Igor Sysoev64304df2007-01-24 09:14:08 +000026#define NGX_HTTP_REQUEST_BODY_FILE_OFF 0
27#define NGX_HTTP_REQUEST_BODY_FILE_ON 1
Igor Sysoevcd5b99a2007-01-25 08:45:04 +000028#define NGX_HTTP_REQUEST_BODY_FILE_CLEAN 2
Igor Sysoev64304df2007-01-24 09:14:08 +000029
30
Igor Sysoev805d9db2005-02-03 19:33:37 +000031static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r,
Igor Sysoevaa828612005-02-09 14:31:07 +000032 ngx_array_t *locations, size_t len);
Igor Sysoev4e9393a2003-01-09 05:36:00 +000033
Igor Sysoev899b44e2005-05-12 14:58:06 +000034static ngx_int_t ngx_http_core_preconfiguration(ngx_conf_t *cf);
Igor Sysoev890fc962003-07-20 21:15:59 +000035static void *ngx_http_core_create_main_conf(ngx_conf_t *cf);
36static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf);
37static void *ngx_http_core_create_srv_conf(ngx_conf_t *cf);
38static char *ngx_http_core_merge_srv_conf(ngx_conf_t *cf,
Igor Sysoevaa828612005-02-09 14:31:07 +000039 void *parent, void *child);
Igor Sysoev890fc962003-07-20 21:15:59 +000040static void *ngx_http_core_create_loc_conf(ngx_conf_t *cf);
41static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
Igor Sysoevaa828612005-02-09 14:31:07 +000042 void *parent, void *child);
Igor Sysoevdc479b42003-03-20 16:09:44 +000043
Igor Sysoev805d9db2005-02-03 19:33:37 +000044static char *ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd,
Igor Sysoevaa828612005-02-09 14:31:07 +000045 void *dummy);
Igor Sysoev805d9db2005-02-03 19:33:37 +000046static char *ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd,
Igor Sysoevaa828612005-02-09 14:31:07 +000047 void *dummy);
Igor Sysoev4d656dc2005-03-22 16:02:46 +000048static int ngx_libc_cdecl ngx_http_core_cmp_locations(const void *first,
49 const void *second);
Igor Sysoev805d9db2005-02-03 19:33:37 +000050
51static char *ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd,
Igor Sysoevaa828612005-02-09 14:31:07 +000052 void *conf);
Igor Sysoev805d9db2005-02-03 19:33:37 +000053static char *ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy,
Igor Sysoevaa828612005-02-09 14:31:07 +000054 void *conf);
Igor Sysoev4e9393a2003-01-09 05:36:00 +000055
Igor Sysoev805d9db2005-02-03 19:33:37 +000056static char *ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd,
Igor Sysoevaa828612005-02-09 14:31:07 +000057 void *conf);
Igor Sysoev805d9db2005-02-03 19:33:37 +000058static char *ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd,
Igor Sysoevaa828612005-02-09 14:31:07 +000059 void *conf);
Igor Sysoev805d9db2005-02-03 19:33:37 +000060static char *ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
Igor Sysoev94e32ce2006-04-07 14:08:04 +000061static char *ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd,
62 void *conf);
Igor Sysoev805d9db2005-02-03 19:33:37 +000063static char *ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd,
Igor Sysoevaa828612005-02-09 14:31:07 +000064 void *conf);
Igor Sysoev805d9db2005-02-03 19:33:37 +000065static char *ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd,
Igor Sysoevaa828612005-02-09 14:31:07 +000066 void *conf);
Igor Sysoev805d9db2005-02-03 19:33:37 +000067static char *ngx_http_core_keepalive(ngx_conf_t *cf, ngx_command_t *cmd,
Igor Sysoevaa828612005-02-09 14:31:07 +000068 void *conf);
Igor Sysoev899b44e2005-05-12 14:58:06 +000069static char *ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd,
70 void *conf);
Igor Sysoevb5faed22003-10-29 08:30:44 +000071
Igor Sysoev805d9db2005-02-03 19:33:37 +000072static char *ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data);
73
74static ngx_conf_post_t ngx_http_core_lowat_post =
75 { ngx_http_core_lowat_check };
Igor Sysoevb5faed22003-10-29 08:30:44 +000076
Igor Sysoev8290d282006-02-03 12:58:48 +000077static ngx_conf_deprecated_t ngx_conf_deprecated_optimize_host_names = {
78 ngx_conf_deprecated, "optimize_host_names", "optimize_server_names"
79};
80
Igor Sysoev4e9393a2003-01-09 05:36:00 +000081
Igor Sysoev64304df2007-01-24 09:14:08 +000082static ngx_conf_enum_t ngx_http_core_request_body_in_file[] = {
83 { ngx_string("off"), NGX_HTTP_REQUEST_BODY_FILE_OFF },
84 { ngx_string("on"), NGX_HTTP_REQUEST_BODY_FILE_ON },
Igor Sysoevcd5b99a2007-01-25 08:45:04 +000085 { ngx_string("clean"), NGX_HTTP_REQUEST_BODY_FILE_CLEAN },
Igor Sysoev64304df2007-01-24 09:14:08 +000086 { ngx_null_string, 0 }
87};
88
89
Igor Sysoev4e9393a2003-01-09 05:36:00 +000090static ngx_command_t ngx_http_core_commands[] = {
91
Igor Sysoevffe71442006-02-08 15:33:12 +000092 { ngx_string("variables_hash_max_size"),
93 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
94 ngx_conf_set_num_slot,
95 NGX_HTTP_MAIN_CONF_OFFSET,
96 offsetof(ngx_http_core_main_conf_t, variables_hash_max_size),
97 NULL },
98
99 { ngx_string("variables_hash_bucket_size"),
100 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
101 ngx_conf_set_num_slot,
102 NGX_HTTP_MAIN_CONF_OFFSET,
103 offsetof(ngx_http_core_main_conf_t, variables_hash_bucket_size),
104 NULL },
105
Igor Sysoev305a9d82005-12-26 17:07:48 +0000106 { ngx_string("server_names_hash_max_size"),
Igor Sysoevb1dfe472004-12-21 12:30:30 +0000107 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
108 ngx_conf_set_num_slot,
109 NGX_HTTP_MAIN_CONF_OFFSET,
Igor Sysoev305a9d82005-12-26 17:07:48 +0000110 offsetof(ngx_http_core_main_conf_t, server_names_hash_max_size),
Igor Sysoevb1dfe472004-12-21 12:30:30 +0000111 NULL },
112
Igor Sysoev305a9d82005-12-26 17:07:48 +0000113 { ngx_string("server_names_hash_bucket_size"),
Igor Sysoevb1dfe472004-12-21 12:30:30 +0000114 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
115 ngx_conf_set_num_slot,
116 NGX_HTTP_MAIN_CONF_OFFSET,
Igor Sysoev305a9d82005-12-26 17:07:48 +0000117 offsetof(ngx_http_core_main_conf_t, server_names_hash_bucket_size),
Igor Sysoevb1dfe472004-12-21 12:30:30 +0000118 NULL },
119
Igor Sysoev865c1502003-11-30 20:03:18 +0000120 { ngx_string("server"),
Igor Sysoev6f134cc2006-05-23 14:54:58 +0000121 NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_MULTI|NGX_CONF_NOARGS,
Igor Sysoev805d9db2005-02-03 19:33:37 +0000122 ngx_http_core_server,
Igor Sysoev865c1502003-11-30 20:03:18 +0000123 0,
124 0,
125 NULL },
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000126
Igor Sysoev865c1502003-11-30 20:03:18 +0000127 { ngx_string("connection_pool_size"),
128 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
129 ngx_conf_set_size_slot,
130 NGX_HTTP_SRV_CONF_OFFSET,
131 offsetof(ngx_http_core_srv_conf_t, connection_pool_size),
132 NULL },
Igor Sysoev6a644c62003-03-04 06:33:48 +0000133
Igor Sysoev865c1502003-11-30 20:03:18 +0000134 { ngx_string("request_pool_size"),
135 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
136 ngx_conf_set_size_slot,
137 NGX_HTTP_SRV_CONF_OFFSET,
138 offsetof(ngx_http_core_srv_conf_t, request_pool_size),
139 NULL },
Igor Sysoev187fcd82003-05-23 11:53:01 +0000140
Igor Sysoev865c1502003-11-30 20:03:18 +0000141 { ngx_string("client_header_timeout"),
142 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
143 ngx_conf_set_msec_slot,
144 NGX_HTTP_SRV_CONF_OFFSET,
145 offsetof(ngx_http_core_srv_conf_t, client_header_timeout),
146 NULL },
Igor Sysoev6a644c62003-03-04 06:33:48 +0000147
Igor Sysoev865c1502003-11-30 20:03:18 +0000148 { ngx_string("client_header_buffer_size"),
149 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
150 ngx_conf_set_size_slot,
151 NGX_HTTP_SRV_CONF_OFFSET,
152 offsetof(ngx_http_core_srv_conf_t, client_header_buffer_size),
153 NULL },
Igor Sysoev6a644c62003-03-04 06:33:48 +0000154
Igor Sysoevf7abd722004-09-23 06:32:00 +0000155 { ngx_string("large_client_header_buffers"),
Igor Sysoev85080d02004-09-22 16:18:21 +0000156 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE2,
157 ngx_conf_set_bufs_slot,
158 NGX_HTTP_SRV_CONF_OFFSET,
Igor Sysoevf7abd722004-09-23 06:32:00 +0000159 offsetof(ngx_http_core_srv_conf_t, large_client_header_buffers),
Igor Sysoev865c1502003-11-30 20:03:18 +0000160 NULL },
Igor Sysoev6a644c62003-03-04 06:33:48 +0000161
Igor Sysoev8290d282006-02-03 12:58:48 +0000162 { ngx_string("optimize_server_names"),
163 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
164 ngx_conf_set_flag_slot,
165 NGX_HTTP_SRV_CONF_OFFSET,
166 offsetof(ngx_http_core_srv_conf_t, optimize_server_names),
167 NULL },
168
Igor Sysoev34303462006-01-24 16:08:27 +0000169 { ngx_string("optimize_host_names"),
170 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
171 ngx_conf_set_flag_slot,
172 NGX_HTTP_SRV_CONF_OFFSET,
Igor Sysoev8290d282006-02-03 12:58:48 +0000173 offsetof(ngx_http_core_srv_conf_t, optimize_server_names),
174 &ngx_conf_deprecated_optimize_host_names },
Igor Sysoev34303462006-01-24 16:08:27 +0000175
Igor Sysoev3362b8d2005-05-14 18:42:03 +0000176 { ngx_string("ignore_invalid_headers"),
177 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
178 ngx_conf_set_flag_slot,
179 NGX_HTTP_SRV_CONF_OFFSET,
180 offsetof(ngx_http_core_srv_conf_t, ignore_invalid_headers),
181 NULL },
182
Igor Sysoev865c1502003-11-30 20:03:18 +0000183 { ngx_string("location"),
Igor Sysoev74a5ddb2004-07-18 19:11:20 +0000184 NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12,
Igor Sysoev805d9db2005-02-03 19:33:37 +0000185 ngx_http_core_location,
Igor Sysoev865c1502003-11-30 20:03:18 +0000186 NGX_HTTP_SRV_CONF_OFFSET,
187 0,
188 NULL },
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000189
Igor Sysoev865c1502003-11-30 20:03:18 +0000190 { ngx_string("listen"),
Igor Sysoevb145b062005-06-15 18:33:41 +0000191 NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
Igor Sysoev805d9db2005-02-03 19:33:37 +0000192 ngx_http_core_listen,
Igor Sysoev865c1502003-11-30 20:03:18 +0000193 NGX_HTTP_SRV_CONF_OFFSET,
194 0,
195 NULL },
Igor Sysoeva19a85e2003-01-28 15:56:37 +0000196
Igor Sysoev865c1502003-11-30 20:03:18 +0000197 { ngx_string("server_name"),
198 NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
Igor Sysoev805d9db2005-02-03 19:33:37 +0000199 ngx_http_core_server_name,
Igor Sysoev865c1502003-11-30 20:03:18 +0000200 NGX_HTTP_SRV_CONF_OFFSET,
201 0,
202 NULL },
Igor Sysoev13933252003-05-29 13:02:09 +0000203
Igor Sysoev24025022005-12-16 15:07:08 +0000204 { ngx_string("types_hash_max_size"),
205 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
206 ngx_conf_set_num_slot,
207 NGX_HTTP_LOC_CONF_OFFSET,
208 offsetof(ngx_http_core_loc_conf_t, types_hash_max_size),
209 NULL },
210
211 { ngx_string("types_hash_bucket_size"),
212 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
213 ngx_conf_set_num_slot,
214 NGX_HTTP_LOC_CONF_OFFSET,
215 offsetof(ngx_http_core_loc_conf_t, types_hash_bucket_size),
216 NULL },
217
Igor Sysoev865c1502003-11-30 20:03:18 +0000218 { ngx_string("types"),
219 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
220 |NGX_CONF_BLOCK|NGX_CONF_NOARGS,
Igor Sysoev805d9db2005-02-03 19:33:37 +0000221 ngx_http_core_types,
Igor Sysoev865c1502003-11-30 20:03:18 +0000222 NGX_HTTP_LOC_CONF_OFFSET,
223 0,
224 NULL },
Igor Sysoev79a80482003-05-14 17:13:13 +0000225
Igor Sysoev865c1502003-11-30 20:03:18 +0000226 { ngx_string("default_type"),
227 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
228 ngx_conf_set_str_slot,
229 NGX_HTTP_LOC_CONF_OFFSET,
230 offsetof(ngx_http_core_loc_conf_t, default_type),
231 NULL },
Igor Sysoev6253ca12003-05-27 12:18:54 +0000232
Igor Sysoev865c1502003-11-30 20:03:18 +0000233 { ngx_string("root"),
Igor Sysoev899b44e2005-05-12 14:58:06 +0000234 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
235 |NGX_CONF_TAKE1,
Igor Sysoev805d9db2005-02-03 19:33:37 +0000236 ngx_http_core_root,
Igor Sysoev865c1502003-11-30 20:03:18 +0000237 NGX_HTTP_LOC_CONF_OFFSET,
Igor Sysoev10a543a2004-03-16 07:10:12 +0000238 0,
239 NULL },
240
241 { ngx_string("alias"),
242 NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
Igor Sysoev805d9db2005-02-03 19:33:37 +0000243 ngx_http_core_root,
Igor Sysoev10a543a2004-03-16 07:10:12 +0000244 NGX_HTTP_LOC_CONF_OFFSET,
245 0,
Igor Sysoev865c1502003-11-30 20:03:18 +0000246 NULL },
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000247
Igor Sysoev94e32ce2006-04-07 14:08:04 +0000248 { ngx_string("limit_except"),
249 NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_1MORE,
250 ngx_http_core_limit_except,
251 NGX_HTTP_LOC_CONF_OFFSET,
252 0,
253 NULL },
254
Igor Sysoevae02c192004-03-19 05:25:53 +0000255 { ngx_string("client_max_body_size"),
256 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
Igor Sysoev1765f472006-07-07 16:33:19 +0000257 ngx_conf_set_off_slot,
Igor Sysoevae02c192004-03-19 05:25:53 +0000258 NGX_HTTP_LOC_CONF_OFFSET,
259 offsetof(ngx_http_core_loc_conf_t, client_max_body_size),
260 NULL },
261
Igor Sysoevdbb27762004-04-01 16:20:53 +0000262 { ngx_string("client_body_buffer_size"),
263 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
264 ngx_conf_set_size_slot,
265 NGX_HTTP_LOC_CONF_OFFSET,
266 offsetof(ngx_http_core_loc_conf_t, client_body_buffer_size),
267 NULL },
268
Igor Sysoev865c1502003-11-30 20:03:18 +0000269 { ngx_string("client_body_timeout"),
270 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
271 ngx_conf_set_msec_slot,
272 NGX_HTTP_LOC_CONF_OFFSET,
273 offsetof(ngx_http_core_loc_conf_t, client_body_timeout),
274 NULL },
Igor Sysoev2b0c76c2003-10-27 21:01:00 +0000275
Igor Sysoev02025fd2005-01-18 13:03:58 +0000276 { ngx_string("client_body_temp_path"),
277 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
278 ngx_conf_set_path_slot,
279 NGX_HTTP_LOC_CONF_OFFSET,
280 offsetof(ngx_http_core_loc_conf_t, client_body_temp_path),
281 (void *) ngx_garbage_collector_temp_handler },
282
Igor Sysoev8a2b2fb2006-04-14 09:53:38 +0000283 { ngx_string("client_body_in_file_only"),
284 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
Igor Sysoev64304df2007-01-24 09:14:08 +0000285 ngx_conf_set_enum_slot,
Igor Sysoev8a2b2fb2006-04-14 09:53:38 +0000286 NGX_HTTP_LOC_CONF_OFFSET,
287 offsetof(ngx_http_core_loc_conf_t, client_body_in_file_only),
Igor Sysoev64304df2007-01-24 09:14:08 +0000288 &ngx_http_core_request_body_in_file },
Igor Sysoev8a2b2fb2006-04-14 09:53:38 +0000289
Igor Sysoev865c1502003-11-30 20:03:18 +0000290 { ngx_string("sendfile"),
Igor Sysoev300de4f2007-01-21 17:42:28 +0000291 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
292 |NGX_CONF_TAKE1,
Igor Sysoev865c1502003-11-30 20:03:18 +0000293 ngx_conf_set_flag_slot,
294 NGX_HTTP_LOC_CONF_OFFSET,
295 offsetof(ngx_http_core_loc_conf_t, sendfile),
296 NULL },
Igor Sysoev5bf3d252003-10-22 07:05:29 +0000297
Igor Sysoev3c3ca172004-01-05 20:55:48 +0000298 { ngx_string("tcp_nopush"),
299 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
300 ngx_conf_set_flag_slot,
301 NGX_HTTP_LOC_CONF_OFFSET,
302 offsetof(ngx_http_core_loc_conf_t, tcp_nopush),
303 NULL },
304
Igor Sysoev924bd792004-10-11 15:07:03 +0000305 { ngx_string("tcp_nodelay"),
306 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
307 ngx_conf_set_flag_slot,
308 NGX_HTTP_LOC_CONF_OFFSET,
309 offsetof(ngx_http_core_loc_conf_t, tcp_nodelay),
310 NULL },
311
Igor Sysoev865c1502003-11-30 20:03:18 +0000312 { ngx_string("send_timeout"),
313 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
314 ngx_conf_set_msec_slot,
315 NGX_HTTP_LOC_CONF_OFFSET,
316 offsetof(ngx_http_core_loc_conf_t, send_timeout),
317 NULL },
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000318
Igor Sysoev865c1502003-11-30 20:03:18 +0000319 { ngx_string("send_lowat"),
320 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
321 ngx_conf_set_size_slot,
322 NGX_HTTP_LOC_CONF_OFFSET,
323 offsetof(ngx_http_core_loc_conf_t, send_lowat),
Igor Sysoev805d9db2005-02-03 19:33:37 +0000324 &ngx_http_core_lowat_post },
Igor Sysoevb5faed22003-10-29 08:30:44 +0000325
Igor Sysoev7823cc32004-07-14 16:01:42 +0000326 { ngx_string("postpone_output"),
327 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
328 ngx_conf_set_size_slot,
329 NGX_HTTP_LOC_CONF_OFFSET,
330 offsetof(ngx_http_core_loc_conf_t, postpone_output),
331 NULL },
332
333 { ngx_string("limit_rate"),
Igor Sysoev805d9db2005-02-03 19:33:37 +0000334 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
335 |NGX_CONF_TAKE1,
Igor Sysoev7823cc32004-07-14 16:01:42 +0000336 ngx_conf_set_size_slot,
337 NGX_HTTP_LOC_CONF_OFFSET,
338 offsetof(ngx_http_core_loc_conf_t, limit_rate),
339 NULL },
340
Igor Sysoev865c1502003-11-30 20:03:18 +0000341 { ngx_string("keepalive_timeout"),
Igor Sysoev307c3ad2004-09-17 16:07:35 +0000342 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
Igor Sysoev805d9db2005-02-03 19:33:37 +0000343 ngx_http_core_keepalive,
Igor Sysoev865c1502003-11-30 20:03:18 +0000344 NGX_HTTP_LOC_CONF_OFFSET,
Igor Sysoev307c3ad2004-09-17 16:07:35 +0000345 0,
Igor Sysoev865c1502003-11-30 20:03:18 +0000346 NULL },
Igor Sysoevfa73aac2003-05-21 13:28:21 +0000347
Igor Sysoev31eb8c02005-09-23 11:02:22 +0000348 { ngx_string("satisfy_any"),
349 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
350 ngx_conf_set_flag_slot,
351 NGX_HTTP_LOC_CONF_OFFSET,
352 offsetof(ngx_http_core_loc_conf_t, satisfy_any),
353 NULL },
354
Igor Sysoev899b44e2005-05-12 14:58:06 +0000355 { ngx_string("internal"),
356 NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
357 ngx_http_core_internal,
358 NGX_HTTP_LOC_CONF_OFFSET,
359 0,
360 NULL },
361
Igor Sysoev865c1502003-11-30 20:03:18 +0000362 { ngx_string("lingering_time"),
363 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
364 ngx_conf_set_msec_slot,
365 NGX_HTTP_LOC_CONF_OFFSET,
366 offsetof(ngx_http_core_loc_conf_t, lingering_time),
367 NULL },
Igor Sysoevb7387572003-03-11 20:38:13 +0000368
Igor Sysoev865c1502003-11-30 20:03:18 +0000369 { ngx_string("lingering_timeout"),
370 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
371 ngx_conf_set_msec_slot,
372 NGX_HTTP_LOC_CONF_OFFSET,
373 offsetof(ngx_http_core_loc_conf_t, lingering_timeout),
374 NULL },
Igor Sysoevb7387572003-03-11 20:38:13 +0000375
Igor Sysoev0ab91b92004-06-06 19:49:18 +0000376 { ngx_string("reset_timedout_connection"),
377 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
378 ngx_conf_set_flag_slot,
379 NGX_HTTP_LOC_CONF_OFFSET,
380 offsetof(ngx_http_core_loc_conf_t, reset_timedout_connection),
381 NULL },
382
Igor Sysoev7b190b42005-06-07 15:56:31 +0000383 { ngx_string("port_in_redirect"),
384 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
385 ngx_conf_set_flag_slot,
386 NGX_HTTP_LOC_CONF_OFFSET,
387 offsetof(ngx_http_core_loc_conf_t, port_in_redirect),
388 NULL },
389
Igor Sysoev865c1502003-11-30 20:03:18 +0000390 { ngx_string("msie_padding"),
391 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
392 ngx_conf_set_flag_slot,
393 NGX_HTTP_LOC_CONF_OFFSET,
394 offsetof(ngx_http_core_loc_conf_t, msie_padding),
395 NULL },
Igor Sysoev12b4b002003-10-24 06:53:41 +0000396
Igor Sysoev3f8dc592006-08-28 16:57:48 +0000397 { ngx_string("msie_refresh"),
398 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
399 ngx_conf_set_flag_slot,
400 NGX_HTTP_LOC_CONF_OFFSET,
401 offsetof(ngx_http_core_loc_conf_t, msie_refresh),
402 NULL },
403
Igor Sysoev5192b362005-07-08 14:34:20 +0000404 { ngx_string("log_not_found"),
405 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
406 ngx_conf_set_flag_slot,
407 NGX_HTTP_LOC_CONF_OFFSET,
408 offsetof(ngx_http_core_loc_conf_t, log_not_found),
409 NULL },
410
Igor Sysoev3f8dc592006-08-28 16:57:48 +0000411 { ngx_string("recursive_error_pages"),
412 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
413 ngx_conf_set_flag_slot,
414 NGX_HTTP_LOC_CONF_OFFSET,
415 offsetof(ngx_http_core_loc_conf_t, recursive_error_pages),
416 NULL },
417
Igor Sysoev865c1502003-11-30 20:03:18 +0000418 { ngx_string("error_page"),
Igor Sysoev899b44e2005-05-12 14:58:06 +0000419 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
420 |NGX_CONF_2MORE,
Igor Sysoev805d9db2005-02-03 19:33:37 +0000421 ngx_http_core_error_page,
Igor Sysoev865c1502003-11-30 20:03:18 +0000422 NGX_HTTP_LOC_CONF_OFFSET,
423 0,
424 NULL },
Igor Sysoev74e95c22003-11-09 20:03:38 +0000425
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +0000426 { ngx_string("post_action"),
427 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
428 |NGX_CONF_TAKE1,
429 ngx_conf_set_str_slot,
430 NGX_HTTP_LOC_CONF_OFFSET,
431 offsetof(ngx_http_core_loc_conf_t, post_action),
432 NULL },
433
Igor Sysoev865c1502003-11-30 20:03:18 +0000434 { ngx_string("error_log"),
Igor Sysoev03420a62004-01-20 20:40:08 +0000435 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
Igor Sysoev805d9db2005-02-03 19:33:37 +0000436 ngx_http_core_error_log,
Igor Sysoev865c1502003-11-30 20:03:18 +0000437 NGX_HTTP_LOC_CONF_OFFSET,
438 0,
439 NULL },
Igor Sysoev890fc962003-07-20 21:15:59 +0000440
Igor Sysoev67f88e92004-03-12 16:57:08 +0000441#if (NGX_HTTP_CACHE)
442
Igor Sysoev865c1502003-11-30 20:03:18 +0000443 { ngx_string("open_file_cache"),
444 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE4,
445 ngx_http_set_cache_slot,
446 NGX_HTTP_LOC_CONF_OFFSET,
447 offsetof(ngx_http_core_loc_conf_t, open_files),
448 NULL },
449
Igor Sysoev67f88e92004-03-12 16:57:08 +0000450#endif
451
Igor Sysoev865c1502003-11-30 20:03:18 +0000452 ngx_null_command
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000453};
454
455
Igor Sysoev8f125582006-07-28 15:16:17 +0000456static ngx_http_module_t ngx_http_core_module_ctx = {
Igor Sysoev899b44e2005-05-12 14:58:06 +0000457 ngx_http_core_preconfiguration, /* preconfiguration */
Igor Sysoev09c684b2005-11-09 17:25:55 +0000458 NULL, /* postconfiguration */
Igor Sysoev78329332003-11-10 17:17:31 +0000459
Igor Sysoeva9830112003-05-19 16:39:14 +0000460 ngx_http_core_create_main_conf, /* create main configuration */
461 ngx_http_core_init_main_conf, /* init main configuration */
Igor Sysoevdc479b42003-03-20 16:09:44 +0000462
Igor Sysoeva9830112003-05-19 16:39:14 +0000463 ngx_http_core_create_srv_conf, /* create server configuration */
464 ngx_http_core_merge_srv_conf, /* merge server configuration */
465
466 ngx_http_core_create_loc_conf, /* create location configuration */
467 ngx_http_core_merge_loc_conf /* merge location configuration */
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000468};
469
470
471ngx_module_t ngx_http_core_module = {
Igor Sysoev899b44e2005-05-12 14:58:06 +0000472 NGX_MODULE_V1,
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000473 &ngx_http_core_module_ctx, /* module context */
474 ngx_http_core_commands, /* module directives */
Igor Sysoev6253ca12003-05-27 12:18:54 +0000475 NGX_HTTP_MODULE, /* module type */
Igor Sysoeve5733802005-09-08 14:36:09 +0000476 NULL, /* init master */
Igor Sysoev899b44e2005-05-12 14:58:06 +0000477 NULL, /* init module */
Igor Sysoeve5733802005-09-08 14:36:09 +0000478 NULL, /* init process */
479 NULL, /* init thread */
480 NULL, /* exit thread */
481 NULL, /* exit process */
482 NULL, /* exit master */
483 NGX_MODULE_V1_PADDING
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000484};
485
486
Igor Sysoevaa828612005-02-09 14:31:07 +0000487void
488ngx_http_handler(ngx_http_request_t *r)
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000489{
Igor Sysoevda173ab2006-08-30 10:39:17 +0000490 ngx_http_core_main_conf_t *cmcf;
491
Igor Sysoeve5a222c2005-01-25 12:27:35 +0000492 r->connection->log->action = NULL;
Igor Sysoev6ddfbf02003-05-15 15:42:53 +0000493
494 r->connection->unexpected_eof = 0;
495
Igor Sysoevef316432006-08-16 13:09:33 +0000496 if (!r->internal) {
Igor Sysoev31eb8c02005-09-23 11:02:22 +0000497 switch (r->headers_in.connection_type) {
498 case 0:
499 if (r->http_version > NGX_HTTP_VERSION_10) {
500 r->keepalive = 1;
501 } else {
502 r->keepalive = 0;
503 }
504 break;
505
506 case NGX_HTTP_CONNECTION_CLOSE:
507 r->keepalive = 0;
508 break;
509
510 case NGX_HTTP_CONNECTION_KEEP_ALIVE:
Igor Sysoev419f9ac2003-10-21 16:49:56 +0000511 r->keepalive = 1;
Igor Sysoev31eb8c02005-09-23 11:02:22 +0000512 break;
513 }
514
515 if (r->keepalive && r->headers_in.msie && r->method == NGX_HTTP_POST) {
516
517 /*
Igor Sysoevda173ab2006-08-30 10:39:17 +0000518 * MSIE may wait for some time if an response for
519 * a POST request was sent over a keepalive connection
Igor Sysoev31eb8c02005-09-23 11:02:22 +0000520 */
521
Igor Sysoev9760a132003-10-21 07:47:21 +0000522 r->keepalive = 0;
523 }
Igor Sysoev419f9ac2003-10-21 16:49:56 +0000524
Igor Sysoev31eb8c02005-09-23 11:02:22 +0000525 if (r->headers_in.content_length_n > 0) {
526 r->lingering_close = 1;
Igor Sysoev419f9ac2003-10-21 16:49:56 +0000527
Igor Sysoev31eb8c02005-09-23 11:02:22 +0000528 } else {
529 r->lingering_close = 0;
530 }
Igor Sysoev9760a132003-10-21 07:47:21 +0000531
Igor Sysoevda173ab2006-08-30 10:39:17 +0000532 r->phase_handler = 0;
Igor Sysoev805d9db2005-02-03 19:33:37 +0000533
Igor Sysoevda173ab2006-08-30 10:39:17 +0000534 } else {
535 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
536 r->phase_handler = cmcf->phase_engine.server_rewrite_index;
537 }
538
Igor Sysoev8a3cdc02006-09-25 17:49:49 +0000539 if (r->unparsed_uri.len) {
540 r->valid_unparsed_uri = 1;
541 }
542
543 r->valid_location = 1;
544
Igor Sysoevda173ab2006-08-30 10:39:17 +0000545 r->write_event_handler = ngx_http_core_run_phases;
Igor Sysoev805d9db2005-02-03 19:33:37 +0000546 ngx_http_core_run_phases(r);
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000547}
Igor Sysoeve2a31542003-04-08 15:40:10 +0000548
549
Igor Sysoevda173ab2006-08-30 10:39:17 +0000550void
Igor Sysoevaa828612005-02-09 14:31:07 +0000551ngx_http_core_run_phases(ngx_http_request_t *r)
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000552{
Igor Sysoev865c1502003-11-30 20:03:18 +0000553 ngx_int_t rc;
Igor Sysoevda173ab2006-08-30 10:39:17 +0000554 ngx_http_phase_handler_t *ph;
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000555 ngx_http_core_main_conf_t *cmcf;
556
557 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
558
Igor Sysoevda173ab2006-08-30 10:39:17 +0000559 ph = cmcf->phase_engine.handlers;
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000560
Igor Sysoevda173ab2006-08-30 10:39:17 +0000561 while (ph[r->phase_handler].checker) {
Igor Sysoev805d9db2005-02-03 19:33:37 +0000562
Igor Sysoevda173ab2006-08-30 10:39:17 +0000563 rc = ph[r->phase_handler].checker(r, &ph[r->phase_handler]);
Igor Sysoev805d9db2005-02-03 19:33:37 +0000564
Igor Sysoevda173ab2006-08-30 10:39:17 +0000565 if (rc == NGX_OK) {
Igor Sysoev31eb8c02005-09-23 11:02:22 +0000566 return;
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000567 }
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000568 }
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000569}
570
571
Igor Sysoevaa828612005-02-09 14:31:07 +0000572ngx_int_t
Igor Sysoevda173ab2006-08-30 10:39:17 +0000573ngx_http_core_generic_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
574{
575 ngx_int_t rc;
576
577 /*
578 * generic phase checker,
579 * used by the post read, server rewrite, rewrite, and pre-access phases
580 */
581
582 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
583 "generic phase: %ui", r->phase_handler);
584
585 rc = ph->handler(r);
586
587 if (rc == NGX_OK) {
588 r->phase_handler = ph->next;
589 return NGX_AGAIN;
590 }
591
592 if (rc == NGX_DECLINED) {
593 r->phase_handler++;
594 return NGX_AGAIN;
595 }
596
597 if (rc == NGX_AGAIN || rc == NGX_DONE) {
598 return NGX_OK;
599 }
600
601 /* rc == NGX_ERROR || rc == NGX_HTTP_... */
602
603 ngx_http_finalize_request(r, rc);
604
605 return NGX_OK;
606}
607
608
609ngx_int_t
610ngx_http_core_find_config_phase(ngx_http_request_t *r,
611 ngx_http_phase_handler_t *ph)
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000612{
Igor Sysoev74a5ddb2004-07-18 19:11:20 +0000613 ngx_int_t rc;
614 ngx_http_core_loc_conf_t *clcf;
615 ngx_http_core_srv_conf_t *cscf;
Igor Sysoeve2a31542003-04-08 15:40:10 +0000616
Igor Sysoev1ebfead2005-02-16 13:40:36 +0000617 r->content_handler = NULL;
618 r->uri_changed = 0;
619
Igor Sysoev6253ca12003-05-27 12:18:54 +0000620 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
Igor Sysoeve2a31542003-04-08 15:40:10 +0000621
Igor Sysoev805d9db2005-02-03 19:33:37 +0000622 rc = ngx_http_core_find_location(r, &cscf->locations, 0);
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000623
Igor Sysoev74a5ddb2004-07-18 19:11:20 +0000624 if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) {
Igor Sysoevda173ab2006-08-30 10:39:17 +0000625 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
626 return NGX_OK;
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000627 }
628
Igor Sysoev419f9ac2003-10-21 16:49:56 +0000629 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
630
Igor Sysoev899b44e2005-05-12 14:58:06 +0000631 if (!r->internal && clcf->internal) {
Igor Sysoevda173ab2006-08-30 10:39:17 +0000632 ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
633 return NGX_OK;
Igor Sysoev899b44e2005-05-12 14:58:06 +0000634 }
635
Igor Sysoeva2573672005-10-05 14:46:21 +0000636 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
637 "using configuration \"%s%V\"",
638 (clcf->noname ? "*" : (clcf->exact_match ? "=" : "")),
639 &clcf->name);
640
Igor Sysoevb85fd592005-08-23 15:36:54 +0000641 ngx_http_update_location_config(r);
Igor Sysoev89690bf2004-03-23 06:01:52 +0000642
643 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
Igor Sysoev1765f472006-07-07 16:33:19 +0000644 "http cl:%O max:%O",
Igor Sysoev1b735832004-11-11 14:07:14 +0000645 r->headers_in.content_length_n, clcf->client_max_body_size);
Igor Sysoev89690bf2004-03-23 06:01:52 +0000646
647 if (r->headers_in.content_length_n != -1
Igor Sysoev08e63d42006-08-14 15:09:38 +0000648 && !r->discard_body
Igor Sysoev89690bf2004-03-23 06:01:52 +0000649 && clcf->client_max_body_size
Igor Sysoev1765f472006-07-07 16:33:19 +0000650 && clcf->client_max_body_size < r->headers_in.content_length_n)
Igor Sysoev89690bf2004-03-23 06:01:52 +0000651 {
652 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
Igor Sysoev1765f472006-07-07 16:33:19 +0000653 "client intented to send too large body: %O bytes",
Igor Sysoev89690bf2004-03-23 06:01:52 +0000654 r->headers_in.content_length_n);
655
Igor Sysoevda173ab2006-08-30 10:39:17 +0000656 ngx_http_finalize_request(r, NGX_HTTP_REQUEST_ENTITY_TOO_LARGE);
657 return NGX_OK;
Igor Sysoev89690bf2004-03-23 06:01:52 +0000658 }
659
660
Igor Sysoev74a5ddb2004-07-18 19:11:20 +0000661 if (rc == NGX_HTTP_LOCATION_AUTO_REDIRECT) {
Igor Sysoevaab4d8c2004-09-06 18:45:00 +0000662 r->headers_out.location = ngx_list_push(&r->headers_out.headers);
663 if (r->headers_out.location == NULL) {
Igor Sysoevda173ab2006-08-30 10:39:17 +0000664 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
665 return NGX_OK;
Igor Sysoev1b138ed2003-11-18 21:34:08 +0000666 }
667
Igor Sysoev899b44e2005-05-12 14:58:06 +0000668 /*
669 * we do not need to set the r->headers_out.location->hash and
670 * r->headers_out.location->key fields
671 */
672
Igor Sysoev74a5ddb2004-07-18 19:11:20 +0000673 r->headers_out.location->value = clcf->name;
Igor Sysoev1b138ed2003-11-18 21:34:08 +0000674
Igor Sysoevda173ab2006-08-30 10:39:17 +0000675 ngx_http_finalize_request(r, NGX_HTTP_MOVED_PERMANENTLY);
676 return NGX_OK;
Igor Sysoev1b138ed2003-11-18 21:34:08 +0000677 }
678
Igor Sysoevda173ab2006-08-30 10:39:17 +0000679 r->phase_handler++;
680 return NGX_AGAIN;
681}
682
683
684ngx_int_t
685ngx_http_core_post_rewrite_phase(ngx_http_request_t *r,
686 ngx_http_phase_handler_t *ph)
687{
688 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
689 "post rewrite phase: %ui", r->phase_handler);
690
691 if (!r->uri_changed) {
692 r->phase_handler++;
693 return NGX_AGAIN;
694 }
695
696 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
697 "uri changes: %d", r->uri_changes);
698
699 /*
700 * gcc before 3.3 compiles the broken code for
701 * if (r->uri_changes-- == 0)
702 * if the r->uri_changes is defined as
703 * unsigned uri_changes:4
704 */
705
706 r->uri_changes--;
707
708 if (r->uri_changes == 0) {
709 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
710 "rewrite or internal redirection cycle "
711 "while processing \"%V\"", &r->uri);
712
713 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
714 return NGX_OK;
715 }
716
717 r->phase_handler = ph->next;
718
719 return NGX_AGAIN;
720}
721
722
723ngx_int_t
724ngx_http_core_access_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
725{
726 ngx_int_t rc;
727 ngx_http_core_loc_conf_t *clcf;
728
729 if (r != r->main) {
730 r->phase_handler = ph->next;
731 return NGX_AGAIN;
732 }
733
734 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
735 "access phase: %ui", r->phase_handler);
736
737 rc = ph->handler(r);
738
739 if (rc == NGX_DECLINED) {
740 r->phase_handler++;
741 return NGX_AGAIN;
742 }
743
744 if (rc == NGX_AGAIN || rc == NGX_DONE) {
745 return NGX_OK;
746 }
747
748 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
749
750 if (clcf->satisfy_any == 0) {
751
752 if (rc == NGX_OK) {
753 r->phase_handler++;
754 return NGX_AGAIN;
755 }
756
757 } else {
758 if (rc == NGX_OK) {
759 r->access_code = 0;
760
761 if (r->headers_out.www_authenticate) {
762 r->headers_out.www_authenticate->hash = 0;
763 }
764
765 r->phase_handler = ph->next;
766 return NGX_AGAIN;
767 }
768
769 if (rc == NGX_HTTP_FORBIDDEN || rc == NGX_HTTP_UNAUTHORIZED) {
770 r->access_code = rc;
771
772 r->phase_handler++;
773 return NGX_AGAIN;
774 }
775 }
776
777 /* rc == NGX_ERROR || rc == NGX_HTTP_... */
778
779 ngx_http_finalize_request(r, rc);
780 return NGX_OK;
781}
782
783
784ngx_int_t
785ngx_http_core_post_access_phase(ngx_http_request_t *r,
786 ngx_http_phase_handler_t *ph)
787{
788 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
789 "post access phase: %ui", r->phase_handler);
790
791 if (r->access_code) {
792
793 if (r->access_code == NGX_HTTP_FORBIDDEN) {
794 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
795 "access forbidden by rule");
796 }
797
798 ngx_http_finalize_request(r, r->access_code);
799 return NGX_OK;
800 }
801
802 r->phase_handler++;
803 return NGX_AGAIN;
804}
805
806
807ngx_int_t
808ngx_http_core_content_phase(ngx_http_request_t *r,
809 ngx_http_phase_handler_t *ph)
810{
Igor Sysoev0e5f86d2006-10-12 13:36:54 +0000811 size_t root;
Igor Sysoevda173ab2006-08-30 10:39:17 +0000812 ngx_int_t rc;
813 ngx_str_t path;
814
815 if (r->content_handler) {
816 r->write_event_handler = ngx_http_request_empty_handler;
817 ngx_http_finalize_request(r, r->content_handler(r));
818 return NGX_OK;
819 }
820
821 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
822 "content phase: %ui", r->phase_handler);
823
824 rc = ph->handler(r);
825
826 if (rc == NGX_DONE) {
827 return NGX_OK;
828 }
829
830 if (rc != NGX_DECLINED) {
831 ngx_http_finalize_request(r, rc);
832 return NGX_OK;
833 }
834
835 /* rc == NGX_DECLINED */
836
837 ph++;
838
839 if (ph->checker) {
840 r->phase_handler++;
841 return NGX_AGAIN;
842 }
843
844 /* no content handler was found */
845
846 if (r->uri.data[r->uri.len - 1] == '/' && !r->zero_in_uri) {
847
Igor Sysoev0e5f86d2006-10-12 13:36:54 +0000848 if (ngx_http_map_uri_to_path(r, &path, &root, 0) != NULL) {
Igor Sysoevda173ab2006-08-30 10:39:17 +0000849 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
850 "directory index of \"%V\" is forbidden", &path);
851 }
852
853 ngx_http_finalize_request(r, NGX_HTTP_FORBIDDEN);
854 return NGX_OK;
855 }
856
857 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no handler found");
858
859 ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
Igor Sysoevb85fd592005-08-23 15:36:54 +0000860 return NGX_OK;
861}
862
863
864void
865ngx_http_update_location_config(ngx_http_request_t *r)
866{
867 ngx_http_core_loc_conf_t *clcf;
868
869 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
870
Igor Sysoev94e32ce2006-04-07 14:08:04 +0000871 if (r->method & clcf->limit_except) {
872 r->loc_conf = clcf->limit_except_loc_conf;
873 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
874 }
875
Igor Sysoevb0518172006-04-26 15:21:08 +0000876 if (r == r->main) {
877 r->connection->log->file = clcf->err_log->file;
878 if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
879 r->connection->log->log_level = clcf->err_log->log_level;
880 }
Igor Sysoevb85fd592005-08-23 15:36:54 +0000881 }
882
883 if ((ngx_io.flags & NGX_IO_SENDFILE) && clcf->sendfile) {
884 r->connection->sendfile = 1;
885
886 } else {
887 r->connection->sendfile = 0;
888 }
889
Igor Sysoev8a2b2fb2006-04-14 09:53:38 +0000890 if (clcf->client_body_in_file_only) {
891 r->request_body_in_file_only = 1;
892 r->request_body_in_persistent_file = 1;
Igor Sysoevcd5b99a2007-01-25 08:45:04 +0000893 r->request_body_in_clean_file =
894 clcf->client_body_in_file_only == NGX_HTTP_REQUEST_BODY_FILE_CLEAN;
Igor Sysoev7bdb7202006-04-19 15:30:56 +0000895 r->request_body_file_log_level = NGX_LOG_NOTICE;
896
897 } else {
898 r->request_body_file_log_level = NGX_LOG_WARN;
Igor Sysoev8a2b2fb2006-04-14 09:53:38 +0000899 }
900
Igor Sysoevb85fd592005-08-23 15:36:54 +0000901 if (r->keepalive && clcf->keepalive_timeout == 0) {
902 r->keepalive = 0;
903 }
904
905 if (!clcf->tcp_nopush) {
906 /* disable TCP_NOPUSH/TCP_CORK use */
907 r->connection->tcp_nopush = NGX_TCP_NOPUSH_DISABLED;
908 }
909
Igor Sysoevc2807ec2006-02-16 15:26:46 +0000910 if (r->limit_rate == 0) {
911 r->limit_rate = clcf->limit_rate;
912 }
Igor Sysoev5192b362005-07-08 14:34:20 +0000913
Igor Sysoev6253ca12003-05-27 12:18:54 +0000914 if (clcf->handler) {
Igor Sysoevb3e73d82003-10-10 15:10:50 +0000915 r->content_handler = clcf->handler;
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000916 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +0000917}
918
919
Igor Sysoevaa828612005-02-09 14:31:07 +0000920static ngx_int_t
921ngx_http_core_find_location(ngx_http_request_t *r,
922 ngx_array_t *locations, size_t len)
Igor Sysoev74a5ddb2004-07-18 19:11:20 +0000923{
924 ngx_int_t n, rc;
Igor Sysoevd43bee82004-11-20 19:52:20 +0000925 ngx_uint_t i, found, noregex;
Igor Sysoev74a5ddb2004-07-18 19:11:20 +0000926 ngx_http_core_loc_conf_t *clcf, **clcfp;
927
Igor Sysoeva2573672005-10-05 14:46:21 +0000928 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
929 "find location for \"%V\"", &r->uri);
Igor Sysoev74a5ddb2004-07-18 19:11:20 +0000930
931 found = 0;
Igor Sysoevd43bee82004-11-20 19:52:20 +0000932 noregex = 0;
Igor Sysoev74a5ddb2004-07-18 19:11:20 +0000933
934 clcfp = locations->elts;
935 for (i = 0; i < locations->nelts; i++) {
936
Igor Sysoevc0edbcc2004-10-21 15:34:38 +0000937#if (NGX_PCRE)
Igor Sysoev74a5ddb2004-07-18 19:11:20 +0000938 if (clcfp[i]->regex) {
939 break;
940 }
941#endif
942
Igor Sysoev805d9db2005-02-03 19:33:37 +0000943 if (clcfp[i]->noname) {
944 break;
945 }
946
Igor Sysoev74a5ddb2004-07-18 19:11:20 +0000947 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
Igor Sysoev1b735832004-11-11 14:07:14 +0000948 "find location: %s\"%V\"",
949 clcfp[i]->exact_match ? "= " : "", &clcfp[i]->name);
Igor Sysoev74a5ddb2004-07-18 19:11:20 +0000950
951 if (clcfp[i]->auto_redirect
952 && r->uri.len == clcfp[i]->name.len - 1
953 && ngx_strncmp(r->uri.data, clcfp[i]->name.data,
Igor Sysoeva1e82cc2007-01-12 21:57:20 +0000954 clcfp[i]->name.len - 1)
955 == 0)
Igor Sysoev74a5ddb2004-07-18 19:11:20 +0000956 {
957 /* the locations are lexicographically sorted */
958
959 r->loc_conf = clcfp[i]->loc_conf;
960
961 return NGX_HTTP_LOCATION_AUTO_REDIRECT;
962 }
963
964 if (r->uri.len < clcfp[i]->name.len) {
965 continue;
966 }
967
968 n = ngx_strncmp(r->uri.data, clcfp[i]->name.data, clcfp[i]->name.len);
969
970 if (n < 0) {
971 /* the locations are lexicographically sorted */
972 break;
973 }
974
975 if (n == 0) {
Igor Sysoev805d9db2005-02-03 19:33:37 +0000976 if (clcfp[i]->exact_match) {
977
978 if (r->uri.len == clcfp[i]->name.len) {
979 r->loc_conf = clcfp[i]->loc_conf;
980 return NGX_HTTP_LOCATION_EXACT;
981 }
982
983 continue;
Igor Sysoevea521232004-07-26 16:21:18 +0000984 }
985
Igor Sysoev71057632004-08-30 19:24:51 +0000986 if (len > clcfp[i]->name.len) {
Igor Sysoev74a5ddb2004-07-18 19:11:20 +0000987 /* the previous match is longer */
988 break;
989 }
990
991 r->loc_conf = clcfp[i]->loc_conf;
Igor Sysoevd43bee82004-11-20 19:52:20 +0000992 noregex = clcfp[i]->noregex;
Igor Sysoev74a5ddb2004-07-18 19:11:20 +0000993 found = 1;
994 }
995 }
996
997 if (found) {
998 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
999
1000 if (clcf->locations.nelts) {
Igor Sysoev805d9db2005-02-03 19:33:37 +00001001 rc = ngx_http_core_find_location(r, &clcf->locations, len);
Igor Sysoev74a5ddb2004-07-18 19:11:20 +00001002
1003 if (rc != NGX_OK) {
1004 return rc;
1005 }
1006 }
1007 }
1008
Igor Sysoevc0edbcc2004-10-21 15:34:38 +00001009#if (NGX_PCRE)
Igor Sysoev74a5ddb2004-07-18 19:11:20 +00001010
Igor Sysoevd43bee82004-11-20 19:52:20 +00001011 if (noregex) {
1012 return NGX_HTTP_LOCATION_NOREGEX;
1013 }
1014
Igor Sysoev74a5ddb2004-07-18 19:11:20 +00001015 /* regex matches */
1016
1017 for (/* void */; i < locations->nelts; i++) {
1018
1019 if (!clcfp[i]->regex) {
1020 continue;
1021 }
1022
Igor Sysoev805d9db2005-02-03 19:33:37 +00001023 if (clcfp[i]->noname) {
1024 break;
1025 }
1026
Igor Sysoev74a5ddb2004-07-18 19:11:20 +00001027 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
Igor Sysoev1b735832004-11-11 14:07:14 +00001028 "find location: ~ \"%V\"", &clcfp[i]->name);
Igor Sysoev74a5ddb2004-07-18 19:11:20 +00001029
1030 n = ngx_regex_exec(clcfp[i]->regex, &r->uri, NULL, 0);
1031
Igor Sysoev3259e852005-01-19 13:10:56 +00001032 if (n == NGX_REGEX_NO_MATCHED) {
Igor Sysoev74a5ddb2004-07-18 19:11:20 +00001033 continue;
1034 }
1035
1036 if (n < 0) {
1037 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
1038 ngx_regex_exec_n
Igor Sysoev1b735832004-11-11 14:07:14 +00001039 " failed: %d on \"%V\" using \"%V\"",
1040 n, &r->uri, &clcfp[i]->name);
Igor Sysoev74a5ddb2004-07-18 19:11:20 +00001041 return NGX_HTTP_INTERNAL_SERVER_ERROR;
1042 }
1043
1044 /* match */
1045
1046 r->loc_conf = clcfp[i]->loc_conf;
1047
1048 return NGX_HTTP_LOCATION_REGEX;
1049 }
1050
Igor Sysoevc0edbcc2004-10-21 15:34:38 +00001051#endif /* NGX_PCRE */
Igor Sysoev74a5ddb2004-07-18 19:11:20 +00001052
1053 return NGX_OK;
1054}
1055
1056
Igor Sysoevaa828612005-02-09 14:31:07 +00001057ngx_int_t
1058ngx_http_set_content_type(ngx_http_request_t *r)
Igor Sysoev865c1502003-11-30 20:03:18 +00001059{
Igor Sysoev805d9db2005-02-03 19:33:37 +00001060 u_char c, *p, *exten;
Igor Sysoev24025022005-12-16 15:07:08 +00001061 ngx_str_t *type;
Igor Sysoev3338cfd2006-05-11 14:43:47 +00001062 ngx_uint_t i, hash;
Igor Sysoev865c1502003-11-30 20:03:18 +00001063 ngx_http_core_loc_conf_t *clcf;
1064
Igor Sysoev08e63d42006-08-14 15:09:38 +00001065 if (r->headers_out.content_type.len) {
1066 return NGX_OK;
1067 }
1068
Igor Sysoev865c1502003-11-30 20:03:18 +00001069 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1070
1071 if (r->exten.len) {
Igor Sysoev805d9db2005-02-03 19:33:37 +00001072
Igor Sysoev3338cfd2006-05-11 14:43:47 +00001073 hash = 0;
Igor Sysoev805d9db2005-02-03 19:33:37 +00001074
Igor Sysoev3338cfd2006-05-11 14:43:47 +00001075 for (i = 0; i < r->exten.len; i++) {
1076 c = r->exten.data[i];
1077
1078 if (c >= 'A' && c <= 'Z') {
1079
Igor Sysoevc1571722005-03-19 12:38:37 +00001080 p = ngx_palloc(r->pool, r->exten.len);
1081 if (p == NULL) {
Igor Sysoev805d9db2005-02-03 19:33:37 +00001082 return NGX_HTTP_INTERNAL_SERVER_ERROR;
1083 }
1084
Igor Sysoev3338cfd2006-05-11 14:43:47 +00001085 hash = 0;
Igor Sysoev805d9db2005-02-03 19:33:37 +00001086 exten = p;
1087
1088 for (i = 0; i < r->exten.len; i++) {
Igor Sysoev3338cfd2006-05-11 14:43:47 +00001089 c = ngx_tolower(r->exten.data[i]);
1090 hash = ngx_hash(hash, c);
1091 *p++ = c;
Igor Sysoev805d9db2005-02-03 19:33:37 +00001092 }
1093
1094 r->exten.data = exten;
Igor Sysoev3338cfd2006-05-11 14:43:47 +00001095
1096 break;
Igor Sysoev805d9db2005-02-03 19:33:37 +00001097 }
1098
Igor Sysoev3338cfd2006-05-11 14:43:47 +00001099 hash = ngx_hash(hash, c);
Igor Sysoev805d9db2005-02-03 19:33:37 +00001100 }
1101
Igor Sysoev3338cfd2006-05-11 14:43:47 +00001102 type = ngx_hash_find(&clcf->types_hash, hash,
Igor Sysoev24025022005-12-16 15:07:08 +00001103 r->exten.data, r->exten.len);
Igor Sysoev865c1502003-11-30 20:03:18 +00001104
Igor Sysoev24025022005-12-16 15:07:08 +00001105 if (type) {
Igor Sysoevef809b82006-06-28 16:00:26 +00001106 r->headers_out.content_type_len = type->len;
Igor Sysoev24025022005-12-16 15:07:08 +00001107 r->headers_out.content_type = *type;
Igor Sysoevef809b82006-06-28 16:00:26 +00001108
Igor Sysoev24025022005-12-16 15:07:08 +00001109 return NGX_OK;
Igor Sysoev865c1502003-11-30 20:03:18 +00001110 }
1111 }
1112
Igor Sysoevef809b82006-06-28 16:00:26 +00001113 r->headers_out.content_type_len = clcf->default_type.len;
Igor Sysoev24025022005-12-16 15:07:08 +00001114 r->headers_out.content_type = clcf->default_type;
Igor Sysoev865c1502003-11-30 20:03:18 +00001115
1116 return NGX_OK;
1117}
1118
1119
Igor Sysoevaa828612005-02-09 14:31:07 +00001120ngx_int_t
Igor Sysoevaa828612005-02-09 14:31:07 +00001121ngx_http_set_exten(ngx_http_request_t *r)
Igor Sysoev3b30a902003-12-25 20:26:58 +00001122{
1123 ngx_int_t i;
1124
1125 r->exten.len = 0;
1126 r->exten.data = NULL;
1127
1128 for (i = r->uri.len - 1; i > 1; i--) {
1129 if (r->uri.data[i] == '.' && r->uri.data[i - 1] != '/') {
Igor Sysoev3338cfd2006-05-11 14:43:47 +00001130
Igor Sysoev3b30a902003-12-25 20:26:58 +00001131 r->exten.len = r->uri.len - i - 1;
Igor Sysoev3338cfd2006-05-11 14:43:47 +00001132 r->exten.data = &r->uri.data[i + 1];
Igor Sysoev3b30a902003-12-25 20:26:58 +00001133
1134 break;
1135
1136 } else if (r->uri.data[i] == '/') {
1137 break;
1138 }
1139 }
1140
1141 return NGX_OK;
1142}
1143
1144
Igor Sysoevaa828612005-02-09 14:31:07 +00001145ngx_int_t
Igor Sysoev208eed22005-10-07 13:30:52 +00001146ngx_http_send_header(ngx_http_request_t *r)
1147{
1148 if (r->err_status) {
1149 r->headers_out.status = r->err_status;
1150 r->headers_out.status_line.len = 0;
1151 }
1152
1153 return ngx_http_top_header_filter(r);
1154}
1155
1156
1157ngx_int_t
1158ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in)
1159{
1160 ngx_int_t rc;
1161
Igor Sysoevd3283ff2005-12-05 13:18:09 +00001162 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1163 "http output filter \"%V?%V\"", &r->uri, &r->args);
Igor Sysoev208eed22005-10-07 13:30:52 +00001164
1165 rc = ngx_http_top_body_filter(r, in);
1166
1167 if (rc == NGX_ERROR) {
1168 /* NGX_ERROR may be returned by any filter */
Igor Sysoevd3283ff2005-12-05 13:18:09 +00001169 r->connection->error = 1;
Igor Sysoev208eed22005-10-07 13:30:52 +00001170 }
1171
1172 return rc;
1173}
1174
1175
1176u_char *
1177ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *path,
Igor Sysoev0e5f86d2006-10-12 13:36:54 +00001178 size_t *root_length, size_t reserved)
Igor Sysoev208eed22005-10-07 13:30:52 +00001179{
Igor Sysoev8fea8852006-03-15 09:53:04 +00001180 u_char *last;
1181 size_t alias;
1182 ngx_http_core_loc_conf_t *clcf;
Igor Sysoev208eed22005-10-07 13:30:52 +00001183
1184 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1185
1186 alias = clcf->alias ? clcf->name.len : 0;
1187
Igor Sysoev34303462006-01-24 16:08:27 +00001188 if (alias && !r->valid_location) {
1189 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
1190 "\"alias\" could not be used in location \"%V\" "
1191 "where URI was rewritten", &clcf->name);
1192 return NULL;
1193 }
1194
Igor Sysoev8fea8852006-03-15 09:53:04 +00001195 reserved += r->uri.len - alias + 1;
1196
Igor Sysoev3ca233e2005-12-28 14:23:52 +00001197 if (clcf->root_lengths == NULL) {
Igor Sysoev208eed22005-10-07 13:30:52 +00001198
Igor Sysoev0e5f86d2006-10-12 13:36:54 +00001199 *root_length = clcf->root.len;
Igor Sysoev3ca233e2005-12-28 14:23:52 +00001200
Igor Sysoev8fea8852006-03-15 09:53:04 +00001201 path->len = clcf->root.len + reserved;
Igor Sysoev3ca233e2005-12-28 14:23:52 +00001202
1203 path->data = ngx_palloc(r->pool, path->len);
1204 if (path->data == NULL) {
1205 return NULL;
1206 }
1207
1208 last = ngx_copy(path->data, clcf->root.data, clcf->root.len);
Igor Sysoev3ca233e2005-12-28 14:23:52 +00001209
Igor Sysoev8fea8852006-03-15 09:53:04 +00001210 } else {
Igor Sysoev8f125582006-07-28 15:16:17 +00001211 if (ngx_http_script_run(r, path, clcf->root_lengths->elts, reserved,
Igor Sysoevc55a1042006-08-09 19:59:45 +00001212 clcf->root_values->elts)
Igor Sysoev8f125582006-07-28 15:16:17 +00001213 == NULL)
1214 {
1215 return NULL;
1216 }
1217
1218 if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, path) == NGX_ERROR) {
Igor Sysoev8fea8852006-03-15 09:53:04 +00001219 return NULL;
1220 }
1221
Igor Sysoev0e5f86d2006-10-12 13:36:54 +00001222 *root_length = path->len - reserved;
1223 last = path->data + *root_length;
Igor Sysoev3ca233e2005-12-28 14:23:52 +00001224 }
1225
Igor Sysoev8fea8852006-03-15 09:53:04 +00001226 last = ngx_cpystrn(last, r->uri.data + alias, r->uri.len - alias + 1);
Igor Sysoev208eed22005-10-07 13:30:52 +00001227
1228 return last;
1229}
1230
1231
1232ngx_int_t
Igor Sysoevceb99292005-09-06 16:09:32 +00001233ngx_http_auth_basic_user(ngx_http_request_t *r)
1234{
1235 ngx_str_t auth, encoded;
1236 ngx_uint_t len;
1237
1238 if (r->headers_in.user.len == 0 && r->headers_in.user.data != NULL) {
1239 return NGX_DECLINED;
1240 }
1241
1242 if (r->headers_in.authorization == NULL) {
1243 r->headers_in.user.data = (u_char *) "";
1244 return NGX_DECLINED;
1245 }
1246
1247 encoded = r->headers_in.authorization->value;
1248
1249 if (encoded.len < sizeof("Basic ") - 1
1250 || ngx_strncasecmp(encoded.data, "Basic ", sizeof("Basic ") - 1) != 0)
1251 {
1252 r->headers_in.user.data = (u_char *) "";
1253 return NGX_DECLINED;
1254 }
1255
1256 encoded.len -= sizeof("Basic ") - 1;
1257 encoded.data += sizeof("Basic ") - 1;
1258
1259 while (encoded.len && encoded.data[0] == ' ') {
1260 encoded.len--;
1261 encoded.data++;
1262 }
1263
1264 if (encoded.len == 0) {
1265 r->headers_in.user.data = (u_char *) "";
1266 return NGX_DECLINED;
1267 }
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +00001268
Igor Sysoevceb99292005-09-06 16:09:32 +00001269 auth.len = ngx_base64_decoded_length(encoded.len);
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +00001270 auth.data = ngx_palloc(r->pool, auth.len + 1);
Igor Sysoevceb99292005-09-06 16:09:32 +00001271 if (auth.data == NULL) {
1272 return NGX_ERROR;
1273 }
1274
1275 if (ngx_decode_base64(&auth, &encoded) != NGX_OK) {
1276 r->headers_in.user.data = (u_char *) "";
1277 return NGX_DECLINED;
1278 }
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +00001279
Igor Sysoevceb99292005-09-06 16:09:32 +00001280 auth.data[auth.len] = '\0';
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +00001281
1282 for (len = 0; len < auth.len; len++) {
Igor Sysoevceb99292005-09-06 16:09:32 +00001283 if (auth.data[len] == ':') {
1284 break;
1285 }
1286 }
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +00001287
Igor Sysoev09c684b2005-11-09 17:25:55 +00001288 if (len == 0 || len == auth.len) {
Igor Sysoevceb99292005-09-06 16:09:32 +00001289 r->headers_in.user.data = (u_char *) "";
1290 return NGX_DECLINED;
1291 }
1292
1293 r->headers_in.user.len = len;
1294 r->headers_in.user.data = auth.data;
1295 r->headers_in.passwd.len = auth.len - len - 1;
1296 r->headers_in.passwd.data = &auth.data[len + 1];
1297
1298 return NGX_OK;
1299}
1300
1301
1302ngx_int_t
Igor Sysoev899b44e2005-05-12 14:58:06 +00001303ngx_http_subrequest(ngx_http_request_t *r,
Igor Sysoev9fcccaf2006-10-10 14:30:39 +00001304 ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **psr,
Igor Sysoev960100e2006-10-13 15:20:10 +00001305 ngx_http_post_subrequest_t *ps, ngx_uint_t flags)
Igor Sysoev899b44e2005-05-12 14:58:06 +00001306{
Igor Sysoevd3283ff2005-12-05 13:18:09 +00001307 ngx_connection_t *c;
Igor Sysoev899b44e2005-05-12 14:58:06 +00001308 ngx_http_request_t *sr;
Igor Sysoevbb28b6d2006-07-11 13:20:19 +00001309 ngx_http_log_ctx_t *ctx;
Igor Sysoev899b44e2005-05-12 14:58:06 +00001310 ngx_http_core_srv_conf_t *cscf;
1311 ngx_http_postponed_request_t *pr, *p;
1312
Igor Sysoevef809b82006-06-28 16:00:26 +00001313 r->main->subrequests--;
1314
1315 if (r->main->subrequests == 0) {
1316 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
Igor Sysoev3f8dc592006-08-28 16:57:48 +00001317 "subrequests cycle while processing \"%V\"", uri);
Igor Sysoev5fd6d342006-11-02 13:48:28 +00001318 r->main->subrequests = 1;
Igor Sysoevef809b82006-06-28 16:00:26 +00001319 return NGX_ERROR;
1320 }
1321
Igor Sysoev899b44e2005-05-12 14:58:06 +00001322 sr = ngx_pcalloc(r->pool, sizeof(ngx_http_request_t));
1323 if (sr == NULL) {
Igor Sysoevac72bd12006-05-04 15:32:46 +00001324 return NGX_ERROR;
Igor Sysoev899b44e2005-05-12 14:58:06 +00001325 }
1326
1327 sr->signature = NGX_HTTP_MODULE;
Igor Sysoevd3283ff2005-12-05 13:18:09 +00001328
1329 c = r->connection;
1330 sr->connection = c;
Igor Sysoev899b44e2005-05-12 14:58:06 +00001331
1332 sr->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
1333 if (sr->ctx == NULL) {
Igor Sysoevac72bd12006-05-04 15:32:46 +00001334 return NGX_ERROR;
Igor Sysoev899b44e2005-05-12 14:58:06 +00001335 }
1336
1337 if (ngx_list_init(&sr->headers_out.headers, r->pool, 20,
Igor Sysoevc31a9bb2005-11-26 10:11:11 +00001338 sizeof(ngx_table_elt_t))
1339 == NGX_ERROR)
Igor Sysoev899b44e2005-05-12 14:58:06 +00001340 {
Igor Sysoevac72bd12006-05-04 15:32:46 +00001341 return NGX_ERROR;
Igor Sysoev899b44e2005-05-12 14:58:06 +00001342 }
1343
1344 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
1345 sr->main_conf = cscf->ctx->main_conf;
1346 sr->srv_conf = cscf->ctx->srv_conf;
1347 sr->loc_conf = cscf->ctx->loc_conf;
1348
1349 sr->pool = r->pool;
1350
1351 sr->headers_in = r->headers_in;
1352
1353 sr->start_time = ngx_time();
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +00001354
1355 ngx_http_clear_content_length(sr);
1356 ngx_http_clear_accept_ranges(sr);
1357 ngx_http_clear_last_modified(sr);
Igor Sysoev899b44e2005-05-12 14:58:06 +00001358
1359 sr->request_body = r->request_body;
1360
1361 sr->method = NGX_HTTP_GET;
1362 sr->http_version = r->http_version;
Igor Sysoev899b44e2005-05-12 14:58:06 +00001363
1364 sr->request_line = r->request_line;
1365 sr->uri = *uri;
Igor Sysoev09c684b2005-11-09 17:25:55 +00001366
Igor Sysoev899b44e2005-05-12 14:58:06 +00001367 if (args) {
1368 sr->args = *args;
1369 }
Igor Sysoev09c684b2005-11-09 17:25:55 +00001370
Igor Sysoevd3283ff2005-12-05 13:18:09 +00001371 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
1372 "http subrequest \"%V?%V\"", uri, &sr->args);
1373
Igor Sysoev960100e2006-10-13 15:20:10 +00001374 sr->zero_in_uri = (flags & NGX_HTTP_ZERO_IN_URI) != 0;
1375 sr->subrequest_in_memory = (flags & NGX_HTTP_SUBREQUEST_IN_MEMORY) != 0;
Igor Sysoev09c684b2005-11-09 17:25:55 +00001376
Igor Sysoev899b44e2005-05-12 14:58:06 +00001377 sr->unparsed_uri = r->unparsed_uri;
1378 sr->method_name = r->method_name;
1379 sr->http_protocol = r->http_protocol;
1380
1381 if (ngx_http_set_exten(sr) != NGX_OK) {
Igor Sysoevac72bd12006-05-04 15:32:46 +00001382 return NGX_ERROR;
Igor Sysoev899b44e2005-05-12 14:58:06 +00001383 }
1384
Igor Sysoevf6e1fe32005-10-04 10:38:53 +00001385 sr->main = r->main;
Igor Sysoev899b44e2005-05-12 14:58:06 +00001386 sr->parent = r;
Igor Sysoev960100e2006-10-13 15:20:10 +00001387 sr->post_subrequest = ps;
Igor Sysoev899b44e2005-05-12 14:58:06 +00001388 sr->read_event_handler = ngx_http_request_empty_handler;
1389 sr->write_event_handler = ngx_http_request_empty_handler;
1390
Igor Sysoevd3283ff2005-12-05 13:18:09 +00001391 if (c->data == r) {
1392 c->data = sr;
Igor Sysoev899b44e2005-05-12 14:58:06 +00001393 }
1394
1395 sr->in_addr = r->in_addr;
1396 sr->port = r->port;
1397 sr->port_text = r->port_text;
1398 sr->server_name = r->server_name;
1399
1400 sr->variables = r->variables;
1401
1402 sr->log_handler = r->log_handler;
1403
1404 pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t));
1405 if (pr == NULL) {
Igor Sysoevac72bd12006-05-04 15:32:46 +00001406 return NGX_ERROR;
Igor Sysoev899b44e2005-05-12 14:58:06 +00001407 }
1408
1409 pr->request = sr;
1410 pr->out = NULL;
1411 pr->next = NULL;
1412
1413 if (r->postponed) {
1414 for (p = r->postponed; p->next; p = p->next) { /* void */ }
1415 p->next = pr;
1416
1417 } else {
1418 r->postponed = pr;
1419 }
1420
Igor Sysoevbb28b6d2006-07-11 13:20:19 +00001421 ctx = c->log->data;
1422 ctx->current_request = sr;
1423
Igor Sysoev899b44e2005-05-12 14:58:06 +00001424 sr->internal = 1;
Igor Sysoevdf3254a2006-01-11 15:26:57 +00001425 sr->fast_subrequest = 1;
Igor Sysoev899b44e2005-05-12 14:58:06 +00001426
Igor Sysoev31eb8c02005-09-23 11:02:22 +00001427 sr->discard_body = r->discard_body;
Igor Sysoevd52477f2005-05-16 13:53:20 +00001428 sr->main_filter_need_in_memory = r->main_filter_need_in_memory;
1429
Igor Sysoev6f134cc2006-05-23 14:54:58 +00001430 sr->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1;
1431
Igor Sysoev899b44e2005-05-12 14:58:06 +00001432 ngx_http_handler(sr);
1433
Igor Sysoevd3283ff2005-12-05 13:18:09 +00001434 if (!c->destroyed) {
1435 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
1436 "http subrequest done \"%V?%V\"", uri, &sr->args);
Igor Sysoevac72bd12006-05-04 15:32:46 +00001437
Igor Sysoev85300c32006-11-02 13:38:25 +00001438 r->main->subrequests++;
1439
Igor Sysoev9fcccaf2006-10-10 14:30:39 +00001440 *psr = sr;
1441
Igor Sysoevac72bd12006-05-04 15:32:46 +00001442 if (sr->fast_subrequest) {
1443 sr->fast_subrequest = 0;
1444
1445 if (sr->done) {
1446 return NGX_OK;
1447 }
1448 }
1449
1450 return NGX_AGAIN;
Igor Sysoevd3283ff2005-12-05 13:18:09 +00001451 }
Igor Sysoev899b44e2005-05-12 14:58:06 +00001452
Igor Sysoev960100e2006-10-13 15:20:10 +00001453 return NGX_DONE;
Igor Sysoev899b44e2005-05-12 14:58:06 +00001454}
1455
1456
1457ngx_int_t
Igor Sysoevaa828612005-02-09 14:31:07 +00001458ngx_http_internal_redirect(ngx_http_request_t *r,
1459 ngx_str_t *uri, ngx_str_t *args)
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001460{
Igor Sysoevaa828612005-02-09 14:31:07 +00001461 ngx_http_core_srv_conf_t *cscf;
1462
Igor Sysoev5fede1e2006-08-18 14:17:54 +00001463 r->uri_changes--;
1464
1465 if (r->uri_changes == 0) {
1466 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
Igor Sysoev3f8dc592006-08-28 16:57:48 +00001467 "rewrite or internal redirection cycle "
1468 "while internal redirect to \"%V\"", uri);
1469
Igor Sysoev5fede1e2006-08-18 14:17:54 +00001470 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1471 return NGX_DONE;
1472 }
1473
Igor Sysoev1b735832004-11-11 14:07:14 +00001474 r->uri = *uri;
Igor Sysoev13933252003-05-29 13:02:09 +00001475
1476 if (args) {
Igor Sysoev1b735832004-11-11 14:07:14 +00001477 r->args = *args;
Igor Sysoev899b44e2005-05-12 14:58:06 +00001478
1479 } else {
1480 r->args.len = 0;
1481 r->args.data = NULL;
Igor Sysoev13933252003-05-29 13:02:09 +00001482 }
1483
Igor Sysoevd3283ff2005-12-05 13:18:09 +00001484 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1485 "internal redirect: \"%V?%V\"", uri, &r->args);
1486
Igor Sysoev3b30a902003-12-25 20:26:58 +00001487 if (ngx_http_set_exten(r) != NGX_OK) {
Igor Sysoev5fede1e2006-08-18 14:17:54 +00001488 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
1489 return NGX_DONE;
Igor Sysoev13933252003-05-29 13:02:09 +00001490 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001491
Igor Sysoevef316432006-08-16 13:09:33 +00001492 /* clear the modules contexts */
1493 ngx_memzero(r->ctx, sizeof(void *) * ngx_http_max_module);
Igor Sysoev0a280a32003-10-12 16:49:16 +00001494
Igor Sysoevaa828612005-02-09 14:31:07 +00001495 cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
1496 r->loc_conf = cscf->ctx->loc_conf;
1497
Igor Sysoevb85fd592005-08-23 15:36:54 +00001498 ngx_http_update_location_config(r);
1499
Igor Sysoev899b44e2005-05-12 14:58:06 +00001500 r->internal = 1;
1501
Igor Sysoev79a80482003-05-14 17:13:13 +00001502 ngx_http_handler(r);
Igor Sysoev13933252003-05-29 13:02:09 +00001503
Igor Sysoev9760a132003-10-21 07:47:21 +00001504 return NGX_DONE;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001505}
1506
1507
Igor Sysoev9ac946b2005-10-24 15:09:41 +00001508ngx_http_cleanup_t *
1509ngx_http_cleanup_add(ngx_http_request_t *r, size_t size)
Igor Sysoev0a280a32003-10-12 16:49:16 +00001510{
Igor Sysoev9ac946b2005-10-24 15:09:41 +00001511 ngx_http_cleanup_t *cln;
Igor Sysoev0a280a32003-10-12 16:49:16 +00001512
Igor Sysoev9ac946b2005-10-24 15:09:41 +00001513 r = r->main;
1514
1515 cln = ngx_palloc(r->pool, sizeof(ngx_http_cleanup_t));
1516 if (cln == NULL) {
1517 return NULL;
Igor Sysoev0a280a32003-10-12 16:49:16 +00001518 }
1519
Igor Sysoev9ac946b2005-10-24 15:09:41 +00001520 if (size) {
1521 cln->data = ngx_palloc(r->pool, size);
1522 if (cln->data == NULL) {
1523 return NULL;
1524 }
Igor Sysoev0a280a32003-10-12 16:49:16 +00001525
Igor Sysoev9ac946b2005-10-24 15:09:41 +00001526 } else {
1527 cln->data = NULL;
1528 }
1529
1530 cln->handler = NULL;
1531 cln->next = r->cleanup;
1532
1533 r->cleanup = cln;
1534
1535 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1536 "http cleanup add: %p", cln);
1537
1538 return cln;
1539}
Igor Sysoev0a280a32003-10-12 16:49:16 +00001540
1541
Igor Sysoevaa828612005-02-09 14:31:07 +00001542static char *
1543ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001544{
Igor Sysoevaa828612005-02-09 14:31:07 +00001545 char *rv;
1546 void *mconf;
Igor Sysoev7b190b42005-06-07 15:56:31 +00001547 ngx_uint_t m;
1548 ngx_conf_t pcf;
Igor Sysoevaa828612005-02-09 14:31:07 +00001549 ngx_http_module_t *module;
1550 ngx_http_conf_ctx_t *ctx, *http_ctx;
1551 ngx_http_core_srv_conf_t *cscf, **cscfp;
1552 ngx_http_core_main_conf_t *cmcf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001553
Igor Sysoevc1571722005-03-19 12:38:37 +00001554 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
1555 if (ctx == NULL) {
Igor Sysoevaa828612005-02-09 14:31:07 +00001556 return NGX_CONF_ERROR;
1557 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001558
Igor Sysoev74a5ddb2004-07-18 19:11:20 +00001559 http_ctx = cf->ctx;
1560 ctx->main_conf = http_ctx->main_conf;
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +00001561
Igor Sysoeva9830112003-05-19 16:39:14 +00001562 /* the server{}'s srv_conf */
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +00001563
Igor Sysoevaa828612005-02-09 14:31:07 +00001564 ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
1565 if (ctx->srv_conf == NULL) {
1566 return NGX_CONF_ERROR;
1567 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001568
Igor Sysoeva9830112003-05-19 16:39:14 +00001569 /* the server{}'s loc_conf */
Igor Sysoevbb4ec5c2003-05-16 15:27:48 +00001570
Igor Sysoevaa828612005-02-09 14:31:07 +00001571 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
1572 if (ctx->loc_conf == NULL) {
1573 return NGX_CONF_ERROR;
1574 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001575
Igor Sysoev1c13c662003-05-20 15:37:55 +00001576 for (m = 0; ngx_modules[m]; m++) {
Igor Sysoev6253ca12003-05-27 12:18:54 +00001577 if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001578 continue;
1579 }
1580
Igor Sysoev6253ca12003-05-27 12:18:54 +00001581 module = ngx_modules[m]->ctx;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001582
1583 if (module->create_srv_conf) {
Igor Sysoevc1571722005-03-19 12:38:37 +00001584 mconf = module->create_srv_conf(cf);
1585 if (mconf == NULL) {
Igor Sysoevaa828612005-02-09 14:31:07 +00001586 return NGX_CONF_ERROR;
1587 }
1588
1589 ctx->srv_conf[ngx_modules[m]->ctx_index] = mconf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001590 }
1591
1592 if (module->create_loc_conf) {
Igor Sysoevc1571722005-03-19 12:38:37 +00001593 mconf = module->create_loc_conf(cf);
1594 if (mconf == NULL) {
Igor Sysoevaa828612005-02-09 14:31:07 +00001595 return NGX_CONF_ERROR;
1596 }
1597
1598 ctx->loc_conf[ngx_modules[m]->ctx_index] = mconf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001599 }
1600 }
1601
Igor Sysoevaa828612005-02-09 14:31:07 +00001602
1603 /* the server configuration context */
Igor Sysoeva9830112003-05-19 16:39:14 +00001604
Igor Sysoev6253ca12003-05-27 12:18:54 +00001605 cscf = ctx->srv_conf[ngx_http_core_module.ctx_index];
Igor Sysoeva9830112003-05-19 16:39:14 +00001606 cscf->ctx = ctx;
1607
Igor Sysoevaa828612005-02-09 14:31:07 +00001608
Igor Sysoev6253ca12003-05-27 12:18:54 +00001609 cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
Igor Sysoevaa828612005-02-09 14:31:07 +00001610
Igor Sysoevc1571722005-03-19 12:38:37 +00001611 cscfp = ngx_array_push(&cmcf->servers);
1612 if (cscfp == NULL) {
Igor Sysoevaa828612005-02-09 14:31:07 +00001613 return NGX_CONF_ERROR;
1614 }
1615
Igor Sysoeva9830112003-05-19 16:39:14 +00001616 *cscfp = cscf;
1617
Igor Sysoevaa828612005-02-09 14:31:07 +00001618
Igor Sysoeva9830112003-05-19 16:39:14 +00001619 /* parse inside server{} */
1620
Igor Sysoev7b190b42005-06-07 15:56:31 +00001621 pcf = *cf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001622 cf->ctx = ctx;
Igor Sysoev79a80482003-05-14 17:13:13 +00001623 cf->cmd_type = NGX_HTTP_SRV_CONF;
Igor Sysoev805d9db2005-02-03 19:33:37 +00001624
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001625 rv = ngx_conf_parse(cf, NULL);
Igor Sysoev805d9db2005-02-03 19:33:37 +00001626
Igor Sysoev7b190b42005-06-07 15:56:31 +00001627 *cf = pcf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001628
Igor Sysoev13933252003-05-29 13:02:09 +00001629 if (rv != NGX_CONF_OK) {
1630 return rv;
1631 }
1632
Igor Sysoevd9d0ca12003-11-21 06:30:49 +00001633 ngx_qsort(cscf->locations.elts, (size_t) cscf->locations.nelts,
Igor Sysoev805d9db2005-02-03 19:33:37 +00001634 sizeof(ngx_http_core_loc_conf_t *), ngx_http_core_cmp_locations);
Igor Sysoev13933252003-05-29 13:02:09 +00001635
Igor Sysoeva9830112003-05-19 16:39:14 +00001636 return rv;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001637}
1638
1639
Igor Sysoevaa828612005-02-09 14:31:07 +00001640static char *
1641ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001642{
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001643 char *rv;
Igor Sysoeva8fa0a62003-11-25 20:44:56 +00001644 ngx_int_t m;
Igor Sysoevfc5a10a2004-03-09 19:47:07 +00001645 ngx_str_t *value;
Igor Sysoev805d9db2005-02-03 19:33:37 +00001646 ngx_conf_t save;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001647 ngx_http_module_t *module;
Igor Sysoev74a5ddb2004-07-18 19:11:20 +00001648 ngx_http_conf_ctx_t *ctx, *pctx;
Igor Sysoeva9830112003-05-19 16:39:14 +00001649 ngx_http_core_srv_conf_t *cscf;
Igor Sysoev74a5ddb2004-07-18 19:11:20 +00001650 ngx_http_core_loc_conf_t *clcf, *pclcf, **clcfp;
Igor Sysoevc0edbcc2004-10-21 15:34:38 +00001651#if (NGX_PCRE)
Igor Sysoevfc5a10a2004-03-09 19:47:07 +00001652 ngx_str_t err;
Igor Sysoev10a543a2004-03-16 07:10:12 +00001653 u_char errstr[NGX_MAX_CONF_ERRSTR];
Igor Sysoevfc5a10a2004-03-09 19:47:07 +00001654#endif
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001655
Igor Sysoevc1571722005-03-19 12:38:37 +00001656 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
1657 if (ctx == NULL) {
Igor Sysoeva8fa0a62003-11-25 20:44:56 +00001658 return NGX_CONF_ERROR;
1659 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001660
Igor Sysoev74a5ddb2004-07-18 19:11:20 +00001661 pctx = cf->ctx;
1662 ctx->main_conf = pctx->main_conf;
1663 ctx->srv_conf = pctx->srv_conf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001664
Igor Sysoeva8fa0a62003-11-25 20:44:56 +00001665 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
1666 if (ctx->loc_conf == NULL) {
1667 return NGX_CONF_ERROR;
1668 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001669
Igor Sysoev6253ca12003-05-27 12:18:54 +00001670 for (m = 0; ngx_modules[m]; m++) {
1671 if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001672 continue;
1673 }
1674
Igor Sysoev6253ca12003-05-27 12:18:54 +00001675 module = ngx_modules[m]->ctx;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001676
1677 if (module->create_loc_conf) {
Igor Sysoeva8fa0a62003-11-25 20:44:56 +00001678 ctx->loc_conf[ngx_modules[m]->ctx_index] =
1679 module->create_loc_conf(cf);
1680 if (ctx->loc_conf[ngx_modules[m]->ctx_index] == NULL) {
1681 return NGX_CONF_ERROR;
1682 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001683 }
1684 }
1685
Igor Sysoev6253ca12003-05-27 12:18:54 +00001686 clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
Igor Sysoeva9830112003-05-19 16:39:14 +00001687 clcf->loc_conf = ctx->loc_conf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001688
Igor Sysoev3b30a902003-12-25 20:26:58 +00001689 value = cf->args->elts;
Igor Sysoeva8fa0a62003-11-25 20:44:56 +00001690
1691 if (cf->args->nelts == 3) {
1692 if (value[1].len == 1 && value[1].data[0] == '=') {
Igor Sysoev2a3f4902004-11-11 20:58:09 +00001693 clcf->name = value[2];
Igor Sysoeva8fa0a62003-11-25 20:44:56 +00001694 clcf->exact_match = 1;
1695
Igor Sysoevd43bee82004-11-20 19:52:20 +00001696 } else if (value[1].len == 2
1697 && value[1].data[0] == '^'
1698 && value[1].data[1] == '~')
1699 {
1700 clcf->name = value[2];
1701 clcf->noregex = 1;
1702
Igor Sysoeva8fa0a62003-11-25 20:44:56 +00001703 } else if ((value[1].len == 1 && value[1].data[0] == '~')
1704 || (value[1].len == 2
1705 && value[1].data[0] == '~'
1706 && value[1].data[1] == '*'))
1707 {
Igor Sysoevc0edbcc2004-10-21 15:34:38 +00001708#if (NGX_PCRE)
Igor Sysoeva8fa0a62003-11-25 20:44:56 +00001709 err.len = NGX_MAX_CONF_ERRSTR;
1710 err.data = errstr;
1711
1712 clcf->regex = ngx_regex_compile(&value[2],
1713 value[1].len == 2 ? NGX_REGEX_CASELESS: 0,
1714 cf->pool, &err);
1715
1716 if (clcf->regex == NULL) {
1717 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
1718 return NGX_CONF_ERROR;
1719 }
1720
Igor Sysoev3b30a902003-12-25 20:26:58 +00001721 clcf->name = value[2];
Igor Sysoevdc867cd2003-12-14 20:10:27 +00001722#else
1723 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
Igor Sysoev1b735832004-11-11 14:07:14 +00001724 "the using of the regex \"%V\" "
1725 "requires PCRE library", &value[2]);
Igor Sysoevdc867cd2003-12-14 20:10:27 +00001726 return NGX_CONF_ERROR;
1727#endif
Igor Sysoeva8fa0a62003-11-25 20:44:56 +00001728
1729 } else {
1730 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
Igor Sysoev1b735832004-11-11 14:07:14 +00001731 "invalid location modifier \"%V\"", &value[1]);
Igor Sysoeva8fa0a62003-11-25 20:44:56 +00001732 return NGX_CONF_ERROR;
1733 }
1734
1735 } else {
Igor Sysoev2a3f4902004-11-11 20:58:09 +00001736 clcf->name = value[1];
Igor Sysoeva8fa0a62003-11-25 20:44:56 +00001737 }
1738
Igor Sysoev74a5ddb2004-07-18 19:11:20 +00001739 pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index];
1740
1741 if (pclcf->name.len == 0) {
1742 cscf = ctx->srv_conf[ngx_http_core_module.ctx_index];
Igor Sysoevc1571722005-03-19 12:38:37 +00001743
1744 clcfp = ngx_array_push(&cscf->locations);
1745 if (clcfp == NULL) {
Igor Sysoev74a5ddb2004-07-18 19:11:20 +00001746 return NGX_CONF_ERROR;
1747 }
1748
1749 } else {
Igor Sysoev805d9db2005-02-03 19:33:37 +00001750#if 0
Igor Sysoev74a5ddb2004-07-18 19:11:20 +00001751 clcf->prev_location = pclcf;
Igor Sysoev805d9db2005-02-03 19:33:37 +00001752#endif
Igor Sysoev74a5ddb2004-07-18 19:11:20 +00001753
1754 if (pclcf->exact_match) {
1755 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
Igor Sysoev1b735832004-11-11 14:07:14 +00001756 "location \"%V\" could not be inside "
1757 "the exact location \"%V\"",
1758 &clcf->name, &pclcf->name);
Igor Sysoev74a5ddb2004-07-18 19:11:20 +00001759 return NGX_CONF_ERROR;
1760 }
1761
Igor Sysoevc0edbcc2004-10-21 15:34:38 +00001762#if (NGX_PCRE)
Igor Sysoev74a5ddb2004-07-18 19:11:20 +00001763 if (clcf->regex == NULL
1764 && ngx_strncmp(clcf->name.data, pclcf->name.data, pclcf->name.len)
1765 != 0)
Igor Sysoevea521232004-07-26 16:21:18 +00001766#else
1767 if (ngx_strncmp(clcf->name.data, pclcf->name.data, pclcf->name.len)
1768 != 0)
1769#endif
Igor Sysoev74a5ddb2004-07-18 19:11:20 +00001770 {
1771 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
Igor Sysoev1b735832004-11-11 14:07:14 +00001772 "location \"%V\" is outside location \"%V\"",
1773 &clcf->name, &pclcf->name);
Igor Sysoev74a5ddb2004-07-18 19:11:20 +00001774 return NGX_CONF_ERROR;
1775 }
1776
1777 if (pclcf->locations.elts == NULL) {
Igor Sysoevc1571722005-03-19 12:38:37 +00001778 if (ngx_array_init(&pclcf->locations, cf->pool, 4, sizeof(void *))
1779 != NGX_OK)
1780 {
1781 return NGX_CONF_ERROR;
1782 }
Igor Sysoev74a5ddb2004-07-18 19:11:20 +00001783 }
1784
Igor Sysoevc1571722005-03-19 12:38:37 +00001785 clcfp = ngx_array_push(&pclcf->locations);
1786 if (clcfp == NULL) {
Igor Sysoev74a5ddb2004-07-18 19:11:20 +00001787 return NGX_CONF_ERROR;
1788 }
Igor Sysoeva8fa0a62003-11-25 20:44:56 +00001789 }
Igor Sysoev74a5ddb2004-07-18 19:11:20 +00001790
Igor Sysoeva9830112003-05-19 16:39:14 +00001791 *clcfp = clcf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001792
Igor Sysoev805d9db2005-02-03 19:33:37 +00001793 save = *cf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001794 cf->ctx = ctx;
Igor Sysoev79a80482003-05-14 17:13:13 +00001795 cf->cmd_type = NGX_HTTP_LOC_CONF;
Igor Sysoev805d9db2005-02-03 19:33:37 +00001796
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001797 rv = ngx_conf_parse(cf, NULL);
Igor Sysoev805d9db2005-02-03 19:33:37 +00001798
1799 *cf = save;
1800
1801 if (rv != NGX_CONF_OK) {
1802 return rv;
1803 }
1804
1805 ngx_qsort(clcf->locations.elts, (size_t) clcf->locations.nelts,
1806 sizeof(ngx_http_core_loc_conf_t *), ngx_http_core_cmp_locations);
Igor Sysoev79a80482003-05-14 17:13:13 +00001807
1808 return rv;
1809}
1810
1811
Igor Sysoev4d656dc2005-03-22 16:02:46 +00001812static int ngx_libc_cdecl
Igor Sysoevaa828612005-02-09 14:31:07 +00001813ngx_http_core_cmp_locations(const void *one, const void *two)
Igor Sysoev805d9db2005-02-03 19:33:37 +00001814{
1815 ngx_int_t rc;
1816 ngx_http_core_loc_conf_t *first, *second;
1817
1818 first = *(ngx_http_core_loc_conf_t **) one;
1819 second = *(ngx_http_core_loc_conf_t **) two;
1820
1821 if (first->noname && !second->noname) {
1822 /* shift no named locations to the end */
1823 return 1;
1824 }
1825
1826 if (!first->noname && second->noname) {
1827 /* shift no named locations to the end */
1828 return -1;
1829 }
1830
1831 if (first->noname || second->noname) {
1832 /* do not sort no named locations */
1833 return 0;
1834 }
1835
1836#if (NGX_PCRE)
1837
1838 if (first->regex && !second->regex) {
1839 /* shift the regex matches to the end */
1840 return 1;
1841 }
1842
1843 if (!first->regex && second->regex) {
1844 /* shift the regex matches to the end */
1845 return -1;
1846 }
1847
1848 if (first->regex || second->regex) {
1849 /* do not sort the regex matches */
1850 return 0;
1851 }
1852
1853#endif
1854
1855 rc = ngx_strcmp(first->name.data, second->name.data);
1856
1857 if (rc == 0 && second->exact_match) {
1858 /* an exact match must be before the same inclusive one */
1859 return 1;
1860 }
1861
1862 return (int) rc;
1863}
1864
1865
Igor Sysoevaa828612005-02-09 14:31:07 +00001866static char *
1867ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev79a80482003-05-14 17:13:13 +00001868{
Igor Sysoev7bdb7202006-04-19 15:30:56 +00001869 ngx_http_core_loc_conf_t *lcf = conf;
1870
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001871 char *rv;
Igor Sysoev805d9db2005-02-03 19:33:37 +00001872 ngx_conf_t save;
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001873
Igor Sysoev7bdb7202006-04-19 15:30:56 +00001874 if (lcf->types == NULL) {
1875 lcf->types = ngx_array_create(cf->pool, 64, sizeof(ngx_hash_key_t));
1876 if (lcf->types == NULL) {
1877 return NGX_CONF_ERROR;
1878 }
1879 }
1880
Igor Sysoev805d9db2005-02-03 19:33:37 +00001881 save = *cf;
1882 cf->handler = ngx_http_core_type;
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001883 cf->handler_conf = conf;
Igor Sysoev805d9db2005-02-03 19:33:37 +00001884
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001885 rv = ngx_conf_parse(cf, NULL);
Igor Sysoev805d9db2005-02-03 19:33:37 +00001886
1887 *cf = save;
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001888
1889 return rv;
1890}
1891
1892
Igor Sysoevaa828612005-02-09 14:31:07 +00001893static char *
1894ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
Igor Sysoevaa3436c2003-05-30 14:27:59 +00001895{
1896 ngx_http_core_loc_conf_t *lcf = conf;
Igor Sysoev79a80482003-05-14 17:13:13 +00001897
Igor Sysoev24025022005-12-16 15:07:08 +00001898 ngx_str_t *value, *content_type, *old;
1899 ngx_uint_t i, n;
1900 ngx_hash_key_t *type;
Igor Sysoev79a80482003-05-14 17:13:13 +00001901
Igor Sysoev24025022005-12-16 15:07:08 +00001902 content_type = ngx_palloc(cf->pool, sizeof(ngx_str_t));
1903 if (content_type == NULL) {
1904 return NGX_CONF_ERROR;
Igor Sysoev79a80482003-05-14 17:13:13 +00001905 }
1906
Igor Sysoev805d9db2005-02-03 19:33:37 +00001907 value = cf->args->elts;
Igor Sysoev24025022005-12-16 15:07:08 +00001908 *content_type = value[0];
Igor Sysoev79a80482003-05-14 17:13:13 +00001909
1910 for (i = 1; i < cf->args->nelts; i++) {
Igor Sysoev79a80482003-05-14 17:13:13 +00001911
Igor Sysoev24025022005-12-16 15:07:08 +00001912 for (n = 0; n < value[i].len; n++) {
1913 value[i].data[n] = ngx_tolower(value[i].data[n]);
1914 }
1915
1916 type = lcf->types->elts;
1917 for (n = 0; n < lcf->types->nelts; n++) {
1918 if (ngx_strcmp(value[i].data, type[n].key.data) == 0) {
1919 old = type[n].value;
1920 type[n].value = content_type;
1921
1922 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
1923 "duplicate extention \"%V\", "
1924 "content type: \"%V\", "
1925 "old content type: \"%V\"",
1926 &value[i], content_type, old);
1927 continue;
1928 }
1929 }
1930
1931
1932 type = ngx_array_push(lcf->types);
Igor Sysoevc1571722005-03-19 12:38:37 +00001933 if (type == NULL) {
Igor Sysoevdc3b2a72004-09-14 19:39:54 +00001934 return NGX_CONF_ERROR;
1935 }
1936
Igor Sysoev24025022005-12-16 15:07:08 +00001937 type->key = value[i];
1938 type->key_hash = ngx_hash_key(value[i].data, value[i].len);
1939 type->value = content_type;
Igor Sysoev79a80482003-05-14 17:13:13 +00001940 }
1941
1942 return NGX_CONF_OK;
1943}
1944
1945
Igor Sysoev899b44e2005-05-12 14:58:06 +00001946static ngx_int_t
1947ngx_http_core_preconfiguration(ngx_conf_t *cf)
1948{
1949 return ngx_http_variables_add_core_vars(cf);
1950}
1951
1952
Igor Sysoevaa828612005-02-09 14:31:07 +00001953static void *
1954ngx_http_core_create_main_conf(ngx_conf_t *cf)
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001955{
Igor Sysoev805d9db2005-02-03 19:33:37 +00001956 ngx_http_core_main_conf_t *cmcf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001957
Igor Sysoevc1571722005-03-19 12:38:37 +00001958 cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_main_conf_t));
1959 if (cmcf == NULL) {
Igor Sysoev805d9db2005-02-03 19:33:37 +00001960 return NGX_CONF_ERROR;
1961 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001962
Igor Sysoev8184d1b2005-03-04 14:06:57 +00001963 if (ngx_array_init(&cmcf->servers, cf->pool, 4,
Igor Sysoev9ac946b2005-10-24 15:09:41 +00001964 sizeof(ngx_http_core_srv_conf_t *))
Igor Sysoev6f134cc2006-05-23 14:54:58 +00001965 != NGX_OK)
Igor Sysoev805d9db2005-02-03 19:33:37 +00001966 {
1967 return NGX_CONF_ERROR;
1968 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001969
Igor Sysoev305a9d82005-12-26 17:07:48 +00001970 cmcf->server_names_hash_max_size = NGX_CONF_UNSET_UINT;
1971 cmcf->server_names_hash_bucket_size = NGX_CONF_UNSET_UINT;
Igor Sysoevb1dfe472004-12-21 12:30:30 +00001972
Igor Sysoevffe71442006-02-08 15:33:12 +00001973 cmcf->variables_hash_max_size = NGX_CONF_UNSET_UINT;
1974 cmcf->variables_hash_bucket_size = NGX_CONF_UNSET_UINT;
1975
Igor Sysoeva9830112003-05-19 16:39:14 +00001976 return cmcf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001977}
1978
1979
Igor Sysoevaa828612005-02-09 14:31:07 +00001980static char *
1981ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf)
Igor Sysoev4e9393a2003-01-09 05:36:00 +00001982{
Igor Sysoev6253ca12003-05-27 12:18:54 +00001983 ngx_http_core_main_conf_t *cmcf = conf;
Igor Sysoeva9830112003-05-19 16:39:14 +00001984
Igor Sysoev305a9d82005-12-26 17:07:48 +00001985 if (cmcf->server_names_hash_max_size == NGX_CONF_UNSET_UINT) {
1986 cmcf->server_names_hash_max_size = 512;
Igor Sysoevb1dfe472004-12-21 12:30:30 +00001987 }
1988
Igor Sysoev305a9d82005-12-26 17:07:48 +00001989 if (cmcf->server_names_hash_bucket_size == NGX_CONF_UNSET_UINT) {
1990 cmcf->server_names_hash_bucket_size = ngx_cacheline_size;
Igor Sysoevb1dfe472004-12-21 12:30:30 +00001991 }
Igor Sysoeva9830112003-05-19 16:39:14 +00001992
Igor Sysoev305a9d82005-12-26 17:07:48 +00001993 cmcf->server_names_hash_bucket_size =
1994 ngx_align(cmcf->server_names_hash_bucket_size, ngx_cacheline_size);
1995
Igor Sysoevffe71442006-02-08 15:33:12 +00001996
1997 if (cmcf->variables_hash_max_size == NGX_CONF_UNSET_UINT) {
1998 cmcf->variables_hash_max_size = 512;
1999 }
2000
2001 if (cmcf->variables_hash_bucket_size == NGX_CONF_UNSET_UINT) {
2002 cmcf->variables_hash_bucket_size = 64;
2003 }
2004
2005 cmcf->variables_hash_bucket_size =
2006 ngx_align(cmcf->variables_hash_bucket_size, ngx_cacheline_size);
2007
Igor Sysoeva9830112003-05-19 16:39:14 +00002008 return NGX_CONF_OK;
2009}
2010
2011
Igor Sysoevaa828612005-02-09 14:31:07 +00002012static void *
2013ngx_http_core_create_srv_conf(ngx_conf_t *cf)
Igor Sysoeva9830112003-05-19 16:39:14 +00002014{
2015 ngx_http_core_srv_conf_t *cscf;
2016
Igor Sysoevc1571722005-03-19 12:38:37 +00002017 cscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_srv_conf_t));
2018 if (cscf == NULL) {
Igor Sysoevaa828612005-02-09 14:31:07 +00002019 return NGX_CONF_ERROR;
2020 }
2021
Igor Sysoev85080d02004-09-22 16:18:21 +00002022 /*
Igor Sysoev02025fd2005-01-18 13:03:58 +00002023 * set by ngx_pcalloc():
Igor Sysoevaa828612005-02-09 14:31:07 +00002024 *
Igor Sysoev02025fd2005-01-18 13:03:58 +00002025 * conf->client_large_buffers.num = 0;
2026 */
Igor Sysoev85080d02004-09-22 16:18:21 +00002027
Igor Sysoev8184d1b2005-03-04 14:06:57 +00002028 if (ngx_array_init(&cscf->locations, cf->pool, 4, sizeof(void *))
Igor Sysoev305a9d82005-12-26 17:07:48 +00002029 == NGX_ERROR)
Igor Sysoevaa828612005-02-09 14:31:07 +00002030 {
2031 return NGX_CONF_ERROR;
2032 }
2033
Igor Sysoev8184d1b2005-03-04 14:06:57 +00002034 if (ngx_array_init(&cscf->listen, cf->pool, 4, sizeof(ngx_http_listen_t))
Igor Sysoev305a9d82005-12-26 17:07:48 +00002035 == NGX_ERROR)
Igor Sysoevaa828612005-02-09 14:31:07 +00002036 {
2037 return NGX_CONF_ERROR;
2038 }
2039
Igor Sysoevda173ab2006-08-30 10:39:17 +00002040 if (ngx_array_init(&cscf->server_names, cf->temp_pool, 4,
Igor Sysoev305a9d82005-12-26 17:07:48 +00002041 sizeof(ngx_http_server_name_t))
2042 == NGX_ERROR)
Igor Sysoevaa828612005-02-09 14:31:07 +00002043 {
2044 return NGX_CONF_ERROR;
2045 }
Igor Sysoeva9830112003-05-19 16:39:14 +00002046
Igor Sysoev10a543a2004-03-16 07:10:12 +00002047 cscf->connection_pool_size = NGX_CONF_UNSET_SIZE;
Igor Sysoev10a543a2004-03-16 07:10:12 +00002048 cscf->request_pool_size = NGX_CONF_UNSET_SIZE;
2049 cscf->client_header_timeout = NGX_CONF_UNSET_MSEC;
2050 cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE;
Igor Sysoev8290d282006-02-03 12:58:48 +00002051 cscf->optimize_server_names = NGX_CONF_UNSET;
Igor Sysoev3362b8d2005-05-14 18:42:03 +00002052 cscf->ignore_invalid_headers = NGX_CONF_UNSET;
Igor Sysoev187fcd82003-05-23 11:53:01 +00002053
Igor Sysoeva9830112003-05-19 16:39:14 +00002054 return cscf;
2055}
2056
2057
Igor Sysoevaa828612005-02-09 14:31:07 +00002058static char *
2059ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
Igor Sysoeva9830112003-05-19 16:39:14 +00002060{
Igor Sysoevaa3436c2003-05-30 14:27:59 +00002061 ngx_http_core_srv_conf_t *prev = parent;
2062 ngx_http_core_srv_conf_t *conf = child;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00002063
Igor Sysoev305a9d82005-12-26 17:07:48 +00002064 ngx_http_listen_t *ls;
2065 ngx_http_server_name_t *sn;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00002066
Igor Sysoev7578ec92003-06-02 15:24:30 +00002067 /* TODO: it does not merge, it inits only */
Igor Sysoeva9830112003-05-19 16:39:14 +00002068
2069 if (conf->listen.nelts == 0) {
Igor Sysoevc1571722005-03-19 12:38:37 +00002070 ls = ngx_array_push(&conf->listen);
2071 if (ls == NULL) {
Igor Sysoevaa828612005-02-09 14:31:07 +00002072 return NGX_CONF_ERROR;
2073 }
2074
Igor Sysoevb145b062005-06-15 18:33:41 +00002075 ngx_memzero(ls, sizeof(ngx_http_listen_t));
2076
Igor Sysoevaa828612005-02-09 14:31:07 +00002077 ls->addr = INADDR_ANY;
Igor Sysoev1b735832004-11-11 14:07:14 +00002078#if (NGX_WIN32)
Igor Sysoevaa828612005-02-09 14:31:07 +00002079 ls->port = 80;
Igor Sysoev1c104622003-06-03 15:42:58 +00002080#else
Igor Sysoev7578ec92003-06-02 15:24:30 +00002081 /* STUB: getuid() should be cached */
Igor Sysoevaa828612005-02-09 14:31:07 +00002082 ls->port = (getuid() == 0) ? 80 : 8000;
Igor Sysoev1c104622003-06-03 15:42:58 +00002083#endif
Igor Sysoevaa828612005-02-09 14:31:07 +00002084 ls->family = AF_INET;
Igor Sysoev9ac946b2005-10-24 15:09:41 +00002085
2086 ls->conf.backlog = -1;
2087 ls->conf.rcvbuf = -1;
2088 ls->conf.sndbuf = -1;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00002089 }
2090
Igor Sysoev9e580192006-02-01 18:22:15 +00002091 if (conf->server_name.data == NULL) {
2092 conf->server_name.data = ngx_palloc(cf->pool, NGX_MAXHOSTNAMELEN);
2093 if (conf->server_name.data == NULL) {
Igor Sysoevaa828612005-02-09 14:31:07 +00002094 return NGX_CONF_ERROR;
2095 }
Igor Sysoev13933252003-05-29 13:02:09 +00002096
Igor Sysoev9e580192006-02-01 18:22:15 +00002097 if (gethostname((char *) conf->server_name.data, NGX_MAXHOSTNAMELEN)
2098 == -1)
2099 {
Igor Sysoev8e1fbe62003-07-18 14:44:05 +00002100 ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
2101 "gethostname() failed");
2102 return NGX_CONF_ERROR;
Igor Sysoevad22e012003-01-15 07:02:27 +00002103 }
Igor Sysoev13933252003-05-29 13:02:09 +00002104
Igor Sysoev9e580192006-02-01 18:22:15 +00002105 conf->server_name.len = ngx_strlen(conf->server_name.data);
2106
2107 sn = ngx_array_push(&conf->server_names);
2108 if (sn == NULL) {
2109 return NGX_CONF_ERROR;
2110 }
2111
2112 sn->name.len = conf->server_name.len;
2113 sn->name.data = conf->server_name.data;
Igor Sysoevaa828612005-02-09 14:31:07 +00002114 sn->core_srv_conf = conf;
Igor Sysoevad22e012003-01-15 07:02:27 +00002115 }
2116
Igor Sysoev239baac2003-06-11 15:28:34 +00002117 ngx_conf_merge_size_value(conf->connection_pool_size,
Igor Sysoev8035fd22004-10-01 15:53:53 +00002118 prev->connection_pool_size, 256);
Igor Sysoev187fcd82003-05-23 11:53:01 +00002119 ngx_conf_merge_size_value(conf->request_pool_size,
Igor Sysoev8035fd22004-10-01 15:53:53 +00002120 prev->request_pool_size, 4096);
Igor Sysoev187fcd82003-05-23 11:53:01 +00002121 ngx_conf_merge_msec_value(conf->client_header_timeout,
2122 prev->client_header_timeout, 60000);
2123 ngx_conf_merge_size_value(conf->client_header_buffer_size,
2124 prev->client_header_buffer_size, 1024);
Igor Sysoevf7abd722004-09-23 06:32:00 +00002125 ngx_conf_merge_bufs_value(conf->large_client_header_buffers,
2126 prev->large_client_header_buffers,
2127 4, ngx_pagesize);
2128
2129 if (conf->large_client_header_buffers.size < conf->connection_pool_size) {
2130 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2131 "the \"large_client_header_buffers\" size must be "
2132 "equal to or bigger than \"connection_pool_size\"");
2133 return NGX_CONF_ERROR;
2134 }
2135
Igor Sysoev8290d282006-02-03 12:58:48 +00002136 ngx_conf_merge_value(conf->optimize_server_names,
2137 prev->optimize_server_names, 1);
Igor Sysoev34303462006-01-24 16:08:27 +00002138
Igor Sysoev3362b8d2005-05-14 18:42:03 +00002139 ngx_conf_merge_value(conf->ignore_invalid_headers,
2140 prev->ignore_invalid_headers, 1);
2141
Igor Sysoev4e9393a2003-01-09 05:36:00 +00002142 return NGX_CONF_OK;
2143}
2144
2145
Igor Sysoevaa828612005-02-09 14:31:07 +00002146static void *
2147ngx_http_core_create_loc_conf(ngx_conf_t *cf)
Igor Sysoev4e9393a2003-01-09 05:36:00 +00002148{
Igor Sysoev805d9db2005-02-03 19:33:37 +00002149 ngx_http_core_loc_conf_t *lcf;
Igor Sysoev4e9393a2003-01-09 05:36:00 +00002150
Igor Sysoevc1571722005-03-19 12:38:37 +00002151 lcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_loc_conf_t));
2152 if (lcf == NULL) {
Igor Sysoevaa828612005-02-09 14:31:07 +00002153 return NGX_CONF_ERROR;
2154 }
Igor Sysoev4e9393a2003-01-09 05:36:00 +00002155
Igor Sysoev02025fd2005-01-18 13:03:58 +00002156 /*
2157 * set by ngx_pcalloc():
2158 *
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +00002159 * lcf->root = { 0, NULL };
Igor Sysoev94e32ce2006-04-07 14:08:04 +00002160 * lcf->limit_except = 0;
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +00002161 * lcf->post_action = { 0, NULL };
Igor Sysoev02025fd2005-01-18 13:03:58 +00002162 * lcf->types = NULL;
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +00002163 * lcf->default_type = { 0, NULL };
Igor Sysoev02025fd2005-01-18 13:03:58 +00002164 * lcf->err_log = NULL;
2165 * lcf->error_pages = NULL;
2166 * lcf->client_body_path = NULL;
2167 * lcf->regex = NULL;
2168 * lcf->exact_match = 0;
2169 * lcf->auto_redirect = 0;
2170 * lcf->alias = 0;
2171 */
Igor Sysoev4e9393a2003-01-09 05:36:00 +00002172
Igor Sysoev1765f472006-07-07 16:33:19 +00002173 lcf->client_max_body_size = NGX_CONF_UNSET;
Igor Sysoevdbb27762004-04-01 16:20:53 +00002174 lcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE;
Igor Sysoev10a543a2004-03-16 07:10:12 +00002175 lcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
Igor Sysoev31eb8c02005-09-23 11:02:22 +00002176 lcf->satisfy_any = NGX_CONF_UNSET;
Igor Sysoev899b44e2005-05-12 14:58:06 +00002177 lcf->internal = NGX_CONF_UNSET;
Igor Sysoev8a2b2fb2006-04-14 09:53:38 +00002178 lcf->client_body_in_file_only = NGX_CONF_UNSET;
Igor Sysoev5bf3d252003-10-22 07:05:29 +00002179 lcf->sendfile = NGX_CONF_UNSET;
Igor Sysoev3c3ca172004-01-05 20:55:48 +00002180 lcf->tcp_nopush = NGX_CONF_UNSET;
Igor Sysoev924bd792004-10-11 15:07:03 +00002181 lcf->tcp_nodelay = NGX_CONF_UNSET;
Igor Sysoev10a543a2004-03-16 07:10:12 +00002182 lcf->send_timeout = NGX_CONF_UNSET_MSEC;
2183 lcf->send_lowat = NGX_CONF_UNSET_SIZE;
Igor Sysoev7823cc32004-07-14 16:01:42 +00002184 lcf->postpone_output = NGX_CONF_UNSET_SIZE;
2185 lcf->limit_rate = NGX_CONF_UNSET_SIZE;
Igor Sysoev10a543a2004-03-16 07:10:12 +00002186 lcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
Igor Sysoev307c3ad2004-09-17 16:07:35 +00002187 lcf->keepalive_header = NGX_CONF_UNSET;
Igor Sysoev10a543a2004-03-16 07:10:12 +00002188 lcf->lingering_time = NGX_CONF_UNSET_MSEC;
2189 lcf->lingering_timeout = NGX_CONF_UNSET_MSEC;
Igor Sysoev0ab91b92004-06-06 19:49:18 +00002190 lcf->reset_timedout_connection = NGX_CONF_UNSET;
Igor Sysoev7b190b42005-06-07 15:56:31 +00002191 lcf->port_in_redirect = NGX_CONF_UNSET;
Igor Sysoev12b4b002003-10-24 06:53:41 +00002192 lcf->msie_padding = NGX_CONF_UNSET;
Igor Sysoev3f8dc592006-08-28 16:57:48 +00002193 lcf->msie_refresh = NGX_CONF_UNSET;
Igor Sysoev5192b362005-07-08 14:34:20 +00002194 lcf->log_not_found = NGX_CONF_UNSET;
Igor Sysoev3f8dc592006-08-28 16:57:48 +00002195 lcf->recursive_error_pages = NGX_CONF_UNSET;
Igor Sysoev24025022005-12-16 15:07:08 +00002196 lcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
2197 lcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;
Igor Sysoev12b4b002003-10-24 06:53:41 +00002198
Igor Sysoev4e9393a2003-01-09 05:36:00 +00002199 return lcf;
2200}
Igor Sysoeva19a85e2003-01-28 15:56:37 +00002201
Igor Sysoev79a80482003-05-14 17:13:13 +00002202
Igor Sysoev24025022005-12-16 15:07:08 +00002203static ngx_str_t ngx_http_core_text_html_type = ngx_string("text/html");
2204static ngx_str_t ngx_http_core_image_gif_type = ngx_string("image/gif");
2205static ngx_str_t ngx_http_core_image_jpeg_type = ngx_string("image/jpeg");
2206
2207static ngx_hash_key_t ngx_http_core_default_types[] = {
2208 { ngx_string("html"), 0, &ngx_http_core_text_html_type },
2209 { ngx_string("gif"), 0, &ngx_http_core_image_gif_type },
2210 { ngx_string("jpg"), 0, &ngx_http_core_image_jpeg_type },
2211 { ngx_null_string, 0, NULL }
Igor Sysoev79a80482003-05-14 17:13:13 +00002212};
2213
2214
Igor Sysoevaa828612005-02-09 14:31:07 +00002215static char *
Igor Sysoev24025022005-12-16 15:07:08 +00002216ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
Igor Sysoeve2a31542003-04-08 15:40:10 +00002217{
Igor Sysoevaa3436c2003-05-30 14:27:59 +00002218 ngx_http_core_loc_conf_t *prev = parent;
2219 ngx_http_core_loc_conf_t *conf = child;
Igor Sysoev79a80482003-05-14 17:13:13 +00002220
Igor Sysoevaa828612005-02-09 14:31:07 +00002221 ngx_uint_t i;
Igor Sysoev24025022005-12-16 15:07:08 +00002222 ngx_hash_key_t *type;
2223 ngx_hash_init_t types_hash;
Igor Sysoev79a80482003-05-14 17:13:13 +00002224
Igor Sysoev34303462006-01-24 16:08:27 +00002225 if (conf->root.data == NULL) {
Igor Sysoev79a80482003-05-14 17:13:13 +00002226
Igor Sysoev455a7fc2006-03-21 08:20:41 +00002227 conf->alias = prev->alias;
Igor Sysoev34303462006-01-24 16:08:27 +00002228 conf->root = prev->root;
2229 conf->root_lengths = prev->root_lengths;
2230 conf->root_values = prev->root_values;
2231
2232 if (prev->root.data == NULL) {
2233 conf->root.len = sizeof("html") - 1;
2234 conf->root.data = (u_char *) "html";
2235
2236 if (ngx_conf_full_name(cf->cycle, &conf->root) == NGX_ERROR) {
2237 return NGX_CONF_ERROR;
2238 }
2239 }
Igor Sysoev6d2a14a2004-09-27 16:03:21 +00002240 }
2241
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +00002242 if (conf->post_action.data == NULL) {
2243 conf->post_action = prev->post_action;
2244 }
2245
Igor Sysoev1765f472006-07-07 16:33:19 +00002246 ngx_conf_merge_uint_value(conf->types_hash_max_size,
2247 prev->types_hash_max_size, 1024);
Igor Sysoev79a80482003-05-14 17:13:13 +00002248
Igor Sysoev1765f472006-07-07 16:33:19 +00002249 ngx_conf_merge_uint_value(conf->types_hash_bucket_size,
2250 prev->types_hash_bucket_size,
2251 ngx_cacheline_size);
Igor Sysoev24025022005-12-16 15:07:08 +00002252
2253 conf->types_hash_bucket_size = ngx_align(conf->types_hash_bucket_size,
2254 ngx_cacheline_size);
2255
2256 /*
2257 * the special handling the "types" directive in the "http" section
2258 * to inherit the http's conf->types_hash to all servers
2259 */
2260
2261 if (prev->types && prev->types_hash.buckets == NULL) {
2262
2263 types_hash.hash = &prev->types_hash;
2264 types_hash.key = ngx_hash_key_lc;
2265 types_hash.max_size = conf->types_hash_max_size;
2266 types_hash.bucket_size = conf->types_hash_bucket_size;
Igor Sysoev3ca233e2005-12-28 14:23:52 +00002267 types_hash.name = "types_hash";
Igor Sysoev24025022005-12-16 15:07:08 +00002268 types_hash.pool = cf->pool;
2269 types_hash.temp_pool = NULL;
2270
2271 if (ngx_hash_init(&types_hash, prev->types->elts, prev->types->nelts)
2272 != NGX_OK)
2273 {
2274 return NGX_CONF_ERROR;
2275 }
2276 }
2277
2278 if (conf->types == NULL) {
2279 conf->types = prev->types;
2280 conf->types_hash = prev->types_hash;
2281 }
2282
2283 if (conf->types == NULL) {
2284 conf->types = ngx_array_create(cf->pool, 4, sizeof(ngx_hash_key_t));
2285 if (conf->types == NULL) {
2286 return NGX_CONF_ERROR;
2287 }
2288
2289 for (i = 0; ngx_http_core_default_types[i].key.len; i++) {
2290 type = ngx_array_push(conf->types);
2291 if (type == NULL) {
Igor Sysoevaa828612005-02-09 14:31:07 +00002292 return NGX_CONF_ERROR;
Igor Sysoev79a80482003-05-14 17:13:13 +00002293 }
2294
Igor Sysoev24025022005-12-16 15:07:08 +00002295 type->key = ngx_http_core_default_types[i].key;
2296 type->key_hash =
2297 ngx_hash_key_lc(ngx_http_core_default_types[i].key.data,
2298 ngx_http_core_default_types[i].key.len);
2299 type->value = ngx_http_core_default_types[i].value;
2300 }
2301 }
Igor Sysoev79a80482003-05-14 17:13:13 +00002302
Igor Sysoev24025022005-12-16 15:07:08 +00002303 if (conf->types_hash.buckets == NULL) {
Igor Sysoevaa828612005-02-09 14:31:07 +00002304
Igor Sysoev24025022005-12-16 15:07:08 +00002305 types_hash.hash = &conf->types_hash;
2306 types_hash.key = ngx_hash_key_lc;
2307 types_hash.max_size = conf->types_hash_max_size;
2308 types_hash.bucket_size = conf->types_hash_bucket_size;
Igor Sysoev3ca233e2005-12-28 14:23:52 +00002309 types_hash.name = "mime_types_hash";
Igor Sysoev24025022005-12-16 15:07:08 +00002310 types_hash.pool = cf->pool;
2311 types_hash.temp_pool = NULL;
Igor Sysoevaa828612005-02-09 14:31:07 +00002312
Igor Sysoev24025022005-12-16 15:07:08 +00002313 if (ngx_hash_init(&types_hash, conf->types->elts, conf->types->nelts)
2314 != NGX_OK)
2315 {
2316 return NGX_CONF_ERROR;
Igor Sysoev79a80482003-05-14 17:13:13 +00002317 }
2318 }
2319
Igor Sysoev890fc962003-07-20 21:15:59 +00002320 if (conf->err_log == NULL) {
2321 if (prev->err_log) {
2322 conf->err_log = prev->err_log;
2323 } else {
Igor Sysoev630ad0c2004-04-16 05:14:16 +00002324 conf->err_log = cf->cycle->new_log;
Igor Sysoev890fc962003-07-20 21:15:59 +00002325 }
2326 }
2327
Igor Sysoev74e95c22003-11-09 20:03:38 +00002328 if (conf->error_pages == NULL && prev->error_pages) {
2329 conf->error_pages = prev->error_pages;
2330 }
2331
Igor Sysoev6253ca12003-05-27 12:18:54 +00002332 ngx_conf_merge_str_value(conf->default_type,
Igor Sysoevaa828612005-02-09 14:31:07 +00002333 prev->default_type, "text/plain");
Igor Sysoev6253ca12003-05-27 12:18:54 +00002334
Igor Sysoev1765f472006-07-07 16:33:19 +00002335 ngx_conf_merge_off_value(conf->client_max_body_size,
Igor Sysoev8035fd22004-10-01 15:53:53 +00002336 prev->client_max_body_size, 1 * 1024 * 1024);
Igor Sysoevdbb27762004-04-01 16:20:53 +00002337 ngx_conf_merge_size_value(conf->client_body_buffer_size,
Igor Sysoev8035fd22004-10-01 15:53:53 +00002338 prev->client_body_buffer_size,
2339 (size_t) 2 * ngx_pagesize);
Igor Sysoev2b0c76c2003-10-27 21:01:00 +00002340 ngx_conf_merge_msec_value(conf->client_body_timeout,
Igor Sysoev7af6b162004-02-09 07:46:43 +00002341 prev->client_body_timeout, 60000);
Igor Sysoev899b44e2005-05-12 14:58:06 +00002342
Igor Sysoev31eb8c02005-09-23 11:02:22 +00002343 ngx_conf_merge_value(conf->satisfy_any, prev->satisfy_any, 0);
Igor Sysoev899b44e2005-05-12 14:58:06 +00002344 ngx_conf_merge_value(conf->internal, prev->internal, 0);
Igor Sysoev8a2b2fb2006-04-14 09:53:38 +00002345 ngx_conf_merge_value(conf->client_body_in_file_only,
2346 prev->client_body_in_file_only, 0);
Igor Sysoev5bf3d252003-10-22 07:05:29 +00002347 ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0);
Igor Sysoev3c3ca172004-01-05 20:55:48 +00002348 ngx_conf_merge_value(conf->tcp_nopush, prev->tcp_nopush, 0);
Igor Sysoev3f8dc592006-08-28 16:57:48 +00002349 ngx_conf_merge_value(conf->tcp_nodelay, prev->tcp_nodelay, 1);
Igor Sysoev899b44e2005-05-12 14:58:06 +00002350
Igor Sysoev7af6b162004-02-09 07:46:43 +00002351 ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 60000);
Igor Sysoevb5faed22003-10-29 08:30:44 +00002352 ngx_conf_merge_size_value(conf->send_lowat, prev->send_lowat, 0);
Igor Sysoev7823cc32004-07-14 16:01:42 +00002353 ngx_conf_merge_size_value(conf->postpone_output, prev->postpone_output,
2354 1460);
2355 ngx_conf_merge_size_value(conf->limit_rate, prev->limit_rate, 0);
Igor Sysoev187fcd82003-05-23 11:53:01 +00002356 ngx_conf_merge_msec_value(conf->keepalive_timeout,
Igor Sysoev307c3ad2004-09-17 16:07:35 +00002357 prev->keepalive_timeout, 75000);
2358 ngx_conf_merge_sec_value(conf->keepalive_header,
2359 prev->keepalive_header, 0);
Igor Sysoev187fcd82003-05-23 11:53:01 +00002360 ngx_conf_merge_msec_value(conf->lingering_time,
2361 prev->lingering_time, 30000);
2362 ngx_conf_merge_msec_value(conf->lingering_timeout,
2363 prev->lingering_timeout, 5000);
Igor Sysoev79a80482003-05-14 17:13:13 +00002364
Igor Sysoev02025fd2005-01-18 13:03:58 +00002365 ngx_conf_merge_path_value(conf->client_body_temp_path,
2366 prev->client_body_temp_path,
2367 NGX_HTTP_CLIENT_TEMP_PATH, 0, 0, 0,
2368 ngx_garbage_collector_temp_handler, cf);
2369
Igor Sysoev0ab91b92004-06-06 19:49:18 +00002370 ngx_conf_merge_value(conf->reset_timedout_connection,
Igor Sysoevaa828612005-02-09 14:31:07 +00002371 prev->reset_timedout_connection, 0);
Igor Sysoev7b190b42005-06-07 15:56:31 +00002372 ngx_conf_merge_value(conf->port_in_redirect, prev->port_in_redirect, 1);
Igor Sysoev12b4b002003-10-24 06:53:41 +00002373 ngx_conf_merge_value(conf->msie_padding, prev->msie_padding, 1);
Igor Sysoev3f8dc592006-08-28 16:57:48 +00002374 ngx_conf_merge_value(conf->msie_refresh, prev->msie_refresh, 0);
Igor Sysoev5192b362005-07-08 14:34:20 +00002375 ngx_conf_merge_value(conf->log_not_found, prev->log_not_found, 1);
Igor Sysoev3f8dc592006-08-28 16:57:48 +00002376 ngx_conf_merge_value(conf->recursive_error_pages,
2377 prev->recursive_error_pages, 0);
Igor Sysoev12b4b002003-10-24 06:53:41 +00002378
Igor Sysoev865c1502003-11-30 20:03:18 +00002379 if (conf->open_files == NULL) {
2380 conf->open_files = prev->open_files;
2381 }
2382
Igor Sysoeve2a31542003-04-08 15:40:10 +00002383 return NGX_CONF_OK;
2384}
2385
Igor Sysoev79a80482003-05-14 17:13:13 +00002386
Igor Sysoevb145b062005-06-15 18:33:41 +00002387/* AF_INET only */
2388
Igor Sysoevaa828612005-02-09 14:31:07 +00002389static char *
2390ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoeva19a85e2003-01-28 15:56:37 +00002391{
Igor Sysoevaa3436c2003-05-30 14:27:59 +00002392 ngx_http_core_srv_conf_t *scf = conf;
Igor Sysoeva9830112003-05-19 16:39:14 +00002393
Igor Sysoev20bf47b2006-10-24 13:06:55 +00002394 ngx_str_t *value, size;
2395 ngx_url_t u;
2396 ngx_uint_t n;
2397 ngx_http_listen_t *ls;
Igor Sysoeva19a85e2003-01-28 15:56:37 +00002398
Igor Sysoeve2ff3ea2004-09-14 15:55:24 +00002399 /*
2400 * TODO: check duplicate 'listen' directives,
2401 * add resolved name to server names ???
2402 */
Igor Sysoev6ddfbf02003-05-15 15:42:53 +00002403
Igor Sysoevb145b062005-06-15 18:33:41 +00002404 value = cf->args->elts;
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +00002405
Igor Sysoev20bf47b2006-10-24 13:06:55 +00002406 ngx_memzero(&u, sizeof(ngx_url_t));
Igor Sysoevb145b062005-06-15 18:33:41 +00002407
Igor Sysoev20bf47b2006-10-24 13:06:55 +00002408 u.url = value[1];
2409 u.listen = 1;
Igor Sysoevbf3aaac2006-12-12 16:46:16 +00002410 u.default_port = 80;
Igor Sysoevb145b062005-06-15 18:33:41 +00002411
Igor Sysoev20bf47b2006-10-24 13:06:55 +00002412 if (ngx_parse_url(cf, &u) != NGX_OK) {
2413 if (u.err) {
2414 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2415 "%s in \"%V\" of the \"listen\" directive",
2416 u.err, &u.url);
2417 }
Igor Sysoevb145b062005-06-15 18:33:41 +00002418
Igor Sysoev0e5dc5c2005-11-15 13:30:52 +00002419 return NGX_CONF_ERROR;
Igor Sysoevb145b062005-06-15 18:33:41 +00002420 }
2421
Igor Sysoevc1571722005-03-19 12:38:37 +00002422 ls = ngx_array_push(&scf->listen);
2423 if (ls == NULL) {
Igor Sysoeve2ff3ea2004-09-14 15:55:24 +00002424 return NGX_CONF_ERROR;
2425 }
Igor Sysoeva19a85e2003-01-28 15:56:37 +00002426
Igor Sysoevb145b062005-06-15 18:33:41 +00002427 ngx_memzero(ls, sizeof(ngx_http_listen_t));
Igor Sysoeva19a85e2003-01-28 15:56:37 +00002428
2429 ls->family = AF_INET;
Igor Sysoev20bf47b2006-10-24 13:06:55 +00002430 ls->addr = u.addr.in_addr;
Igor Sysoevbf3aaac2006-12-12 16:46:16 +00002431 ls->port = u.port;
Igor Sysoevfe5cb6b2003-01-29 07:25:51 +00002432 ls->file_name = cf->conf_file->file.name;
Igor Sysoeva19a85e2003-01-28 15:56:37 +00002433 ls->line = cf->conf_file->line;
Igor Sysoevb145b062005-06-15 18:33:41 +00002434 ls->conf.backlog = -1;
Igor Sysoevc2068d02005-10-19 12:33:58 +00002435 ls->conf.rcvbuf = -1;
2436 ls->conf.sndbuf = -1;
Igor Sysoeva19a85e2003-01-28 15:56:37 +00002437
Igor Sysoev94e32ce2006-04-07 14:08:04 +00002438 n = ngx_inet_ntop(AF_INET, &ls->addr, ls->conf.addr, INET_ADDRSTRLEN + 6);
2439 ngx_sprintf(&ls->conf.addr[n], ":%ui", ls->port);
2440
Igor Sysoevb145b062005-06-15 18:33:41 +00002441 if (cf->args->nelts == 2) {
2442 return NGX_CONF_OK;
2443 }
Igor Sysoevaa828612005-02-09 14:31:07 +00002444
Igor Sysoevb145b062005-06-15 18:33:41 +00002445 if (ngx_strcmp(value[2].data, "default") == 0) {
2446 ls->conf.default_server = 1;
2447 n = 3;
Igor Sysoev24025022005-12-16 15:07:08 +00002448
Igor Sysoevb145b062005-06-15 18:33:41 +00002449 } else {
2450 n = 2;
2451 }
Igor Sysoev13933252003-05-29 13:02:09 +00002452
Igor Sysoevb145b062005-06-15 18:33:41 +00002453 for ( /* void */ ; n < cf->args->nelts; n++) {
2454
2455 if (ls->conf.default_server == 0) {
Igor Sysoev8e1fbe62003-07-18 14:44:05 +00002456 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
Igor Sysoevb145b062005-06-15 18:33:41 +00002457 "\"%V\" parameter can be specified for "
2458 "the default \"listen\" directive only",
2459 &value[n]);
Igor Sysoev8e1fbe62003-07-18 14:44:05 +00002460 return NGX_CONF_ERROR;
Igor Sysoev13933252003-05-29 13:02:09 +00002461 }
2462
Igor Sysoevb145b062005-06-15 18:33:41 +00002463 if (ngx_strcmp(value[n].data, "bind") == 0) {
2464 ls->conf.bind = 1;
2465 continue;
2466 }
2467
Igor Sysoevc2068d02005-10-19 12:33:58 +00002468 if (ngx_strncmp(value[n].data, "backlog=", 8) == 0) {
2469 ls->conf.backlog = ngx_atoi(value[n].data + 8, value[n].len - 8);
Igor Sysoevb145b062005-06-15 18:33:41 +00002470 ls->conf.bind = 1;
2471
2472 if (ls->conf.backlog == NGX_ERROR || ls->conf.backlog == 0) {
2473 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2474 "invalid backlog \"%V\"", &value[n]);
2475 return NGX_CONF_ERROR;
2476 }
2477
2478 continue;
2479 }
2480
Igor Sysoevc2068d02005-10-19 12:33:58 +00002481 if (ngx_strncmp(value[n].data, "rcvbuf=", 7) == 0) {
2482 size.len = value[n].len - 7;
2483 size.data = value[n].data + 7;
2484
2485 ls->conf.rcvbuf = ngx_parse_size(&size);
2486 ls->conf.bind = 1;
2487
2488 if (ls->conf.rcvbuf == NGX_ERROR) {
2489 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2490 "invalid rcvbuf \"%V\"", &value[n]);
2491 return NGX_CONF_ERROR;
2492 }
2493
2494 continue;
2495 }
2496
2497 if (ngx_strncmp(value[n].data, "sndbuf=", 7) == 0) {
2498 size.len = value[n].len - 7;
2499 size.data = value[n].data + 7;
2500
2501 ls->conf.sndbuf = ngx_parse_size(&size);
2502 ls->conf.bind = 1;
2503
2504 if (ls->conf.sndbuf == NGX_ERROR) {
2505 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2506 "invalid sndbuf \"%V\"", &value[n]);
2507 return NGX_CONF_ERROR;
2508 }
2509
2510 continue;
2511 }
2512
2513 if (ngx_strncmp(value[n].data, "accept_filter=", 14) == 0) {
Igor Sysoevb145b062005-06-15 18:33:41 +00002514#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
Igor Sysoevc2068d02005-10-19 12:33:58 +00002515 ls->conf.accept_filter = (char *) &value[n].data[14];
Igor Sysoevb145b062005-06-15 18:33:41 +00002516 ls->conf.bind = 1;
2517#else
2518 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2519 "accept filters \"%V\" are not supported "
2520 "on this platform, ignored",
2521 &value[n]);
2522#endif
2523 continue;
2524 }
2525
2526 if (ngx_strcmp(value[n].data, "deferred") == 0) {
2527#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
2528 ls->conf.deferred_accept = 1;
2529 ls->conf.bind = 1;
2530#else
2531 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2532 "the deferred accept is not supported "
2533 "on this platform, ignored");
2534#endif
2535 continue;
2536 }
2537
2538 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2539 "the invalid \"%V\" parameter", &value[n]);
2540 return NGX_CONF_ERROR;
Igor Sysoev13933252003-05-29 13:02:09 +00002541 }
2542
2543 return NGX_CONF_OK;
2544}
2545
2546
Igor Sysoevaa828612005-02-09 14:31:07 +00002547static char *
2548ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev13933252003-05-29 13:02:09 +00002549{
Igor Sysoev305a9d82005-12-26 17:07:48 +00002550 ngx_http_core_srv_conf_t *cscf = conf;
Igor Sysoev13933252003-05-29 13:02:09 +00002551
Igor Sysoev305a9d82005-12-26 17:07:48 +00002552 u_char ch;
2553 ngx_str_t *value, name;
2554 ngx_uint_t i;
2555 ngx_http_server_name_t *sn;
Igor Sysoevb1af9bb2004-06-25 14:42:03 +00002556
Igor Sysoevaa3436c2003-05-30 14:27:59 +00002557 value = cf->args->elts;
Igor Sysoev13933252003-05-29 13:02:09 +00002558
Igor Sysoev305a9d82005-12-26 17:07:48 +00002559 ch = value[1].data[0];
2560
2561 if (cscf->server_name.data == NULL && value[1].len) {
2562 if (ch == '*') {
Igor Sysoev8e1fbe62003-07-18 14:44:05 +00002563 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
Igor Sysoev305a9d82005-12-26 17:07:48 +00002564 "first server name \"%V\" must not be wildcard",
2565 &value[1]);
Igor Sysoev8e1fbe62003-07-18 14:44:05 +00002566 return NGX_CONF_ERROR;
Igor Sysoevaa3436c2003-05-30 14:27:59 +00002567 }
Igor Sysoev13933252003-05-29 13:02:09 +00002568
Igor Sysoev305a9d82005-12-26 17:07:48 +00002569 name = value[1];
2570
2571 if (ch == '.') {
2572 name.len--;
2573 name.data++;
2574 }
2575
2576 cscf->server_name.len = name.len;
2577 cscf->server_name.data = ngx_pstrdup(cf->pool, &name);
2578 if (cscf->server_name.data == NULL) {
2579 return NGX_CONF_ERROR;
2580 }
2581 }
2582
2583 for (i = 1; i < cf->args->nelts; i++) {
2584
2585 ch = value[i].data[0];
2586
Igor Sysoev1765f472006-07-07 16:33:19 +00002587 if (value[i].len == 1 && ch == '*') {
2588 cscf->wildcard = 1;
2589 continue;
2590 }
2591
Igor Sysoev305a9d82005-12-26 17:07:48 +00002592 if (value[i].len == 0
2593 || (ch == '*' && (value[i].len < 3 || value[i].data[1] != '.'))
2594 || (ch == '.' && value[i].len < 2))
2595 {
2596 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2597 "server name \"%V\" is invalid", &value[i]);
2598 return NGX_CONF_ERROR;
2599 }
2600
2601 sn = ngx_array_push(&cscf->server_names);
Igor Sysoevc1571722005-03-19 12:38:37 +00002602 if (sn == NULL) {
Igor Sysoevc0edbcc2004-10-21 15:34:38 +00002603 return NGX_CONF_ERROR;
2604 }
Igor Sysoevaa3436c2003-05-30 14:27:59 +00002605
2606 sn->name.len = value[i].len;
2607 sn->name.data = value[i].data;
Igor Sysoev305a9d82005-12-26 17:07:48 +00002608 sn->core_srv_conf = cscf;
Igor Sysoevaa3436c2003-05-30 14:27:59 +00002609 }
Igor Sysoev13933252003-05-29 13:02:09 +00002610
Igor Sysoeva19a85e2003-01-28 15:56:37 +00002611 return NGX_CONF_OK;
2612}
Igor Sysoev9d639522003-07-07 06:11:50 +00002613
2614
Igor Sysoevaa828612005-02-09 14:31:07 +00002615static char *
2616ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev10a543a2004-03-16 07:10:12 +00002617{
2618 ngx_http_core_loc_conf_t *lcf = conf;
2619
Igor Sysoev3ca233e2005-12-28 14:23:52 +00002620 ngx_str_t *value;
2621 ngx_uint_t alias, n;
2622 ngx_http_script_compile_t sc;
Igor Sysoev10a543a2004-03-16 07:10:12 +00002623
2624 alias = (cmd->name.len == sizeof("alias") - 1) ? 1 : 0;
2625
2626 if (lcf->root.data) {
Igor Sysoeva741f8d2004-03-30 20:31:58 +00002627
2628 /* the (ngx_uint_t) cast is required by gcc 2.7.2.3 */
2629
2630 if ((ngx_uint_t) lcf->alias == alias) {
Igor Sysoev10a543a2004-03-16 07:10:12 +00002631 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
Igor Sysoev1b735832004-11-11 14:07:14 +00002632 "\"%V\" directive is duplicate",
2633 &cmd->name);
Igor Sysoev10a543a2004-03-16 07:10:12 +00002634 } else {
2635 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
Igor Sysoev1b735832004-11-11 14:07:14 +00002636 "\"%V\" directive is duplicate, "
Igor Sysoev10a543a2004-03-16 07:10:12 +00002637 "\"%s\" directive is specified before",
Igor Sysoev1b735832004-11-11 14:07:14 +00002638 &cmd->name, lcf->alias ? "alias" : "root");
Igor Sysoev10a543a2004-03-16 07:10:12 +00002639 }
2640
2641 return NGX_CONF_ERROR;
2642 }
2643
2644 value = cf->args->elts;
2645
2646 lcf->alias = alias;
2647 lcf->root = value[1];
2648
Igor Sysoev71057632004-08-30 19:24:51 +00002649 if (!alias && lcf->root.data[lcf->root.len - 1] == '/') {
2650 lcf->root.len--;
2651 }
2652
Igor Sysoev8f125582006-07-28 15:16:17 +00002653 if (lcf->root.data[0] != '$') {
2654 if (ngx_conf_full_name(cf->cycle, &lcf->root) == NGX_ERROR) {
2655 return NGX_CONF_ERROR;
2656 }
Igor Sysoev34303462006-01-24 16:08:27 +00002657 }
2658
2659 n = ngx_http_script_variables_count(&lcf->root);
Igor Sysoev3ca233e2005-12-28 14:23:52 +00002660
2661 if (n == 0) {
2662 return NGX_CONF_OK;
2663 }
2664
2665 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
2666
2667 sc.cf = cf;
Igor Sysoev34303462006-01-24 16:08:27 +00002668 sc.source = &lcf->root;
Igor Sysoev3ca233e2005-12-28 14:23:52 +00002669 sc.lengths = &lcf->root_lengths;
2670 sc.values = &lcf->root_values;
2671 sc.variables = n;
2672 sc.complete_lengths = 1;
2673 sc.complete_values = 1;
2674
2675 if (ngx_http_script_compile(&sc) != NGX_OK) {
2676 return NGX_CONF_ERROR;
2677 }
2678
Igor Sysoev10a543a2004-03-16 07:10:12 +00002679 return NGX_CONF_OK;
2680}
2681
2682
Igor Sysoev94e32ce2006-04-07 14:08:04 +00002683static ngx_http_method_name_t ngx_methods_names[] = {
Igor Sysoev8365f732006-11-14 12:43:48 +00002684 { "GET", (uint32_t) ~NGX_HTTP_GET },
2685 { "HEAD", (uint32_t) ~NGX_HTTP_HEAD },
2686 { "POST", (uint32_t) ~NGX_HTTP_POST },
2687 { "PUT", (uint32_t) ~NGX_HTTP_PUT },
2688 { "DELETE", (uint32_t) ~NGX_HTTP_DELETE },
2689 { "MKCOL", (uint32_t) ~NGX_HTTP_MKCOL },
2690 { "COPY", (uint32_t) ~NGX_HTTP_COPY },
2691 { "MOVE", (uint32_t) ~NGX_HTTP_MOVE },
2692 { "OPTIONS", (uint32_t) ~NGX_HTTP_OPTIONS },
2693 { "PROPFIND" , (uint32_t) ~NGX_HTTP_PROPFIND },
2694 { "PROPPATCH", (uint32_t) ~NGX_HTTP_PROPPATCH },
2695 { "LOCK", (uint32_t) ~NGX_HTTP_LOCK },
2696 { "UNLOCK", (uint32_t) ~NGX_HTTP_UNLOCK },
Igor Sysoev94e32ce2006-04-07 14:08:04 +00002697 { NULL, 0 }
2698};
2699
2700
2701static char *
2702ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2703{
2704 ngx_http_core_loc_conf_t *clcf = conf;
2705
2706 char *rv;
2707 void *mconf;
2708 ngx_str_t *value;
2709 ngx_uint_t i;
2710 ngx_conf_t save;
2711 ngx_http_module_t *module;
2712 ngx_http_conf_ctx_t *ctx, *pctx;
2713 ngx_http_method_name_t *name;
2714 ngx_http_core_loc_conf_t *lcf, **clcfp;
2715
2716 if (clcf->limit_except) {
2717 return "duplicate";
2718 }
2719
2720 clcf->limit_except = 0xffffffff;
2721
2722 value = cf->args->elts;
2723
2724 for (i = 1; i < cf->args->nelts; i++) {
2725 for (name = ngx_methods_names; name->name; name++) {
2726
2727 if (ngx_strcasecmp(value[i].data, name->name) == 0) {
2728 clcf->limit_except &= name->method;
2729 goto next;
2730 }
2731 }
2732
2733 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2734 "invalid method \"%V\"", &value[i]);
2735 return NGX_CONF_ERROR;
2736
2737 next:
2738 continue;
2739 }
2740
2741 if (!(clcf->limit_except & NGX_HTTP_GET)) {
2742 clcf->limit_except &= (uint32_t) ~NGX_HTTP_HEAD;
2743 }
2744
2745 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
2746 if (ctx == NULL) {
2747 return NGX_CONF_ERROR;
2748 }
2749
2750 pctx = cf->ctx;
2751 ctx->main_conf = pctx->main_conf;
2752 ctx->srv_conf = pctx->srv_conf;
2753
2754 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
2755 if (ctx->loc_conf == NULL) {
2756 return NGX_CONF_ERROR;
2757 }
2758
2759 for (i = 0; ngx_modules[i]; i++) {
2760 if (ngx_modules[i]->type != NGX_HTTP_MODULE) {
2761 continue;
2762 }
2763
2764 module = ngx_modules[i]->ctx;
2765
2766 if (module->create_loc_conf) {
2767
2768 mconf = module->create_loc_conf(cf);
2769 if (mconf == NULL) {
2770 return NGX_CONF_ERROR;
2771 }
2772
2773 ctx->loc_conf[ngx_modules[i]->ctx_index] = mconf;
2774 }
2775 }
2776
2777
2778 lcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
2779 clcf->limit_except_loc_conf = ctx->loc_conf;
2780 lcf->loc_conf = ctx->loc_conf;
2781 lcf->name = clcf->name;
2782 lcf->noname = 1;
2783
2784 if (clcf->locations.elts == NULL) {
2785 if (ngx_array_init(&clcf->locations, cf->pool, 4, sizeof(void *))
2786 == NGX_ERROR)
2787 {
2788 return NGX_CONF_ERROR;
2789 }
2790 }
2791
2792 clcfp = ngx_array_push(&clcf->locations);
2793 if (clcfp == NULL) {
2794 return NGX_CONF_ERROR;
2795 }
2796
2797 *clcfp = lcf;
2798
2799
2800 save = *cf;
2801 cf->ctx = ctx;
2802 cf->cmd_type = NGX_HTTP_LMT_CONF;
2803
2804 rv = ngx_conf_parse(cf, NULL);
2805
2806 *cf = save;
2807
2808 return rv;
2809}
2810
2811
Igor Sysoevaa828612005-02-09 14:31:07 +00002812static char *
2813ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev74e95c22003-11-09 20:03:38 +00002814{
2815 ngx_http_core_loc_conf_t *lcf = conf;
2816
Igor Sysoev08e63d42006-08-14 15:09:38 +00002817 ngx_int_t overwrite;
2818 ngx_str_t *value, uri;
2819 ngx_uint_t i, n, nvar;
2820 ngx_array_t *uri_lengths, *uri_values;
2821 ngx_http_err_page_t *err;
2822 ngx_http_script_compile_t sc;
Igor Sysoev74e95c22003-11-09 20:03:38 +00002823
2824 if (lcf->error_pages == NULL) {
Igor Sysoevaa828612005-02-09 14:31:07 +00002825 lcf->error_pages = ngx_array_create(cf->pool, 4,
Igor Sysoev74e95c22003-11-09 20:03:38 +00002826 sizeof(ngx_http_err_page_t));
2827 if (lcf->error_pages == NULL) {
2828 return NGX_CONF_ERROR;
2829 }
2830 }
2831
2832 value = cf->args->elts;
2833
Igor Sysoev732a2712004-04-21 18:54:33 +00002834 i = cf->args->nelts - 2;
2835
2836 if (value[i].data[0] == '=') {
2837 if (i == 1) {
2838 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
Igor Sysoev1b735832004-11-11 14:07:14 +00002839 "invalid value \"%V\"", &value[i]);
Igor Sysoev732a2712004-04-21 18:54:33 +00002840 return NGX_CONF_ERROR;
2841 }
2842
Igor Sysoeva2573672005-10-05 14:46:21 +00002843 if (value[i].len > 1) {
2844 overwrite = ngx_atoi(&value[i].data[1], value[i].len - 1);
Igor Sysoev732a2712004-04-21 18:54:33 +00002845
Igor Sysoeva2573672005-10-05 14:46:21 +00002846 if (overwrite == NGX_ERROR) {
2847 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2848 "invalid value \"%V\"", &value[i]);
2849 return NGX_CONF_ERROR;
2850 }
2851
2852 } else {
2853 overwrite = 0;
Igor Sysoev732a2712004-04-21 18:54:33 +00002854 }
2855
2856 n = 2;
2857
2858 } else {
Igor Sysoeva2573672005-10-05 14:46:21 +00002859 overwrite = -1;
Igor Sysoev732a2712004-04-21 18:54:33 +00002860 n = 1;
2861 }
2862
Igor Sysoev08e63d42006-08-14 15:09:38 +00002863 uri = value[cf->args->nelts - 1];
2864 uri_lengths = NULL;
2865 uri_values = NULL;
2866
2867 nvar = ngx_http_script_variables_count(&uri);
2868
2869 if (nvar) {
2870 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
2871
2872 sc.cf = cf;
2873 sc.source = &uri;
2874 sc.lengths = &uri_lengths;
2875 sc.values = &uri_values;
2876 sc.variables = nvar;
2877 sc.complete_lengths = 1;
2878 sc.complete_values = 1;
2879
2880 if (ngx_http_script_compile(&sc) != NGX_OK) {
2881 return NGX_CONF_ERROR;
2882 }
2883 }
2884
Igor Sysoev732a2712004-04-21 18:54:33 +00002885 for (i = 1; i < cf->args->nelts - n; i++) {
Igor Sysoevc1571722005-03-19 12:38:37 +00002886 err = ngx_array_push(lcf->error_pages);
2887 if (err == NULL) {
Igor Sysoev732a2712004-04-21 18:54:33 +00002888 return NGX_CONF_ERROR;
2889 }
2890
Igor Sysoev3f4685f2004-04-25 20:13:21 +00002891 err->status = ngx_atoi(value[i].data, value[i].len);
Igor Sysoevaa828612005-02-09 14:31:07 +00002892
Igor Sysoev586f7a52006-09-25 17:48:34 +00002893 if (err->status == NGX_ERROR || err->status == 499) {
Igor Sysoev74e95c22003-11-09 20:03:38 +00002894 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
Igor Sysoev1b735832004-11-11 14:07:14 +00002895 "invalid value \"%V\"", &value[i]);
Igor Sysoev74e95c22003-11-09 20:03:38 +00002896 return NGX_CONF_ERROR;
2897 }
2898
Igor Sysoev3f4685f2004-04-25 20:13:21 +00002899 if (err->status < 400 || err->status > 599) {
Igor Sysoev74e95c22003-11-09 20:03:38 +00002900 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
Igor Sysoev1b735832004-11-11 14:07:14 +00002901 "value \"%V\" must be between 400 and 599",
2902 &value[i]);
Igor Sysoev74e95c22003-11-09 20:03:38 +00002903 return NGX_CONF_ERROR;
2904 }
2905
Igor Sysoeva2573672005-10-05 14:46:21 +00002906 err->overwrite = (overwrite >= 0) ? overwrite : err->status;
2907
Igor Sysoev08e63d42006-08-14 15:09:38 +00002908 err->uri = uri;
2909 err->uri_lengths = uri_lengths;
2910 err->uri_values = uri_values;
Igor Sysoev74e95c22003-11-09 20:03:38 +00002911 }
2912
2913 return NGX_CONF_OK;
2914}
2915
2916
Igor Sysoevaa828612005-02-09 14:31:07 +00002917static char *
Igor Sysoev899b44e2005-05-12 14:58:06 +00002918ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2919{
2920 ngx_http_core_loc_conf_t *lcf = conf;
2921
2922 lcf->err_log = ngx_log_create_errlog(cf->cycle, cf->args);
2923 if (lcf->err_log == NULL) {
2924 return NGX_CONF_ERROR;
2925 }
2926
2927 return ngx_set_error_log_levels(cf, lcf->err_log);
2928}
2929
2930
2931static char *
Igor Sysoevaa828612005-02-09 14:31:07 +00002932ngx_http_core_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev307c3ad2004-09-17 16:07:35 +00002933{
2934 ngx_http_core_loc_conf_t *lcf = conf;
2935
2936 ngx_str_t *value;
2937
2938 if (lcf->keepalive_timeout != NGX_CONF_UNSET_MSEC) {
2939 return "is duplicate";
2940 }
2941
2942 value = cf->args->elts;
2943
2944 lcf->keepalive_timeout = ngx_parse_time(&value[1], 0);
Igor Sysoevaa828612005-02-09 14:31:07 +00002945
Igor Sysoev307c3ad2004-09-17 16:07:35 +00002946 if (lcf->keepalive_timeout == (ngx_msec_t) NGX_ERROR) {
2947 return "invalid value";
2948 }
2949
2950 if (lcf->keepalive_timeout == (ngx_msec_t) NGX_PARSE_LARGE_TIME) {
2951 return "value must be less than 597 hours";
2952 }
2953
2954 if (cf->args->nelts == 2) {
2955 return NGX_CONF_OK;
2956 }
2957
2958 lcf->keepalive_header = ngx_parse_time(&value[2], 1);
Igor Sysoevaa828612005-02-09 14:31:07 +00002959
Igor Sysoev307c3ad2004-09-17 16:07:35 +00002960 if (lcf->keepalive_header == NGX_ERROR) {
2961 return "invalid value";
2962 }
2963
2964 if (lcf->keepalive_header == NGX_PARSE_LARGE_TIME) {
2965 return "value must be less than 68 years";
2966 }
2967
2968 return NGX_CONF_OK;
2969}
2970
2971
Igor Sysoevaa828612005-02-09 14:31:07 +00002972static char *
Igor Sysoev899b44e2005-05-12 14:58:06 +00002973ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
Igor Sysoev9d639522003-07-07 06:11:50 +00002974{
2975 ngx_http_core_loc_conf_t *lcf = conf;
2976
Igor Sysoev899b44e2005-05-12 14:58:06 +00002977 if (lcf->internal != NGX_CONF_UNSET) {
2978 return "is duplicate";
Igor Sysoev03420a62004-01-20 20:40:08 +00002979 }
Igor Sysoev9d639522003-07-07 06:11:50 +00002980
Igor Sysoev899b44e2005-05-12 14:58:06 +00002981 lcf->internal = 1;
2982
2983 return NGX_CONF_OK;
Igor Sysoev9d639522003-07-07 06:11:50 +00002984}
Igor Sysoevb5faed22003-10-29 08:30:44 +00002985
2986
Igor Sysoevaa828612005-02-09 14:31:07 +00002987static char *
2988ngx_http_core_lowat_check(ngx_conf_t *cf, void *post, void *data)
Igor Sysoevb5faed22003-10-29 08:30:44 +00002989{
Igor Sysoevc0edbcc2004-10-21 15:34:38 +00002990#if (NGX_FREEBSD)
Igor Sysoev42b12b32004-12-02 18:40:46 +00002991 ssize_t *np = data;
Igor Sysoev924bd792004-10-11 15:07:03 +00002992
Igor Sysoev08e63d42006-08-14 15:09:38 +00002993 if ((u_long) *np >= ngx_freebsd_net_inet_tcp_sendspace) {
Igor Sysoevb5faed22003-10-29 08:30:44 +00002994 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
2995 "\"send_lowat\" must be less than %d "
2996 "(sysctl net.inet.tcp.sendspace)",
2997 ngx_freebsd_net_inet_tcp_sendspace);
2998
2999 return NGX_CONF_ERROR;
3000 }
3001
Igor Sysoevf6906042004-11-25 16:17:31 +00003002#elif !(NGX_HAVE_SO_SNDLOWAT)
Igor Sysoev42b12b32004-12-02 18:40:46 +00003003 ssize_t *np = data;
Igor Sysoevb5faed22003-10-29 08:30:44 +00003004
3005 ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
3006 "\"send_lowat\" is not supported, ignored");
3007
Igor Sysoev924bd792004-10-11 15:07:03 +00003008 *np = 0;
3009
Igor Sysoevb5faed22003-10-29 08:30:44 +00003010#endif
3011
3012 return NGX_CONF_OK;
3013}