buffer_t *value_buf;
size_t skip;
+ int skip_initial_lwsp;
int has_nuls;
};
struct message_header_line *hdr;
hdr_ctx = message_parse_header_init(parser_ctx->input,
- &part->header_size);
+ &part->header_size, TRUE);
while ((hdr = message_parse_header_next(hdr_ctx)) != NULL) {
/* call the user-defined header parser */
if (parser_ctx->callback != NULL)
struct message_header_parser_ctx *hdr_ctx;
struct message_header_line *hdr;
- hdr_ctx = message_parse_header_init(input, hdr_size);
+ hdr_ctx = message_parse_header_init(input, hdr_size, TRUE);
while ((hdr = message_parse_header_next(hdr_ctx)) != NULL)
callback(part, hdr, context);
message_parse_header_deinit(hdr_ctx);
}
struct message_header_parser_ctx *
-message_parse_header_init(struct istream *input, struct message_size *hdr_size)
+message_parse_header_init(struct istream *input, struct message_size *hdr_size,
+ int skip_initial_lwsp)
{
struct message_header_parser_ctx *ctx;
ctx->input = input;
ctx->hdr_size = hdr_size;
ctx->name = str_new(default_pool, 128);
+ ctx->skip_initial_lwsp = skip_initial_lwsp;
if (hdr_size != NULL)
memset(hdr_size, 0, sizeof(*hdr_size));
if (msg[i] <= ':') {
if (msg[i] == ':') {
colon_pos = i;
- // FIXME: correct?
line->full_value_offset =
ctx->input->v_offset +
i + 1;
line->name = str_c(ctx->name);
line->name_len = str_len(ctx->name);
} else {
- /* get value. skip all LWSP after ':'. Note that RFC2822
- doesn't say we should, but history behind it..
+ size_t pos;
- Exception to this is if the value consists only of LWSP,
- then skip only the one LWSP after ':'. */
line->value = msg + colon_pos+1;
line->value_len = size - colon_pos - 1;
- while (line->value_len > 0 && IS_LWSP(line->value[0])) {
- line->value++;
- line->value_len--;
- }
+ if (ctx->skip_initial_lwsp) {
+ /* get value. skip all LWSP after ':'. Note that
+ RFC2822 doesn't say we should, but history behind
+ it..
+
+ Exception to this is if the value consists only of
+ LWSP, then skip only the one LWSP after ':'. */
+ for (pos = 0; pos < line->value_len; pos++) {
+ if (!IS_LWSP(line->value[0]))
+ break;
+ }
- if (line->value_len == 0) {
- /* everything was LWSP */
- line->value = msg + colon_pos+1;
- line->value_len = size - colon_pos - 1;
- if (line->value_len > 0 && IS_LWSP(line->value[0])) {
- line->value++;
- line->value_len--;
+ if (pos == line->value_len) {
+ /* everything was LWSP */
+ if (line->value_len > 0 &&
+ IS_LWSP(line->value[0]))
+ pos = 1;
}
+ } else {
+ pos = line->value_len > 0 &&
+ IS_LWSP(line->value[0]) ? 1 : 0;
}
+ line->value += pos;
+ line->value_len -= pos;
+ line->full_value_offset += pos;
+
/* get name, skip LWSP before ':' */
while (colon_pos > 0 && IS_LWSP(msg[colon_pos-1]))
colon_pos--;
const unsigned char *value;
size_t value_len;
- const unsigned char *full_value; // FIXME: should contain \n too
+ const unsigned char *full_value;
size_t full_value_len;
uoff_t name_offset, full_value_offset;
message_body_callback_t *body_callback,
void *context);
+/* skip_initial_lwsp controls if we should skip LWSP after "header: ".
+ Note that there may not be the single whitespace after "header:", and that
+ "header : " is also possible. These two conditions can't be determined from
+ struct message_header_line. */
struct message_header_parser_ctx *
-message_parse_header_init(struct istream *input, struct message_size *hdr_size);
+message_parse_header_init(struct istream *input, struct message_size *hdr_size,
+ int skip_initial_lwsp);
void message_parse_header_deinit(struct message_header_parser_ctx *ctx);
/* Read and return next header line. */