Optimize some string handling in chunk parser

personal/stbuehler/wip
Stefan Bühler 13 years ago
parent 254ba2a1f6
commit cae0c15710
  1. 4
      include/lighttpd/chunk_parser.h
  2. 23
      src/main/chunk_parser.c
  3. 8
      src/main/http_request_parser.rl

@ -22,7 +22,7 @@ struct liChunkParserCtx {
struct liChunkParserMark {
liChunkIter ci;
off_t pos;
off_t pos, abs_pos;
};
LI_API void li_chunk_parser_init(liChunkParserCtx *ctx, liChunkQueue *cq);
@ -31,6 +31,7 @@ LI_API liHandlerResult li_chunk_parser_prepare(liChunkParserCtx *ctx);
LI_API liHandlerResult li_chunk_parser_next(liVRequest *vr, liChunkParserCtx *ctx, char **p, char **pe);
LI_API void li_chunk_parser_done(liChunkParserCtx *ctx, goffset len);
/* extract [from..to) */
LI_API gboolean li_chunk_extract_to(liVRequest *vr, liChunkParserMark from, liChunkParserMark to, GString *dest);
LI_API GString* li_chunk_extract(liVRequest *vr, liChunkParserMark from, liChunkParserMark to);
@ -44,6 +45,7 @@ INLINE liChunkParserMark li_chunk_parser_getmark(liChunkParserCtx *ctx, const ch
liChunkParserMark m;
m.ci = ctx->curi;
m.pos = ctx->start + fpc - ctx->buf;
m.abs_pos = ctx->bytes_in + fpc - ctx->buf;
return m;
}

@ -55,7 +55,8 @@ void li_chunk_parser_done(liChunkParserCtx *ctx, goffset len) {
gboolean li_chunk_extract_to(liVRequest *vr, liChunkParserMark from, liChunkParserMark to, GString *dest) {
liChunkParserMark i;
g_string_set_size(dest, 0);
g_string_set_size(dest, to.abs_pos - from.abs_pos);
li_g_string_clear(dest);
for ( i = from; i.ci.element != to.ci.element; li_chunkiter_next(&i.ci) ) {
goffset len = li_chunkiter_length(i.ci);
@ -63,7 +64,14 @@ gboolean li_chunk_extract_to(liVRequest *vr, liChunkParserMark from, liChunkPars
char *buf;
off_t we_have;
if (LI_HANDLER_GO_ON != li_chunkiter_read(vr, i.ci, i.pos, len - i.pos, &buf, &we_have)) goto error;
g_string_append_len(dest, buf, we_have);
if (dest->len + we_have < dest->allocated_len) {
/* "fast" append */
memcpy(dest->str + dest->len, buf, we_have);
dest->len += we_have;
dest->str[dest->len] = '\0';
} else {
g_string_append_len(dest, buf, we_have);
}
i.pos += we_have;
}
i.pos = 0;
@ -72,14 +80,21 @@ gboolean li_chunk_extract_to(liVRequest *vr, liChunkParserMark from, liChunkPars
char *buf;
off_t we_have;
if (LI_HANDLER_GO_ON != li_chunkiter_read(vr, i.ci, i.pos, to.pos - i.pos, &buf, &we_have)) goto error;
g_string_append_len(dest, buf, we_have);
if (dest->len + we_have < dest->allocated_len) {
/* "fast" append */
memcpy(dest->str + dest->len, buf, we_have);
dest->len += we_have;
dest->str[dest->len] = '\0';
} else {
g_string_append_len(dest, buf, we_have);
}
i.pos += we_have;
}
return TRUE;
error:
g_string_assign(dest, "");
li_g_string_clear(dest);
return FALSE;
}

@ -24,15 +24,17 @@
action header_key {
getStringTo(fpc, ctx->h_key);
g_string_truncate(ctx->h_value, 0);
li_g_string_clear(ctx->h_value);
}
action header_value {
getStringTo(fpc, ctx->h_value);
/* Remove CRLF */
if (ctx->h_value->len > 2) {
g_string_truncate(ctx->h_value, ctx->h_value->len - 2);
ctx->h_value->len -= 2;
ctx->h_value->str[ctx->h_value->len] = '\0';
/* g_string_truncate(ctx->h_value, ctx->h_value->len - 2); */
} else {
g_string_truncate(ctx->h_value, 0);
li_g_string_clear(ctx->h_value);
}
}
action header {

Loading…
Cancel
Save