Patch IIS-FastCGI-transfer-encoding-chuncked for CGI/CLI related Bug #60826
Patch version 2012-04-11 13:52 UTC
Return to Bug #60826 |
Download this patch
Patch Revisions:
Developer: andres@fenestrae.com
The patch covers 2 files
file: sapi/cgi/fastcgi.c
// Do not read data from more then 1 chunk, thus preventing to read the terminating chunk
// as additional data in attempt to fill the buffer up to 100%
int fcgi_read(fcgi_request *req, char *str, int len)
{
int ret, n, rest;
fcgi_header hdr;
unsigned char buf[255];
n = 0;
rest = len;
- while (rest > 0) {
+ if (rest > 0) {
if (req->in_len == 0) {
if (safe_read(req, &hdr, sizeof(fcgi_header)) != sizeof(fcgi_header) ||
hdr.version < FCGI_VERSION_1 ||
hdr.type != FCGI_STDIN) {
req->keep = 0;
return 0;
}
req->in_len = (hdr.contentLengthB1 << 8) | hdr.contentLengthB0;
req->in_pad = hdr.paddingLength;
if (req->in_len == 0) {
return n;
}
}
if (req->in_len >= rest) {
ret = safe_read(req, str, rest);
} else {
ret = safe_read(req, str, req->in_len);
}
if (ret < 0) {
req->keep = 0;
return ret;
} else if (ret > 0) {
req->in_len -= ret;
rest -= ret;
n += ret;
str += ret;
if (req->in_len == 0) {
if (req->in_pad) {
if (safe_read(req, buf, req->in_pad) != req->in_pad) {
req->keep = 0;
return ret;
}
}
} else {
return n;
}
} else {
return n;
}
}
return n;
}
file: sapi/cgi/cgi_main.c
// in case of reading the terminator calculate the actual content-length
// and remember this value, preventing consecutive calls to sapi_cgi_read_post
// to attempt and read data that will never come.
static int sapi_cgi_read_post(char *buffer, uint count_bytes TSRMLS_DC)
{
uint read_bytes = 0;
int tmp_read_bytes;
count_bytes = MIN(count_bytes, (uint) SG(request_info).content_length - SG(read_post_bytes));
while (read_bytes < count_bytes) {
if (fcgi_is_fastcgi()) {
fcgi_request *request = (fcgi_request*) SG(server_context);
tmp_read_bytes = fcgi_read(request, buffer + read_bytes, count_bytes - read_bytes);
+ if ((tmp_read_bytes == 0) && (SG(request_info).content_length == -1 ) ){
+ SG(request_info).content_length = SG(read_post_bytes) + read_bytes;
+ }
} else {
tmp_read_bytes = read(STDIN_FILENO, buffer + read_bytes, count_bytes - read_bytes);
}
if (tmp_read_bytes <= 0) {
break;
}
read_bytes += tmp_read_bytes;
}
return read_bytes;
}
|