2
0
Fork 0
lighttpd2/src/chunk_parser.c

79 lines
2.0 KiB
C
Raw Normal View History

#include "chunk_parser.h"
void chunk_parser_init(chunk_parser_ctx *ctx, chunkqueue *cq) {
ctx->cq = cq;
ctx->bytes_in = 0;
ctx->curi.element = NULL;
ctx->start = 0;
ctx->length = 0;
ctx->buf = NULL;
}
handler_t chunk_parser_prepare(chunk_parser_ctx *ctx) {
if (NULL == ctx->curi.element) {
ctx->curi = chunkqueue_iter(ctx->cq);
if (NULL == ctx->curi.element) return HANDLER_WAIT_FOR_EVENT;
}
return HANDLER_GO_ON;
}
handler_t chunk_parser_next(server *srv, connection *con, chunk_parser_ctx *ctx, char **p, char **pe) {
off_t l;
handler_t res;
if (NULL == ctx->curi.element) return HANDLER_WAIT_FOR_EVENT;
while (ctx->start >= (l = chunkiter_length(ctx->curi))) {
chunkiter i = ctx->curi;
/* Wait at the end of the last chunk if it gets extended */
if (!chunkiter_next(&i)) return HANDLER_WAIT_FOR_EVENT;
ctx->curi = i;
ctx->start = 0;
}
if (NULL == ctx->curi.element) return HANDLER_WAIT_FOR_EVENT;
if (HANDLER_GO_ON != (res = chunkiter_read(srv, con, ctx->curi, ctx->start, l - ctx->start, &ctx->buf, &ctx->length))) {
return res;
}
*p = ctx->buf;
*pe = ctx->buf + ctx->length;
return HANDLER_GO_ON;
}
void chunk_parser_done(chunk_parser_ctx *ctx, goffset len) {
ctx->bytes_in += len;
ctx->start += len;
}
GString* chunk_extract(server *srv, connection *con, chunk_parser_mark from, chunk_parser_mark to) {
GString *str = g_string_sized_new(0);
chunk_parser_mark i;
for ( i = from; i.ci.element != to.ci.element; chunkiter_next(&i.ci) ) {
goffset len = chunkiter_length(i.ci);
while (i.pos < len) {
char *buf;
off_t we_have;
if (HANDLER_GO_ON != chunkiter_read(srv, con, i.ci, i.pos, len - i.pos, &buf, &we_have)) goto error;
g_string_append_len(str, buf, we_have);
i.pos += we_have;
}
i.pos = 0;
}
while (i.pos < to.pos) {
char *buf;
off_t we_have;
if (HANDLER_GO_ON != chunkiter_read(srv, con, i.ci, i.pos, to.pos - i.pos, &buf, &we_have)) goto error;
g_string_append_len(str, buf, we_have);
i.pos += we_have;
}
return str;
error:
g_string_free(str, TRUE);
return NULL;
}