ARRAY_DEFINE(match_change_lines, unsigned int);
unsigned int header_read:1;
+ unsigned int seen_eoh:1;
unsigned int header_parsed:1;
unsigned int exclude:1;
unsigned int crlf:1;
unsigned int hide_body:1;
+ unsigned int add_missing_eoh:1;
};
header_filter_callback *null_header_filter_callback = NULL;
cmp_uint) != NULL;
}
+static void add_eol(struct header_filter_istream *mstream)
+{
+ if (mstream->crlf)
+ buffer_append(mstream->hdr_buf, "\r\n", 2);
+ else
+ buffer_append_c(mstream->hdr_buf, '\n');
+}
+
static ssize_t read_header(struct header_filter_istream *mstream)
{
struct message_header_line *hdr;
mstream->cur_line++;
if (hdr->eoh) {
+ mstream->seen_eoh = TRUE;
matched = TRUE;
if (!mstream->header_parsed &&
mstream->callback != NULL) {
if (!matched)
continue;
- if (mstream->crlf)
- buffer_append(mstream->hdr_buf, "\r\n", 2);
- else
- buffer_append_c(mstream->hdr_buf, '\n');
+ add_eol(mstream);
continue;
}
}
buffer_append(mstream->hdr_buf,
hdr->value, hdr->value_len);
- if (!hdr->no_newline) {
- if (mstream->crlf) {
- buffer_append(mstream->hdr_buf,
- "\r\n", 2);
- } else
- buffer_append_c(mstream->hdr_buf, '\n');
- }
+ if (!hdr->no_newline)
+ add_eol(mstream);
if (mstream->skip_count >= mstream->hdr_buf->used) {
/* we need more */
}
}
+ if (!mstream->seen_eoh && mstream->add_missing_eoh) {
+ mstream->seen_eoh = TRUE;
+ add_eol(mstream);
+ }
+
/* don't copy eof here because we're only returning headers here.
the body will be returned in separate read() call. */
mstream->istream.buffer = buffer_get_data(mstream->hdr_buf, &pos);
mstream->skip_count = v_offset;
mstream->cur_line = 0;
mstream->header_read = FALSE;
+ mstream->seen_eoh = FALSE;
} else {
/* body */
v_offset += mstream->header_size.physical_size -
mstream->exclude = (flags & HEADER_FILTER_EXCLUDE) != 0;
mstream->crlf = (flags & HEADER_FILTER_NO_CR) == 0;
mstream->hide_body = (flags & HEADER_FILTER_HIDE_BODY) != 0;
+ mstream->add_missing_eoh = (flags & HEADER_FILTER_ADD_MISSING_EOH) != 0;
mstream->istream.iostream.destroy = i_stream_header_filter_destroy;
mstream->istream.iostream.set_max_buffer_size =
enum header_filter_flags {
/* Include only specified headers in output.*/
- HEADER_FILTER_INCLUDE = 0x01,
+ HEADER_FILTER_INCLUDE = 0x01,
/* Exclude specified headers from output. */
- HEADER_FILTER_EXCLUDE = 0x02,
+ HEADER_FILTER_EXCLUDE = 0x02,
/* Use LF linefeeds instead of CRLF. */
- HEADER_FILTER_NO_CR = 0x04,
+ HEADER_FILTER_NO_CR = 0x04,
/* Return EOF at the beginning of message body. */
- HEADER_FILTER_HIDE_BODY = 0x08
+ HEADER_FILTER_HIDE_BODY = 0x08,
+ /* If the empty "end of headers" line doesn't exist, add it. */
+ HEADER_FILTER_ADD_MISSING_EOH = 0x10
};
struct message_header_line;