1 2 /* 3 * Copyright (C) Igor Sysoev 4 * Copyright (C) NGINX, Inc. 5 */ 6 7 #ifndef _NXT_HTTP_H_INCLUDED_ 8 #define _NXT_HTTP_H_INCLUDED_ 9 10 11 typedef enum { 12 NXT_HTTP_INVALID = 0, 13 14 NXT_HTTP_CONTINUE = 100, 15 NXT_HTTP_SWITCHING_PROTOCOLS = 101, 16 17 NXT_HTTP_OK = 200, 18 NXT_HTTP_NO_CONTENT = 204, 19 20 NXT_HTTP_MULTIPLE_CHOICES = 300, 21 NXT_HTTP_MOVED_PERMANENTLY = 301, 22 NXT_HTTP_FOUND = 302, 23 NXT_HTTP_SEE_OTHER = 303, 24 NXT_HTTP_NOT_MODIFIED = 304, 25 26 NXT_HTTP_BAD_REQUEST = 400, 27 NXT_HTTP_NOT_FOUND = 404, 28 NXT_HTTP_REQUEST_TIMEOUT = 408, 29 NXT_HTTP_LENGTH_REQUIRED = 411, 30 NXT_HTTP_PAYLOAD_TOO_LARGE = 413, 31 NXT_HTTP_URI_TOO_LONG = 414, 32 NXT_HTTP_UPGRADE_REQUIRED = 426, 33 NXT_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431, 34 35 NXT_HTTP_TO_HTTPS = 497, 36 37 NXT_HTTP_INTERNAL_SERVER_ERROR = 500, 38 NXT_HTTP_NOT_IMPLEMENTED = 501, 39 NXT_HTTP_BAD_GATEWAY = 502, 40 NXT_HTTP_SERVICE_UNAVAILABLE = 503, 41 NXT_HTTP_GATEWAY_TIMEOUT = 504, 42 NXT_HTTP_VERSION_NOT_SUPPORTED = 505, 43 } nxt_http_status_t; 44 45 46 typedef enum { 47 NXT_HTTP_TE_NONE = 0, 48 NXT_HTTP_TE_CHUNKED = 1, 49 NXT_HTTP_TE_UNSUPPORTED = 2, 50 } nxt_http_te_t; 51 52 53 typedef enum { 54 NXT_HTTP_PROTO_H1 = 0, 55 NXT_HTTP_PROTO_H2, 56 NXT_HTTP_PROTO_DEVNULL, 57 } nxt_http_protocol_t; 58 59 60 typedef struct { 61 nxt_work_handler_t ready_handler; 62 nxt_work_handler_t error_handler; 63 } nxt_http_request_state_t; 64 65 66 typedef struct nxt_h1proto_s nxt_h1proto_t; 67 68 struct nxt_h1p_websocket_timer_s { 69 nxt_timer_t timer; 70 nxt_h1proto_t *h1p; 71 nxt_msec_t keepalive_interval; 72 }; 73 74 75 typedef union { 76 void *any; 77 nxt_h1proto_t *h1; 78 } nxt_http_proto_t; 79 80 81 #define nxt_http_field_name_set(_field, _name) \ 82 do { \ 83 (_field)->name_length = nxt_length(_name); \ 84 (_field)->name = (u_char *) _name; \ 85 } while (0) 86 87 88 #define nxt_http_field_set(_field, _name, _value) \ 89 do { \ 90 (_field)->name_length = nxt_length(_name); \ 91 (_field)->value_length = nxt_length(_value); \ 92 (_field)->name = (u_char *) _name; \ 93 (_field)->value = (u_char *) _value; \ 94 } while (0) 95 96 97 typedef struct { 98 nxt_list_t *fields; 99 nxt_http_field_t *date; 100 nxt_http_field_t *content_type; 101 nxt_http_field_t *content_length; 102 nxt_off_t content_length_n; 103 } nxt_http_response_t; 104 105 106 struct nxt_http_request_s { 107 nxt_http_proto_t proto; 108 nxt_socket_conf_joint_t *conf; 109 110 nxt_mp_t *mem_pool; 111 112 nxt_buf_t *body; 113 nxt_buf_t *ws_frame; 114 nxt_buf_t *out; 115 const nxt_http_request_state_t *state; 116 117 nxt_str_t host; 118 nxt_str_t server_name; 119 nxt_str_t target; 120 nxt_str_t version; 121 nxt_str_t *method; 122 nxt_str_t *path; 123 nxt_str_t *args; 124 125 nxt_array_t *arguments; /* of nxt_http_name_value_t */ 126 nxt_array_t *cookies; /* of nxt_http_name_value_t */ 127 nxt_list_t *fields; 128 nxt_http_field_t *content_type; 129 nxt_http_field_t *content_length; 130 nxt_http_field_t *cookie; 131 nxt_http_field_t *referer; 132 nxt_http_field_t *user_agent; 133 nxt_off_t content_length_n; 134 135 nxt_sockaddr_t *remote; 136 nxt_sockaddr_t *local; 137 void *tls; 138 139 nxt_timer_t timer; 140 void *timer_data; 141 142 void *req_rpc_data; 143 144 nxt_buf_t *last; 145 146 nxt_http_response_t resp; 147 148 nxt_http_status_t status:16; 149 150 uint8_t pass_count; /* 8 bits */ 151 nxt_http_protocol_t protocol:8; /* 2 bits */ 152 uint8_t logged; /* 1 bit */ 153 uint8_t header_sent; /* 1 bit */ 154 uint8_t error; /* 1 bit */ 155 uint8_t websocket_handshake; /* 1 bit */ 156 }; 157 158 159 typedef struct nxt_http_route_s nxt_http_route_t; 160 161 162 struct nxt_http_pass_s { 163 nxt_http_pass_t *(*handler)(nxt_task_t *task, 164 nxt_http_request_t *r, 165 nxt_http_pass_t *pass); 166 union { 167 nxt_http_route_t *route; 168 nxt_app_t *application; 169 } u; 170 171 nxt_str_t name; 172 }; 173 174 175 typedef struct { 176 void (*body_read)(nxt_task_t *task, nxt_http_request_t *r); 177 void (*local_addr)(nxt_task_t *task, nxt_http_request_t *r); 178 void (*header_send)(nxt_task_t *task, nxt_http_request_t *r); 179 void (*send)(nxt_task_t *task, nxt_http_request_t *r, nxt_buf_t *out); 180 nxt_off_t (*body_bytes_sent)(nxt_task_t *task, nxt_http_proto_t proto); 181 void (*discard)(nxt_task_t *task, nxt_http_request_t *r, nxt_buf_t *last); 182 void (*close)(nxt_task_t *task, nxt_http_proto_t proto, 183 nxt_socket_conf_joint_t *joint); 184 void (*ws_frame_start)(nxt_task_t *task, nxt_http_request_t *r, 185 nxt_buf_t *ws_frame); 186 } nxt_http_proto_table_t; 187 188 189 nxt_int_t nxt_http_init(nxt_task_t *task, nxt_runtime_t *rt); 190 nxt_int_t nxt_h1p_init(nxt_task_t *task, nxt_runtime_t *rt); 191 nxt_int_t nxt_http_response_hash_init(nxt_task_t *task, nxt_runtime_t *rt); 192 193 void nxt_http_conn_init(nxt_task_t *task, void *obj, void *data); 194 nxt_http_request_t *nxt_http_request_create(nxt_task_t *task); 195 void nxt_http_request_error(nxt_task_t *task, nxt_http_request_t *r, 196 nxt_http_status_t status); 197 void nxt_http_request_read_body(nxt_task_t *task, nxt_http_request_t *r); 198 void nxt_http_request_header_send(nxt_task_t *task, nxt_http_request_t *r); 199 void nxt_http_request_ws_frame_start(nxt_task_t *task, nxt_http_request_t *r, 200 nxt_buf_t *ws_frame); 201 void nxt_http_request_send(nxt_task_t *task, nxt_http_request_t *r, 202 nxt_buf_t *out); 203 nxt_buf_t *nxt_http_buf_mem(nxt_task_t *task, nxt_http_request_t *r, 204 size_t size); 205 nxt_buf_t *nxt_http_buf_last(nxt_http_request_t *r); 206 void nxt_http_request_error_handler(nxt_task_t *task, void *obj, void *data); 207 void nxt_http_request_close_handler(nxt_task_t *task, void *obj, void *data); 208 209 nxt_int_t nxt_http_request_host(void *ctx, nxt_http_field_t *field, 210 uintptr_t data); 211 nxt_int_t nxt_http_request_field(void *ctx, nxt_http_field_t *field, 212 uintptr_t offset); 213 nxt_int_t nxt_http_request_content_length(void *ctx, nxt_http_field_t *field, 214 uintptr_t data); 215 216 nxt_http_routes_t *nxt_http_routes_create(nxt_task_t *task, 217 nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *routes_conf); 218 nxt_http_pass_t *nxt_http_pass_create(nxt_task_t *task, 219 nxt_router_temp_conf_t *tmcf, nxt_str_t *name); 220 void nxt_http_routes_resolve(nxt_task_t *task, nxt_router_temp_conf_t *tmcf); 221 nxt_http_pass_t *nxt_http_pass_application(nxt_task_t *task, 222 nxt_router_temp_conf_t *tmcf, nxt_str_t *name); 223 void nxt_http_routes_cleanup(nxt_task_t *task, nxt_http_routes_t *routes); 224 void nxt_http_pass_cleanup(nxt_task_t *task, nxt_http_pass_t *pass); 225 226 nxt_http_pass_t *nxt_http_request_application(nxt_task_t *task, 227 nxt_http_request_t *r, nxt_http_pass_t *pass); 228 229 extern nxt_time_string_t nxt_http_date_cache; 230 231 extern nxt_lvlhsh_t nxt_response_fields_hash; 232 233 extern const nxt_http_proto_table_t nxt_http_proto[]; 234 235 void nxt_h1p_websocket_first_frame_start(nxt_task_t *task, 236 nxt_http_request_t *r, nxt_buf_t *ws_frame); 237 void nxt_h1p_websocket_frame_start(nxt_task_t *task, nxt_http_request_t *r, 238 nxt_buf_t *ws_frame); 239 void nxt_h1p_complete_buffers(nxt_task_t *task, nxt_h1proto_t *h1p); 240 nxt_msec_t nxt_h1p_conn_request_timer_value(nxt_conn_t *c, uintptr_t data); 241 242 extern const nxt_conn_state_t nxt_h1p_idle_close_state; 243 244 #endif /* _NXT_HTTP_H_INCLUDED_ */ 245