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