Hello. My callback for get_stream is called from mail_get_stream in mail_storage_copy. Further, mbox_save_init is called and it called mbox_save_get_input_stream. backtrace (A) for my callback: #0 i_stream_header_filter_read (stream=0x8147e00) at istream-header- filter.c:314 #1 0x080cdbaa in parse_header (mstream=0x8147e00) at istream-header- filter.c:356 #2 0x080cdc0c in i_stream_header_filter_seek (stream=0x8147e00, v_offset=0, mark=false) at istream-header-filter.c:370 #3 0x080dea5b in i_stream_seek (stream=0x8147e28, v_offset=0) at istream.c:155 #4 0x080dfeae in i_stream_create_concat (input=0x8115528) at istream- concat.c:260 #5 0x2831e03d in rarules_get_stream (mail=0x8141860, hdr_size=0x0, body_size=0x0, stream_r=0xbfbfe920) at /home/pitman/work/rarules/src/rarules-plugin.c:181 #6 0x0809d830 in mail_get_stream (mail=0x8141860, hdr_size=0x0, body_size=0x0, stream_r=0xbfbfe920) at mail.c:149 #7 0x0809d936 in mail_storage_copy (t=0x811b980, mail=0x8141860, flags=0, keywords=0x0, dest_mail=0x0) at mail-copy.c:17 #8 0x080a0632 in mailbox_copy (t=0x811b980, mail=0x8141860, flags=0, keywords=0x0, dest_mail=0x0) at mail-storage.c:763 #9 0x0805960d in deliver_save (namespaces=0x8121c68, storage_r=0xbfbfeb94, mailbox=0x811a360 "Draft", mail=0x8141860, flags=0, keywords=0x0) at deliver.c:234 ... backtrace (B) for mbox_save_init: #0 mbox_save_get_input_stream (ctx=0x811bb00, input=0x814c728) at mbox-save.c:384 #1 0x08078165 in mbox_save_init (_t=0x811b980, flags=0, keywords=0x0, received_date=1239634649, timezone_offset=0, from_envelope=0x80f292b "MAILER-DAEMON", input=0x814c728, dest_mail=0x8150060, ctx_r=0xbfbfe924) at mbox-save.c:512 #2 0x080a0560 in mailbox_save_init (t=0x811b980, flags=0, keywords=0x0, received_date=-1, timezone_offset=0, from_envelope=0x80f292b "MAILER-DAEMON", input=0x814c728, dest_mail=0x0, ctx_r=0xbfbfe924) at mail-storage.c:728 #3 0x0809d9c4 in mail_storage_copy (t=0x811b980, mail=0x8141860, flags=0, keywords=0x0, dest_mail=0x0) at mail-copy.c:28 #4 0x080a0632 in mailbox_copy (t=0x811b980, mail=0x8141860, flags=0, keywords=0x0, dest_mail=0x0) at mail-storage.c:763 #5 0x0805960d in deliver_save (namespaces=0x8121c68, storage_r=0xbfbfeb94, mailbox=0x80f2af9 "INBOX", mail=0x8141860, flags=0, keywords=0x0) at deliver.c:234 ... The function mbox_save_get_input_stream calls i_stream_create_header_filter and i_stream_create_concat. The function read_header (istream-header-filter.c) finds EOH for call of i_stream_seek (backtrace B), but my calls of i_stream_create_header_filter and i_stream_create_concat doesn't find EOH (backtrace A). Why? I don't understand. I want to call rarules_header_callback for disable eoh so as to add my headers. Thanks P.S. Sorry for my bad english :-( It's mbox_save_get_input_stream: -------------------------------------------- mbox_save_get_input_stream(struct mbox_save_context *ctx, struct istream *input) { struct istream *filter, *ret, *cache_input, *streams[3]; /* filter out unwanted headers and keep track of headers' MD5 sum */ filter = i_stream_create_header_filter(input, HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR | HEADER_FILTER_ADD_MISSING_EOH, mbox_save_drop_headers, mbox_save_drop_headers_count, save_header_callback, ctx); if ((ctx->mbox->storage->storage.flags & MAIL_STORAGE_FLAG_KEEP_HEADER_MD5) != 0) { /* we're using MD5 sums to generate POP3 UIDLs. clients don't like it much if there are duplicates, so make sure that there can't be any by appending our own X-Delivery-ID header. */ const char *hdr; T_BEGIN { mbox_save_x_delivery_id(ctx); } T_END; hdr = ctx->x_delivery_id_header; streams[0] = i_stream_create_from_data(hdr, strlen(hdr)); streams[1] = filter; streams[2] = NULL; ret = i_stream_create_concat(streams); i_stream_unref(&filter); filter = ret; } It's my callback for get_stream: --------------------------------------- static int rarules_get_stream(struct mail *mail, struct message_size *hdr_size, struct message_size *body_size, struct istream **stream_r) { struct rarules_mail *m = RA_MAIL_CONTEXT(mail); struct istream *stream = NULL; unsigned int deleted = 0; unsigned int added = 0; int ret = 0; DPRINT("func is called"); /* standard get_stream for mail storage format */ ret = m->module_ctx.super.get_stream(mail, hdr_size, body_size, &stream); added = array_count(&m->add_hdr_arr); deleted = array_count(&m->del_hdr_arr); if (m->enabled && (deleted || added)) { struct istream * tmp = NULL; struct istream **chunks = NULL; const unsigned int max_chunks = 4; unsigned int i = 0; unsigned int cnt = 0; DPRINT("modifing message headers"); /* create message from chunks with new hdrs and skip excluded hdrs */ chunks = t_new(struct istream *, max_chunks); chunks[cnt++] make_header_filter(stream, &m->del_hdr_arr, deleted); if (added) { chunks[cnt++] create_header_stream(&m->add_hdr_arr, added); } chunks[cnt++] = create_stream_for_msgbody(stream); chunks[cnt++] = NULL; tmp = i_stream_create_concat(chunks); for (i = 0; chunks[i] != NULL; ++i) { i_stream_unref(&chunks[i]); } i_stream_unref(&stream); stream = tmp; } *stream_r = stream; DPRINT("func is executed"); return ret; }