xref: /unit/src/nxt_application.h (revision 584:28e8e1877e62)
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