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