1 2 /* 3 * Copyright (C) Max Romanov 4 * Copyright (C) Valentin V. Bartenev 5 * Copyright (C) NGINX, Inc. 6 */ 7 8 #ifndef _NXT_APPLICATION_H_INCLUDED_ 9 #define _NXT_APPLICATION_H_INCLUDED_ 10 11 12 typedef enum { 13 NXT_APP_PYTHON, 14 NXT_APP_PHP, 15 NXT_APP_GO, 16 NXT_APP_PERL, 17 NXT_APP_RUBY, 18 19 NXT_APP_UNKNOWN, 20 } nxt_app_type_t; 21 22 23 typedef struct nxt_app_module_s nxt_application_module_t; 24 typedef struct nxt_app_module_s nxt_app_module_t; 25 26 27 typedef struct { 28 nxt_app_type_t type; 29 u_char *version; 30 char *file; 31 nxt_application_module_t *module; 32 } nxt_app_lang_module_t; 33 34 35 typedef struct nxt_common_app_conf_s nxt_common_app_conf_t; 36 37 38 typedef struct { 39 char *home; 40 nxt_str_t path; 41 nxt_str_t module; 42 } nxt_python_app_conf_t; 43 44 45 typedef struct { 46 char *root; 47 nxt_str_t script; 48 nxt_str_t index; 49 } nxt_php_app_conf_t; 50 51 52 typedef struct { 53 char *executable; 54 } nxt_go_app_conf_t; 55 56 57 typedef struct { 58 char *script; 59 } nxt_perl_app_conf_t; 60 61 62 typedef struct { 63 nxt_str_t script; 64 } nxt_ruby_app_conf_t; 65 66 67 struct nxt_common_app_conf_s { 68 nxt_str_t name; 69 nxt_str_t type; 70 nxt_str_t user; 71 nxt_str_t group; 72 73 char *working_directory; 74 75 union { 76 nxt_python_app_conf_t python; 77 nxt_php_app_conf_t php; 78 nxt_go_app_conf_t go; 79 nxt_perl_app_conf_t perl; 80 nxt_ruby_app_conf_t ruby; 81 } u; 82 }; 83 84 85 typedef struct { 86 nxt_str_t name; 87 nxt_str_t value; 88 } nxt_app_header_field_t; 89 90 91 typedef struct { 92 nxt_str_t method; 93 nxt_str_t target; 94 nxt_str_t version; 95 nxt_str_t path; 96 nxt_str_t query; 97 98 nxt_list_t *fields; 99 100 nxt_str_t cookie; 101 nxt_str_t content_length; 102 nxt_str_t content_type; 103 nxt_str_t host; 104 105 off_t parsed_content_length; 106 nxt_bool_t done; 107 108 size_t bufs; 109 nxt_buf_t *buf; 110 } nxt_app_request_header_t; 111 112 113 typedef struct { 114 size_t preread_size; 115 nxt_bool_t done; 116 117 nxt_buf_t *buf; 118 } nxt_app_request_body_t; 119 120 121 typedef struct { 122 nxt_app_request_header_t header; 123 nxt_app_request_body_t body; 124 125 nxt_str_t remote; 126 nxt_str_t local; 127 } nxt_app_request_t; 128 129 130 typedef struct nxt_app_parse_ctx_s nxt_app_parse_ctx_t; 131 132 struct nxt_app_parse_ctx_s { 133 nxt_app_request_t r; 134 nxt_http_request_t *request; 135 nxt_timer_t timer; 136 nxt_http_request_parse_t parser; 137 nxt_http_request_parse_t resp_parser; 138 nxt_mp_t *mem_pool; 139 }; 140 141 142 nxt_int_t nxt_app_http_req_done(nxt_task_t *task, nxt_app_parse_ctx_t *ctx); 143 144 145 typedef struct nxt_app_wmsg_s nxt_app_wmsg_t; 146 typedef struct nxt_app_rmsg_s nxt_app_rmsg_t; 147 148 struct nxt_app_wmsg_s { 149 nxt_port_t *port; /* where prepared buf will be sent */ 150 nxt_buf_t *write; 151 nxt_buf_t **buf; 152 uint32_t stream; 153 }; 154 155 156 struct nxt_app_rmsg_s { 157 nxt_buf_t *buf; /* current buffer to read */ 158 }; 159 160 161 nxt_inline u_char * 162 nxt_app_msg_write_length(u_char *dst, size_t length); 163 164 /* TODO asynchronous mmap buffer assignment */ 165 NXT_EXPORT u_char *nxt_app_msg_write_get_buf(nxt_task_t *task, 166 nxt_app_wmsg_t *msg, size_t size); 167 168 NXT_EXPORT nxt_int_t nxt_app_msg_write(nxt_task_t *task, nxt_app_wmsg_t *msg, 169 u_char *c, size_t size); 170 171 NXT_EXPORT nxt_int_t nxt_app_msg_write_prefixed_upcase(nxt_task_t *task, 172 nxt_app_wmsg_t *msg, const nxt_str_t *prefix, u_char *c, size_t size); 173 174 nxt_inline nxt_int_t 175 nxt_app_msg_write_nvp_(nxt_task_t *task, nxt_app_wmsg_t *msg, 176 u_char *n, size_t nsize, u_char *v, size_t vsize); 177 178 179 #define nxt_app_msg_write_const(task, msg, c) \ 180 nxt_app_msg_write((task), (msg), (u_char *)(c), sizeof(c) - 1) 181 182 #define nxt_app_msg_write_str(task, msg, str) \ 183 nxt_app_msg_write((task), (msg), (str)->start, (str)->length) 184 185 #define nxt_app_msg_write_cstr(task, msg, c) \ 186 nxt_app_msg_write((task), (msg), (c), nxt_strlen(c)) 187 188 #define nxt_app_msg_write_nvp(task, msg, n, v) \ 189 nxt_app_msg_write_nvp_((task), (msg), (u_char *)(n), sizeof(n) - 1, \ 190 (v)->start, (v)->length) 191 192 nxt_inline nxt_int_t nxt_app_msg_write_size(nxt_task_t *task, 193 nxt_app_wmsg_t *msg, size_t size); 194 195 NXT_EXPORT nxt_int_t nxt_app_msg_flush(nxt_task_t *task, nxt_app_wmsg_t *msg, 196 nxt_bool_t last); 197 198 NXT_EXPORT nxt_int_t nxt_app_msg_write_raw(nxt_task_t *task, 199 nxt_app_wmsg_t *msg, const u_char *c, size_t size); 200 201 NXT_EXPORT nxt_int_t nxt_app_msg_read_str(nxt_task_t *task, nxt_app_rmsg_t *msg, 202 nxt_str_t *str); 203 204 NXT_EXPORT size_t nxt_app_msg_read_raw(nxt_task_t *task, 205 nxt_app_rmsg_t *msg, void *buf, size_t size); 206 207 NXT_EXPORT nxt_int_t nxt_app_msg_read_nvp(nxt_task_t *task, 208 nxt_app_rmsg_t *rmsg, nxt_str_t *n, nxt_str_t *v); 209 210 NXT_EXPORT nxt_int_t nxt_app_msg_read_size(nxt_task_t *task, 211 nxt_app_rmsg_t *rmsg, size_t *size); 212 213 214 struct nxt_app_module_s { 215 size_t compat_length; 216 uint32_t *compat; 217 218 nxt_str_t type; 219 nxt_str_t version; 220 221 nxt_int_t (*init)(nxt_task_t *task, 222 nxt_common_app_conf_t *conf); 223 nxt_int_t (*run)(nxt_task_t *task, 224 nxt_app_rmsg_t *rmsg, 225 nxt_app_wmsg_t *wmsg); 226 void (*atexit)(nxt_task_t *task); 227 }; 228 229 230 nxt_int_t nxt_app_http_read_body(nxt_app_request_t *r, u_char *data, 231 size_t len); 232 nxt_int_t nxt_app_write(nxt_app_request_t *r, const u_char *data, size_t len); 233 234 nxt_inline u_char * 235 nxt_app_msg_write_length(u_char *dst, size_t length) 236 { 237 if (length < 128) { 238 *dst = length; 239 dst++; 240 241 } else { 242 dst[0] = 0x80U | (length >> 24); 243 dst[1] = 0xFFU & (length >> 16); 244 dst[2] = 0xFFU & (length >> 8); 245 dst[3] = 0xFFU & length; 246 dst += 4; 247 } 248 249 return dst; 250 } 251 252 253 nxt_inline nxt_int_t 254 nxt_app_msg_write_nvp_(nxt_task_t *task, nxt_app_wmsg_t *msg, 255 u_char *n, size_t nsize, u_char *v, size_t vsize) 256 { 257 nxt_int_t rc; 258 259 rc = nxt_app_msg_write(task, msg, n, nsize); 260 if (nxt_slow_path(rc != NXT_OK)) { 261 return rc; 262 } 263 264 return nxt_app_msg_write(task, msg, v, vsize); 265 } 266 267 268 nxt_inline nxt_int_t 269 nxt_app_msg_write_size(nxt_task_t *task, nxt_app_wmsg_t *msg, size_t size) 270 { 271 u_char *dst; 272 size_t dst_length; 273 274 dst_length = size < 128 ? 1 : 4; 275 276 dst = nxt_app_msg_write_get_buf(task, msg, dst_length); 277 if (nxt_slow_path(dst == NULL)) { 278 return NXT_ERROR; 279 } 280 281 nxt_app_msg_write_length(dst, size); 282 283 return NXT_OK; 284 } 285 286 287 nxt_inline u_char * 288 nxt_app_msg_read_length(u_char *src, size_t *length) 289 { 290 if (src[0] < 128) { 291 *length = src[0]; 292 src++; 293 294 } else { 295 *length = ((src[0] & 0x7fU) << 24) + 296 (src[1] << 16) + 297 (src[2] << 8) + 298 src[3]; 299 src += 4; 300 } 301 302 return src; 303 } 304 305 306 nxt_app_lang_module_t *nxt_app_lang_module(nxt_runtime_t *rt, nxt_str_t *name); 307 nxt_app_type_t nxt_app_parse_type(u_char *p, size_t length); 308 309 extern nxt_application_module_t nxt_go_module; 310 311 312 #endif /* _NXT_APPLICATION_H_INCLIDED_ */ 313