Mercurial > dovecot > original-hg > dovecot-1.2
changeset 2448:f1e4c99cbb2b HEAD
Added netscape-eoh workaround.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 22 Aug 2004 12:52:11 +0300 |
parents | be2e8dfe25be |
children | 1543762353aa |
files | dovecot-example.conf src/imap/common.h src/imap/imap-fetch-body.c src/imap/imap-fetch.h src/imap/main.c |
diffstat | 5 files changed, 65 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/dovecot-example.conf Sun Aug 22 12:46:50 2004 +0300 +++ b/dovecot-example.conf Sun Aug 22 12:52:11 2004 +0300 @@ -353,6 +353,12 @@ # arrives in half a hour, Dovecot closes the connection. This is still # fine, except Outlook doesn't connect back so you don't see if new mail # arrives. + # netscape-eoh: + # Netscape 4.x breaks if message headers don't end with the empty "end of + # headers" line. Normally all messages have this, but setting this + # workaround makes sure that Netscape never breaks by adding the line if + # it doesn't exist. This is done only for FETCH BODY[HEADER.FIELDS..] + # commands. Note that RFC says this shouldn't be done. #imap_client_workarounds = }
--- a/src/imap/common.h Sun Aug 22 12:46:50 2004 +0300 +++ b/src/imap/common.h Sun Aug 22 12:52:11 2004 +0300 @@ -25,7 +25,8 @@ enum client_workarounds { WORKAROUND_OE6_FETCH_NO_NEWMAIL = 0x01, - WORKAROUND_OUTLOOK_IDLE = 0x02 + WORKAROUND_OUTLOOK_IDLE = 0x02, + WORKAROUND_NETSCAPE_EOH = 0x04 }; extern struct ioloop *ioloop;
--- a/src/imap/imap-fetch-body.c Sun Aug 22 12:46:50 2004 +0300 +++ b/src/imap/imap-fetch-body.c Sun Aug 22 12:52:11 2004 +0300 @@ -119,7 +119,8 @@ } static off_t imap_fetch_send(struct ostream *output, struct istream *input, - int cr_skipped, uoff_t virtual_size, int *last_cr) + int cr_skipped, uoff_t virtual_size, + int add_missing_eoh, int *last_cr) { const unsigned char *msg; size_t i, size; @@ -173,6 +174,14 @@ } } + if (add_missing_eoh && sent + 2 == virtual_size) { + /* Netscape missing EOH workaround. */ + o_stream_set_max_buffer_size(output, (size_t)-1); + if (o_stream_send(output, "\r\n", 2) < 0) + return -1; + sent += 2; + } + if ((uoff_t)sent != virtual_size && !blocks) { /* Input stream gave less data then we expected. Two choices here: either we fill the missing data with spaces or we @@ -201,7 +210,7 @@ o_stream_set_max_buffer_size(ctx->client->output, 0); ret = imap_fetch_send(ctx->client->output, ctx->cur_input, ctx->skip_cr, ctx->cur_size - ctx->cur_offset, - &ctx->skip_cr); + ctx->cur_append_eoh, &ctx->skip_cr); o_stream_set_max_buffer_size(ctx->client->output, (size_t)-1); if (ret < 0) @@ -230,6 +239,15 @@ return -1; ctx->cur_offset += ret; + + if (ctx->cur_append_eoh && ctx->cur_offset + 2 == ctx->cur_size) { + /* Netscape missing EOH workaround. */ + if (o_stream_send(ctx->client->output, "\r\n", 2) < 0) + return -1; + ctx->cur_offset += 2; + ctx->cur_append_eoh = FALSE; + } + return ctx->cur_offset == ctx->cur_size; } @@ -316,12 +334,28 @@ return fetch_data(ctx, body, fetch_size); } +static void header_filter_eoh(struct message_header_line *hdr, + int *matched __attr_unused__, void *context) +{ + struct imap_fetch_context *ctx = context; + + if (hdr != NULL && hdr->eoh) + ctx->cur_have_eoh = TRUE; +} + static void header_filter_mime(struct message_header_line *hdr, - int *matched, void *context __attr_unused__) + int *matched, void *context) { + struct imap_fetch_context *ctx = context; + if (hdr == NULL) return; + if (hdr->eoh) { + ctx->cur_have_eoh = TRUE; + return; + } + *matched = strncasecmp(hdr->name, "Content-", 8) == 0 || strcasecmp(hdr->name, "Mime-Version") == 0; } @@ -337,26 +371,27 @@ /* MIME, HEADER.FIELDS (list), HEADER.FIELDS.NOT (list) */ + ctx->cur_have_eoh = FALSE; if (strncmp(header_section, "HEADER.FIELDS ", 14) == 0) { fields = imap_fetch_get_body_fields(header_section + 14, &fields_count); input = i_stream_create_header_filter(ctx->cur_input, FALSE, TRUE, fields, fields_count, - NULL, NULL); + header_filter_eoh, ctx); } else if (strncmp(header_section, "HEADER.FIELDS.NOT ", 18) == 0) { fields = imap_fetch_get_body_fields(header_section + 18, &fields_count); input = i_stream_create_header_filter(ctx->cur_input, TRUE, TRUE, fields, fields_count, - NULL, NULL); + header_filter_eoh, ctx); } else if (strcmp(header_section, "MIME") == 0) { /* Mime-Version + Content-* fields */ input = i_stream_create_header_filter(ctx->cur_input, FALSE, TRUE, NULL, 0, - header_filter_mime, NULL); + header_filter_mime, ctx); } else { i_error("BUG: Accepted invalid section from user: '%s'", header_section); @@ -367,16 +402,17 @@ ctx->cur_input = input; ctx->update_partial = FALSE; - /* FIXME: We'll just always add the end of headers mark now. - mail-storage should rather include it in the header stream.. - however, not much of a problem since all non-broken mails have it. - - Also, Netscape 4.x seems to require this or it won't show the - mail.. So if we do make this as RFC says, we'll need to add - netscape-workaround. */ message_get_header_size(ctx->cur_input, &msg_size, NULL); i_stream_seek(ctx->cur_input, 0); + if (!ctx->cur_have_eoh && + (client_workarounds & WORKAROUND_NETSCAPE_EOH) != 0) { + /* Netscape 4.x doesn't like if end of headers line is + missing. */ + msg_size.virtual_size += 2; + ctx->cur_append_eoh = TRUE; + } + return fetch_data(ctx, body, &msg_size); } @@ -411,6 +447,11 @@ message_get_body_size(ctx->cur_input, &size, NULL); i_stream_seek(ctx->cur_input, 0); + /* FIXME: We'll just always add the end of headers line now. + ideally mail-storage would have a way to tell us if it exists. */ + size.virtual_size += 2; + ctx->cur_append_eoh = TRUE; + return fetch_data(ctx, body, &size); }
--- a/src/imap/imap-fetch.h Sun Aug 22 12:46:50 2004 +0300 +++ b/src/imap/imap-fetch.h Sun Aug 22 12:52:11 2004 +0300 @@ -49,6 +49,8 @@ unsigned int flags_update_seen:1; unsigned int flags_show_only_seen_changes:1; unsigned int update_partial:1; + unsigned int cur_have_eoh:1; + unsigned int cur_append_eoh:1; unsigned int first:1; unsigned int failed:1; };
--- a/src/imap/main.c Sun Aug 22 12:46:50 2004 +0300 +++ b/src/imap/main.c Sun Aug 22 12:52:11 2004 +0300 @@ -29,6 +29,7 @@ struct client_workaround_list client_workaround_list[] = { { "oe6-fetch-no-newmail", WORKAROUND_OE6_FETCH_NO_NEWMAIL }, { "outlook-idle", WORKAROUND_OUTLOOK_IDLE }, + { "netscape-eoh", WORKAROUND_NETSCAPE_EOH }, { NULL, 0 } };