source: nginx/src/http/ngx_http_request.h @ 5621:345e4fd4bb64

Last change on this file since 5621:345e4fd4bb64 was 5621:345e4fd4bb64, checked in by Maxim Dounin <mdounin@…>, 4 years ago

Range filter: single_range flag in request.

If set, it means that response body is going to be in more than one buffer,
hence only range requests with a single range should be honored.

The flag is now used by mp4 and cacheable upstream responses, thus allowing
range requests of mp4 files with start/end, as well as range processing
on a first request to a not-yet-cached files with proxy_cache.

Notably this makes it possible to play mp4 files (with proxy_cache, or with
mp4 module) on iOS devices, as byte-range support is required by Apple.

File size: 19.6 KB
Line 
1
2/*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) Nginx, Inc.
5 */
6
7
8#ifndef _NGX_HTTP_REQUEST_H_INCLUDED_
9#define _NGX_HTTP_REQUEST_H_INCLUDED_
10
11
12#define NGX_HTTP_MAX_URI_CHANGES           10
13#define NGX_HTTP_MAX_SUBREQUESTS           200
14
15/* must be 2^n */
16#define NGX_HTTP_LC_HEADER_LEN             32
17
18
19#define NGX_HTTP_DISCARD_BUFFER_SIZE       4096
20#define NGX_HTTP_LINGERING_BUFFER_SIZE     4096
21
22
23#define NGX_HTTP_VERSION_9                 9
24#define NGX_HTTP_VERSION_10                1000
25#define NGX_HTTP_VERSION_11                1001
26
27#define NGX_HTTP_UNKNOWN                   0x0001
28#define NGX_HTTP_GET                       0x0002
29#define NGX_HTTP_HEAD                      0x0004
30#define NGX_HTTP_POST                      0x0008
31#define NGX_HTTP_PUT                       0x0010
32#define NGX_HTTP_DELETE                    0x0020
33#define NGX_HTTP_MKCOL                     0x0040
34#define NGX_HTTP_COPY                      0x0080
35#define NGX_HTTP_MOVE                      0x0100
36#define NGX_HTTP_OPTIONS                   0x0200
37#define NGX_HTTP_PROPFIND                  0x0400
38#define NGX_HTTP_PROPPATCH                 0x0800
39#define NGX_HTTP_LOCK                      0x1000
40#define NGX_HTTP_UNLOCK                    0x2000
41#define NGX_HTTP_PATCH                     0x4000
42#define NGX_HTTP_TRACE                     0x8000
43
44#define NGX_HTTP_CONNECTION_CLOSE          1
45#define NGX_HTTP_CONNECTION_KEEP_ALIVE     2
46
47
48#define NGX_NONE                           1
49
50
51#define NGX_HTTP_PARSE_HEADER_DONE         1
52
53#define NGX_HTTP_CLIENT_ERROR              10
54#define NGX_HTTP_PARSE_INVALID_METHOD      10
55#define NGX_HTTP_PARSE_INVALID_REQUEST     11
56#define NGX_HTTP_PARSE_INVALID_09_METHOD   12
57
58#define NGX_HTTP_PARSE_INVALID_HEADER      13
59
60
61/* unused                                  1 */
62#define NGX_HTTP_SUBREQUEST_IN_MEMORY      2
63#define NGX_HTTP_SUBREQUEST_WAITED         4
64#define NGX_HTTP_LOG_UNSAFE                8
65
66
67#define NGX_HTTP_CONTINUE                  100
68#define NGX_HTTP_SWITCHING_PROTOCOLS       101
69#define NGX_HTTP_PROCESSING                102
70
71#define NGX_HTTP_OK                        200
72#define NGX_HTTP_CREATED                   201
73#define NGX_HTTP_ACCEPTED                  202
74#define NGX_HTTP_NO_CONTENT                204
75#define NGX_HTTP_PARTIAL_CONTENT           206
76
77#define NGX_HTTP_SPECIAL_RESPONSE          300
78#define NGX_HTTP_MOVED_PERMANENTLY         301
79#define NGX_HTTP_MOVED_TEMPORARILY         302
80#define NGX_HTTP_SEE_OTHER                 303
81#define NGX_HTTP_NOT_MODIFIED              304
82#define NGX_HTTP_TEMPORARY_REDIRECT        307
83
84#define NGX_HTTP_BAD_REQUEST               400
85#define NGX_HTTP_UNAUTHORIZED              401
86#define NGX_HTTP_FORBIDDEN                 403
87#define NGX_HTTP_NOT_FOUND                 404
88#define NGX_HTTP_NOT_ALLOWED               405
89#define NGX_HTTP_REQUEST_TIME_OUT          408
90#define NGX_HTTP_CONFLICT                  409
91#define NGX_HTTP_LENGTH_REQUIRED           411
92#define NGX_HTTP_PRECONDITION_FAILED       412
93#define NGX_HTTP_REQUEST_ENTITY_TOO_LARGE  413
94#define NGX_HTTP_REQUEST_URI_TOO_LARGE     414
95#define NGX_HTTP_UNSUPPORTED_MEDIA_TYPE    415
96#define NGX_HTTP_RANGE_NOT_SATISFIABLE     416
97
98
99/* Our own HTTP codes */
100
101/* The special code to close connection without any response */
102#define NGX_HTTP_CLOSE                     444
103
104#define NGX_HTTP_NGINX_CODES               494
105
106#define NGX_HTTP_REQUEST_HEADER_TOO_LARGE  494
107
108#define NGX_HTTPS_CERT_ERROR               495
109#define NGX_HTTPS_NO_CERT                  496
110
111/*
112 * We use the special code for the plain HTTP requests that are sent to
113 * HTTPS port to distinguish it from 4XX in an error page redirection
114 */
115#define NGX_HTTP_TO_HTTPS                  497
116
117/* 498 is the canceled code for the requests with invalid host name */
118
119/*
120 * HTTP does not define the code for the case when a client closed
121 * the connection while we are processing its request so we introduce
122 * own code to log such situation when a client has closed the connection
123 * before we even try to send the HTTP header to it
124 */
125#define NGX_HTTP_CLIENT_CLOSED_REQUEST     499
126
127
128#define NGX_HTTP_INTERNAL_SERVER_ERROR     500
129#define NGX_HTTP_NOT_IMPLEMENTED           501
130#define NGX_HTTP_BAD_GATEWAY               502
131#define NGX_HTTP_SERVICE_UNAVAILABLE       503
132#define NGX_HTTP_GATEWAY_TIME_OUT          504
133#define NGX_HTTP_INSUFFICIENT_STORAGE      507
134
135
136#define NGX_HTTP_LOWLEVEL_BUFFERED         0xf0
137#define NGX_HTTP_WRITE_BUFFERED            0x10
138#define NGX_HTTP_GZIP_BUFFERED             0x20
139#define NGX_HTTP_SSI_BUFFERED              0x01
140#define NGX_HTTP_SUB_BUFFERED              0x02
141#define NGX_HTTP_COPY_BUFFERED             0x04
142
143
144typedef enum {
145    NGX_HTTP_INITING_REQUEST_STATE = 0,
146    NGX_HTTP_READING_REQUEST_STATE,
147    NGX_HTTP_PROCESS_REQUEST_STATE,
148
149    NGX_HTTP_CONNECT_UPSTREAM_STATE,
150    NGX_HTTP_WRITING_UPSTREAM_STATE,
151    NGX_HTTP_READING_UPSTREAM_STATE,
152
153    NGX_HTTP_WRITING_REQUEST_STATE,
154    NGX_HTTP_LINGERING_CLOSE_STATE,
155    NGX_HTTP_KEEPALIVE_STATE
156} ngx_http_state_e;
157
158
159typedef struct {
160    ngx_str_t                         name;
161    ngx_uint_t                        offset;
162    ngx_http_header_handler_pt        handler;
163} ngx_http_header_t;
164
165
166typedef struct {
167    ngx_str_t                         name;
168    ngx_uint_t                        offset;
169} ngx_http_header_out_t;
170
171
172typedef struct {
173    ngx_list_t                        headers;
174
175    ngx_table_elt_t                  *host;
176    ngx_table_elt_t                  *connection;
177    ngx_table_elt_t                  *if_modified_since;
178    ngx_table_elt_t                  *if_unmodified_since;
179    ngx_table_elt_t                  *if_match;
180    ngx_table_elt_t                  *if_none_match;
181    ngx_table_elt_t                  *user_agent;
182    ngx_table_elt_t                  *referer;
183    ngx_table_elt_t                  *content_length;
184    ngx_table_elt_t                  *content_type;
185
186    ngx_table_elt_t                  *range;
187    ngx_table_elt_t                  *if_range;
188
189    ngx_table_elt_t                  *transfer_encoding;
190    ngx_table_elt_t                  *expect;
191    ngx_table_elt_t                  *upgrade;
192
193#if (NGX_HTTP_GZIP)
194    ngx_table_elt_t                  *accept_encoding;
195    ngx_table_elt_t                  *via;
196#endif
197
198    ngx_table_elt_t                  *authorization;
199
200    ngx_table_elt_t                  *keep_alive;
201
202#if (NGX_HTTP_X_FORWARDED_FOR)
203    ngx_array_t                       x_forwarded_for;
204#endif
205
206#if (NGX_HTTP_REALIP)
207    ngx_table_elt_t                  *x_real_ip;
208#endif
209
210#if (NGX_HTTP_HEADERS)
211    ngx_table_elt_t                  *accept;
212    ngx_table_elt_t                  *accept_language;
213#endif
214
215#if (NGX_HTTP_DAV)
216    ngx_table_elt_t                  *depth;
217    ngx_table_elt_t                  *destination;
218    ngx_table_elt_t                  *overwrite;
219    ngx_table_elt_t                  *date;
220#endif
221
222    ngx_str_t                         user;
223    ngx_str_t                         passwd;
224
225    ngx_array_t                       cookies;
226
227    ngx_str_t                         server;
228    off_t                             content_length_n;
229    time_t                            keep_alive_n;
230
231    unsigned                          connection_type:2;
232    unsigned                          chunked:1;
233    unsigned                          msie:1;
234    unsigned                          msie6:1;
235    unsigned                          opera:1;
236    unsigned                          gecko:1;
237    unsigned                          chrome:1;
238    unsigned                          safari:1;
239    unsigned                          konqueror:1;
240} ngx_http_headers_in_t;
241
242
243typedef struct {
244    ngx_list_t                        headers;
245
246    ngx_uint_t                        status;
247    ngx_str_t                         status_line;
248
249    ngx_table_elt_t                  *server;
250    ngx_table_elt_t                  *date;
251    ngx_table_elt_t                  *content_length;
252    ngx_table_elt_t                  *content_encoding;
253    ngx_table_elt_t                  *location;
254    ngx_table_elt_t                  *refresh;
255    ngx_table_elt_t                  *last_modified;
256    ngx_table_elt_t                  *content_range;
257    ngx_table_elt_t                  *accept_ranges;
258    ngx_table_elt_t                  *www_authenticate;
259    ngx_table_elt_t                  *expires;
260    ngx_table_elt_t                  *etag;
261
262    ngx_str_t                        *override_charset;
263
264    size_t                            content_type_len;
265    ngx_str_t                         content_type;
266    ngx_str_t                         charset;
267    u_char                           *content_type_lowcase;
268    ngx_uint_t                        content_type_hash;
269
270    ngx_array_t                       cache_control;
271
272    off_t                             content_length_n;
273    time_t                            date_time;
274    time_t                            last_modified_time;
275} ngx_http_headers_out_t;
276
277
278typedef void (*ngx_http_client_body_handler_pt)(ngx_http_request_t *r);
279
280typedef struct {
281    ngx_temp_file_t                  *temp_file;
282    ngx_chain_t                      *bufs;
283    ngx_buf_t                        *buf;
284    off_t                             rest;
285    ngx_chain_t                      *free;
286    ngx_chain_t                      *busy;
287    ngx_http_chunked_t               *chunked;
288    ngx_http_client_body_handler_pt   post_handler;
289} ngx_http_request_body_t;
290
291
292typedef struct ngx_http_addr_conf_s  ngx_http_addr_conf_t;
293
294typedef struct {
295    ngx_http_addr_conf_t             *addr_conf;
296    ngx_http_conf_ctx_t              *conf_ctx;
297
298#if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)
299    ngx_str_t                        *ssl_servername;
300#if (NGX_PCRE)
301    ngx_http_regex_t                 *ssl_servername_regex;
302#endif
303#endif
304
305    ngx_buf_t                       **busy;
306    ngx_int_t                         nbusy;
307
308    ngx_buf_t                       **free;
309    ngx_int_t                         nfree;
310
311#if (NGX_HTTP_SSL)
312    unsigned                          ssl:1;
313#endif
314    unsigned                          proxy_protocol:1;
315} ngx_http_connection_t;
316
317
318typedef void (*ngx_http_cleanup_pt)(void *data);
319
320typedef struct ngx_http_cleanup_s  ngx_http_cleanup_t;
321
322struct ngx_http_cleanup_s {
323    ngx_http_cleanup_pt               handler;
324    void                             *data;
325    ngx_http_cleanup_t               *next;
326};
327
328
329typedef ngx_int_t (*ngx_http_post_subrequest_pt)(ngx_http_request_t *r,
330    void *data, ngx_int_t rc);
331
332typedef struct {
333    ngx_http_post_subrequest_pt       handler;
334    void                             *data;
335} ngx_http_post_subrequest_t;
336
337
338typedef struct ngx_http_postponed_request_s  ngx_http_postponed_request_t;
339
340struct ngx_http_postponed_request_s {
341    ngx_http_request_t               *request;
342    ngx_chain_t                      *out;
343    ngx_http_postponed_request_t     *next;
344};
345
346
347typedef struct ngx_http_posted_request_s  ngx_http_posted_request_t;
348
349struct ngx_http_posted_request_s {
350    ngx_http_request_t               *request;
351    ngx_http_posted_request_t        *next;
352};
353
354
355typedef ngx_int_t (*ngx_http_handler_pt)(ngx_http_request_t *r);
356typedef void (*ngx_http_event_handler_pt)(ngx_http_request_t *r);
357
358
359struct ngx_http_request_s {
360    uint32_t                          signature;         /* "HTTP" */
361
362    ngx_connection_t                 *connection;
363
364    void                            **ctx;
365    void                            **main_conf;
366    void                            **srv_conf;
367    void                            **loc_conf;
368
369    ngx_http_event_handler_pt         read_event_handler;
370    ngx_http_event_handler_pt         write_event_handler;
371
372#if (NGX_HTTP_CACHE)
373    ngx_http_cache_t                 *cache;
374#endif
375
376    ngx_http_upstream_t              *upstream;
377    ngx_array_t                      *upstream_states;
378                                         /* of ngx_http_upstream_state_t */
379
380    ngx_pool_t                       *pool;
381    ngx_buf_t                        *header_in;
382
383    ngx_http_headers_in_t             headers_in;
384    ngx_http_headers_out_t            headers_out;
385
386    ngx_http_request_body_t          *request_body;
387
388    time_t                            lingering_time;
389    time_t                            start_sec;
390    ngx_msec_t                        start_msec;
391
392    ngx_uint_t                        method;
393    ngx_uint_t                        http_version;
394
395    ngx_str_t                         request_line;
396    ngx_str_t                         uri;
397    ngx_str_t                         args;
398    ngx_str_t                         exten;
399    ngx_str_t                         unparsed_uri;
400
401    ngx_str_t                         method_name;
402    ngx_str_t                         http_protocol;
403
404    ngx_chain_t                      *out;
405    ngx_http_request_t               *main;
406    ngx_http_request_t               *parent;
407    ngx_http_postponed_request_t     *postponed;
408    ngx_http_post_subrequest_t       *post_subrequest;
409    ngx_http_posted_request_t        *posted_requests;
410
411    ngx_int_t                         phase_handler;
412    ngx_http_handler_pt               content_handler;
413    ngx_uint_t                        access_code;
414
415    ngx_http_variable_value_t        *variables;
416
417#if (NGX_PCRE)
418    ngx_uint_t                        ncaptures;
419    int                              *captures;
420    u_char                           *captures_data;
421#endif
422
423    size_t                            limit_rate;
424    size_t                            limit_rate_after;
425
426    /* used to learn the Apache compatible response length without a header */
427    size_t                            header_size;
428
429    off_t                             request_length;
430
431    ngx_uint_t                        err_status;
432
433    ngx_http_connection_t            *http_connection;
434#if (NGX_HTTP_SPDY)
435    ngx_http_spdy_stream_t           *spdy_stream;
436#endif
437
438    ngx_http_log_handler_pt           log_handler;
439
440    ngx_http_cleanup_t               *cleanup;
441
442    unsigned                          subrequests:8;
443    unsigned                          count:8;
444    unsigned                          blocked:8;
445
446    unsigned                          aio:1;
447
448    unsigned                          http_state:4;
449
450    /* URI with "/." and on Win32 with "//" */
451    unsigned                          complex_uri:1;
452
453    /* URI with "%" */
454    unsigned                          quoted_uri:1;
455
456    /* URI with "+" */
457    unsigned                          plus_in_uri:1;
458
459    /* URI with " " */
460    unsigned                          space_in_uri:1;
461
462    unsigned                          invalid_header:1;
463
464    unsigned                          add_uri_to_alias:1;
465    unsigned                          valid_location:1;
466    unsigned                          valid_unparsed_uri:1;
467    unsigned                          uri_changed:1;
468    unsigned                          uri_changes:4;
469
470    unsigned                          request_body_in_single_buf:1;
471    unsigned                          request_body_in_file_only:1;
472    unsigned                          request_body_in_persistent_file:1;
473    unsigned                          request_body_in_clean_file:1;
474    unsigned                          request_body_file_group_access:1;
475    unsigned                          request_body_file_log_level:3;
476
477    unsigned                          subrequest_in_memory:1;
478    unsigned                          waited:1;
479
480#if (NGX_HTTP_CACHE)
481    unsigned                          cached:1;
482#endif
483
484#if (NGX_HTTP_GZIP)
485    unsigned                          gzip_tested:1;
486    unsigned                          gzip_ok:1;
487    unsigned                          gzip_vary:1;
488#endif
489
490    unsigned                          proxy:1;
491    unsigned                          bypass_cache:1;
492    unsigned                          no_cache:1;
493
494    /*
495     * instead of using the request context data in
496     * ngx_http_limit_conn_module and ngx_http_limit_req_module
497     * we use the single bits in the request structure
498     */
499    unsigned                          limit_conn_set:1;
500    unsigned                          limit_req_set:1;
501
502#if 0
503    unsigned                          cacheable:1;
504#endif
505
506    unsigned                          pipeline:1;
507    unsigned                          chunked:1;
508    unsigned                          header_only:1;
509    unsigned                          keepalive:1;
510    unsigned                          lingering_close:1;
511    unsigned                          discard_body:1;
512    unsigned                          internal:1;
513    unsigned                          error_page:1;
514    unsigned                          ignore_content_encoding:1;
515    unsigned                          filter_finalize:1;
516    unsigned                          post_action:1;
517    unsigned                          request_complete:1;
518    unsigned                          request_output:1;
519    unsigned                          header_sent:1;
520    unsigned                          expect_tested:1;
521    unsigned                          root_tested:1;
522    unsigned                          done:1;
523    unsigned                          logged:1;
524
525    unsigned                          buffered:4;
526
527    unsigned                          main_filter_need_in_memory:1;
528    unsigned                          filter_need_in_memory:1;
529    unsigned                          filter_need_temporary:1;
530    unsigned                          allow_ranges:1;
531    unsigned                          single_range:1;
532
533#if (NGX_STAT_STUB)
534    unsigned                          stat_reading:1;
535    unsigned                          stat_writing:1;
536#endif
537
538    /* used to parse HTTP headers */
539
540    ngx_uint_t                        state;
541
542    ngx_uint_t                        header_hash;
543    ngx_uint_t                        lowcase_index;
544    u_char                            lowcase_header[NGX_HTTP_LC_HEADER_LEN];
545
546    u_char                           *header_name_start;
547    u_char                           *header_name_end;
548    u_char                           *header_start;
549    u_char                           *header_end;
550
551    /*
552     * a memory that can be reused after parsing a request line
553     * via ngx_http_ephemeral_t
554     */
555
556    u_char                           *uri_start;
557    u_char                           *uri_end;
558    u_char                           *uri_ext;
559    u_char                           *args_start;
560    u_char                           *request_start;
561    u_char                           *request_end;
562    u_char                           *method_end;
563    u_char                           *schema_start;
564    u_char                           *schema_end;
565    u_char                           *host_start;
566    u_char                           *host_end;
567    u_char                           *port_start;
568    u_char                           *port_end;
569
570    unsigned                          http_minor:16;
571    unsigned                          http_major:16;
572};
573
574
575typedef struct {
576    ngx_http_posted_request_t         terminal_posted_request;
577#if (NGX_HAVE_AIO_SENDFILE)
578    u_char                            aio_preload;
579#endif
580} ngx_http_ephemeral_t;
581
582
583extern ngx_http_header_t       ngx_http_headers_in[];
584extern ngx_http_header_out_t   ngx_http_headers_out[];
585
586
587#define ngx_http_set_connection_log(c, l)                                     \
588                                                                              \
589    c->log->file = l->file;                                                   \
590    c->log->next = l->next;                                                   \
591    if (!(c->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {                    \
592        c->log->log_level = l->log_level;                                     \
593    }
594
595
596#endif /* _NGX_HTTP_REQUEST_H_INCLUDED_ */
Note: See TracBrowser for help on using the repository browser.