in flood_socket_keepalive.c [158:277]
static apr_status_t keepalive_read_chunk(response_t *resp,
keepalive_socket_t *sock,
int chunk_length,
char **bp, int bplen)
{
apr_status_t status = APR_SUCCESS;
int old_length = 0;
if (!resp->chunk) {
chunk_length = 0;
} else if (chunk_length < 0) {
old_length = chunk_length;
chunk_length = 0;
} else if (chunk_length == 0) {
return status;
}
do {
/* Sentinel value */
apr_size_t blen = 0;
char *start_chunk, *end_chunk, *b;
/* Always reset the b. */
b = *bp;
/* Time to read the next chunk size. At this point,
* we should be ready to read a CRLF followed by
* a line that contains the next chunk size.
*/
while (!chunk_length)
{
/* We are reading the next chunk and see a CRLF. */
if (blen >= 1 && b[0] == '\r') {
b++;
blen--;
if (blen >= 1 && b[0] == '\n') {
b++;
blen--;
}
else {
old_length = -1;
}
}
/* If blen is 0, we're empty so read more data. */
while (!blen)
{
/* Reset and read as much as we can. */
blen = bplen;
b = *bp;
status = ksock_read_socket(sock, b, &blen);
if (status != APR_SUCCESS) {
return status;
}
/* We got caught in the middle of a chunk last time. */
if (old_length < 0) {
b -= old_length;
blen += old_length;
old_length = 0;
}
/* We are reading the next chunk and see a CRLF. */
if (blen >= 2 && b[0] == '\r' && b[1] == '\n') {
b += 2;
blen -= 2;
}
}
start_chunk = b;
chunk_length = keepalive_read_chunk_size(start_chunk);
/* last-chunk */
if (!chunk_length)
{
/* See if we already read the trailer and final CRLF */
end_chunk = strstr(b, CRLF CRLF);
if (!end_chunk)
{
/* Read as much as we can. */
blen = bplen;
b = *bp;
status = ksock_read_socket(sock, b, &blen);
if (status != APR_SUCCESS)
return status;
}
/* FIXME: If we add pipelining, we need to put
* the remainder back so that it can be read. */
blen -= end_chunk - b + 4;
return APR_SUCCESS;
}
/* If this fails, we're very unlikely to have read a chunk! */
end_chunk = strstr(start_chunk, CRLF) + 2;
blen -= end_chunk - b;
/* Oh no, we read more than one chunk this go-around! */
if (chunk_length <= blen) {
b += chunk_length + (end_chunk - b);
blen -= chunk_length;
chunk_length = 0;
}
else
chunk_length -= blen;
}
if (chunk_length > bplen)
blen = bplen;
else
blen = chunk_length;
status = ksock_read_socket(sock, b, &blen);
chunk_length -= blen;
}
while (status == APR_SUCCESS);
return APR_SUCCESS;
}