istream-header-filter.c revision 9e095dd6a77097356aca8216356d4d71ef1bea45
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
573f0491a5733fe21fa062a455acb4790b4e0499Timo Sirainen const char **headers;
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainenstatic void _close(struct _iostream *stream __attr_unused__)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen message_parse_header_deinit(mstream->hdr_ctx);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainenstatic void _set_max_buffer_size(struct _iostream *stream, size_t max_size)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen i_stream_set_max_buffer_size(mstream->input, max_size);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenstatic ssize_t read_header(struct header_filter_istream *mstream)
4ba9a1d3facc515b3feb5238a16bcf91f76fac61Timo Sirainen mstream->istream.istream.v_offset + mstream->istream.pos ==
dfaefeabae939803ceb8c503101e86b5496541d1Timo Sirainen /* we don't support mixing headers and body.
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen it shouldn't be needed. */
9847ec56efa15fa063eea9988eee2d4ed9ec7d58Timo Sirainen message_parse_header_init(mstream->input, NULL, FALSE);
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainen mstream->hdr_buf, mstream->istream.skip, (size_t)-1);
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainen mstream->istream.pos -= mstream->istream.skip;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen buffer_set_used_size(mstream->hdr_buf, mstream->istream.pos);
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen while ((hdr_ret = message_parse_header_next(mstream->hdr_ctx,
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen matched = bsearch(hdr->name, mstream->headers,
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen if (mstream->cur_line > mstream->parsed_lines &&
57a8c6a95e4bce3eeaba36985adb81c07dd683ffTimo Sirainen mstream->callback(hdr, &matched, mstream->context);
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen if (mstream->skip_count >= mstream->hdr_buf->used) {
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen /* we need more */
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen mstream->skip_count -= mstream->hdr_buf->used;
c5ab90cfad9cc3e33bcb1baeb30ffc82a7b7053aTimo Sirainen mstream->istream.istream.eof = mstream->input->eof;
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen mstream->istream.buffer = buffer_get_data(mstream->hdr_buf, &pos);
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen ret = (ssize_t)(pos - mstream->istream.pos - mstream->istream.skip);
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen /* finished */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen message_parse_header_deinit(mstream->hdr_ctx);
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen mstream->header_size.physical_size = mstream->input->v_offset;
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen stream->istream.v_offset < mstream->header_size.virtual_size) {
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen if (mstream->input->v_offset - mstream->header_size.physical_size !=
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen stream->istream.v_offset - mstream->header_size.virtual_size) {
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen i_stream_seek(mstream->input, stream->istream.v_offset -
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen stream->buffer = i_stream_get_data(mstream->input, &pos);
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen stream->buffer = i_stream_get_data(mstream->input, &pos);
2584e86cc2d8c31ba30a4109cf4ba09d1e37e28aTimo Sirainenstatic void _seek(struct _istream *stream, uoff_t v_offset)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen message_parse_header_deinit(mstream->hdr_ctx);
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen if (v_offset < mstream->header_size.virtual_size) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* seek into headers. we'll have to re-parse them, use
dbe64f3893616a4005c8946be75d2dc8f6823d72Timo Sirainen skip_count to set the wanted position */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen v_offset += mstream->header_size.physical_size -
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Siraineni_stream_create_header_filter(struct istream *input, int filter,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *const *headers, size_t headers_count,
f3bb2fbe87425dc89a839908985af496f7f65702Timo Sirainen header_filter_callback *callback, void *context)
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen pool = pool_alloconly_create("header filter stream", 1024);
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen mstream = p_new(pool, struct header_filter_istream, 1);
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen mstream->headers = p_new(pool, const char *, headers_count);
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen for (i = 0; i < headers_count; i++)
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen mstream->headers[i] = p_strdup(pool, headers[i]);
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen mstream->hdr_buf = buffer_create_dynamic(pool, 512, (size_t)-1);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen mstream->istream.iostream.set_max_buffer_size = _set_max_buffer_size;
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen return _i_stream_create(&mstream->istream, pool, -1, 0);