in src/incoming.c [251:356]
static apr_status_t read_from_client(serf_incoming_t *client)
{
apr_status_t status = APR_SUCCESS;
serf_incoming_request_t *rq;
if (client->proto_peek_bkt)
{
status = perform_peek_protocol(client);
/* Did we switch protocol? */
if (!status
&& client->framing_type != SERF_CONNECTION_FRAMING_TYPE_NONE
&& client->framing_type != SERF_CONNECTION_FRAMING_TYPE_HTTP1)
{
return client->perform_read(client);
}
/* On error fall through in connection cleanup below while */
}
while (status == APR_SUCCESS) {
rq = client->current_request;
if (!rq) {
serf_bucket_t *read_bkt;
rq = serf__incoming_request_create(client);
if (client->proto_peek_bkt) {
read_bkt = client->proto_peek_bkt;
client->proto_peek_bkt = NULL;
}
else
read_bkt = serf_bucket_barrier_create(client->pump.stream,
client->allocator);
status = client->req_setup(&rq->req_bkt, read_bkt, rq,
client->req_setup_baton,
&rq->handler, &rq->handler_baton,
&rq->response_setup,
&rq->response_setup_baton,
rq->pool);
if (status) {
apr_pool_destroy(rq->pool);
serf_bucket_mem_free(client->allocator, rq);
return status;
}
}
/* Run handler once or multiple times until status? */
status = rq->handler(rq, rq->req_bkt, rq->handler_baton, rq->pool);
if (SERF_BUCKET_READ_ERROR(status))
return status;
if (APR_STATUS_IS_EOF(status)) {
/* Write response if this hasn't been done yet */
status = serf_incoming_response_create(rq);
if (SERF_BUCKET_READ_ERROR(status))
return status;
rq->request_read = true;
client->current_request = NULL;
if (rq->request_read && rq->response_finished) {
serf__incoming_request_destroy(rq);
}
/* Is the connection at eof or just the request? */
{
const char *data;
apr_size_t len;
status = serf_bucket_peek(client->pump.stream, &data, &len);
}
}
}
if (!SERF_BUCKET_READ_ERROR(status) && !APR_STATUS_IS_EOF(status))
return APR_SUCCESS;
{
apr_pollfd_t tdesc = { 0 };
/* Remove us from the pollset */
tdesc.desc_type = APR_POLL_SOCKET;
tdesc.desc.s = client->skt;
tdesc.reqevents = client->io.reqevents;
client->ctx->pollset_rm(client->ctx->pollset_baton,
&tdesc, &client->io);
client->seen_in_pollset |= APR_POLLHUP; /* No more events */
/* Note that the client is done. The pool containing skt
and this listener will now be cleared from the context
handlers dirty pollset support */
client->skt = NULL;
serf_io__set_pollset_dirty(&client->io);
}
status = client->closed(client, client->closed_baton, status,
client->pool);
return status;
}