in protocols/fcgi_protocol.c [137:337]
static apr_status_t fcgi_process(serf_fcgi_protocol_t *fcgi)
{
while (true)
{
apr_status_t status;
serf_bucket_t *body;
if (fcgi->processor)
{
status = fcgi->processor(fcgi->processor_baton, fcgi,
fcgi->read_frame);
if (SERF_BUCKET_READ_ERROR(status))
return status;
else if (APR_STATUS_IS_EOF(status))
{
/* ### frame ended */
SERF_FCGI_assert(fcgi->read_frame == NULL);
fcgi->processor = NULL;
fcgi->processor_baton = NULL;
}
else if (fcgi->in_frame)
{
if (status)
return status;
else
continue;
}
}
else
{
SERF_FCGI_assert(!fcgi->in_frame);
}
body = fcgi->read_frame;
if (!body)
{
SERF_FCGI_assert(!fcgi->in_frame);
body = serf__bucket_fcgi_unframe_create(fcgi->pump->stream,
fcgi->allocator);
serf__bucket_fcgi_unframe_set_eof(body,
fcgi_end_of_frame, fcgi);
serf_bucket_set_config(body, fcgi->config);
fcgi->read_frame = body;
}
if (!fcgi->in_frame)
{
apr_uint16_t sid;
apr_uint16_t frametype;
apr_size_t remaining;
serf_fcgi_processor_t process_handler = NULL;
void *process_baton = NULL;
serf_bucket_t *process_bucket = NULL;
serf_fcgi_stream_t *stream;
status = serf__bucket_fcgi_unframe_read_info(body, &sid,
&frametype);
if (APR_STATUS_IS_EOF(status))
{
/* Entire frame is already read (just header) */
SERF_FCGI_assert(fcgi->read_frame == NULL);
SERF_FCGI_assert(!fcgi->in_frame);
}
else if (status)
{
SERF_FCGI_assert(fcgi->read_frame != NULL);
SERF_FCGI_assert(!fcgi->in_frame);
return (status == SERF_ERROR_EMPTY_READ) ? APR_SUCCESS
: status;
}
else
{
fcgi->in_frame = TRUE;
SERF_FCGI_assert(fcgi->read_frame != NULL);
}
serf__log(LOGLVL_INFO, SERF_LOGCOMP_PROTOCOL, __FILE__,
fcgi->config,
"Reading 0x%x frame, stream=0x%x\n",
frametype, sid);
/* If status is EOF then the frame doesn't have/declare a body */
switch (frametype)
{
case FCGI_FRAMETYPE(FCGI_V1, FCGI_BEGIN_REQUEST):
stream = serf_fcgi__stream_get(fcgi, sid, false);
if (stream) {
/* Stream must be new */
return SERF_ERROR_FCGI_PROTOCOL_ERROR;
}
stream = serf_fcgi__stream_get(fcgi, sid, true);
remaining = (apr_size_t)serf_bucket_get_remaining(body);
if (remaining != sizeof(FCGI_BeginRequestBody)) {
return SERF_ERROR_FCGI_RECORD_SIZE_ERROR;
}
body = serf_bucket_prefix_create(
body,
sizeof(FCGI_BeginRequestBody),
fcgi_begin_request, stream,
fcgi->allocator);
/* Just reading will handle this frame now*/
process_bucket = body;
break;
case FCGI_FRAMETYPE(FCGI_V1, FCGI_ABORT_REQUEST):
process_bucket = body;
break;
case FCGI_FRAMETYPE(FCGI_V1, FCGI_END_REQUEST):
process_bucket = body;
break;
case FCGI_FRAMETYPE(FCGI_V1, FCGI_PARAMS):
stream = serf_fcgi__stream_get(fcgi, sid, false);
if (!stream) {
return SERF_ERROR_FCGI_PROTOCOL_ERROR;
}
body = serf_fcgi__stream_handle_params(stream, body,
fcgi->config,
fcgi->allocator);
if (body) {
/* We will take care of discarding */
process_bucket = body;
}
else
{
/* The stream wants to handle the reading itself */
process_handler = serf_fcgi__stream_processor;
process_baton = stream;
}
break;
case FCGI_FRAMETYPE(FCGI_V1, FCGI_STDIN):
stream = serf_fcgi__stream_get(fcgi, sid, false);
if (!stream) {
return SERF_ERROR_FCGI_PROTOCOL_ERROR;
}
body = serf_fcgi__stream_handle_stdin(stream, body,
fcgi->config,
fcgi->allocator);
if (body) {
/* We will take care of discarding */
process_bucket = body;
}
else
{
/* The stream wants to handle the reading itself */
process_handler = serf_fcgi__stream_processor;
process_baton = stream;
}
break;
case FCGI_FRAMETYPE(FCGI_V1, FCGI_STDOUT):
process_bucket = body;
break;
case FCGI_FRAMETYPE(FCGI_V1, FCGI_STDERR):
process_bucket = body;
break;
case FCGI_FRAMETYPE(FCGI_V1, FCGI_DATA):
process_bucket = body;
break;
case FCGI_FRAMETYPE(FCGI_V1, FCGI_GET_VALUES):
process_bucket = body;
break;
case FCGI_FRAMETYPE(FCGI_V1, FCGI_GET_VALUES_RESULT):
process_bucket = body;
break;
case FCGI_FRAMETYPE(FCGI_V1, FCGI_UNKNOWN_TYPE):
process_bucket = body;
break;
default:
process_bucket = body;
};
if (body)
serf_bucket_set_config(body, fcgi->config);
SERF_FCGI_assert(fcgi->processor == NULL);
if (process_handler)
{
fcgi->processor = process_handler;
fcgi->processor_baton = process_baton;
}
else
{
SERF_FCGI_assert(process_bucket != NULL);
fcgi->processor = fcgi_bucket_processor;
fcgi->processor_baton = process_bucket;
}
}
} /* while(TRUE) */
}