2
0
Fork 0
lighttpd2/src/main/stream_http_response.c

80 lines
2.3 KiB
C

#include <lighttpd/stream_http_response.h>
typedef struct liStreamHttpResponse liStreamHttpResponse;
struct liStreamHttpResponse {
liHttpResponseCtx parse_response_ctx;
liStream stream;
liVRequest *vr;
gboolean response_headers_finished;
};
static void stream_http_respone_data(liStreamHttpResponse* shr) {
if (NULL == shr->stream.source) return;
if (!shr->response_headers_finished) {
switch (li_http_response_parse(shr->vr, &shr->parse_response_ctx)) {
case LI_HANDLER_GO_ON:
shr->response_headers_finished = TRUE;
li_vrequest_indirect_headers_ready(shr->vr);
break;
case LI_HANDLER_ERROR:
VR_ERROR(shr->vr, "%s", "Parsing response header failed");
li_vrequest_error(shr->vr);
return;
case LI_HANDLER_WAIT_FOR_EVENT:
if (shr->stream.source == NULL || shr->stream.source->out->is_closed) {
VR_ERROR(shr->vr, "%s", "Parsing response header failed (eos)");
li_vrequest_error(shr->vr);
}
default:
return;
}
}
li_chunkqueue_steal_all(shr->stream.out, shr->stream.source->out);
if (shr->stream.source->out->is_closed) {
shr->stream.out->is_closed = TRUE;
li_stream_disconnect(&shr->stream);
}
li_stream_notify(&shr->stream);
}
static void stream_http_respone_cb(liStream *stream, liStreamEvent event) {
liStreamHttpResponse* shr = LI_CONTAINER_OF(stream, liStreamHttpResponse, stream);
switch (event) {
case LI_STREAM_NEW_DATA:
stream_http_respone_data(shr);
break;
case LI_STREAM_DISCONNECTED_DEST:
li_stream_disconnect(stream);
break;
case LI_STREAM_DISCONNECTED_SOURCE:
if (NULL != stream->dest && !stream->out->is_closed) {
/* "abort" */
li_stream_disconnect_dest(stream);
}
break;
case LI_STREAM_DESTROY:
li_http_response_parser_clear(&shr->parse_response_ctx);
g_slice_free(liStreamHttpResponse, shr);
break;
default:
break;
}
}
LI_API liStream* li_stream_http_response_handle(liStream *http_in, liVRequest *vr, gboolean accept_cgi, gboolean accept_nph) {
liStreamHttpResponse *shr = g_slice_new0(liStreamHttpResponse);
shr->response_headers_finished = FALSE;
shr->vr = vr;
li_stream_init(&shr->stream, &vr->wrk->loop, stream_http_respone_cb);
li_http_response_parser_init(&shr->parse_response_ctx, &vr->response, http_in->out,
accept_cgi, accept_nph);
li_stream_connect(http_in, &shr->stream);
return &shr->stream;
}