1 
2 /*
3  * Copyright (C) Igor Sysoev
4  * Copyright (C) Nginx, Inc.
5  */
6 
7 
8 #ifndef _NGX_HTTP_CORE_H_INCLUDED_
9 #define _NGX_HTTP_CORE_H_INCLUDED_
10 
11 
12 #include <ngx_config.h>
13 #include <ngx_core.h>
14 #include <ngx_http.h>
15 
16 #if (NGX_THREADS)
17 #include <ngx_thread_pool.h>
18 #elif (NGX_COMPAT)
19 typedef struct ngx_thread_pool_s  ngx_thread_pool_t;
20 #endif
21 
22 
23 #define NGX_HTTP_GZIP_PROXIED_OFF       0x0002
24 #define NGX_HTTP_GZIP_PROXIED_EXPIRED   0x0004
25 #define NGX_HTTP_GZIP_PROXIED_NO_CACHE  0x0008
26 #define NGX_HTTP_GZIP_PROXIED_NO_STORE  0x0010
27 #define NGX_HTTP_GZIP_PROXIED_PRIVATE   0x0020
28 #define NGX_HTTP_GZIP_PROXIED_NO_LM     0x0040
29 #define NGX_HTTP_GZIP_PROXIED_NO_ETAG   0x0080
30 #define NGX_HTTP_GZIP_PROXIED_AUTH      0x0100
31 #define NGX_HTTP_GZIP_PROXIED_ANY       0x0200
32 
33 
34 #define NGX_HTTP_AIO_OFF                0
35 #define NGX_HTTP_AIO_ON                 1
36 #define NGX_HTTP_AIO_THREADS            2
37 
38 
39 #define NGX_HTTP_SATISFY_ALL            0
40 #define NGX_HTTP_SATISFY_ANY            1
41 
42 
43 #define NGX_HTTP_LINGERING_OFF          0
44 #define NGX_HTTP_LINGERING_ON           1
45 #define NGX_HTTP_LINGERING_ALWAYS       2
46 
47 
48 #define NGX_HTTP_IMS_OFF                0
49 #define NGX_HTTP_IMS_EXACT              1
50 #define NGX_HTTP_IMS_BEFORE             2
51 
52 
53 #define NGX_HTTP_KEEPALIVE_DISABLE_NONE    0x0002
54 #define NGX_HTTP_KEEPALIVE_DISABLE_MSIE6   0x0004
55 #define NGX_HTTP_KEEPALIVE_DISABLE_SAFARI  0x0008
56 
57 
58 #define NGX_HTTP_SERVER_TOKENS_OFF      0
59 #define NGX_HTTP_SERVER_TOKENS_ON       1
60 #define NGX_HTTP_SERVER_TOKENS_BUILD    2
61 
62 
63 typedef struct ngx_http_location_tree_node_s  ngx_http_location_tree_node_t;
64 typedef struct ngx_http_core_loc_conf_s  ngx_http_core_loc_conf_t;
65 
66 
67 typedef struct {
68     struct sockaddr           *sockaddr;
69     socklen_t                  socklen;
70     ngx_str_t                  addr_text;
71 
72     unsigned                   set:1;
73     unsigned                   default_server:1;
74     unsigned                   bind:1;
75     unsigned                   wildcard:1;
76     unsigned                   ssl:1;
77     unsigned                   http2:1;
78 #if (NGX_HAVE_INET6)
79     unsigned                   ipv6only:1;
80 #endif
81     unsigned                   deferred_accept:1;
82     unsigned                   reuseport:1;
83     unsigned                   so_keepalive:2;
84     unsigned                   proxy_protocol:1;
85 
86     int                        backlog;
87     int                        rcvbuf;
88     int                        sndbuf;
89 #if (NGX_HAVE_SETFIB)
90     int                        setfib;
91 #endif
92 #if (NGX_HAVE_TCP_FASTOPEN)
93     int                        fastopen;
94 #endif
95 #if (NGX_HAVE_KEEPALIVE_TUNABLE)
96     int                        tcp_keepidle;
97     int                        tcp_keepintvl;
98     int                        tcp_keepcnt;
99 #endif
100 
101 #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
102     char                      *accept_filter;
103 #endif
104 } ngx_http_listen_opt_t;
105 
106 
107 typedef enum {
108     NGX_HTTP_POST_READ_PHASE = 0,
109 
110     NGX_HTTP_SERVER_REWRITE_PHASE,
111 
112     NGX_HTTP_FIND_CONFIG_PHASE,
113     NGX_HTTP_REWRITE_PHASE,
114     NGX_HTTP_POST_REWRITE_PHASE,
115 
116     NGX_HTTP_PREACCESS_PHASE,
117 
118     NGX_HTTP_ACCESS_PHASE,
119     NGX_HTTP_POST_ACCESS_PHASE,
120 
121     NGX_HTTP_PRECONTENT_PHASE,
122 
123     NGX_HTTP_CONTENT_PHASE,
124 
125     NGX_HTTP_LOG_PHASE
126 } ngx_http_phases;
127 
128 typedef struct ngx_http_phase_handler_s  ngx_http_phase_handler_t;
129 
130 typedef ngx_int_t (*ngx_http_phase_handler_pt)(ngx_http_request_t *r,
131     ngx_http_phase_handler_t *ph);
132 
133 struct ngx_http_phase_handler_s {
134     ngx_http_phase_handler_pt  checker;
135     ngx_http_handler_pt        handler;
136     ngx_uint_t                 next;
137 };
138 
139 
140 typedef struct {
141     ngx_http_phase_handler_t  *handlers;
142     ngx_uint_t                 server_rewrite_index;
143     ngx_uint_t                 location_rewrite_index;
144 } ngx_http_phase_engine_t;
145 
146 
147 typedef struct {
148     ngx_array_t                handlers;
149 } ngx_http_phase_t;
150 
151 
152 typedef struct {
153     ngx_array_t                servers;         /* ngx_http_core_srv_conf_t */
154 
155     ngx_http_phase_engine_t    phase_engine;
156 
157     ngx_hash_t                 headers_in_hash;
158 
159     ngx_hash_t                 variables_hash;
160 
161     ngx_array_t                variables;         /* ngx_http_variable_t */
162     ngx_array_t                prefix_variables;  /* ngx_http_variable_t */
163     ngx_uint_t                 ncaptures;
164 
165     ngx_uint_t                 server_names_hash_max_size;
166     ngx_uint_t                 server_names_hash_bucket_size;
167 
168     ngx_uint_t                 variables_hash_max_size;
169     ngx_uint_t                 variables_hash_bucket_size;
170 
171     ngx_hash_keys_arrays_t    *variables_keys;
172 
173     ngx_array_t               *ports;
174 
175     ngx_http_phase_t           phases[NGX_HTTP_LOG_PHASE + 1];
176 } ngx_http_core_main_conf_t;
177 
178 
179 typedef struct {
180     /* array of the ngx_http_server_name_t, "server_name" directive */
181     ngx_array_t                 server_names;
182 
183     /* server ctx */
184     ngx_http_conf_ctx_t        *ctx;
185 
186     u_char                     *file_name;
187     ngx_uint_t                  line;
188 
189     ngx_str_t                   server_name;
190 
191     size_t                      connection_pool_size;
192     size_t                      request_pool_size;
193     size_t                      client_header_buffer_size;
194 
195     ngx_bufs_t                  large_client_header_buffers;
196 
197     ngx_msec_t                  client_header_timeout;
198 
199     ngx_flag_t                  ignore_invalid_headers;
200     ngx_flag_t                  merge_slashes;
201     ngx_flag_t                  underscores_in_headers;
202 
203 #if (NGX_HAVE_FSTACK)
204     ngx_flag_t                  kernel_network_stack;    /* kernel_network_stack */
205 #endif
206 
207     unsigned                    listen:1;
208 #if (NGX_PCRE)
209     unsigned                    captures:1;
210 #endif
211 
212     ngx_http_core_loc_conf_t  **named_locations;
213 } ngx_http_core_srv_conf_t;
214 
215 
216 /* list of structures to find core_srv_conf quickly at run time */
217 
218 
219 typedef struct {
220 #if (NGX_PCRE)
221     ngx_http_regex_t          *regex;
222 #endif
223     ngx_http_core_srv_conf_t  *server;   /* virtual name server conf */
224     ngx_str_t                  name;
225 } ngx_http_server_name_t;
226 
227 
228 typedef struct {
229     ngx_hash_combined_t        names;
230 
231     ngx_uint_t                 nregex;
232     ngx_http_server_name_t    *regex;
233 } ngx_http_virtual_names_t;
234 
235 
236 struct ngx_http_addr_conf_s {
237     /* the default server configuration for this address:port */
238     ngx_http_core_srv_conf_t  *default_server;
239 
240     ngx_http_virtual_names_t  *virtual_names;
241 
242     unsigned                   ssl:1;
243     unsigned                   http2:1;
244     unsigned                   proxy_protocol:1;
245 };
246 
247 
248 typedef struct {
249     in_addr_t                  addr;
250     ngx_http_addr_conf_t       conf;
251 } ngx_http_in_addr_t;
252 
253 
254 #if (NGX_HAVE_INET6)
255 
256 typedef struct {
257     struct in6_addr            addr6;
258     ngx_http_addr_conf_t       conf;
259 } ngx_http_in6_addr_t;
260 
261 #endif
262 
263 
264 typedef struct {
265     /* ngx_http_in_addr_t or ngx_http_in6_addr_t */
266     void                      *addrs;
267     ngx_uint_t                 naddrs;
268 } ngx_http_port_t;
269 
270 
271 typedef struct {
272     ngx_int_t                  family;
273     in_port_t                  port;
274     ngx_array_t                addrs;     /* array of ngx_http_conf_addr_t */
275 } ngx_http_conf_port_t;
276 
277 
278 typedef struct {
279     ngx_http_listen_opt_t      opt;
280 
281     ngx_hash_t                 hash;
282     ngx_hash_wildcard_t       *wc_head;
283     ngx_hash_wildcard_t       *wc_tail;
284 
285 #if (NGX_PCRE)
286     ngx_uint_t                 nregex;
287     ngx_http_server_name_t    *regex;
288 #endif
289 
290     /* the default server configuration for this address:port */
291     ngx_http_core_srv_conf_t  *default_server;
292     ngx_array_t                servers;  /* array of ngx_http_core_srv_conf_t */
293 } ngx_http_conf_addr_t;
294 
295 
296 typedef struct {
297     ngx_int_t                  status;
298     ngx_int_t                  overwrite;
299     ngx_http_complex_value_t   value;
300     ngx_str_t                  args;
301 } ngx_http_err_page_t;
302 
303 
304 struct ngx_http_core_loc_conf_s {
305     ngx_str_t     name;          /* location name */
306 
307 #if (NGX_PCRE)
308     ngx_http_regex_t  *regex;
309 #endif
310 
311     unsigned      noname:1;   /* "if () {}" block or limit_except */
312     unsigned      lmt_excpt:1;
313     unsigned      named:1;
314 
315     unsigned      exact_match:1;
316     unsigned      noregex:1;
317 
318     unsigned      auto_redirect:1;
319 #if (NGX_HTTP_GZIP)
320     unsigned      gzip_disable_msie6:2;
321     unsigned      gzip_disable_degradation:2;
322 #endif
323 
324     ngx_http_location_tree_node_t   *static_locations;
325 #if (NGX_PCRE)
326     ngx_http_core_loc_conf_t       **regex_locations;
327 #endif
328 
329     /* pointer to the modules' loc_conf */
330     void        **loc_conf;
331 
332     uint32_t      limit_except;
333     void        **limit_except_loc_conf;
334 
335     ngx_http_handler_pt  handler;
336 
337     /* location name length for inclusive location with inherited alias */
338     size_t        alias;
339     ngx_str_t     root;                    /* root, alias */
340     ngx_str_t     post_action;
341 
342     ngx_array_t  *root_lengths;
343     ngx_array_t  *root_values;
344 
345     ngx_array_t  *types;
346     ngx_hash_t    types_hash;
347     ngx_str_t     default_type;
348 
349     off_t         client_max_body_size;    /* client_max_body_size */
350     off_t         directio;                /* directio */
351     off_t         directio_alignment;      /* directio_alignment */
352 
353     size_t        client_body_buffer_size; /* client_body_buffer_size */
354     size_t        send_lowat;              /* send_lowat */
355     size_t        postpone_output;         /* postpone_output */
356     size_t        limit_rate;              /* limit_rate */
357     size_t        limit_rate_after;        /* limit_rate_after */
358     size_t        sendfile_max_chunk;      /* sendfile_max_chunk */
359     size_t        read_ahead;              /* read_ahead */
360     size_t        subrequest_output_buffer_size;
361                                            /* subrequest_output_buffer_size */
362 
363     ngx_msec_t    client_body_timeout;     /* client_body_timeout */
364     ngx_msec_t    send_timeout;            /* send_timeout */
365     ngx_msec_t    keepalive_timeout;       /* keepalive_timeout */
366     ngx_msec_t    lingering_time;          /* lingering_time */
367     ngx_msec_t    lingering_timeout;       /* lingering_timeout */
368     ngx_msec_t    resolver_timeout;        /* resolver_timeout */
369 
370     ngx_resolver_t  *resolver;             /* resolver */
371 
372     time_t        keepalive_header;        /* keepalive_timeout */
373 
374     ngx_uint_t    keepalive_requests;      /* keepalive_requests */
375     ngx_uint_t    keepalive_disable;       /* keepalive_disable */
376     ngx_uint_t    satisfy;                 /* satisfy */
377     ngx_uint_t    lingering_close;         /* lingering_close */
378     ngx_uint_t    if_modified_since;       /* if_modified_since */
379     ngx_uint_t    max_ranges;              /* max_ranges */
380     ngx_uint_t    client_body_in_file_only; /* client_body_in_file_only */
381 
382     ngx_flag_t    client_body_in_single_buffer;
383                                            /* client_body_in_singe_buffer */
384     ngx_flag_t    internal;                /* internal */
385     ngx_flag_t    sendfile;                /* sendfile */
386     ngx_flag_t    aio;                     /* aio */
387     ngx_flag_t    aio_write;               /* aio_write */
388     ngx_flag_t    tcp_nopush;              /* tcp_nopush */
389     ngx_flag_t    tcp_nodelay;             /* tcp_nodelay */
390     ngx_flag_t    reset_timedout_connection; /* reset_timedout_connection */
391     ngx_flag_t    absolute_redirect;       /* absolute_redirect */
392     ngx_flag_t    server_name_in_redirect; /* server_name_in_redirect */
393     ngx_flag_t    port_in_redirect;        /* port_in_redirect */
394     ngx_flag_t    msie_padding;            /* msie_padding */
395     ngx_flag_t    msie_refresh;            /* msie_refresh */
396     ngx_flag_t    log_not_found;           /* log_not_found */
397     ngx_flag_t    log_subrequest;          /* log_subrequest */
398     ngx_flag_t    recursive_error_pages;   /* recursive_error_pages */
399     ngx_uint_t    server_tokens;           /* server_tokens */
400     ngx_flag_t    chunked_transfer_encoding; /* chunked_transfer_encoding */
401     ngx_flag_t    etag;                    /* etag */
402 
403 #if (NGX_HTTP_GZIP)
404     ngx_flag_t    gzip_vary;               /* gzip_vary */
405 
406     ngx_uint_t    gzip_http_version;       /* gzip_http_version */
407     ngx_uint_t    gzip_proxied;            /* gzip_proxied */
408 
409 #if (NGX_PCRE)
410     ngx_array_t  *gzip_disable;            /* gzip_disable */
411 #endif
412 #endif
413 
414 #if (NGX_THREADS || NGX_COMPAT)
415     ngx_thread_pool_t         *thread_pool;
416     ngx_http_complex_value_t  *thread_pool_value;
417 #endif
418 
419 #if (NGX_HAVE_OPENAT)
420     ngx_uint_t    disable_symlinks;        /* disable_symlinks */
421     ngx_http_complex_value_t  *disable_symlinks_from;
422 #endif
423 
424     ngx_array_t  *error_pages;             /* error_page */
425 
426     ngx_path_t   *client_body_temp_path;   /* client_body_temp_path */
427 
428     ngx_open_file_cache_t  *open_file_cache;
429     time_t        open_file_cache_valid;
430     ngx_uint_t    open_file_cache_min_uses;
431     ngx_flag_t    open_file_cache_errors;
432     ngx_flag_t    open_file_cache_events;
433 
434     ngx_log_t    *error_log;
435 
436     ngx_uint_t    types_hash_max_size;
437     ngx_uint_t    types_hash_bucket_size;
438 
439     ngx_queue_t  *locations;
440 
441 #if 0
442     ngx_http_core_loc_conf_t  *prev_location;
443 #endif
444 };
445 
446 
447 typedef struct {
448     ngx_queue_t                      queue;
449     ngx_http_core_loc_conf_t        *exact;
450     ngx_http_core_loc_conf_t        *inclusive;
451     ngx_str_t                       *name;
452     u_char                          *file_name;
453     ngx_uint_t                       line;
454     ngx_queue_t                      list;
455 } ngx_http_location_queue_t;
456 
457 
458 struct ngx_http_location_tree_node_s {
459     ngx_http_location_tree_node_t   *left;
460     ngx_http_location_tree_node_t   *right;
461     ngx_http_location_tree_node_t   *tree;
462 
463     ngx_http_core_loc_conf_t        *exact;
464     ngx_http_core_loc_conf_t        *inclusive;
465 
466     u_char                           auto_redirect;
467     u_char                           len;
468     u_char                           name[1];
469 };
470 
471 
472 void ngx_http_core_run_phases(ngx_http_request_t *r);
473 ngx_int_t ngx_http_core_generic_phase(ngx_http_request_t *r,
474     ngx_http_phase_handler_t *ph);
475 ngx_int_t ngx_http_core_rewrite_phase(ngx_http_request_t *r,
476     ngx_http_phase_handler_t *ph);
477 ngx_int_t ngx_http_core_find_config_phase(ngx_http_request_t *r,
478     ngx_http_phase_handler_t *ph);
479 ngx_int_t ngx_http_core_post_rewrite_phase(ngx_http_request_t *r,
480     ngx_http_phase_handler_t *ph);
481 ngx_int_t ngx_http_core_access_phase(ngx_http_request_t *r,
482     ngx_http_phase_handler_t *ph);
483 ngx_int_t ngx_http_core_post_access_phase(ngx_http_request_t *r,
484     ngx_http_phase_handler_t *ph);
485 ngx_int_t ngx_http_core_content_phase(ngx_http_request_t *r,
486     ngx_http_phase_handler_t *ph);
487 
488 
489 void *ngx_http_test_content_type(ngx_http_request_t *r, ngx_hash_t *types_hash);
490 ngx_int_t ngx_http_set_content_type(ngx_http_request_t *r);
491 void ngx_http_set_exten(ngx_http_request_t *r);
492 ngx_int_t ngx_http_set_etag(ngx_http_request_t *r);
493 void ngx_http_weak_etag(ngx_http_request_t *r);
494 ngx_int_t ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
495     ngx_str_t *ct, ngx_http_complex_value_t *cv);
496 u_char *ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *name,
497     size_t *root_length, size_t reserved);
498 ngx_int_t ngx_http_auth_basic_user(ngx_http_request_t *r);
499 #if (NGX_HTTP_GZIP)
500 ngx_int_t ngx_http_gzip_ok(ngx_http_request_t *r);
501 #endif
502 
503 
504 ngx_int_t ngx_http_subrequest(ngx_http_request_t *r,
505     ngx_str_t *uri, ngx_str_t *args, ngx_http_request_t **sr,
506     ngx_http_post_subrequest_t *psr, ngx_uint_t flags);
507 ngx_int_t ngx_http_internal_redirect(ngx_http_request_t *r,
508     ngx_str_t *uri, ngx_str_t *args);
509 ngx_int_t ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name);
510 
511 
512 ngx_http_cleanup_t *ngx_http_cleanup_add(ngx_http_request_t *r, size_t size);
513 
514 
515 typedef ngx_int_t (*ngx_http_output_header_filter_pt)(ngx_http_request_t *r);
516 typedef ngx_int_t (*ngx_http_output_body_filter_pt)
517     (ngx_http_request_t *r, ngx_chain_t *chain);
518 typedef ngx_int_t (*ngx_http_request_body_filter_pt)
519     (ngx_http_request_t *r, ngx_chain_t *chain);
520 
521 
522 ngx_int_t ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *chain);
523 ngx_int_t ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *chain);
524 ngx_int_t ngx_http_request_body_save_filter(ngx_http_request_t *r,
525     ngx_chain_t *chain);
526 
527 
528 ngx_int_t ngx_http_set_disable_symlinks(ngx_http_request_t *r,
529     ngx_http_core_loc_conf_t *clcf, ngx_str_t *path, ngx_open_file_info_t *of);
530 
531 ngx_int_t ngx_http_get_forwarded_addr(ngx_http_request_t *r, ngx_addr_t *addr,
532     ngx_array_t *headers, ngx_str_t *value, ngx_array_t *proxies,
533     int recursive);
534 
535 
536 extern ngx_module_t  ngx_http_core_module;
537 
538 extern ngx_uint_t ngx_http_max_module;
539 
540 extern ngx_str_t  ngx_http_core_get_method;
541 
542 
543 #define ngx_http_clear_content_length(r)                                      \
544                                                                               \
545     r->headers_out.content_length_n = -1;                                     \
546     if (r->headers_out.content_length) {                                      \
547         r->headers_out.content_length->hash = 0;                              \
548         r->headers_out.content_length = NULL;                                 \
549     }
550 
551 #define ngx_http_clear_accept_ranges(r)                                       \
552                                                                               \
553     r->allow_ranges = 0;                                                      \
554     if (r->headers_out.accept_ranges) {                                       \
555         r->headers_out.accept_ranges->hash = 0;                               \
556         r->headers_out.accept_ranges = NULL;                                  \
557     }
558 
559 #define ngx_http_clear_last_modified(r)                                       \
560                                                                               \
561     r->headers_out.last_modified_time = -1;                                   \
562     if (r->headers_out.last_modified) {                                       \
563         r->headers_out.last_modified->hash = 0;                               \
564         r->headers_out.last_modified = NULL;                                  \
565     }
566 
567 #define ngx_http_clear_location(r)                                            \
568                                                                               \
569     if (r->headers_out.location) {                                            \
570         r->headers_out.location->hash = 0;                                    \
571         r->headers_out.location = NULL;                                       \
572     }
573 
574 #define ngx_http_clear_etag(r)                                                \
575                                                                               \
576     if (r->headers_out.etag) {                                                \
577         r->headers_out.etag->hash = 0;                                        \
578         r->headers_out.etag = NULL;                                           \
579     }
580 
581 
582 #endif /* _NGX_HTTP_CORE_H_INCLUDED_ */
583