Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib-mail/message-parser.c @ 856:e49f7397af98 HEAD
Some bugfixes and speedups for partial fetch handling.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 27 Dec 2002 15:05:53 +0200 |
parents | 553f050c8313 |
children | a60e12a66ad3 |
rev | line source |
---|---|
0 | 1 /* Copyright (C) 2002 Timo Sirainen */ |
2 | |
3 #include "lib.h" | |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
4 #include "istream.h" |
0 | 5 #include "rfc822-tokenize.h" |
6 #include "message-content-parser.h" | |
7 #include "message-parser.h" | |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
8 #include "message-size.h" |
0 | 9 |
10 typedef struct _MessageBoundary { | |
11 struct _MessageBoundary *next; | |
12 | |
13 MessagePart *part; | |
14 const char *boundary; | |
184 | 15 size_t len; |
0 | 16 } MessageBoundary; |
17 | |
18 typedef struct { | |
19 Pool pool; | |
20 MessagePart *part; | |
21 | |
22 char *last_boundary; | |
23 char *last_content_type; | |
24 MessageBoundary *boundaries; | |
25 | |
26 MessageHeaderFunc func; | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
27 void *context; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
28 } MessageParseContext; |
0 | 29 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
30 static MessagePart *message_parse_part(IStream *input, |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
31 MessageParseContext *parse_ctx); |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
32 static MessagePart *message_parse_body(IStream *input, |
0 | 33 MessageBoundary *boundaries, |
34 MessageSize *body_size); | |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
35 static MessagePart *message_skip_boundary(IStream *input, |
0 | 36 MessageBoundary *boundaries, |
37 MessageSize *boundary_size); | |
38 | |
39 static void message_size_add_part(MessageSize *dest, MessagePart *part) | |
40 { | |
41 dest->physical_size += | |
42 part->header_size.physical_size + | |
43 part->body_size.physical_size; | |
44 dest->virtual_size += | |
45 part->header_size.virtual_size + | |
46 part->body_size.virtual_size; | |
47 dest->lines += part->header_size.lines + part->body_size.lines; | |
48 } | |
49 | |
50 static MessagePart *message_part_append(Pool pool, MessagePart *parent) | |
51 { | |
52 MessagePart *part, **list; | |
53 | |
54 part = p_new(pool, MessagePart, 1); | |
55 part->parent = parent; | |
56 | |
212
4327b1266604
message/rfc822 mime parts weren't parsed correctly
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
57 /* set child position */ |
4327b1266604
message/rfc822 mime parts weren't parsed correctly
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
58 part->physical_pos = |
4327b1266604
message/rfc822 mime parts weren't parsed correctly
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
59 parent->physical_pos + |
4327b1266604
message/rfc822 mime parts weren't parsed correctly
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
60 parent->body_size.physical_size + |
4327b1266604
message/rfc822 mime parts weren't parsed correctly
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
61 parent->header_size.physical_size; |
4327b1266604
message/rfc822 mime parts weren't parsed correctly
Timo Sirainen <tss@iki.fi>
parents:
184
diff
changeset
|
62 |
0 | 63 list = &part->parent->children; |
64 while (*list != NULL) | |
65 list = &(*list)->next; | |
66 | |
67 *list = part; | |
68 return part; | |
69 } | |
70 | |
71 static void parse_content_type(const Rfc822Token *tokens, int count, | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
72 void *context) |
0 | 73 { |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
74 MessageParseContext *parse_ctx = context; |
0 | 75 const char *str; |
76 | |
77 if (tokens[0].token != 'A') | |
78 return; | |
79 | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
80 if (parse_ctx->last_content_type != NULL) |
0 | 81 return; |
82 | |
112
d6105a8a6ca9
Fixed rfc822_tokens_get_value(). It doesn't have "put spaces around all
Timo Sirainen <tss@iki.fi>
parents:
106
diff
changeset
|
83 str = rfc822_tokens_get_value(tokens, count); |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
84 parse_ctx->last_content_type = p_strdup(parse_ctx->pool, str); |
0 | 85 |
86 if (strcasecmp(str, "message/rfc822") == 0) | |
106
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
87 parse_ctx->part->flags |= MESSAGE_PART_FLAG_MESSAGE_RFC822; |
0 | 88 else if (strncasecmp(str, "text/", 5) == 0) |
106
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
89 parse_ctx->part->flags |= MESSAGE_PART_FLAG_TEXT; |
0 | 90 else if (strncasecmp(str, "multipart/", 10) == 0) { |
106
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
91 parse_ctx->part->flags |= MESSAGE_PART_FLAG_MULTIPART; |
0 | 92 |
106
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
93 if (strcasecmp(str+10, "digest") == 0) { |
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
94 parse_ctx->part->flags |= |
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
95 MESSAGE_PART_FLAG_MULTIPART_DIGEST; |
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
96 } |
0 | 97 } |
98 } | |
99 | |
100 static void parse_content_type_param(const Rfc822Token *name, | |
101 const Rfc822Token *value, | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
102 int value_count, void *context) |
0 | 103 { |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
104 MessageParseContext *parse_ctx = context; |
0 | 105 const char *str; |
106 | |
106
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
107 if ((parse_ctx->part->flags & MESSAGE_PART_FLAG_MULTIPART) == 0 || |
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
108 name->len != 8 || strncasecmp(name->ptr, "boundary", 8) != 0) |
0 | 109 return; |
110 | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
111 if (parse_ctx->last_boundary == NULL) { |
112
d6105a8a6ca9
Fixed rfc822_tokens_get_value(). It doesn't have "put spaces around all
Timo Sirainen <tss@iki.fi>
parents:
106
diff
changeset
|
112 str = rfc822_tokens_get_value(value, value_count); |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
113 parse_ctx->last_boundary = p_strdup(parse_ctx->pool, str); |
0 | 114 } |
115 } | |
116 | |
117 static void parse_header_field(MessagePart *part, | |
184 | 118 const char *name, size_t name_len, |
119 const char *value, size_t value_len, | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
120 void *context) |
0 | 121 { |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
122 MessageParseContext *parse_ctx = context; |
0 | 123 |
124 /* call the user-defined header parser */ | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
125 if (parse_ctx->func != NULL) { |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
126 parse_ctx->func(part, name, name_len, value, value_len, |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
127 parse_ctx->context); |
0 | 128 } |
129 | |
130 if (name_len == 12 && strncasecmp(name, "Content-Type", 12) == 0) { | |
131 /* we need to know the boundary */ | |
132 (void)message_content_parse_header(t_strndup(value, value_len), | |
133 parse_content_type, | |
134 parse_content_type_param, | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
135 parse_ctx); |
0 | 136 } |
137 } | |
138 | |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
139 static MessagePart *message_parse_multipart(IStream *input, |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
140 MessageParseContext *parse_ctx) |
0 | 141 { |
142 MessagePart *parent_part, *next_part, *part; | |
143 MessageBoundary *b; | |
144 | |
145 /* multipart message. add new boundary */ | |
146 b = t_new(MessageBoundary, 1); | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
147 b->part = parse_ctx->part; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
148 b->boundary = parse_ctx->last_boundary; |
0 | 149 b->len = strlen(b->boundary); |
150 | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
151 b->next = parse_ctx->boundaries; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
152 parse_ctx->boundaries = b; |
0 | 153 |
154 /* reset fields */ | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
155 parse_ctx->last_boundary = NULL; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
156 parse_ctx->last_content_type = NULL; |
0 | 157 |
158 /* skip the data before the first boundary */ | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
159 parent_part = parse_ctx->part; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
160 next_part = message_skip_boundary(input, parse_ctx->boundaries, |
0 | 161 &parent_part->body_size); |
162 | |
163 /* now, parse the parts */ | |
164 while (next_part == parent_part) { | |
165 /* new child */ | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
166 part = message_part_append(parse_ctx->pool, parent_part); |
0 | 167 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
168 parse_ctx->part = part; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
169 next_part = message_parse_part(input, parse_ctx); |
0 | 170 |
171 /* update our size */ | |
172 message_size_add_part(&parent_part->body_size, part); | |
173 | |
174 if (next_part != parent_part) | |
175 break; | |
176 | |
177 /* skip the boundary */ | |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
178 next_part = message_skip_boundary(input, parse_ctx->boundaries, |
0 | 179 &parent_part->body_size); |
180 } | |
181 | |
182 /* remove boundary */ | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
183 i_assert(parse_ctx->boundaries == b); |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
184 parse_ctx->boundaries = b->next; |
0 | 185 return next_part; |
186 } | |
187 | |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
188 static MessagePart *message_parse_part(IStream *input, |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
189 MessageParseContext *parse_ctx) |
0 | 190 { |
191 MessagePart *next_part, *part; | |
50
d493b9cc265e
Introduced uoff_t which is the unsigned-equilevant of off_t. This was needed
Timo Sirainen <tss@iki.fi>
parents:
10
diff
changeset
|
192 uoff_t hdr_size; |
0 | 193 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
194 message_parse_header(parse_ctx->part, input, |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
195 &parse_ctx->part->header_size, |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
196 parse_header_field, parse_ctx); |
0 | 197 |
198 /* update message position/size */ | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
199 hdr_size = parse_ctx->part->header_size.physical_size; |
0 | 200 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
201 if (parse_ctx->last_boundary != NULL) |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
202 return message_parse_multipart(input, parse_ctx); |
0 | 203 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
204 if (parse_ctx->last_content_type == NULL) { |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
205 if (parse_ctx->part->parent != NULL && |
106
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
206 (parse_ctx->part->parent->flags & |
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
207 MESSAGE_PART_FLAG_MULTIPART_DIGEST)) { |
0 | 208 /* when there's no content-type specified and we're |
209 below multipart/digest, the assume message/rfc822 | |
210 content-type */ | |
106
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
211 parse_ctx->part->flags |= |
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
212 MESSAGE_PART_FLAG_MESSAGE_RFC822; |
0 | 213 } else { |
214 /* otherwise we default to text/plain */ | |
106
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
215 parse_ctx->part->flags |= MESSAGE_PART_FLAG_TEXT; |
0 | 216 } |
217 } | |
218 | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
219 parse_ctx->last_boundary = NULL; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
220 parse_ctx->last_content_type = NULL; |
0 | 221 |
106
5fe3e04ca8d9
Added support for caching of MessagePart data. This is useful for fetching
Timo Sirainen <tss@iki.fi>
parents:
105
diff
changeset
|
222 if (parse_ctx->part->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822) { |
0 | 223 /* message/rfc822 part - the message body begins with |
224 headers again, this works pretty much the same as | |
225 a single multipart/mixed item */ | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
226 part = message_part_append(parse_ctx->pool, parse_ctx->part); |
0 | 227 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
228 parse_ctx->part = part; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
229 next_part = message_parse_part(input, parse_ctx); |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
230 parse_ctx->part = part->parent; |
0 | 231 |
232 /* our body size is the size of header+body in message/rfc822 */ | |
233 message_size_add_part(&part->parent->body_size, part); | |
234 } else { | |
235 /* normal message, read until the next boundary */ | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
236 part = parse_ctx->part; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
237 next_part = message_parse_body(input, parse_ctx->boundaries, |
0 | 238 &part->body_size); |
239 } | |
240 | |
241 return next_part; | |
242 } | |
243 | |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
244 MessagePart *message_parse(Pool pool, IStream *input, |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
245 MessageHeaderFunc func, void *context) |
0 | 246 { |
247 MessagePart *part; | |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
248 MessageParseContext parse_ctx; |
0 | 249 |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
250 memset(&parse_ctx, 0, sizeof(parse_ctx)); |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
251 parse_ctx.pool = pool; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
252 parse_ctx.func = func; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
253 parse_ctx.context = context; |
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
254 parse_ctx.part = part = p_new(pool, MessagePart, 1); |
0 | 255 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
256 message_parse_part(input, &parse_ctx); |
0 | 257 return part; |
258 } | |
259 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
260 /* skip over to next line increasing message size */ |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
261 static void message_skip_line(IStream *input, MessageSize *msg_size) |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
262 { |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
369
diff
changeset
|
263 const unsigned char *msg; |
184 | 264 size_t i, size, startpos; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
265 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
266 startpos = 0; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
267 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
268 while (i_stream_read_data(input, &msg, &size, startpos) > 0) { |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
269 for (i = startpos; i < size; i++) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
270 if (msg[i] == '\n') { |
153
9660df1ca44f
message_parse_header() was buggy with big headers, and io_buffer_read_data()
Timo Sirainen <tss@iki.fi>
parents:
112
diff
changeset
|
271 if (msg_size != NULL) { |
9660df1ca44f
message_parse_header() was buggy with big headers, and io_buffer_read_data()
Timo Sirainen <tss@iki.fi>
parents:
112
diff
changeset
|
272 if (i == 0 || msg[i-1] != '\r') |
9660df1ca44f
message_parse_header() was buggy with big headers, and io_buffer_read_data()
Timo Sirainen <tss@iki.fi>
parents:
112
diff
changeset
|
273 msg_size->virtual_size++; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
274 msg_size->lines++; |
153
9660df1ca44f
message_parse_header() was buggy with big headers, and io_buffer_read_data()
Timo Sirainen <tss@iki.fi>
parents:
112
diff
changeset
|
275 } |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
276 break; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
277 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
278 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
279 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
280 if (i < size) { |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
281 startpos = i+1; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
282 break; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
283 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
284 |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
285 /* leave the last character, it may be \r */ |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
286 i_stream_skip(input, i - 1); |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
287 startpos = 1; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
288 |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
289 if (msg_size != NULL) { |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
290 msg_size->physical_size += i - 1; |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
291 msg_size->virtual_size += i - 1; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
292 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
293 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
294 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
295 i_stream_skip(input, startpos); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
296 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
297 if (msg_size != NULL) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
298 msg_size->physical_size += startpos; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
299 msg_size->virtual_size += startpos; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
300 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
301 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
302 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
303 void message_parse_header(MessagePart *part, IStream *input, |
0 | 304 MessageSize *hdr_size, |
10
82b7de533f98
s/user_data/context/ and some s/Data/Context/
Timo Sirainen <tss@iki.fi>
parents:
9
diff
changeset
|
305 MessageHeaderFunc func, void *context) |
0 | 306 { |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
369
diff
changeset
|
307 const unsigned char *msg; |
513
01e94a80235d
Header parsing should always keep one character lookahead, so it can see if
Timo Sirainen <tss@iki.fi>
parents:
505
diff
changeset
|
308 size_t i, size, parse_size, startpos, missing_cr_count; |
184 | 309 size_t line_start, colon_pos, end_pos, name_len, value_len; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
310 int ret; |
0 | 311 |
312 if (hdr_size != NULL) | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
313 memset(hdr_size, 0, sizeof(MessageSize)); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
314 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
315 missing_cr_count = startpos = line_start = 0; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
316 colon_pos = UINT_MAX; |
253
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
317 for (;;) { |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
318 ret = i_stream_read_data(input, &msg, &size, startpos+1); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
319 if (ret == -2) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
320 /* overflow, line is too long. just skip it. */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
321 i_assert(size > 2); |
0 | 322 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
323 message_skip_line(input, hdr_size); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
324 startpos = line_start = 0; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
325 colon_pos = UINT_MAX; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
326 continue; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
327 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
328 |
517 | 329 if (ret < 0 || (ret <= 0 && size == startpos)) { |
330 /* EOF and nothing in buffer. the later check is | |
331 needed only when there's no message body */ | |
332 break; | |
253
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
333 } |
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
334 |
517 | 335 parse_size = size <= startpos+1 ? size : size-1; |
513
01e94a80235d
Header parsing should always keep one character lookahead, so it can see if
Timo Sirainen <tss@iki.fi>
parents:
505
diff
changeset
|
336 for (i = startpos; i < parse_size; i++) { |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
337 if (msg[i] == ':' && colon_pos == UINT_MAX) { |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
338 colon_pos = i; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
339 continue; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
340 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
341 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
342 if (msg[i] != '\n') |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
343 continue; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
344 |
0 | 345 if (hdr_size != NULL) |
346 hdr_size->lines++; | |
347 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
348 if (i == 0 || msg[i-1] != '\r') { |
0 | 349 /* missing CR */ |
350 missing_cr_count++; | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
351 } |
0 | 352 |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
353 if (i == 0 || (i == 1 && msg[i-1] == '\r')) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
354 /* no headers at all */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
355 break; |
0 | 356 } |
357 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
358 if ((i > 0 && msg[i-1] == '\n') || |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
359 (i > 1 && msg[i-2] == '\n' && msg[i-1] == '\r')) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
360 /* \n\n or \n\r\n - end of headers */ |
0 | 361 break; |
362 } | |
363 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
364 /* make sure the header doesn't continue to next line */ |
253
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
365 if (i+1 == size || !IS_LWSP(msg[i+1])) { |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
366 if (colon_pos != UINT_MAX && |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
367 colon_pos != line_start && func != NULL && |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
368 !IS_LWSP(msg[line_start])) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
369 /* we have a valid header line */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
370 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
371 /* get length of name-field */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
372 end_pos = colon_pos-1; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
373 while (end_pos > line_start && |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
374 IS_LWSP(msg[end_pos])) |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
375 end_pos--; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
376 name_len = end_pos - line_start + 1; |
0 | 377 |
169
53e8e405266b
Don't strip extra spaces after "field: ".
Timo Sirainen <tss@iki.fi>
parents:
153
diff
changeset
|
378 /* get length of value field. skip |
53e8e405266b
Don't strip extra spaces after "field: ".
Timo Sirainen <tss@iki.fi>
parents:
153
diff
changeset
|
379 only the initial LWSP after ':'. |
53e8e405266b
Don't strip extra spaces after "field: ".
Timo Sirainen <tss@iki.fi>
parents:
153
diff
changeset
|
380 some fields may want to keep |
53e8e405266b
Don't strip extra spaces after "field: ".
Timo Sirainen <tss@iki.fi>
parents:
153
diff
changeset
|
381 the extra spaces.. */ |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
382 colon_pos++; |
169
53e8e405266b
Don't strip extra spaces after "field: ".
Timo Sirainen <tss@iki.fi>
parents:
153
diff
changeset
|
383 if (colon_pos < i && |
53e8e405266b
Don't strip extra spaces after "field: ".
Timo Sirainen <tss@iki.fi>
parents:
153
diff
changeset
|
384 IS_LWSP(msg[colon_pos])) |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
385 colon_pos++; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
386 value_len = i - colon_pos; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
387 if (msg[i-1] == '\r') value_len--; |
0 | 388 |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
389 /* and finally call the function */ |
348 | 390 func(part, |
579
e524da896d92
Several minor fixes: signess, casting away const, missing static, etc.
Timo Sirainen <tss@iki.fi>
parents:
517
diff
changeset
|
391 (const char *) msg + line_start, |
e524da896d92
Several minor fixes: signess, casting away const, missing static, etc.
Timo Sirainen <tss@iki.fi>
parents:
517
diff
changeset
|
392 name_len, |
e524da896d92
Several minor fixes: signess, casting away const, missing static, etc.
Timo Sirainen <tss@iki.fi>
parents:
517
diff
changeset
|
393 (const char *) msg + colon_pos, |
e524da896d92
Several minor fixes: signess, casting away const, missing static, etc.
Timo Sirainen <tss@iki.fi>
parents:
517
diff
changeset
|
394 value_len, context); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
395 } |
0 | 396 |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
397 colon_pos = UINT_MAX; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
398 line_start = i+1; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
399 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
400 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
401 |
516
fc13fbca2fff
Header parser was still a bit wrong.
Timo Sirainen <tss@iki.fi>
parents:
513
diff
changeset
|
402 if (i < parse_size) { |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
403 /* end of header */ |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
404 startpos = i+1; |
0 | 405 break; |
406 } | |
407 | |
253
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
408 /* leave the last line to buffer */ |
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
409 if (colon_pos != UINT_MAX) |
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
410 colon_pos -= line_start; |
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
411 if (hdr_size != NULL) |
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
412 hdr_size->physical_size += line_start; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
413 i_stream_skip(input, line_start); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
414 |
253
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
415 startpos = i-line_start; |
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
416 line_start = 0; |
0 | 417 } |
253
62058959536a
message_parse_header() works now properly if there's no message body at all,
Timo Sirainen <tss@iki.fi>
parents:
232
diff
changeset
|
418 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
419 i_stream_skip(input, startpos); |
0 | 420 |
421 if (hdr_size != NULL) { | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
422 hdr_size->physical_size += startpos; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
423 hdr_size->virtual_size += |
0 | 424 hdr_size->physical_size + missing_cr_count; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
425 i_assert(hdr_size->virtual_size >= hdr_size->physical_size); |
0 | 426 } |
369
d037915978ca
message_parse_header() now calls the function with empty name/value at end
Timo Sirainen <tss@iki.fi>
parents:
348
diff
changeset
|
427 |
d037915978ca
message_parse_header() now calls the function with empty name/value at end
Timo Sirainen <tss@iki.fi>
parents:
348
diff
changeset
|
428 if (func != NULL) { |
d037915978ca
message_parse_header() now calls the function with empty name/value at end
Timo Sirainen <tss@iki.fi>
parents:
348
diff
changeset
|
429 /* "end of headers" notify */ |
d037915978ca
message_parse_header() now calls the function with empty name/value at end
Timo Sirainen <tss@iki.fi>
parents:
348
diff
changeset
|
430 func(part, "", 0, "", 0, context); |
d037915978ca
message_parse_header() now calls the function with empty name/value at end
Timo Sirainen <tss@iki.fi>
parents:
348
diff
changeset
|
431 } |
0 | 432 } |
433 | |
434 static MessageBoundary *boundary_find(MessageBoundary *boundaries, | |
184 | 435 const char *msg, size_t len) |
0 | 436 { |
437 while (boundaries != NULL) { | |
438 if (boundaries->len <= len && | |
439 strncmp(boundaries->boundary, msg, boundaries->len) == 0) | |
440 return boundaries; | |
441 | |
442 boundaries = boundaries->next; | |
443 } | |
444 | |
445 return NULL; | |
446 } | |
447 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
448 /* read until next boundary is found. if skip_over = FALSE, stop at the |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
449 [\r]\n before the boundary, otherwise leave it right after the known |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
450 boundary so the ending "--" can be checked. */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
451 static MessageBoundary * |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
452 message_find_boundary(IStream *input, MessageBoundary *boundaries, |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
453 MessageSize *msg_size, int skip_over) |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
454 { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
455 MessageBoundary *boundary; |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
369
diff
changeset
|
456 const unsigned char *msg; |
184 | 457 size_t i, size, startpos, line_start, missing_cr_count; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
458 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
459 boundary = NULL; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
460 missing_cr_count = startpos = line_start = 0; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
461 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
462 while (i_stream_read_data(input, &msg, &size, startpos) > 0) { |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
463 for (i = startpos; i < size; i++) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
464 if (msg[i] != '\n') |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
465 continue; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
466 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
467 if (i > line_start+2 && msg[line_start] == '-' && |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
468 msg[line_start+1] == '-') { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
469 /* possible boundary */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
470 boundary = boundary_find(boundaries, |
505
78ae6262d6ca
More (char *) -> (const char *) fixes
Timo Sirainen <tss@iki.fi>
parents:
410
diff
changeset
|
471 (const char *) msg + line_start + 2, |
78ae6262d6ca
More (char *) -> (const char *) fixes
Timo Sirainen <tss@iki.fi>
parents:
410
diff
changeset
|
472 i - line_start - 2); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
473 if (boundary != NULL) |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
474 break; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
475 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
476 |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
477 if (i == 0 || msg[i-1] != '\r') { |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
478 /* missing CR */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
479 missing_cr_count++; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
480 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
481 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
482 msg_size->lines++; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
483 line_start = i+1; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
484 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
485 |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
486 if (boundary != NULL) |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
487 break; |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
488 |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
489 if (i - line_start > 128 && |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
490 msg[line_start] == '-' && msg[line_start+1] == '-') { |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
491 /* long partial line, see if it's a boundary. |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
492 RFC-2046 says that the boundaries must be |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
493 70 chars without "--" or less. We allow |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
494 a bit larger.. */ |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
495 boundary = boundary_find(boundaries, |
505
78ae6262d6ca
More (char *) -> (const char *) fixes
Timo Sirainen <tss@iki.fi>
parents:
410
diff
changeset
|
496 (const char *) msg + line_start + 2, |
78ae6262d6ca
More (char *) -> (const char *) fixes
Timo Sirainen <tss@iki.fi>
parents:
410
diff
changeset
|
497 i - line_start - 2); |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
498 if (boundary != NULL) |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
499 break; |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
500 |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
501 /* nope, we can skip over the line, just |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
502 leave the last char since it may be \r */ |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
503 i--; |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
504 } else { |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
505 /* leave the last line to buffer, it may be |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
506 boundary */ |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
507 i = line_start; |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
508 if (i > 2) i -= 2; /* leave the \r\n too */ |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
509 line_start -= i; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
510 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
511 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
512 i_stream_skip(input, i); |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
513 msg_size->physical_size += i; |
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
514 msg_size->virtual_size += i; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
515 |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
516 startpos = size - i; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
517 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
518 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
519 if (boundary != NULL) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
520 if (skip_over) { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
521 /* leave the pointer right after the boundary */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
522 line_start += 2 + boundary->len; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
523 } else if (line_start > 0 && msg[line_start-1] == '\n') { |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
524 /* leave the \r\n before the boundary */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
525 line_start--; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
526 msg_size->lines--; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
527 |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
528 if (line_start > 0 && msg[line_start-1] == '\r') |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
529 line_start--; |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
530 else |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
531 missing_cr_count--; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
532 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
533 startpos = line_start; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
534 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
535 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
536 i_stream_skip(input, startpos); |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
537 msg_size->physical_size += startpos; |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
538 msg_size->virtual_size += startpos + missing_cr_count; |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
539 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
540 i_assert(msg_size->virtual_size >= msg_size->physical_size); |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
541 |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
542 return boundary; |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
543 } |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
544 |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
545 static MessagePart *message_parse_body(IStream *input, |
0 | 546 MessageBoundary *boundaries, |
547 MessageSize *body_size) | |
548 { | |
549 MessageBoundary *boundary; | |
550 | |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
551 if (boundaries == NULL) { |
856
e49f7397af98
Some bugfixes and speedups for partial fetch handling.
Timo Sirainen <tss@iki.fi>
parents:
765
diff
changeset
|
552 message_get_body_size(input, body_size, (uoff_t)-1, NULL); |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
553 return NULL; |
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
554 } else { |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
555 boundary = message_find_boundary(input, boundaries, |
9
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
556 body_size, FALSE); |
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
557 return boundary == NULL ? NULL : boundary->part; |
21c8e080150d
fixes, seems to be somewhat working now.
Timo Sirainen <tss@iki.fi>
parents:
7
diff
changeset
|
558 } |
0 | 559 } |
560 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
561 /* skip data until next boundary is found. if it's end boundary, |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
562 skip the footer as well. */ |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
563 static MessagePart *message_skip_boundary(IStream *input, |
0 | 564 MessageBoundary *boundaries, |
565 MessageSize *boundary_size) | |
566 { | |
567 MessageBoundary *boundary; | |
410
1f0e7229ee58
Split IOBuffer into mmaped IBuffer, file IBuffer, memory data IBuffer and
Timo Sirainen <tss@iki.fi>
parents:
369
diff
changeset
|
568 const unsigned char *msg; |
184 | 569 size_t size; |
0 | 570 int end_boundary; |
571 | |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
572 boundary = message_find_boundary(input, boundaries, |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
573 boundary_size, TRUE); |
0 | 574 if (boundary == NULL) |
575 return NULL; | |
576 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
577 /* now, see if it's end boundary */ |
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
578 end_boundary = FALSE; |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
579 if (i_stream_read_data(input, &msg, &size, 1) > 0) |
232
9277e893304e
s/io_buffer_read_data/io_buffer_read_data_blocking/ and fixed the various
Timo Sirainen <tss@iki.fi>
parents:
212
diff
changeset
|
580 end_boundary = msg[0] == '-' && msg[1] == '-'; |
0 | 581 |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
582 /* skip the rest of the line */ |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
583 message_skip_line(input, boundary_size); |
0 | 584 |
585 if (end_boundary) { | |
586 /* skip the footer */ | |
764
f57c52738f90
Renamed IBuffer and OBuffer to IStream and OStream which describes their
Timo Sirainen <tss@iki.fi>
parents:
579
diff
changeset
|
587 return message_parse_body(input, boundaries, boundary_size); |
0 | 588 } |
589 | |
5
1b34ec11fff8
Message data is parsed in blocks (no longer entirely mmap()ed). Several
Timo Sirainen <tss@iki.fi>
parents:
0
diff
changeset
|
590 return boundary == NULL ? NULL : boundary->part; |
0 | 591 } |