10Sigor@sysoev.ru 20Sigor@sysoev.ru /* 384Smax.romanov@nginx.com * Copyright (C) Max Romanov 40Sigor@sysoev.ru * Copyright (C) Valentin V. Bartenev 50Sigor@sysoev.ru * Copyright (C) NGINX, Inc. 60Sigor@sysoev.ru */ 70Sigor@sysoev.ru 80Sigor@sysoev.ru #ifndef _NXT_APPLICATION_H_INCLUDED_ 90Sigor@sysoev.ru #define _NXT_APPLICATION_H_INCLUDED_ 100Sigor@sysoev.ru 110Sigor@sysoev.ru 12133Sigor@sysoev.ru typedef enum { 13141Smax.romanov@nginx.com NXT_APP_UNKNOWN = 0, 14141Smax.romanov@nginx.com NXT_APP_PYTHON, 15141Smax.romanov@nginx.com NXT_APP_PYTHON2, 16141Smax.romanov@nginx.com NXT_APP_PYTHON3, 17133Sigor@sysoev.ru NXT_APP_PHP, 18141Smax.romanov@nginx.com NXT_APP_PHP5, 19141Smax.romanov@nginx.com NXT_APP_PHP7, 20133Sigor@sysoev.ru NXT_APP_RUBY, 21133Sigor@sysoev.ru NXT_APP_GO, 22141Smax.romanov@nginx.com 23141Smax.romanov@nginx.com NXT_APP_MAX, 24133Sigor@sysoev.ru } nxt_app_type_t; 25133Sigor@sysoev.ru 26133Sigor@sysoev.ru 27141Smax.romanov@nginx.com typedef struct nxt_common_app_conf_s nxt_common_app_conf_t; 28141Smax.romanov@nginx.com 29141Smax.romanov@nginx.com 30141Smax.romanov@nginx.com typedef struct { 31141Smax.romanov@nginx.com nxt_str_t path; 32141Smax.romanov@nginx.com nxt_str_t module; 33141Smax.romanov@nginx.com } nxt_python_app_conf_t; 34141Smax.romanov@nginx.com 35141Smax.romanov@nginx.com 36141Smax.romanov@nginx.com typedef struct { 37141Smax.romanov@nginx.com nxt_str_t root; 38141Smax.romanov@nginx.com nxt_str_t script; 39141Smax.romanov@nginx.com nxt_str_t index; 40141Smax.romanov@nginx.com } nxt_php_app_conf_t; 41141Smax.romanov@nginx.com 42141Smax.romanov@nginx.com 43141Smax.romanov@nginx.com typedef struct { 44141Smax.romanov@nginx.com nxt_str_t executable; 45141Smax.romanov@nginx.com } nxt_go_app_conf_t; 46141Smax.romanov@nginx.com 47141Smax.romanov@nginx.com 48141Smax.romanov@nginx.com struct nxt_common_app_conf_s { 49141Smax.romanov@nginx.com nxt_str_t type; 50141Smax.romanov@nginx.com nxt_app_type_t type_id; 51141Smax.romanov@nginx.com nxt_str_t user; 52141Smax.romanov@nginx.com nxt_str_t group; 53141Smax.romanov@nginx.com 54141Smax.romanov@nginx.com uint32_t workers; 55141Smax.romanov@nginx.com 56141Smax.romanov@nginx.com union { 57141Smax.romanov@nginx.com nxt_python_app_conf_t python; 58141Smax.romanov@nginx.com nxt_php_app_conf_t php; 59141Smax.romanov@nginx.com nxt_go_app_conf_t go; 60141Smax.romanov@nginx.com } u; 61141Smax.romanov@nginx.com }; 62141Smax.romanov@nginx.com 63141Smax.romanov@nginx.com 640Sigor@sysoev.ru typedef struct { 650Sigor@sysoev.ru nxt_str_t name; 660Sigor@sysoev.ru nxt_str_t value; 670Sigor@sysoev.ru } nxt_app_header_field_t; 680Sigor@sysoev.ru 690Sigor@sysoev.ru 700Sigor@sysoev.ru typedef struct { 710Sigor@sysoev.ru nxt_str_t method; 72112Smax.romanov@nginx.com nxt_str_t target; 73112Smax.romanov@nginx.com nxt_str_t version; 740Sigor@sysoev.ru nxt_str_t path; 7584Smax.romanov@nginx.com nxt_str_t query; 7684Smax.romanov@nginx.com 7784Smax.romanov@nginx.com nxt_list_t *fields; 780Sigor@sysoev.ru 7984Smax.romanov@nginx.com nxt_str_t cookie; 8084Smax.romanov@nginx.com nxt_str_t content_length; 8184Smax.romanov@nginx.com nxt_str_t content_type; 8284Smax.romanov@nginx.com nxt_str_t host; 8384Smax.romanov@nginx.com 8484Smax.romanov@nginx.com off_t parsed_content_length; 8584Smax.romanov@nginx.com nxt_bool_t done; 860Sigor@sysoev.ru } nxt_app_request_header_t; 870Sigor@sysoev.ru 880Sigor@sysoev.ru 890Sigor@sysoev.ru typedef struct { 9084Smax.romanov@nginx.com nxt_str_t preread; 9184Smax.romanov@nginx.com nxt_bool_t done; 9284Smax.romanov@nginx.com } nxt_app_request_body_t; 930Sigor@sysoev.ru 940Sigor@sysoev.ru 9584Smax.romanov@nginx.com typedef struct { 960Sigor@sysoev.ru nxt_app_request_header_t header; 9784Smax.romanov@nginx.com nxt_app_request_body_t body; 98113Smax.romanov@nginx.com 99113Smax.romanov@nginx.com nxt_str_t remote; 1000Sigor@sysoev.ru } nxt_app_request_t; 1010Sigor@sysoev.ru 1020Sigor@sysoev.ru 103*163Smax.romanov@nginx.com typedef struct nxt_app_parse_ctx_s nxt_app_parse_ctx_t; 104*163Smax.romanov@nginx.com 105*163Smax.romanov@nginx.com struct nxt_app_parse_ctx_s { 10684Smax.romanov@nginx.com nxt_app_request_t r; 10784Smax.romanov@nginx.com nxt_http_request_parse_t parser; 10884Smax.romanov@nginx.com nxt_mp_t *mem_pool; 109*163Smax.romanov@nginx.com }; 11084Smax.romanov@nginx.com 11184Smax.romanov@nginx.com 11284Smax.romanov@nginx.com nxt_int_t nxt_app_http_req_init(nxt_task_t *task, nxt_app_parse_ctx_t *ctx); 11384Smax.romanov@nginx.com 11484Smax.romanov@nginx.com nxt_int_t nxt_app_http_req_parse(nxt_task_t *task, nxt_app_parse_ctx_t *ctx, 11584Smax.romanov@nginx.com nxt_buf_t *buf); 11684Smax.romanov@nginx.com 11784Smax.romanov@nginx.com nxt_int_t nxt_app_http_req_done(nxt_task_t *task, nxt_app_parse_ctx_t *ctx); 11884Smax.romanov@nginx.com 11984Smax.romanov@nginx.com nxt_int_t nxt_app_http_init(nxt_task_t *task, nxt_runtime_t *rt); 12084Smax.romanov@nginx.com 12184Smax.romanov@nginx.com 12284Smax.romanov@nginx.com typedef struct nxt_app_wmsg_s nxt_app_wmsg_t; 12384Smax.romanov@nginx.com typedef struct nxt_app_rmsg_s nxt_app_rmsg_t; 12484Smax.romanov@nginx.com 12584Smax.romanov@nginx.com struct nxt_app_wmsg_s { 12684Smax.romanov@nginx.com nxt_port_t *port; /* where prepared buf will be sent */ 12784Smax.romanov@nginx.com nxt_buf_t *write; 12884Smax.romanov@nginx.com nxt_buf_t **buf; 12984Smax.romanov@nginx.com uint32_t stream; 13084Smax.romanov@nginx.com }; 13184Smax.romanov@nginx.com 13284Smax.romanov@nginx.com struct nxt_app_rmsg_s { 13384Smax.romanov@nginx.com nxt_buf_t *buf; /* current buffer to read */ 13484Smax.romanov@nginx.com }; 13584Smax.romanov@nginx.com 13684Smax.romanov@nginx.com 13784Smax.romanov@nginx.com nxt_inline u_char * 13884Smax.romanov@nginx.com nxt_app_msg_write_length(u_char *dst, size_t length); 13984Smax.romanov@nginx.com 14084Smax.romanov@nginx.com /* TODO asynchronous mmap buffer assignment */ 14184Smax.romanov@nginx.com u_char *nxt_app_msg_write_get_buf(nxt_task_t *task, nxt_app_wmsg_t *msg, 14284Smax.romanov@nginx.com size_t size); 14384Smax.romanov@nginx.com 14484Smax.romanov@nginx.com nxt_int_t nxt_app_msg_write(nxt_task_t *task, nxt_app_wmsg_t *msg, 14584Smax.romanov@nginx.com u_char *c, size_t size); 14684Smax.romanov@nginx.com 14784Smax.romanov@nginx.com nxt_int_t nxt_app_msg_write_prefixed_upcase(nxt_task_t *task, 14884Smax.romanov@nginx.com nxt_app_wmsg_t *msg, const nxt_str_t *prefix, const nxt_str_t *v); 14984Smax.romanov@nginx.com 15084Smax.romanov@nginx.com nxt_inline nxt_int_t 15184Smax.romanov@nginx.com nxt_app_msg_write_nvp_(nxt_task_t *task, nxt_app_wmsg_t *msg, 15284Smax.romanov@nginx.com u_char *n, size_t nsize, u_char *v, size_t vsize); 15384Smax.romanov@nginx.com 15484Smax.romanov@nginx.com 15584Smax.romanov@nginx.com #define nxt_app_msg_write_const(task, msg, c) \ 15684Smax.romanov@nginx.com nxt_app_msg_write((task), (msg), (u_char *)(c), sizeof(c) - 1) 15784Smax.romanov@nginx.com 15884Smax.romanov@nginx.com #define nxt_app_msg_write_str(task, msg, str) \ 15984Smax.romanov@nginx.com nxt_app_msg_write((task), (msg), (str)->start, (str)->length) 16084Smax.romanov@nginx.com 16184Smax.romanov@nginx.com #define nxt_app_msg_write_cstr(task, msg, c) \ 16284Smax.romanov@nginx.com nxt_app_msg_write((task), (msg), (c), nxt_strlen(c)) 16384Smax.romanov@nginx.com 16484Smax.romanov@nginx.com #define nxt_app_msg_write_nvp(task, msg, n, v) \ 16584Smax.romanov@nginx.com nxt_app_msg_write_nvp_((task), (msg), (u_char *)(n), sizeof(n) - 1, \ 16684Smax.romanov@nginx.com (v)->start, (v)->length) 16784Smax.romanov@nginx.com 16884Smax.romanov@nginx.com nxt_inline nxt_int_t nxt_app_msg_write_size(nxt_task_t *task, 16984Smax.romanov@nginx.com nxt_app_wmsg_t *msg, size_t size); 17084Smax.romanov@nginx.com 17184Smax.romanov@nginx.com nxt_int_t nxt_app_msg_flush(nxt_task_t *task, nxt_app_wmsg_t *msg, 17284Smax.romanov@nginx.com nxt_bool_t last); 17384Smax.romanov@nginx.com 17484Smax.romanov@nginx.com nxt_int_t nxt_app_msg_write_raw(nxt_task_t *task, nxt_app_wmsg_t *msg, 17584Smax.romanov@nginx.com const u_char *c, size_t size); 17684Smax.romanov@nginx.com 17784Smax.romanov@nginx.com nxt_int_t nxt_app_msg_read_str(nxt_task_t *task, nxt_app_rmsg_t *msg, 17884Smax.romanov@nginx.com nxt_str_t *str); 17984Smax.romanov@nginx.com 18084Smax.romanov@nginx.com nxt_int_t nxt_app_msg_read_nvp(nxt_task_t *task, nxt_app_rmsg_t *rmsg, 18184Smax.romanov@nginx.com nxt_str_t *n, nxt_str_t *v); 18284Smax.romanov@nginx.com 18384Smax.romanov@nginx.com nxt_int_t nxt_app_msg_read_size(nxt_task_t *task, nxt_app_rmsg_t *rmsg, 18484Smax.romanov@nginx.com size_t *size); 18584Smax.romanov@nginx.com 18684Smax.romanov@nginx.com 187141Smax.romanov@nginx.com typedef struct nxt_app_module_s nxt_application_module_t; 188141Smax.romanov@nginx.com typedef struct nxt_app_module_s nxt_app_module_t; 189141Smax.romanov@nginx.com 190141Smax.romanov@nginx.com struct nxt_app_module_s { 191141Smax.romanov@nginx.com nxt_int_t (*init)(nxt_task_t *task, 192141Smax.romanov@nginx.com nxt_common_app_conf_t *conf); 19384Smax.romanov@nginx.com nxt_int_t (*prepare_msg)(nxt_task_t *task, 19484Smax.romanov@nginx.com nxt_app_request_t *r, 19584Smax.romanov@nginx.com nxt_app_wmsg_t *wmsg); 19684Smax.romanov@nginx.com nxt_int_t (*run)(nxt_task_t *task, 19784Smax.romanov@nginx.com nxt_app_rmsg_t *rmsg, 19884Smax.romanov@nginx.com nxt_app_wmsg_t *wmsg); 199141Smax.romanov@nginx.com }; 2000Sigor@sysoev.ru 2010Sigor@sysoev.ru 202141Smax.romanov@nginx.com extern nxt_application_module_t *nxt_app_modules[NXT_APP_MAX]; 20321Sigor@sysoev.ru 2040Sigor@sysoev.ru 2050Sigor@sysoev.ru 20620Sigor@sysoev.ru nxt_int_t nxt_app_http_read_body(nxt_app_request_t *r, u_char *data, 20720Sigor@sysoev.ru size_t len); 2080Sigor@sysoev.ru nxt_int_t nxt_app_write(nxt_app_request_t *r, const u_char *data, size_t len); 2090Sigor@sysoev.ru 21084Smax.romanov@nginx.com nxt_inline u_char * 21184Smax.romanov@nginx.com nxt_app_msg_write_length(u_char *dst, size_t length) 21284Smax.romanov@nginx.com { 21384Smax.romanov@nginx.com if (length < 128) { 21484Smax.romanov@nginx.com *dst = length; 21584Smax.romanov@nginx.com dst++; 21684Smax.romanov@nginx.com } else { 21784Smax.romanov@nginx.com dst[0] = 0x80U | (length >> 24); 21884Smax.romanov@nginx.com dst[1] = 0xFFU & (length >> 16); 21984Smax.romanov@nginx.com dst[2] = 0xFFU & (length >> 8); 22084Smax.romanov@nginx.com dst[3] = 0xFFU & length; 22184Smax.romanov@nginx.com dst += 4; 22284Smax.romanov@nginx.com } 22384Smax.romanov@nginx.com 22484Smax.romanov@nginx.com return dst; 22584Smax.romanov@nginx.com } 22684Smax.romanov@nginx.com 22784Smax.romanov@nginx.com 22884Smax.romanov@nginx.com nxt_inline nxt_int_t 22984Smax.romanov@nginx.com nxt_app_msg_write_nvp_(nxt_task_t *task, nxt_app_wmsg_t *msg, 23084Smax.romanov@nginx.com u_char *n, size_t nsize, u_char *v, size_t vsize) 23184Smax.romanov@nginx.com { 23284Smax.romanov@nginx.com nxt_int_t rc; 23384Smax.romanov@nginx.com 23484Smax.romanov@nginx.com rc = nxt_app_msg_write(task, msg, n, nsize); 23584Smax.romanov@nginx.com if (nxt_slow_path(rc != NXT_OK)) { 23684Smax.romanov@nginx.com return rc; 23784Smax.romanov@nginx.com } 23884Smax.romanov@nginx.com 23984Smax.romanov@nginx.com return nxt_app_msg_write(task, msg, v, vsize); 24084Smax.romanov@nginx.com } 24184Smax.romanov@nginx.com 24284Smax.romanov@nginx.com 24384Smax.romanov@nginx.com nxt_inline nxt_int_t 24484Smax.romanov@nginx.com nxt_app_msg_write_size(nxt_task_t *task, nxt_app_wmsg_t *msg, size_t size) 24584Smax.romanov@nginx.com { 24684Smax.romanov@nginx.com u_char *dst; 24784Smax.romanov@nginx.com size_t dst_length; 24884Smax.romanov@nginx.com 24984Smax.romanov@nginx.com dst_length = size < 128 ? 1 : 4; 25084Smax.romanov@nginx.com 25184Smax.romanov@nginx.com dst = nxt_app_msg_write_get_buf(task, msg, dst_length); 25284Smax.romanov@nginx.com if (nxt_slow_path(dst == NULL)) { 25384Smax.romanov@nginx.com return NXT_ERROR; 25484Smax.romanov@nginx.com } 25584Smax.romanov@nginx.com 25684Smax.romanov@nginx.com nxt_app_msg_write_length(dst, size); 25784Smax.romanov@nginx.com 25884Smax.romanov@nginx.com return NXT_OK; 25984Smax.romanov@nginx.com } 26084Smax.romanov@nginx.com 26184Smax.romanov@nginx.com 26284Smax.romanov@nginx.com nxt_inline u_char * 26384Smax.romanov@nginx.com nxt_app_msg_read_length(u_char *src, size_t *length) 26484Smax.romanov@nginx.com { 26584Smax.romanov@nginx.com if (src[0] < 128) { 26684Smax.romanov@nginx.com *length = src[0]; 26784Smax.romanov@nginx.com src++; 26884Smax.romanov@nginx.com } else { 26984Smax.romanov@nginx.com *length = ((src[0] & 0x7fU) << 24) + 27084Smax.romanov@nginx.com (src[1] << 16) + 27184Smax.romanov@nginx.com (src[2] << 8) + 27284Smax.romanov@nginx.com src[3]; 27384Smax.romanov@nginx.com src += 4; 27484Smax.romanov@nginx.com } 27584Smax.romanov@nginx.com 27684Smax.romanov@nginx.com return src; 27784Smax.romanov@nginx.com } 27884Smax.romanov@nginx.com 2790Sigor@sysoev.ru 280141Smax.romanov@nginx.com nxt_app_type_t nxt_app_parse_type(nxt_str_t *str); 281141Smax.romanov@nginx.com 2820Sigor@sysoev.ru #endif /* _NXT_APPLICATION_H_INCLIDED_ */ 283