xref: /unit/src/nxt_application.h (revision 718:f6866084cc80)
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                  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     void                      *timer_data;
137     nxt_http_request_parse_t  parser;
138     nxt_http_request_parse_t  resp_parser;
139     nxt_mp_t                  *mem_pool;
140 };
141 
142 
143 nxt_int_t nxt_app_http_req_done(nxt_task_t *task, nxt_app_parse_ctx_t *ctx);
144 
145 
146 typedef struct nxt_app_wmsg_s  nxt_app_wmsg_t;
147 typedef struct nxt_app_rmsg_s  nxt_app_rmsg_t;
148 
149 struct nxt_app_wmsg_s {
150     nxt_port_t                 *port;  /* where prepared buf will be sent */
151     nxt_buf_t                  *write;
152     nxt_buf_t                  **buf;
153     uint32_t                   stream;
154 };
155 
156 
157 struct nxt_app_rmsg_s {
158     nxt_buf_t                  *buf;   /* current buffer to read */
159 };
160 
161 
162 nxt_inline u_char *
163 nxt_app_msg_write_length(u_char *dst, size_t length);
164 
165 /* TODO asynchronous mmap buffer assignment */
166 NXT_EXPORT u_char *nxt_app_msg_write_get_buf(nxt_task_t *task,
167     nxt_app_wmsg_t *msg, size_t size);
168 
169 NXT_EXPORT nxt_int_t nxt_app_msg_write(nxt_task_t *task, nxt_app_wmsg_t *msg,
170     u_char *c, size_t size);
171 
172 NXT_EXPORT nxt_int_t nxt_app_msg_write_prefixed_upcase(nxt_task_t *task,
173     nxt_app_wmsg_t *msg, const nxt_str_t *prefix, u_char *c, size_t size);
174 
175 nxt_inline nxt_int_t
176 nxt_app_msg_write_nvp_(nxt_task_t *task, nxt_app_wmsg_t *msg,
177     u_char *n, size_t nsize, u_char *v, size_t vsize);
178 
179 
180 #define nxt_app_msg_write_const(task, msg, c)                                 \
181     nxt_app_msg_write((task), (msg), (u_char *) (c), nxt_length(c))
182 
183 #define nxt_app_msg_write_str(task, msg, str)                                 \
184     nxt_app_msg_write((task), (msg), (str)->start, (str)->length)
185 
186 #define nxt_app_msg_write_cstr(task, msg, c)                                  \
187     nxt_app_msg_write((task), (msg), (c), nxt_strlen(c))
188 
189 #define nxt_app_msg_write_nvp(task, msg, n, v)                                \
190     nxt_app_msg_write_nvp_((task), (msg), (u_char *) (n), nxt_length(n),      \
191                            (v)->start, (v)->length)
192 
193 nxt_inline nxt_int_t nxt_app_msg_write_size(nxt_task_t *task,
194     nxt_app_wmsg_t *msg, size_t size);
195 
196 NXT_EXPORT nxt_int_t nxt_app_msg_flush(nxt_task_t *task, nxt_app_wmsg_t *msg,
197     nxt_bool_t last);
198 
199 NXT_EXPORT nxt_int_t nxt_app_msg_write_raw(nxt_task_t *task,
200     nxt_app_wmsg_t *msg, const u_char *c, size_t size);
201 
202 NXT_EXPORT nxt_int_t nxt_app_msg_read_str(nxt_task_t *task, nxt_app_rmsg_t *msg,
203     nxt_str_t *str);
204 
205 NXT_EXPORT size_t nxt_app_msg_read_raw(nxt_task_t *task,
206     nxt_app_rmsg_t *msg, void *buf, size_t size);
207 
208 NXT_EXPORT nxt_int_t nxt_app_msg_read_nvp(nxt_task_t *task,
209     nxt_app_rmsg_t *rmsg, nxt_str_t *n, nxt_str_t *v);
210 
211 NXT_EXPORT nxt_int_t nxt_app_msg_read_size(nxt_task_t *task,
212     nxt_app_rmsg_t *rmsg, size_t *size);
213 
214 
215 struct nxt_app_module_s {
216     size_t                     compat_length;
217     uint32_t                   *compat;
218 
219     nxt_str_t                  type;
220     const char                 *version;
221 
222     nxt_int_t                  (*init)(nxt_task_t *task,
223                                     nxt_common_app_conf_t *conf);
224     nxt_int_t                  (*run)(nxt_task_t *task,
225                                     nxt_app_rmsg_t *rmsg,
226                                     nxt_app_wmsg_t *wmsg);
227     void                       (*atexit)(nxt_task_t *task);
228 };
229 
230 
231 nxt_int_t nxt_app_http_read_body(nxt_app_request_t *r, u_char *data,
232     size_t len);
233 nxt_int_t nxt_app_write(nxt_app_request_t *r, const u_char *data, size_t len);
234 
235 nxt_inline u_char *
236 nxt_app_msg_write_length(u_char *dst, size_t length)
237 {
238     if (length < 128) {
239         *dst = length;
240         dst++;
241 
242     } else {
243         dst[0] = 0x80U | (length >> 24);
244         dst[1] = 0xFFU & (length >> 16);
245         dst[2] = 0xFFU & (length >> 8);
246         dst[3] = 0xFFU & length;
247         dst += 4;
248     }
249 
250     return dst;
251 }
252 
253 
254 nxt_inline nxt_int_t
255 nxt_app_msg_write_nvp_(nxt_task_t *task, nxt_app_wmsg_t *msg,
256     u_char *n, size_t nsize, u_char *v, size_t vsize)
257 {
258     nxt_int_t rc;
259 
260     rc = nxt_app_msg_write(task, msg, n, nsize);
261     if (nxt_slow_path(rc != NXT_OK)) {
262         return rc;
263     }
264 
265     return nxt_app_msg_write(task, msg, v, vsize);
266 }
267 
268 
269 nxt_inline nxt_int_t
270 nxt_app_msg_write_size(nxt_task_t *task, nxt_app_wmsg_t *msg, size_t size)
271 {
272     u_char  *dst;
273     size_t  dst_length;
274 
275     dst_length = size < 128 ? 1 : 4;
276 
277     dst = nxt_app_msg_write_get_buf(task, msg, dst_length);
278     if (nxt_slow_path(dst == NULL)) {
279         return NXT_ERROR;
280     }
281 
282     nxt_app_msg_write_length(dst, size);
283 
284     return NXT_OK;
285 }
286 
287 
288 nxt_inline u_char *
289 nxt_app_msg_read_length(u_char *src, size_t *length)
290 {
291     if (src[0] < 128) {
292         *length = src[0];
293         src++;
294 
295     } else {
296         *length = ((src[0] & 0x7FU) << 24)
297                 + ( src[1]          << 16)
298                 + ( src[2]          <<  8)
299                 +   src[3];
300         src += 4;
301     }
302 
303     return src;
304 }
305 
306 
307 nxt_app_lang_module_t *nxt_app_lang_module(nxt_runtime_t *rt, nxt_str_t *name);
308 nxt_app_type_t nxt_app_parse_type(u_char *p, size_t length);
309 
310 NXT_EXPORT extern nxt_str_t      nxt_server;
311 extern nxt_application_module_t  nxt_go_module;
312 
313 
314 #endif /* _NXT_APPLICATION_H_INCLIDED_ */
315