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