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