xref: /unit/src/nxt_application.h (revision 685:99f3d48664de)
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