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