Skip to content
This repository
Newer
Older
100644 730 lines (572 sloc) 19.435 kb
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
3 /* Cherokee
4 *
5 * Authors:
6 * Alvaro Lopez Ortega <alvaro@alobbs.com>
7 *
8 * Copyright (C) 2001-2006 Alvaro Lopez Ortega
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of version 2 of the GNU General Public
12 * License as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 * USA
23 */
24
25 #include "common-internal.h"
26 #include "handler_fcgi.h"
27 #include "header.h"
28 #include "connection-protected.h"
29 #include "util.h"
30 #include "thread.h"
7b0e48a8 »
2006-09-04 git-svn-id: svn://cherokee-project.com/cherokee/trunk@387 5dc97367-97…
31 #include "source_interpreter.h"
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
32
33 #include "fastcgi.h"
34
35 #define POST_PACKAGE_LEN 32600
36 #define ENTRIES "fcgi,handler"
37
38
39 #define set_env(cgi,key,val,len) \
40 set_env_pair (cgi, key, sizeof(key)-1, val, len)
41
42
43 static void set_env_pair (cherokee_handler_cgi_base_t *cgi_base,
44 char *key, int key_len,
45 char *val, int val_len);
46
47 static ret_t
48 process_package (cherokee_handler_fcgi_t *hdl, cherokee_buffer_t *inbuf, cherokee_buffer_t *outbuf)
49 {
50 FCGI_Header *header;
51 FCGI_EndRequestBody *ending;
52 cherokee_connection_t *conn = HANDLER_CONN(hdl);
53
54 cuint_t len;
55 char *data;
56 cint_t return_val;
57 cuint_t type;
58 cuint_t id;
59 cuint_t padding;
60
61 /* Is there enough information?
62 */
63 if (inbuf->len < sizeof(FCGI_Header))
64 return ret_ok;
65
66 /* At least there is a header
67 */
68 header = (FCGI_Header *)inbuf->buf;
69
70 if (header->version != 1) {
71 cherokee_buffer_print_debug (inbuf, -1);
72 PRINT_ERROR_S ("Parsing error: unknown version\n");
73 return ret_error;
74 }
75
76 if (header->type != FCGI_STDERR &&
77 header->type != FCGI_STDOUT &&
78 header->type != FCGI_END_REQUEST)
79 {
80 cherokee_buffer_print_debug (inbuf, -1);
81 PRINT_ERROR_S ("Parsing error: unknown type\n");
82 return ret_error;
83 }
84
85 /* Read the header
86 */
87 type = header->type;
88 padding = header->paddingLength;
89 id = (header->requestIdB0 | (header->requestIdB1 << 8));
90 len = (header->contentLengthB0 | (header->contentLengthB1 << 8));
91 data = inbuf->buf + FCGI_HEADER_LEN;
92
93 // printf ("have %d, hdr=%d exp_len=%d pad=%d\n", inbuf->len, FCGI_HEADER_LEN, len, padding);
94
95 /* Is the package complete?
96 */
97 if (len + padding > inbuf->len - FCGI_HEADER_LEN) {
98 // printf ("Incomplete: %d < %d\n", len + padding, inbuf->len - FCGI_HEADER_LEN);
99 return ret_ok;
100 }
101
102 /* It has received the full package content
103 */
104 switch (type) {
105 case FCGI_STDERR:
106 // printf ("READ:STDERR (%d): %s", len, data?data:"");
107
108 if (CONN_VSRV(conn)->logger != NULL) {
109 cherokee_buffer_t tmp = CHEROKEE_BUF_INIT;
110
111 cherokee_buffer_add (&tmp, data, len);
112 cherokee_logger_write_string (CONN_VSRV(conn)->logger, "%s", tmp.buf);
113 PRINT_ERROR ("%s\n", tmp.buf);
114 cherokee_buffer_mrproper (&tmp);
115 }
116 break;
117
118 case FCGI_STDOUT:
119 // printf ("READ:STDOUT eof=%d: %d", CGI_BASE(hdl)->got_eof, len);
120 cherokee_buffer_add (outbuf, data, len);
121 break;
122
123 case FCGI_END_REQUEST:
124 ending = (FCGI_EndRequestBody *)data;
125
126 return_val = ((ending->appStatusB0) |
127 (ending->appStatusB0 << 8) |
128 (ending->appStatusB0 << 16) |
129 (ending->appStatusB0 << 24));
130
3509796d »
2006-05-09 git-svn-id: svn://cherokee-project.com/cherokee/trunk@282 5dc97367-97…
131 HDL_CGI_BASE(hdl)->got_eof = true;
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
132 // printf ("READ:END");
133 break;
134
135 default:
136 SHOULDNT_HAPPEN;
137 }
138
139 cherokee_buffer_move_to_begin (inbuf, len + FCGI_HEADER_LEN + padding);
140 // printf ("- FCGI quedan %d\n", inbuf->len);
141 return ret_eagain;
142 }
143
144
145 static ret_t
146 process_buffer (cherokee_handler_fcgi_t *hdl, cherokee_buffer_t *inbuf, cherokee_buffer_t *outbuf)
147 {
148 ret_t ret;
149
150 do {
151 ret = process_package (hdl, inbuf, outbuf);
152 } while (ret == ret_eagain);
153
154 if (ret == ret_ok) {
155 if (cherokee_buffer_is_empty (outbuf))
3509796d »
2006-05-09 git-svn-id: svn://cherokee-project.com/cherokee/trunk@282 5dc97367-97…
156 return (HDL_CGI_BASE(hdl)->got_eof) ? ret_eof : ret_eagain;
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
157 }
158
159 return ret;
160 }
161
162 static ret_t
163 read_from_fcgi (cherokee_handler_cgi_base_t *cgi, cherokee_buffer_t *buffer)
164 {
165 ret_t ret;
166 size_t read = 0;
3509796d »
2006-05-09 git-svn-id: svn://cherokee-project.com/cherokee/trunk@282 5dc97367-97…
167 cherokee_handler_fcgi_t *fcgi = HDL_FCGI(cgi);
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
168
169 ret = cherokee_socket_read (&fcgi->socket, &fcgi->write_buffer, DEFAULT_READ_SIZE, &read);
170
171 switch (ret) {
172 case ret_eagain:
173 cherokee_thread_deactive_to_polling (HANDLER_THREAD(cgi), HANDLER_CONN(cgi),
174 fcgi->socket.socket, 0, false);
175 return ret_eagain;
176
177 case ret_ok:
178 ret = process_buffer (fcgi, &fcgi->write_buffer, buffer);
179 TRACE (ENTRIES, "%d bytes readed, buffer.len %d\n", read, buffer->len);
180 if ((ret == ret_ok) && cgi->got_eof && (buffer->len > 0))
181 return ret_eof_have_data;
182 return ret;
183
184 case ret_eof:
185 case ret_error:
186 cgi->got_eof = true;
187 return ret;
188
189 default:
190 RET_UNKNOWN(ret);
191 }
192
193 SHOULDNT_HAPPEN;
2e0ea0ec »
2006-10-14 git-svn-id: svn://cherokee-project.com/cherokee/trunk@430 5dc97367-97…
194 return ret_error;
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
195 }
196
197
b6c69adc »
2006-04-16 git-svn-id: svn://cherokee-project.com/cherokee/trunk@269 5dc97367-97…
198 static ret_t
be048103 »
2006-05-30 git-svn-id: svn://cherokee-project.com/cherokee/trunk@283 5dc97367-97…
199 props_free (cherokee_handler_fcgi_props_t *props)
200 {
7b0e48a8 »
2006-09-04 git-svn-id: svn://cherokee-project.com/cherokee/trunk@387 5dc97367-97…
201 if (props->balancer != NULL)
202 cherokee_balancer_free (props->balancer);
623deda7 »
2006-06-04 git-svn-id: svn://cherokee-project.com/cherokee/trunk@294 5dc97367-97…
203
204 return cherokee_handler_cgi_base_props_free (PROP_CGI_BASE(props));
be048103 »
2006-05-30 git-svn-id: svn://cherokee-project.com/cherokee/trunk@283 5dc97367-97…
205 }
206
207
208 static ret_t
7b0e48a8 »
2006-09-04 git-svn-id: svn://cherokee-project.com/cherokee/trunk@387 5dc97367-97…
209 cherokee_handler_fcgi_configure (cherokee_config_node_t *conf, cherokee_server_t *srv, cherokee_module_props_t **_props)
b6c69adc »
2006-04-16 git-svn-id: svn://cherokee-project.com/cherokee/trunk@269 5dc97367-97…
210 {
3509796d »
2006-05-09 git-svn-id: svn://cherokee-project.com/cherokee/trunk@282 5dc97367-97…
211 ret_t ret;
ee8023f2 »
2006-09-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@384 5dc97367-97…
212 cherokee_list_t *i;
3509796d »
2006-05-09 git-svn-id: svn://cherokee-project.com/cherokee/trunk@282 5dc97367-97…
213 cherokee_handler_fcgi_props_t *props;
b6c69adc »
2006-04-16 git-svn-id: svn://cherokee-project.com/cherokee/trunk@269 5dc97367-97…
214
3509796d »
2006-05-09 git-svn-id: svn://cherokee-project.com/cherokee/trunk@282 5dc97367-97…
215 /* Instance a new property object
216 */
217 if (*_props == NULL) {
218 CHEROKEE_NEW_STRUCT (n, handler_fcgi_props);
be048103 »
2006-05-30 git-svn-id: svn://cherokee-project.com/cherokee/trunk@283 5dc97367-97…
219
7b0e48a8 »
2006-09-04 git-svn-id: svn://cherokee-project.com/cherokee/trunk@387 5dc97367-97…
220 cherokee_module_props_init_base (MODULE_PROPS(n),
221 MODULE_PROPS_FREE(props_free));
3509796d »
2006-05-09 git-svn-id: svn://cherokee-project.com/cherokee/trunk@282 5dc97367-97…
222 INIT_LIST_HEAD(&n->server_list);
7b0e48a8 »
2006-09-04 git-svn-id: svn://cherokee-project.com/cherokee/trunk@387 5dc97367-97…
223 n->balancer = NULL;
224
225 *_props = MODULE_PROPS(n);
3509796d »
2006-05-09 git-svn-id: svn://cherokee-project.com/cherokee/trunk@282 5dc97367-97…
226 }
227
228 props = PROP_FCGI(*_props);
229
230 /* Parse the configuration tree
231 */
b6c69adc »
2006-04-16 git-svn-id: svn://cherokee-project.com/cherokee/trunk@269 5dc97367-97…
232 cherokee_config_node_foreach (i, conf) {
233 cherokee_config_node_t *subconf = CONFIG_NODE(i);
234
7b0e48a8 »
2006-09-04 git-svn-id: svn://cherokee-project.com/cherokee/trunk@387 5dc97367-97…
235 if (equal_buf_str (&subconf->key, "balancer")) {
236 ret = cherokee_balancer_instance (&subconf->val, subconf, srv, &props->balancer);
b6c69adc »
2006-04-16 git-svn-id: svn://cherokee-project.com/cherokee/trunk@269 5dc97367-97…
237 if (ret != ret_ok) return ret;
238 }
239 }
240
7b0e48a8 »
2006-09-04 git-svn-id: svn://cherokee-project.com/cherokee/trunk@387 5dc97367-97…
241 /* Init base class
242 */
243 ret = cherokee_handler_cgi_base_configure (conf, srv, _props);
244 if (ret != ret_ok) return ret;
245
246 /* Final checks
247 */
248 if (props->balancer == NULL) {
249 PRINT_ERROR_S ("ERROR: fcgi handler needs a balancer\n");
250 return ret_error;
251 }
252
253 return ret_ok;
b6c69adc »
2006-04-16 git-svn-id: svn://cherokee-project.com/cherokee/trunk@269 5dc97367-97…
254 }
255
256
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
257 ret_t
7b0e48a8 »
2006-09-04 git-svn-id: svn://cherokee-project.com/cherokee/trunk@387 5dc97367-97…
258 cherokee_handler_fcgi_new (cherokee_handler_t **hdl, void *cnt, cherokee_module_props_t *props)
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
259 {
260 CHEROKEE_NEW_STRUCT (n, handler_fcgi);
261
262 /* Init the base class
263 */
3509796d »
2006-05-09 git-svn-id: svn://cherokee-project.com/cherokee/trunk@282 5dc97367-97…
264 cherokee_handler_cgi_base_init (HDL_CGI_BASE(n), cnt, props, set_env_pair, read_from_fcgi);
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
265
266 /* Virtual methods
267 */
268 MODULE(n)->init = (handler_func_init_t) cherokee_handler_fcgi_init;
423d6fa8 »
2006-08-28 git-svn-id: svn://cherokee-project.com/cherokee/trunk@370 5dc97367-97…
269 MODULE(n)->free = (module_func_free_t) cherokee_handler_fcgi_free;
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
270
271 /* Virtual methods: implemented by handler_cgi_base
272 */
273 HANDLER(n)->step = (handler_func_step_t) cherokee_handler_cgi_base_step;
274 HANDLER(n)->add_headers = (handler_func_add_headers_t) cherokee_handler_cgi_base_add_headers;
275
276 /* Properties
277 */
278 n->post_phase = fcgi_post_init;
279 n->post_len = 0;
280
281 cherokee_socket_init (&n->socket);
282 cherokee_buffer_init (&n->write_buffer);
283 cherokee_buffer_ensure_size (&n->write_buffer, 512);
284
285 /* Return the object
286 */
287 *hdl = HANDLER(n);
288 return ret_ok;
289 }
290
291
292 ret_t
293 cherokee_handler_fcgi_free (cherokee_handler_fcgi_t *hdl)
294 {
295 cherokee_socket_close (&hdl->socket);
296 cherokee_socket_mrproper (&hdl->socket);
297
298 cherokee_buffer_mrproper (&hdl->write_buffer);
299
3509796d »
2006-05-09 git-svn-id: svn://cherokee-project.com/cherokee/trunk@282 5dc97367-97…
300 return cherokee_handler_cgi_base_free (HDL_CGI_BASE(hdl));
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
301 }
302
303
304 static void
305 fcgi_build_header (FCGI_Header *hdr, cuchar_t type, cushort_t request_id, cuint_t content_length, cuchar_t padding)
306 {
307 hdr->version = FCGI_VERSION_1;
308 hdr->type = type;
309 hdr->requestIdB0 = (cuchar_t) request_id;
310 hdr->requestIdB1 = (cuchar_t) (request_id >> 8) & 0xff;
311 hdr->contentLengthB0 = (cuchar_t) (content_length % 256);
312 hdr->contentLengthB1 = (cuchar_t) (content_length / 256);
313 hdr->paddingLength = padding;
314 hdr->reserved = 0;
315 }
316
317 static void
318 fcgi_build_request_body (FCGI_BeginRequestRecord *request)
319 {
320 request->body.roleB0 = FCGI_RESPONDER;
321 request->body.roleB1 = 0;
322 request->body.flags = 0;
323 request->body.reserved[0] = 0;
324 request->body.reserved[1] = 0;
325 request->body.reserved[2] = 0;
326 request->body.reserved[3] = 0;
327 request->body.reserved[4] = 0;
328 }
329
330 static void
331 set_env_pair (cherokee_handler_cgi_base_t *cgi_base,
332 char *key, int key_len,
333 char *val, int val_len)
334 {
335 int len;
336 FCGI_BeginRequestRecord request;
3509796d »
2006-05-09 git-svn-id: svn://cherokee-project.com/cherokee/trunk@282 5dc97367-97…
337 cherokee_handler_fcgi_t *hdl = HDL_FCGI(cgi_base);
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
338 cherokee_buffer_t *buf = &hdl->write_buffer;
339
340 len = key_len + val_len;
341 len += key_len > 127 ? 4 : 1;
342 len += val_len > 127 ? 4 : 1;
343
344 fcgi_build_header (&request.header, FCGI_PARAMS, 1, len, 0);
345
346 cherokee_buffer_ensure_size (buf, buf->len + sizeof(FCGI_Header) + key_len + val_len);
347 cherokee_buffer_add (buf, (void *)&request.header, sizeof(FCGI_Header));
348
349 if (key_len <= 127) {
350 buf->buf[buf->len++] = key_len;
351 } else {
352 buf->buf[buf->len++] = ((key_len >> 24) & 0xff) | 0x80;
353 buf->buf[buf->len++] = (key_len >> 16) & 0xff;
354 buf->buf[buf->len++] = (key_len >> 8) & 0xff;
355 buf->buf[buf->len++] = (key_len >> 0) & 0xff;
356 }
357
358 if (val_len <= 127) {
359 buf->buf[buf->len++] = val_len;
360 } else {
361 buf->buf[buf->len++] = ((val_len >> 24) & 0xff) | 0x80;
362 buf->buf[buf->len++] = (val_len >> 16) & 0xff;
363 buf->buf[buf->len++] = (val_len >> 8) & 0xff;
364 buf->buf[buf->len++] = (val_len >> 0) & 0xff;
365 }
366
367 cherokee_buffer_add (buf, key, key_len);
368 cherokee_buffer_add (buf, val, val_len);
369 }
370
371
372 static ret_t
373 add_extra_fcgi_env (cherokee_handler_fcgi_t *hdl, cuint_t *last_header_offset)
374 {
375 ret_t ret;
3509796d »
2006-05-09 git-svn-id: svn://cherokee-project.com/cherokee/trunk@282 5dc97367-97…
376 cherokee_handler_cgi_base_t *cgi_base = HDL_CGI_BASE(hdl);
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
377 cherokee_buffer_t buffer = CHEROKEE_BUF_INIT;
378 cherokee_connection_t *conn = HANDLER_CONN(hdl);
379
380 /* CONTENT_LENGTH
381 */
382 ret = cherokee_header_copy_known (&conn->header, header_content_length, &buffer);
383 if (ret == ret_ok)
384 set_env (cgi_base, "CONTENT_LENGTH", buffer.buf, buffer.len);
385
386 /* Add PATH_TRANSLATED only it there is pathinfo
387 */
388 #if 0
389 if (! cherokee_buffer_is_empty (&conn->pathinfo)) {
390 cherokee_buffer_add_buffer (&buffer, &conn->local_directory);
391 cherokee_buffer_add_buffer (&buffer, &conn->pathinfo);
392
393 set_env (cgi_base, "PATH_TRANSLATED", buffer.buf, buffer.len);
394 TRACE (ENTRIES, "PATH_TRANSLATED '%s'\n", cgi_base->executable.buf);
395 }
396 #endif
397
398 /* The last one
399 */
400 *last_header_offset = hdl->write_buffer.len;
401
402 set_env (cgi_base, "SCRIPT_FILENAME", cgi_base->executable.buf, cgi_base->executable.len);
403 TRACE (ENTRIES, "SCRIPT_FILENAME '%s'\n", cgi_base->executable.buf);
404
405 cherokee_buffer_mrproper (&buffer);
406 return ret_ok;
407 }
408
409
410 static void
411 fixup_padding (cherokee_buffer_t *buf, cuint_t last_header_offset)
412 {
413 cuint_t rest;
414 cuint_t pad;
415 static char padding[8] = {0, 0, 0, 0, 0, 0, 0, 0};
416 FCGI_Header *last_header;
417
418 if (buf->len <= 0)
419 return;
420 last_header = (FCGI_Header *) (buf->buf + last_header_offset);
421 rest = buf->len % 8;
422 pad = 8 - rest;
423
424 if (rest == 0)
425 return;
426
427 last_header->paddingLength = pad;
428
429 cherokee_buffer_ensure_size (buf, buf->len + pad);
430 cherokee_buffer_add (buf, padding, pad);
431 }
432
433 static void
434 add_empty_packet (cherokee_handler_fcgi_t *hdl, cuint_t type)
435 {
436 FCGI_BeginRequestRecord request;
437
438 fcgi_build_header (&request.header, type, 1, 0, 0);
439 cherokee_buffer_add (&hdl->write_buffer, (void *)&request.header, sizeof(FCGI_Header));
440
441 TRACE (ENTRIES, "empty packet type=%d, len=%d\n", type, hdl->write_buffer.len);
442 }
443
444
445 static ret_t
446 build_header (cherokee_handler_fcgi_t *hdl, cherokee_buffer_t *buffer)
447 {
448 FCGI_BeginRequestRecord request;
449 cuint_t last_header_offset;
2e0ea0ec »
2006-10-14 git-svn-id: svn://cherokee-project.com/cherokee/trunk@430 5dc97367-97…
450 cherokee_connection_t *conn = HANDLER_CONN(hdl);
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
451
452 /* Take care here, if the connection is reinjected, it
453 * shouldn't parse the arguments again.
454 */
455 if (conn->arguments == NULL)
456 cherokee_connection_parse_args (conn);
457
458 cherokee_buffer_clean (buffer);
459
460 /* FCGI_BEGIN_REQUEST
461 */
462 fcgi_build_header (&request.header, FCGI_BEGIN_REQUEST, 1, sizeof(request.body), 0);
463 fcgi_build_request_body (&request);
464
465 cherokee_buffer_add (buffer, (void *)&request, sizeof(FCGI_BeginRequestRecord));
466 TRACE (ENTRIES, "Added FCGI_BEGIN_REQUEST, len=%d\n", buffer->len);
467
468 /* Add enviroment variables
469 */
3509796d »
2006-05-09 git-svn-id: svn://cherokee-project.com/cherokee/trunk@282 5dc97367-97…
470 cherokee_handler_cgi_base_build_envp (HDL_CGI_BASE(hdl), conn);
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
471
472 add_extra_fcgi_env (hdl, &last_header_offset);
473 fixup_padding (buffer, last_header_offset);
474
475 /* There are not more parameters
476 */
477 add_empty_packet (hdl, FCGI_PARAMS);
478
479 TRACE (ENTRIES, "Added FCGI_PARAMS, len=%d\n", buffer->len);
480 return ret_ok;
481 }
482
483
484 static ret_t
485 connect_to_server (cherokee_handler_fcgi_t *hdl)
486 {
3509796d »
2006-05-09 git-svn-id: svn://cherokee-project.com/cherokee/trunk@282 5dc97367-97…
487 ret_t ret;
7b0e48a8 »
2006-09-04 git-svn-id: svn://cherokee-project.com/cherokee/trunk@387 5dc97367-97…
488 int try = 0;
489 cherokee_source_t *src = NULL;
490 cherokee_connection_t *conn = HANDLER_CONN(hdl);
3509796d »
2006-05-09 git-svn-id: svn://cherokee-project.com/cherokee/trunk@282 5dc97367-97…
491 cherokee_handler_fcgi_props_t *props = HDL_FCGI_PROPS(hdl);
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
492
7b0e48a8 »
2006-09-04 git-svn-id: svn://cherokee-project.com/cherokee/trunk@387 5dc97367-97…
493 ret = cherokee_balancer_dispatch (props->balancer, conn, &src);
494 if (ret != ret_ok) return ret;
495
496 ret = cherokee_source_connect (src, &hdl->socket);
497 if (ret != ret_ok) {
498 cherokee_source_interpreter_t *src_int = SOURCE_INT(src);
499
500 ret = cherokee_source_interpreter_spawn (src_int);
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
501 if (ret != ret_ok) {
7b0e48a8 »
2006-09-04 git-svn-id: svn://cherokee-project.com/cherokee/trunk@387 5dc97367-97…
502 TRACE (ENTRIES, "Couldn't spawn: %s\n", src->host.buf ? src->host.buf : src->unix_socket.buf);
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
503 return ret;
504 }
2e0ea0ec »
2006-10-14 git-svn-id: svn://cherokee-project.com/cherokee/trunk@430 5dc97367-97…
505
506 while (true) {
7b0e48a8 »
2006-09-04 git-svn-id: svn://cherokee-project.com/cherokee/trunk@387 5dc97367-97…
507 ret = cherokee_source_connect (src, &hdl->socket);
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
508 if (ret == ret_ok) break;
509
7b0e48a8 »
2006-09-04 git-svn-id: svn://cherokee-project.com/cherokee/trunk@387 5dc97367-97…
510 TRACE (ENTRIES, "Couldn't connect: %s, try %d\n", src->host.buf ? src->host.buf : src->unix_socket.buf, try);
45ead256 »
2006-10-07 git-svn-id: svn://cherokee-project.com/cherokee/trunk@428 5dc97367-97…
511
2e0ea0ec »
2006-10-14 git-svn-id: svn://cherokee-project.com/cherokee/trunk@430 5dc97367-97…
512 if (try++ >= 3)
45ead256 »
2006-10-07 git-svn-id: svn://cherokee-project.com/cherokee/trunk@428 5dc97367-97…
513 return ret;
514
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
515 sleep (1);
516 }
7b0e48a8 »
2006-09-04 git-svn-id: svn://cherokee-project.com/cherokee/trunk@387 5dc97367-97…
517
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
518 }
7b0e48a8 »
2006-09-04 git-svn-id: svn://cherokee-project.com/cherokee/trunk@387 5dc97367-97…
519
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
520 TRACE (ENTRIES, "Connected sucessfully try=%d, fd=%d\n", try, hdl->socket.socket);
521 return ret_ok;
522 }
523
524
525 static ret_t
526 do_send (cherokee_handler_fcgi_t *hdl, cherokee_buffer_t *buffer)
527 {
2e0ea0ec »
2006-10-14 git-svn-id: svn://cherokee-project.com/cherokee/trunk@430 5dc97367-97…
528 ret_t ret;
529 size_t written = 0;
530 cherokee_connection_t *conn = HANDLER_CONN(hdl);
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
531
532 ret = cherokee_socket_write (&hdl->socket, buffer, &written);
2e0ea0ec »
2006-10-14 git-svn-id: svn://cherokee-project.com/cherokee/trunk@430 5dc97367-97…
533 if (ret != ret_ok) {
534 conn->error_code = http_bad_gateway;
535 return ret;
536 }
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
537
538 cherokee_buffer_move_to_begin (buffer, written);
539
540 TRACE (ENTRIES, "sent remaining=%d\n", buffer->len);
541
542 if (! cherokee_buffer_is_empty (buffer))
543 return ret_eagain;
544
545 return ret_ok;
546 }
547
548
549 static ret_t
550 send_post (cherokee_handler_fcgi_t *hdl, cherokee_buffer_t *buf)
551 {
552 ret_t ret;
553 cherokee_connection_t *conn = HANDLER_CONN(hdl);
554 static FCGI_Header empty_header = {0,0,0,0,0,0,0,0};
555
556 switch (hdl->post_phase) {
557 case fcgi_post_init:
558 TRACE (ENTRIES, "Post %s\n", "init");
559
560 /* Init the POST storing object
561 */
562 cherokee_post_walk_reset (&conn->post);
563 cherokee_post_get_len (&conn->post, &hdl->post_len);
564
565 if (hdl->post_len <= 0)
566 return ret_ok;
567
568 hdl->post_phase = fcgi_post_read;
569
570 case fcgi_post_read:
571 TRACE (ENTRIES, "Post %s\n", "read");
572
573 /* Add space for the header, it'll filled out later on..
574 */
575 if (cherokee_buffer_is_empty (buf)) {
576 cherokee_buffer_add (buf, (char *)&empty_header, sizeof (FCGI_Header));
577 }
578
579 /* Take a chunck of post
580 */
581 ret = cherokee_post_walk_read (&conn->post, buf, POST_PACKAGE_LEN);
582 switch (ret) {
583 case ret_ok:
584 case ret_eagain:
585 break;
586 case ret_error:
587 return ret;
588 default:
589 RET_UNKNOWN(ret);
590 return ret_error;
591 }
592
593 TRACE (ENTRIES, "Post buffer.len %d\n", buf->len);
594
595 /* Complete the header
596 */
597 if (buf->len > sizeof(FCGI_Header)) {
598 fcgi_build_header ((FCGI_Header *)buf->buf, FCGI_STDIN, 1,
599 buf->len - sizeof(FCGI_Header), 0);
600 }
601
602 /* Close STDIN if it was the last chunck
603 */
604 ret = cherokee_post_walk_finished (&conn->post);
605 if (ret == ret_ok) {
606 add_empty_packet (hdl, FCGI_STDIN);
607 }
608
609 hdl->post_phase = fcgi_post_write;
610
611 case fcgi_post_write:
612 TRACE (ENTRIES, "Post write, buf.len=%d (header len %d)\n", buf->len, sizeof(FCGI_Header));
613
614 if (! cherokee_buffer_is_empty (buf)) {
615 ret = do_send (hdl, buf);
616 switch (ret) {
617 case ret_ok:
618 break;
619 case ret_eagain:
620 return ret_eagain;
621 case ret_eof:
622 case ret_error:
623 return ret_error;
624 default:
625 RET_UNKNOWN(ret);
626 return ret_error;
627 }
628 }
629
630 if (! cherokee_buffer_is_empty (buf))
631 return ret_eagain;
632
633 ret = cherokee_post_walk_finished (&conn->post);
634 switch (ret) {
635 case ret_ok:
636 break;
637 case ret_error:
638 return ret_error;
639 case ret_eagain:
640 hdl->post_phase = fcgi_post_read;
641 return ret_eagain;
642 default:
643 RET_UNKNOWN(ret);
644 return ret_error;
645 }
646
647 TRACE (ENTRIES, "Post %s\n", "finished");
648 return ret_ok;
649
650 default:
651 SHOULDNT_HAPPEN;
652 }
653
654 return ret_error;
655 }
656
657
658 ret_t
659 cherokee_handler_fcgi_init (cherokee_handler_fcgi_t *hdl)
660 {
661 ret_t ret;
662 cherokee_connection_t *conn = HANDLER_CONN(hdl);
663
3509796d »
2006-05-09 git-svn-id: svn://cherokee-project.com/cherokee/trunk@282 5dc97367-97…
664 switch (HDL_CGI_BASE(hdl)->init_phase) {
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
665 case hcgi_phase_build_headers:
666 TRACE (ENTRIES, "Init %s\n", "begins");
667
668 /* Prepare Post
669 */
670 if (! cherokee_post_is_empty (&conn->post)) {
671 cherokee_post_walk_reset (&conn->post);
672 cherokee_post_get_len (&conn->post, &hdl->post_len);
673 }
674
675 /* Extracts PATH_INFO and filename from request uri
676 */
3509796d »
2006-05-09 git-svn-id: svn://cherokee-project.com/cherokee/trunk@282 5dc97367-97…
677 ret = cherokee_handler_cgi_base_extract_path (HDL_CGI_BASE(hdl), false);
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
678 if (unlikely (ret < ret_ok)) return ret;
679
680 /* Build the headers
681 */
682 ret = build_header (hdl, &hdl->write_buffer);
683 if (unlikely (ret != ret_ok)) return ret;
684
685 /* Connect
686 */
687 ret = connect_to_server (hdl);
688 if (unlikely (ret != ret_ok)) {
2e0ea0ec »
2006-10-14 git-svn-id: svn://cherokee-project.com/cherokee/trunk@430 5dc97367-97…
689 conn->error_code = http_service_unavailable;
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
690 return ret;
691 }
692
3509796d »
2006-05-09 git-svn-id: svn://cherokee-project.com/cherokee/trunk@282 5dc97367-97…
693 HDL_CGI_BASE(hdl)->init_phase = hcgi_phase_send_headers;
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
694
695 case hcgi_phase_send_headers:
696 TRACE (ENTRIES, "Init %s\n", "send_headers");
697
698 /* Send the header
699 */
700 ret = do_send (hdl, &hdl->write_buffer);
701 if (ret != ret_ok) return ret;
702
3509796d »
2006-05-09 git-svn-id: svn://cherokee-project.com/cherokee/trunk@282 5dc97367-97…
703 HDL_CGI_BASE(hdl)->init_phase = hcgi_phase_send_post;
ae9d9717 »
2006-04-01 git-svn-id: svn://cherokee-project.com/cherokee/trunk@243 5dc97367-97…
704
705 case hcgi_phase_send_post:
706 /* Send the Post
707 */
708 if (hdl->post_len > 0) {
709 return send_post (hdl, &hdl->write_buffer);
710 }
711 break;
712 }
713
714 TRACE (ENTRIES, "Init %s\n", "finishes");
715
716 cherokee_buffer_clean (&hdl->write_buffer);
717 return ret_ok;
718 }
719
720
721 /* Module init
722 */
723 void
724 MODULE_INIT(fcgi) (cherokee_module_loader_t *loader)
725 {
726 }
727
83fd8354 »
2006-08-05 git-svn-id: svn://cherokee-project.com/cherokee/trunk@333 5dc97367-97…
728 HANDLER_MODULE_INFO_INIT_EASY (fcgi, http_get | http_post | http_head);
b6c69adc »
2006-04-16 git-svn-id: svn://cherokee-project.com/cherokee/trunk@269 5dc97367-97…
729
Something went wrong with that request. Please try again.