xref: /unit/src/nxt_application.h (revision 703:2d536dde84d2)
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), nxt_length(c))
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), nxt_length(n),      \
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