xref: /lighttpd1.4/src/request.h (revision 3a8fc4bc)
1bcdc6a3bSJan Kneschke #ifndef _REQUEST_H_
2bcdc6a3bSJan Kneschke #define _REQUEST_H_
38abd06a7SGlenn Strauss #include "first.h"
4bcdc6a3bSJan Kneschke 
513ea2d88SGlenn Strauss #include "sys-time.h"   /* (struct timespec) */
66fe031efSGlenn Strauss 
704d76e7aSGlenn Strauss #include "base_decls.h"
804d76e7aSGlenn Strauss #include "buffer.h"
9668cb641SGlenn Strauss #include "array.h"
1081029b8bSGlenn Strauss #include "chunk.h"
11668cb641SGlenn Strauss #include "http_kv.h"
12668cb641SGlenn Strauss 
131474be78SGlenn Strauss struct chunkqueue;      /* declaration */
148131e439SGlenn Strauss struct cond_cache_t;    /* declaration */
158131e439SGlenn Strauss struct cond_match_t;    /* declaration */
169a5e1652SGlenn Strauss struct stat_cache_entry;/* declaration */
17668cb641SGlenn Strauss 
18d5366c0aSGlenn Strauss typedef struct request_config {
198071b803SGlenn Strauss     fdlog_st *errh;
207c7f8c46SGlenn Strauss     unsigned int http_parseopts;
217c7f8c46SGlenn Strauss     uint32_t max_request_field_size;
22668cb641SGlenn Strauss     const array *mimetypes;
23668cb641SGlenn Strauss 
24668cb641SGlenn Strauss     /* virtual-servers */
25668cb641SGlenn Strauss     const buffer *document_root;
26668cb641SGlenn Strauss     const buffer *server_name;
27668cb641SGlenn Strauss     const buffer *server_tag;
28668cb641SGlenn Strauss 
297c7f8c46SGlenn Strauss     unsigned int max_request_size;
30668cb641SGlenn Strauss     unsigned short max_keep_alive_requests;
31668cb641SGlenn Strauss     unsigned short max_keep_alive_idle;
32668cb641SGlenn Strauss     unsigned short max_read_idle;
33668cb641SGlenn Strauss     unsigned short max_write_idle;
34668cb641SGlenn Strauss     unsigned short stream_request_body;
35668cb641SGlenn Strauss     unsigned short stream_response_body;
368071b803SGlenn Strauss     unsigned int high_precision_timestamps:1;
378071b803SGlenn Strauss     unsigned int allow_http11:1;
388071b803SGlenn Strauss     unsigned int range_requests:1;
398071b803SGlenn Strauss     unsigned int follow_symlink:1;
408071b803SGlenn Strauss     unsigned int etag_flags:3;
418071b803SGlenn Strauss     unsigned int use_xattr:1;
428071b803SGlenn Strauss     unsigned int force_lowercase_filenames:2;/*(case-insensitive file systems)*/
438071b803SGlenn Strauss     unsigned int error_intercept:1;
44668cb641SGlenn Strauss 
458071b803SGlenn Strauss     unsigned int h2proto:2; /*(global setting copied for convenient access)*/
461041a56dSGlenn Strauss 
47668cb641SGlenn Strauss     /* debug */
488071b803SGlenn Strauss     unsigned int log_request_handling:1;
498071b803SGlenn Strauss     unsigned int log_state_handling:1;
508071b803SGlenn Strauss     unsigned int log_condition_handling:1;
518071b803SGlenn Strauss     unsigned int log_response_header:1;
528071b803SGlenn Strauss     unsigned int log_request_header:1;
538071b803SGlenn Strauss     unsigned int log_request_header_on_error:1;
548071b803SGlenn Strauss     unsigned int log_file_not_found:1;
558071b803SGlenn Strauss     unsigned int log_timeouts:1;
56668cb641SGlenn Strauss 
57668cb641SGlenn Strauss     unsigned int bytes_per_second; /* connection bytes/sec limit */
58668cb641SGlenn Strauss     unsigned int global_bytes_per_second;/*total bytes/sec limit for scope*/
59668cb641SGlenn Strauss 
60668cb641SGlenn Strauss     /* server-wide traffic-shaper
61668cb641SGlenn Strauss      *
62668cb641SGlenn Strauss      * each context has the counter which is inited once
63668cb641SGlenn Strauss      * a second by the global_bytes_per_second config-var
64668cb641SGlenn Strauss      *
65668cb641SGlenn Strauss      * as soon as global_bytes_per_second gets below 0
66668cb641SGlenn Strauss      * the connected conns are "offline" a little bit
67668cb641SGlenn Strauss      *
68668cb641SGlenn Strauss      * the problem:
69668cb641SGlenn Strauss      * we somehow have to lose our "we are writable" signal on the way.
70668cb641SGlenn Strauss      *
71668cb641SGlenn Strauss      */
72668cb641SGlenn Strauss     off_t *global_bytes_per_second_cnt_ptr; /*  */
73668cb641SGlenn Strauss 
74668cb641SGlenn Strauss     const buffer *error_handler;
75668cb641SGlenn Strauss     const buffer *error_handler_404;
76668cb641SGlenn Strauss     const buffer *errorfile_prefix;
777b615d5dSGlenn Strauss     fdlog_st *serrh; /* script errh */
78668cb641SGlenn Strauss } request_config;
79668cb641SGlenn Strauss 
807c7f8c46SGlenn Strauss typedef struct {
817c7f8c46SGlenn Strauss     buffer scheme; /* scheme without colon or slashes ( "http" or "https" ) */
827c7f8c46SGlenn Strauss 
837c7f8c46SGlenn Strauss     /* authority with optional portnumber ("site.name" or "site.name:8080" ) NOTE: without "username:password@" */
847c7f8c46SGlenn Strauss     buffer authority;
857c7f8c46SGlenn Strauss 
867c7f8c46SGlenn Strauss     /* path including leading slash ("/" or "/index.html") - urldecoded, and sanitized  ( buffer_path_simplify() && buffer_urldecode_path() ) */
877c7f8c46SGlenn Strauss     buffer path;
887c7f8c46SGlenn Strauss     buffer query; /* querystring ( everything after "?", ie: in "/index.php?foo=1", query is "foo=1" ) */
897c7f8c46SGlenn Strauss } request_uri;
907c7f8c46SGlenn Strauss 
917c7f8c46SGlenn Strauss typedef struct {
927c7f8c46SGlenn Strauss     buffer path;
937c7f8c46SGlenn Strauss     buffer basedir; /* path = "(basedir)(.*)" */
947c7f8c46SGlenn Strauss 
957c7f8c46SGlenn Strauss     buffer doc_root; /* path = doc_root + rel_path */
967c7f8c46SGlenn Strauss     buffer rel_path;
977c7f8c46SGlenn Strauss } physical;
987c7f8c46SGlenn Strauss 
997420526dSGlenn Strauss typedef struct {
1007420526dSGlenn Strauss     off_t gw_chunked;
1017420526dSGlenn Strauss     buffer b;
1027420526dSGlenn Strauss     int done;
1037420526dSGlenn Strauss } response_dechunk;
1047420526dSGlenn Strauss 
105aca9d45aSGlenn Strauss /* the order of the items should be the same as they are processed
106aca9d45aSGlenn Strauss  * read before write as we use this later e.g. <= CON_STATE_REQUEST_END */
1075e0d82dcSGlenn Strauss /* NB: must sync with http_request_state_short(), http_request_state_append() */
108aca9d45aSGlenn Strauss typedef enum {
109aca9d45aSGlenn Strauss     CON_STATE_CONNECT,
110aca9d45aSGlenn Strauss     CON_STATE_REQUEST_START,
111aca9d45aSGlenn Strauss     CON_STATE_READ,
112aca9d45aSGlenn Strauss     CON_STATE_REQUEST_END,
113aca9d45aSGlenn Strauss     CON_STATE_READ_POST,
114aca9d45aSGlenn Strauss     CON_STATE_HANDLE_REQUEST,
115aca9d45aSGlenn Strauss     CON_STATE_RESPONSE_START,
116aca9d45aSGlenn Strauss     CON_STATE_WRITE,
117aca9d45aSGlenn Strauss     CON_STATE_RESPONSE_END,
118aca9d45aSGlenn Strauss     CON_STATE_ERROR,
119aca9d45aSGlenn Strauss     CON_STATE_CLOSE
120aca9d45aSGlenn Strauss } request_state_t;
121aca9d45aSGlenn Strauss 
1226870b0f5SGlenn Strauss struct request_st {
123aca9d45aSGlenn Strauss     request_state_t state; /*(modules should not modify request state)*/
1247c7f8c46SGlenn Strauss     int http_status;
1256eca864cSGlenn Strauss     uint32_t h2state;      /*(modules should not modify request h2state)*/
1266eca864cSGlenn Strauss     uint32_t h2id;
1276eca864cSGlenn Strauss      int32_t h2_rwin;
1286eca864cSGlenn Strauss      int32_t h2_swin;
129ad4a7904SGlenn Strauss      int16_t h2_rwin_fudge;
1309a3f6c52SGlenn Strauss      uint8_t h2_prio;
131668cb641SGlenn Strauss 
132668cb641SGlenn Strauss     http_method_t http_method;
133668cb641SGlenn Strauss     http_version_t http_version;
1347c7f8c46SGlenn Strauss 
1357c7f8c46SGlenn Strauss     const plugin *handler_module;
136100dfaa3SGlenn Strauss     void **plugin_ctx;           /* plugin connection specific config */
1377c7f8c46SGlenn Strauss     connection *con;
138668cb641SGlenn Strauss 
1397c7f8c46SGlenn Strauss     /* config conditions (internal) */
1408131e439SGlenn Strauss     uint32_t conditional_is_valid;
1418131e439SGlenn Strauss     struct cond_cache_t *cond_cache;
1427ea2d407SGlenn Strauss     struct cond_match_t **cond_match;
1437ea2d407SGlenn Strauss     struct cond_match_t *cond_match_data;
144a22cdca1SGlenn Strauss 
1457c7f8c46SGlenn Strauss     request_config conf;
1467c7f8c46SGlenn Strauss 
1477c7f8c46SGlenn Strauss     /* request */
1487c7f8c46SGlenn Strauss     uint32_t rqst_header_len;
149367f30a6SGlenn Strauss     uint64_t rqst_htags;/* bitfield of flagged headers present in request */
1507c7f8c46SGlenn Strauss     array rqst_headers;
1517c7f8c46SGlenn Strauss 
1527c7f8c46SGlenn Strauss     request_uri uri;
1537c7f8c46SGlenn Strauss     physical physical;
154a22cdca1SGlenn Strauss     array env; /* used to pass lighttpd internal stuff */
155a22cdca1SGlenn Strauss 
1567c7f8c46SGlenn Strauss     off_t reqbody_length; /* request Content-Length */
1577c7f8c46SGlenn Strauss     off_t te_chunked;
158903024d7SGlenn Strauss     off_t resp_body_scratchpad;
159a22cdca1SGlenn Strauss 
1607c7f8c46SGlenn Strauss     buffer *http_host; /* copy of array value buffer ptr; not alloc'ed */
1617c7f8c46SGlenn Strauss     const buffer *server_name;
1627c7f8c46SGlenn Strauss 
1637c7f8c46SGlenn Strauss     buffer target;
1647c7f8c46SGlenn Strauss     buffer target_orig;
1657c7f8c46SGlenn Strauss 
1667c7f8c46SGlenn Strauss     buffer pathinfo;
1677c7f8c46SGlenn Strauss     buffer server_name_buf;
1687c7f8c46SGlenn Strauss 
169*3a8fc4bcSGlenn Strauss     void *dst_addr;
170*3a8fc4bcSGlenn Strauss     buffer *dst_addr_buf;
171*3a8fc4bcSGlenn Strauss 
1727c7f8c46SGlenn Strauss     /* response */
1737c7f8c46SGlenn Strauss     uint32_t resp_header_len;
174367f30a6SGlenn Strauss     uint64_t resp_htags; /*bitfield of flagged headers present in response*/
1757c7f8c46SGlenn Strauss     array resp_headers;
1767c7f8c46SGlenn Strauss     char resp_body_finished;
1777c7f8c46SGlenn Strauss     char resp_body_started;
1787c7f8c46SGlenn Strauss     char resp_send_chunked;
1797420526dSGlenn Strauss     char resp_decode_chunked;
180ada09a23SGlenn Strauss     char resp_header_repeated;
1817c7f8c46SGlenn Strauss 
1827c7f8c46SGlenn Strauss     char loops_per_request;  /* catch endless loops in a single request */
1834a600dabSGlenn Strauss     int8_t keep_alive; /* only request.c can enable it, all other just disable */
1847c7f8c46SGlenn Strauss     char async_callback;
1857c7f8c46SGlenn Strauss 
1867c7f8c46SGlenn Strauss     buffer *tmp_buf;                    /* shared; same as srv->tmp_buf */
1877420526dSGlenn Strauss     response_dechunk *gw_dechunk;
1887c7f8c46SGlenn Strauss 
189afc2025dSGlenn Strauss     off_t bytes_written_ckpt; /* used by mod_accesslog */
190afc2025dSGlenn Strauss     off_t bytes_read_ckpt;    /* used by mod_accesslog */
191309c1693SGlenn Strauss     unix_timespec64_t start_hp;
1927c7f8c46SGlenn Strauss 
1937c7f8c46SGlenn Strauss     int error_handler_saved_status; /* error-handler */
1947c7f8c46SGlenn Strauss     http_method_t error_handler_saved_method; /* error-handler */
19581029b8bSGlenn Strauss 
19681029b8bSGlenn Strauss     struct chunkqueue write_queue;     /* HTTP response queue [ file, mem ] */
19781029b8bSGlenn Strauss     struct chunkqueue read_queue;      /* HTTP request queue  [ mem ] */
19881029b8bSGlenn Strauss     struct chunkqueue reqbody_queue; /*(might use tempfiles)*/
1999a5e1652SGlenn Strauss 
2009a5e1652SGlenn Strauss     struct stat_cache_entry *tmp_sce; /*(value valid only in sequential code)*/
201ef9608f3SGlenn Strauss     int cond_captures;
2025d1aa5d0SGlenn Strauss     int h2_connect_ext;
2036870b0f5SGlenn Strauss };
204668cb641SGlenn Strauss 
205bcdc6a3bSJan Kneschke 
2068fc8ab89SGlenn Strauss typedef struct http_header_parse_ctx {
2078fc8ab89SGlenn Strauss     char *k;
2088fc8ab89SGlenn Strauss     char *v;
2098fc8ab89SGlenn Strauss     uint32_t klen;
2108fc8ab89SGlenn Strauss     uint32_t vlen;
2118fc8ab89SGlenn Strauss     uint32_t hlen;
2123fbb5773SGlenn Strauss     uint8_t pseudo;
2133fbb5773SGlenn Strauss     uint8_t scheme;
2143fbb5773SGlenn Strauss     uint8_t trailers;
2150f90a9e3SGlenn Strauss     int8_t id;
2168fc8ab89SGlenn Strauss     uint32_t max_request_field_size;
2178fc8ab89SGlenn Strauss     unsigned int http_parseopts;
2188fc8ab89SGlenn Strauss } http_header_parse_ctx;
2198fc8ab89SGlenn Strauss 
2208fc8ab89SGlenn Strauss 
2218fc8ab89SGlenn Strauss int http_request_validate_pseudohdrs (request_st * restrict r, int scheme, unsigned int http_parseopts);
2228fc8ab89SGlenn Strauss int http_request_parse_header (request_st * restrict r, http_header_parse_ctx * restrict hpctx);
2238fc8ab89SGlenn Strauss void http_request_headers_process_h2 (request_st * restrict r, int scheme_port);
2246971c6c8SGlenn Strauss void http_request_headers_process (request_st * restrict r, char * restrict hdrs, const unsigned short * restrict hoff, int scheme_port);
225d013d0abSGlenn Strauss int http_request_parse_target(request_st *r, int scheme_port);
22640f72a41SGlenn Strauss int http_request_host_normalize(buffer *b, int scheme_port);
2271dd58c5aSGlenn Strauss int http_request_host_policy(buffer *b, unsigned int http_parseopts, int scheme_port);
228bcdc6a3bSJan Kneschke 
229e9309ae6SGlenn Strauss int64_t li_restricted_strtoint64 (const char *v, const uint32_t vlen, const char ** const err);
230e9309ae6SGlenn Strauss 
2315e0d82dcSGlenn Strauss 
2325e0d82dcSGlenn Strauss /* convenience macros/functions for display purposes */
2335e0d82dcSGlenn Strauss 
2345e0d82dcSGlenn Strauss #define http_request_state_is_keep_alive(r) \
2355e0d82dcSGlenn Strauss   (CON_STATE_READ == (r)->state && !buffer_is_blank(&(r)->target_orig))
2365e0d82dcSGlenn Strauss 
2375e0d82dcSGlenn Strauss #define http_con_state_is_keep_alive(con) \
2385e0d82dcSGlenn Strauss   ((con)->h2                              \
2395e0d82dcSGlenn Strauss    ? 0 == (con)->h2->rused                \
2405e0d82dcSGlenn Strauss    : http_request_state_is_keep_alive(&(con)->request))
2415e0d82dcSGlenn Strauss 
2425e0d82dcSGlenn Strauss #define http_con_state_append(b, con)                            \
2435e0d82dcSGlenn Strauss    (http_con_state_is_keep_alive(con)                            \
2445e0d82dcSGlenn Strauss     ? buffer_append_string_len((b), CONST_STR_LEN("keep-alive")) \
2455e0d82dcSGlenn Strauss     : http_request_state_append((b), (con)->request.state))
2465e0d82dcSGlenn Strauss 
2475e0d82dcSGlenn Strauss #define http_con_state_short(con)     \
2485e0d82dcSGlenn Strauss    (http_con_state_is_keep_alive(con) \
2495e0d82dcSGlenn Strauss     ? "k"                             \
2505e0d82dcSGlenn Strauss     : http_request_state_short((con)->request.state))
2515e0d82dcSGlenn Strauss 
2522adc62e9SGlenn Strauss #define http_request_stats_bytes_in(r) \
2532adc62e9SGlenn Strauss    ((r)->read_queue.bytes_out - (r)->bytes_read_ckpt)
2542adc62e9SGlenn Strauss 
2552adc62e9SGlenn Strauss #define http_request_stats_bytes_out(r) \
2562adc62e9SGlenn Strauss    ((r)->write_queue.bytes_out - (r)->bytes_written_ckpt)
2572adc62e9SGlenn Strauss 
2585e0d82dcSGlenn Strauss __attribute_pure__
2595e0d82dcSGlenn Strauss const char * http_request_state_short (request_state_t state);
2605e0d82dcSGlenn Strauss 
2615e0d82dcSGlenn Strauss void http_request_state_append (buffer *b, request_state_t state);
2625e0d82dcSGlenn Strauss 
2635e0d82dcSGlenn Strauss 
264bcdc6a3bSJan Kneschke #endif
265