|
Lines 3-9
Link Here
|
| 3 |
* |
3 |
* |
| 4 |
* Apache server module for FastCGI. |
4 |
* Apache server module for FastCGI. |
| 5 |
* |
5 |
* |
| 6 |
* $Id: mod_fastcgi.c,v 1.162 2007/11/12 23:00:10 robs Exp $ |
6 |
* $Id: mod_fastcgi.c,v 1.169 2008/11/09 14:31:03 robs Exp $ |
| 7 |
* |
7 |
* |
| 8 |
* Copyright (c) 1995-1996 Open Market, Inc. |
8 |
* Copyright (c) 1995-1996 Open Market, Inc. |
| 9 |
* |
9 |
* |
|
Lines 647-653
Link Here
|
| 647 |
{ |
647 |
{ |
| 648 |
char *p, *next, *name, *value; |
648 |
char *p, *next, *name, *value; |
| 649 |
int len, flag; |
649 |
int len, flag; |
| 650 |
int hasContentType, hasStatus, hasLocation; |
650 |
int hasLocation = FALSE; |
| 651 |
|
651 |
|
| 652 |
ASSERT(fr->parseHeader == SCAN_CGI_READING_HEADERS); |
652 |
ASSERT(fr->parseHeader == SCAN_CGI_READING_HEADERS); |
| 653 |
|
653 |
|
|
Lines 689-695
Link Here
|
| 689 |
* Parse all the headers. |
689 |
* Parse all the headers. |
| 690 |
*/ |
690 |
*/ |
| 691 |
fr->parseHeader = SCAN_CGI_FINISHED; |
691 |
fr->parseHeader = SCAN_CGI_FINISHED; |
| 692 |
hasContentType = hasStatus = hasLocation = FALSE; |
|
|
| 693 |
next = (char *)fr->header->elts; |
692 |
next = (char *)fr->header->elts; |
| 694 |
for(;;) { |
693 |
for(;;) { |
| 695 |
next = get_header_line(name = next, TRUE); |
694 |
next = get_header_line(name = next, TRUE); |
|
Lines 718-731
Link Here
|
| 718 |
if (strcasecmp(name, "Status") == 0) { |
717 |
if (strcasecmp(name, "Status") == 0) { |
| 719 |
int statusValue = strtol(value, NULL, 10); |
718 |
int statusValue = strtol(value, NULL, 10); |
| 720 |
|
719 |
|
| 721 |
if (hasStatus) { |
|
|
| 722 |
goto DuplicateNotAllowed; |
| 723 |
} |
| 724 |
if (statusValue < 0) { |
720 |
if (statusValue < 0) { |
| 725 |
fr->parseHeader = SCAN_CGI_BAD_HEADER; |
721 |
fr->parseHeader = SCAN_CGI_BAD_HEADER; |
| 726 |
return ap_psprintf(r->pool, "invalid Status '%s'", value); |
722 |
return ap_psprintf(r->pool, "invalid Status '%s'", value); |
| 727 |
} |
723 |
} |
| 728 |
hasStatus = TRUE; |
|
|
| 729 |
r->status = statusValue; |
724 |
r->status = statusValue; |
| 730 |
r->status_line = ap_pstrdup(r->pool, value); |
725 |
r->status_line = ap_pstrdup(r->pool, value); |
| 731 |
continue; |
726 |
continue; |
|
Lines 733-742
Link Here
|
| 733 |
|
728 |
|
| 734 |
if (fr->role == FCGI_RESPONDER) { |
729 |
if (fr->role == FCGI_RESPONDER) { |
| 735 |
if (strcasecmp(name, "Content-type") == 0) { |
730 |
if (strcasecmp(name, "Content-type") == 0) { |
| 736 |
if (hasContentType) { |
|
|
| 737 |
goto DuplicateNotAllowed; |
| 738 |
} |
| 739 |
hasContentType = TRUE; |
| 740 |
#ifdef APACHE2 |
731 |
#ifdef APACHE2 |
| 741 |
ap_set_content_type(r, value); |
732 |
ap_set_content_type(r, value); |
| 742 |
#else |
733 |
#else |
|
Lines 745-756
Link Here
|
| 745 |
continue; |
736 |
continue; |
| 746 |
} |
737 |
} |
| 747 |
|
738 |
|
|
|
739 |
/* |
| 740 |
* Special case headers that should not persist on error |
| 741 |
* or across redirects, i.e. use headers_out rather than |
| 742 |
* err_headers_out. |
| 743 |
*/ |
| 744 |
|
| 748 |
if (strcasecmp(name, "Location") == 0) { |
745 |
if (strcasecmp(name, "Location") == 0) { |
| 749 |
if (hasLocation) { |
|
|
| 750 |
goto DuplicateNotAllowed; |
| 751 |
} |
| 752 |
hasLocation = TRUE; |
746 |
hasLocation = TRUE; |
| 753 |
ap_table_set(r->headers_out, "Location", value); |
747 |
ap_table_set(r->headers_out, name, value); |
|
|
748 |
continue; |
| 749 |
} |
| 750 |
|
| 751 |
if (strcasecmp(name, "Content-Length") == 0) { |
| 752 |
ap_table_set(r->headers_out, name, value); |
| 754 |
continue; |
753 |
continue; |
| 755 |
} |
754 |
} |
| 756 |
|
755 |
|
|
Lines 841-850
Link Here
|
| 841 |
*p = '\0'; |
840 |
*p = '\0'; |
| 842 |
fr->parseHeader = SCAN_CGI_BAD_HEADER; |
841 |
fr->parseHeader = SCAN_CGI_BAD_HEADER; |
| 843 |
return ap_psprintf(r->pool, "malformed header '%s'", name); |
842 |
return ap_psprintf(r->pool, "malformed header '%s'", name); |
| 844 |
|
|
|
| 845 |
DuplicateNotAllowed: |
| 846 |
fr->parseHeader = SCAN_CGI_BAD_HEADER; |
| 847 |
return ap_psprintf(r->pool, "duplicate header '%s'", name); |
| 848 |
} |
843 |
} |
| 849 |
|
844 |
|
| 850 |
/* |
845 |
/* |
|
Lines 1387-1394
Link Here
|
| 1387 |
} |
1382 |
} |
| 1388 |
|
1383 |
|
| 1389 |
/* Connect */ |
1384 |
/* Connect */ |
| 1390 |
if (connect(fr->fd, (struct sockaddr *)socket_addr, socket_addr_len) == 0) |
1385 |
do { |
|
|
1386 |
if (connect(fr->fd, (struct sockaddr *) socket_addr, socket_addr_len) == 0) { |
| 1391 |
goto ConnectionComplete; |
1387 |
goto ConnectionComplete; |
|
|
1388 |
} |
| 1389 |
} while (errno == EINTR); |
| 1392 |
|
1390 |
|
| 1393 |
#ifdef WIN32 |
1391 |
#ifdef WIN32 |
| 1394 |
|
1392 |
|
|
Lines 1432-1438
Link Here
|
| 1432 |
tval.tv_sec = dynamicPleaseStartDelay; |
1430 |
tval.tv_sec = dynamicPleaseStartDelay; |
| 1433 |
tval.tv_usec = 0; |
1431 |
tval.tv_usec = 0; |
| 1434 |
|
1432 |
|
| 1435 |
status = ap_select((fr->fd+1), &read_fds, &write_fds, NULL, &tval); |
1433 |
do { |
|
|
1434 |
status = ap_select(fr->fd + 1, &read_fds, &write_fds, NULL, &tval); |
| 1435 |
} while (status < 0 && errno == EINTR); |
| 1436 |
|
| 1436 |
if (status < 0) |
1437 |
if (status < 0) |
| 1437 |
break; |
1438 |
break; |
| 1438 |
|
1439 |
|
|
Lines 1461-1467
Link Here
|
| 1461 |
FD_SET(fr->fd, &write_fds); |
1462 |
FD_SET(fr->fd, &write_fds); |
| 1462 |
read_fds = write_fds; |
1463 |
read_fds = write_fds; |
| 1463 |
|
1464 |
|
| 1464 |
status = ap_select((fr->fd+1), &read_fds, &write_fds, NULL, &tval); |
1465 |
do { |
|
|
1466 |
status = ap_select(fr->fd + 1, &read_fds, &write_fds, NULL, &tval); |
| 1467 |
} while (status < 0 && errno == EINTR); |
| 1465 |
|
1468 |
|
| 1466 |
if (status == 0) { |
1469 |
if (status == 0) { |
| 1467 |
ap_log_rerror(FCGI_LOG_ERR_NOERRNO, r, |
1470 |
ap_log_rerror(FCGI_LOG_ERR_NOERRNO, r, |
|
Lines 1762-1767
Link Here
|
| 1762 |
} |
1765 |
} |
| 1763 |
|
1766 |
|
| 1764 |
client_send = 0; |
1767 |
client_send = 0; |
|
|
1768 |
|
| 1769 |
if (fcgi_protocol_dequeue(rp, fr)) |
| 1770 |
{ |
| 1771 |
state = STATE_ERROR; |
| 1772 |
break; |
| 1773 |
} |
| 1765 |
} |
1774 |
} |
| 1766 |
|
1775 |
|
| 1767 |
break; |
1776 |
break; |
|
Lines 2107-2112
Link Here
|
| 2107 |
} |
2116 |
} |
| 2108 |
|
2117 |
|
| 2109 |
client_send = 0; |
2118 |
client_send = 0; |
|
|
2119 |
|
| 2120 |
if (fcgi_protocol_dequeue(rp, fr)) |
| 2121 |
{ |
| 2122 |
state = STATE_ERROR; |
| 2123 |
break; |
| 2124 |
} |
| 2110 |
} |
2125 |
} |
| 2111 |
|
2126 |
|
| 2112 |
break; |
2127 |
break; |
|
Lines 2193-2199
Link Here
|
| 2193 |
} |
2208 |
} |
| 2194 |
|
2209 |
|
| 2195 |
/* wait on the socket */ |
2210 |
/* wait on the socket */ |
|
|
2211 |
do { |
| 2196 |
select_status = ap_select(nfds, &read_set, &write_set, NULL, &timeout); |
2212 |
select_status = ap_select(nfds, &read_set, &write_set, NULL, &timeout); |
|
|
2213 |
} while (select_status < 0 && errno == EINTR); |
| 2197 |
|
2214 |
|
| 2198 |
if (select_status < 0) |
2215 |
if (select_status < 0) |
| 2199 |
{ |
2216 |
{ |
|
Lines 2264-2276
Link Here
|
| 2264 |
|
2281 |
|
| 2265 |
if (rv < 0) |
2282 |
if (rv < 0) |
| 2266 |
{ |
2283 |
{ |
|
|
2284 |
if (errno == EAGAIN) |
| 2285 |
{ |
| 2286 |
/* this reportedly occurs on AIX 5.2 sporadically */ |
| 2287 |
struct timeval tv; |
| 2288 |
tv.tv_sec = 1; |
| 2289 |
tv.tv_usec = 0; |
| 2290 |
|
| 2291 |
ap_log_rerror(FCGI_LOG_INFO, r, "FastCGI: comm with server " |
| 2292 |
"\"%s\" interrupted: read will be retried in 1 second", |
| 2293 |
fr->fs_path); |
| 2294 |
|
| 2295 |
/* avoid sleep/alarm interactions */ |
| 2296 |
ap_select(0, NULL, NULL, NULL, &tv); |
| 2297 |
} |
| 2298 |
else |
| 2299 |
{ |
| 2267 |
ap_log_rerror(FCGI_LOG_ERR, r, "FastCGI: comm with server " |
2300 |
ap_log_rerror(FCGI_LOG_ERR, r, "FastCGI: comm with server " |
| 2268 |
"\"%s\" aborted: read failed", fr->fs_path); |
2301 |
"\"%s\" aborted: read failed", fr->fs_path); |
| 2269 |
state = STATE_ERROR; |
2302 |
state = STATE_ERROR; |
| 2270 |
break; |
2303 |
break; |
| 2271 |
} |
2304 |
} |
| 2272 |
|
2305 |
} |
| 2273 |
if (rv == 0) |
2306 |
else if (rv == 0) |
| 2274 |
{ |
2307 |
{ |
| 2275 |
fr->keepReadingFromFcgiApp = FALSE; |
2308 |
fr->keepReadingFromFcgiApp = FALSE; |
| 2276 |
state = STATE_CLIENT_SEND; |
2309 |
state = STATE_CLIENT_SEND; |
|
Lines 2603-2609
Link Here
|
| 2603 |
return HTTP_MOVED_TEMPORARILY; |
2636 |
return HTTP_MOVED_TEMPORARILY; |
| 2604 |
|
2637 |
|
| 2605 |
default: |
2638 |
default: |
|
|
2639 |
#ifdef APACHE2 |
| 2640 |
{ |
| 2641 |
apr_bucket_brigade *brigade = apr_brigade_create(r->pool, r->connection->bucket_alloc); |
| 2642 |
apr_bucket* bucket = apr_bucket_eos_create(r->connection->bucket_alloc); |
| 2643 |
APR_BRIGADE_INSERT_HEAD(brigade, bucket); |
| 2644 |
return ap_pass_brigade(r->output_filters, brigade); |
| 2645 |
} |
| 2646 |
#else |
| 2606 |
return OK; |
2647 |
return OK; |
|
|
2648 |
#endif |
| 2607 |
} |
2649 |
} |
| 2608 |
} |
2650 |
} |
| 2609 |
|
2651 |
|