PageRenderTime 47ms CodeModel.GetById 15ms app.highlight 26ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/llmessage/tests/llmime_test.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 445 lines | 322 code | 38 blank | 85 comment | 0 complexity | 9e7f90c98a196c71011da1380a2d643a MD5 | raw file
  1/** 
  2 * @file llmime_test.cpp
  3 * @author Phoenix
  4 * @date 2006-12-24
  5 * @brief BRIEF_DESC of llmime_test.cpp
  6 *
  7 * $LicenseInfo:firstyear=2006&license=viewerlgpl$
  8 * Second Life Viewer Source Code
  9 * Copyright (C) 2010, Linden Research, Inc.
 10 * 
 11 * This library is free software; you can redistribute it and/or
 12 * modify it under the terms of the GNU Lesser General Public
 13 * License as published by the Free Software Foundation;
 14 * version 2.1 of the License only.
 15 * 
 16 * This library is distributed in the hope that it will be useful,
 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 19 * Lesser General Public License for more details.
 20 * 
 21 * You should have received a copy of the GNU Lesser General Public
 22 * License along with this library; if not, write to the Free Software
 23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 24 * 
 25 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 26 * $/LicenseInfo$
 27 */
 28
 29#include "linden_common.h"
 30
 31#include "llsdserialize.h"
 32
 33#include "../llmime.h"
 34
 35#include "../test/lltut.h"
 36
 37namespace tut
 38{
 39	struct mime_index
 40	{
 41	};
 42	typedef test_group<mime_index> mime_index_t;
 43	typedef mime_index_t::object mime_index_object_t;
 44	tut::mime_index_t tut_mime_index("LLMime");
 45
 46	template<> template<>
 47	void mime_index_object_t::test<1>()
 48	{
 49		LLMimeIndex mime;
 50		ensure("no headers", mime.headers().isUndefined());
 51		ensure_equals("invalid offset", mime.offset(), -1);
 52		ensure_equals("invalid content length", mime.contentLength(), -1);
 53		ensure("no content type", mime.contentType().empty());
 54		ensure("not multipart", !mime.isMultipart());
 55		ensure_equals("no attachments", mime.subPartCount(), 0);
 56	}
 57
 58	template<> template<>
 59	void mime_index_object_t::test<2>()
 60	{
 61		const S32 CONTENT_LENGTH = 6000;
 62		const S32 CONTENT_OFFSET = 100;
 63		const std::string CONTENT_TYPE = std::string("image/j2c");
 64		LLSD headers;
 65		headers["Content-Length"] = CONTENT_LENGTH;
 66		headers["Content-Type"] = CONTENT_TYPE;
 67		LLMimeIndex mime(headers, CONTENT_OFFSET);
 68		ensure("headers are map", mime.headers().isMap());
 69		ensure_equals("offset", mime.offset(), CONTENT_OFFSET);
 70		ensure_equals("content length", mime.contentLength(), CONTENT_LENGTH);
 71		ensure_equals("type is image/j2c", mime.contentType(), CONTENT_TYPE);
 72		ensure("not multipart", !mime.isMultipart());
 73		ensure_equals("no attachments", mime.subPartCount(), 0);
 74	}
 75
 76	template<> template<>
 77	void mime_index_object_t::test<3>()
 78	{
 79		const S32 MULTI_CONTENT_LENGTH = 8000;
 80		const S32 MULTI_CONTENT_OFFSET = 100;
 81		const std::string MULTI_CONTENT_TYPE = std::string("multipart/mixed");
 82		LLSD headers;
 83		headers["Content-Length"] = MULTI_CONTENT_LENGTH;
 84		headers["Content-Type"] = MULTI_CONTENT_TYPE;
 85		LLMimeIndex mime(headers, MULTI_CONTENT_OFFSET);
 86		llinfos << "headers: " << LLSDOStreamer<LLSDNotationFormatter>(headers)
 87			<< llendl;
 88
 89
 90		const S32 META_CONTENT_LENGTH = 700;
 91		const S32 META_CONTENT_OFFSET = 69;
 92		const std::string META_CONTENT_TYPE = std::string(
 93			"text/llsd+xml");
 94		headers = LLSD::emptyMap();
 95		headers["Content-Length"] = META_CONTENT_LENGTH;
 96		headers["Content-Type"] = META_CONTENT_TYPE;
 97		LLMimeIndex meta(headers, META_CONTENT_OFFSET);
 98		mime.attachSubPart(meta);
 99
100		const S32 IMAGE_CONTENT_LENGTH = 6000;
101		const S32 IMAGE_CONTENT_OFFSET = 200;
102		const std::string IMAGE_CONTENT_TYPE = std::string("image/j2c");
103		headers = LLSD::emptyMap();
104		headers["Content-Length"] = IMAGE_CONTENT_LENGTH;
105		headers["Content-Type"] = IMAGE_CONTENT_TYPE;
106		LLMimeIndex image(headers, IMAGE_CONTENT_OFFSET);
107		mime.attachSubPart(image);
108
109		// make sure we have a valid multi-part
110		ensure("is multipart", mime.isMultipart());
111		ensure_equals("multi offset", mime.offset(), MULTI_CONTENT_OFFSET);
112		ensure_equals(
113			"multi content length",
114			mime.contentLength(),
115			MULTI_CONTENT_LENGTH);
116		ensure_equals("two attachments", mime.subPartCount(), 2);
117
118		// make sure ranged gets do the right thing with out of bounds
119		// sub-parts.
120		LLMimeIndex invalid_child(mime.subPart(-1));
121		ensure("no headers", invalid_child.headers().isUndefined());
122		ensure_equals("invalid offset", invalid_child.offset(), -1);
123		ensure_equals(
124			"invalid content length", invalid_child.contentLength(), -1);
125		ensure("no content type", invalid_child.contentType().empty());
126		ensure("not multipart", !invalid_child.isMultipart());
127		ensure_equals("no attachments", invalid_child.subPartCount(), 0);
128
129		invalid_child = mime.subPart(2);
130		ensure("no headers", invalid_child.headers().isUndefined());
131		ensure_equals("invalid offset", invalid_child.offset(), -1);
132		ensure_equals(
133			"invalid content length", invalid_child.contentLength(), -1);
134		ensure("no content type", invalid_child.contentType().empty());
135		ensure("not multipart", !invalid_child.isMultipart());
136		ensure_equals("no attachments", invalid_child.subPartCount(), 0);
137	}
138
139	template<> template<>
140	void mime_index_object_t::test<4>()
141	{
142		const S32 MULTI_CONTENT_LENGTH = 8000;
143		const S32 MULTI_CONTENT_OFFSET = 100;
144		const std::string MULTI_CONTENT_TYPE = std::string("multipart/mixed");
145		LLSD headers;
146		headers["Content-Length"] = MULTI_CONTENT_LENGTH;
147		headers["Content-Type"] = MULTI_CONTENT_TYPE;
148		LLMimeIndex mime(headers, MULTI_CONTENT_OFFSET);
149
150		const S32 META_CONTENT_LENGTH = 700;
151		const S32 META_CONTENT_OFFSET = 69;
152		const std::string META_CONTENT_TYPE = std::string(
153			"application/llsd+xml");
154		headers = LLSD::emptyMap();
155		headers["Content-Length"] = META_CONTENT_LENGTH;
156		headers["Content-Type"] = META_CONTENT_TYPE;
157		LLMimeIndex meta(headers, META_CONTENT_OFFSET);
158		mime.attachSubPart(meta);
159
160		const S32 IMAGE_CONTENT_LENGTH = 6000;
161		const S32 IMAGE_CONTENT_OFFSET = 200;
162		const std::string IMAGE_CONTENT_TYPE = std::string("image/j2c");
163		headers = LLSD::emptyMap();
164		headers["Content-Length"] = IMAGE_CONTENT_LENGTH;
165		headers["Content-Type"] = IMAGE_CONTENT_TYPE;
166		LLMimeIndex image(headers, IMAGE_CONTENT_OFFSET);
167		mime.attachSubPart(image);
168
169		// check what we have
170		ensure("is multipart", mime.isMultipart());
171		ensure_equals("multi offset", mime.offset(), MULTI_CONTENT_OFFSET);
172		ensure_equals(
173			"multi content length",
174			mime.contentLength(),
175			MULTI_CONTENT_LENGTH);
176		ensure_equals("two attachments", mime.subPartCount(), 2);
177
178		LLMimeIndex actual_meta = mime.subPart(0);
179		ensure_equals(
180			"meta type", actual_meta.contentType(), META_CONTENT_TYPE);
181		ensure_equals(
182			"meta offset", actual_meta.offset(), META_CONTENT_OFFSET);
183		ensure_equals(
184			"meta content length",
185			actual_meta.contentLength(),
186			META_CONTENT_LENGTH);
187
188		LLMimeIndex actual_image = mime.subPart(1);
189		ensure_equals(
190			"image type", actual_image.contentType(), IMAGE_CONTENT_TYPE);
191		ensure_equals(
192			"image offset", actual_image.offset(), IMAGE_CONTENT_OFFSET);
193		ensure_equals(
194			"image content length",
195			actual_image.contentLength(),
196			IMAGE_CONTENT_LENGTH);
197	}
198
199/*
200	template<> template<>
201	void mime_index_object_t::test<5>()
202	{
203	}
204	template<> template<>
205	void mime_index_object_t::test<6>()
206	{
207	}
208	template<> template<>
209	void mime_index_object_t::test<7>()
210	{
211	}
212	template<> template<>
213	void mime_index_object_t::test<8>()
214	{
215	}
216	template<> template<>
217	void mime_index_object_t::test<>()
218	{
219	}
220*/
221}
222
223
224namespace tut
225{
226	struct mime_parse
227	{
228	};
229	typedef test_group<mime_parse> mime_parse_t;
230	typedef mime_parse_t::object mime_parse_object_t;
231	tut::mime_parse_t tut_mime_parse("LLMimeParse");
232
233	template<> template<>
234	void mime_parse_object_t::test<1>()
235	{
236		// parse one mime object
237		const std::string SERIALIZED_MIME("Content-Length: 200\r\nContent-Type: text/plain\r\n\r\naaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccc\r\n");
238		std::stringstream istr;
239		istr.str(SERIALIZED_MIME);
240		LLMimeIndex mime;
241		LLMimeParser parser;
242		bool ok = parser.parseIndex(istr, mime);
243		ensure("Parse successful.", ok);
244		ensure_equals("content type", mime.contentType(), "text/plain");
245		ensure_equals("content length", mime.contentLength(), 200);
246		ensure_equals("offset", mime.offset(), 49);
247 	}
248
249	template<> template<>
250	void mime_parse_object_t::test<2>()
251	{
252		// make sure we only parse one.
253		const std::string SERIALIZED_MIME("Content-Length: 200\r\nContent-Type: text/plain\r\n\r\naaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccc\r\n\r\nContent-Length: 200\r\nContent-Type: text/plain\r\n\r\naaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccc\r\n\r\n");
254		std::stringstream istr;
255		istr.str(SERIALIZED_MIME);
256		LLMimeIndex mime;
257		LLMimeParser parser;
258		bool ok = parser.parseIndex(istr, mime);
259		ensure("Parse successful.", ok);
260		ensure("not multipart.", !mime.isMultipart());
261		ensure_equals("content type", mime.contentType(), "text/plain");
262		ensure_equals("content length", mime.contentLength(), 200);
263		ensure_equals("offset", mime.offset(), 49);
264	}
265
266	template<> template<>
267	void mime_parse_object_t::test<3>()
268	{
269		// test multi-part and lack of content length for some of it.
270		/*
271Content-Type: multipart/mixed; boundary="segment"rnContent-Length: 148rnrn--segmentrnContent-Type: text/plainrnrnsome datarnrn--segmentrnContent-Type: text/xml; charset=UTF-8rnContent-Length: 22rnrn<llsd><undef /></llsd>rnrn
272		 */
273		const std::string SERIALIZED_MIME("Content-Type: multipart/mixed; boundary=\"segment\"\r\nContent-Length: 150\r\n\r\n--segment\r\nContent-Type: text/plain\r\n\r\nsome data\r\n\r\n--segment\r\nContent-Type: text/xml; charset=UTF-8\r\nContent-Length: 22\r\n\r\n<llsd><undef /></llsd>\r\n\r\n");
274		std::stringstream istr;
275		istr.str(SERIALIZED_MIME);
276		LLMimeIndex mime;
277		LLMimeParser parser;
278		bool ok = parser.parseIndex(istr, mime);
279		ensure("Parse successful.", ok);
280		ensure("is multipart.", mime.isMultipart());
281		ensure_equals("sub-part count", mime.subPartCount(), 2);
282		ensure_equals("content length", mime.contentLength(), 150);
283		ensure_equals("data offset for multipart", mime.offset(), 74);
284
285		LLMimeIndex mime_plain(mime.subPart(0));
286		ensure_equals(
287			"first part type",
288			mime_plain.contentType(),
289			"text/plain");
290		ensure_equals(
291			"first part content length not known.",
292			mime_plain.contentLength(),
293			-1);
294		ensure_equals("first part offset", mime_plain.offset(), 113);
295
296		LLMimeIndex mime_xml(mime.subPart(1));
297		ensure_equals(
298			"second part type",
299			mime_xml.contentType(),
300			"text/xml; charset=UTF-8");
301		ensure_equals(
302			"second part content length",
303			mime_xml.contentLength(),
304			22);
305		ensure_equals("second part offset", mime_xml.offset(), 198);
306	}
307
308	template<> template<>
309	void mime_parse_object_t::test<4>()
310	{
311		// test multi-part, unquoted separator, and premature eof conditions
312		/*
313Content-Type: multipart/mixed; boundary=segmentrnContent-Length: 220rnrn--segmentrnContent-Type: text/plainrnContent-Length: 55rnrnhow are you today?rnI do not know. I guess I am:n'fine'rnrn--segmentrnContent-Type: text/xml; charset=UTF-8rnContent-Length: 22rnrn<llsd><undef /></llsd>rnrn		 */
314		const std::string SERIALIZED_MIME("Content-Type: multipart/mixed; boundary=segment\r\nContent-Length: 220\r\n\r\n--segment\r\nContent-Type: text/plain\r\nContent-Length: 55\r\n\r\nhow are you today?\r\nI do not know. I guess I am:\n'fine'\r\n\r\n--segment\r\nContent-Type: text/xml; charset=UTF-8\r\nContent-Length: 22\r\n\r\n<llsd><undef /></llsd>\r\n\r\n");
315		std::stringstream istr;
316		istr.str(SERIALIZED_MIME);
317		LLMimeIndex mime;
318		LLMimeParser parser;
319		bool ok = parser.parseIndex(istr, mime);
320		ensure("Parse successful.", ok);
321		ensure("is multipart.", mime.isMultipart());
322		ensure_equals("sub-part count", mime.subPartCount(), 2);
323		ensure_equals("content length", mime.contentLength(), 220);
324		ensure_equals("data offset for multipart", mime.offset(), 72);
325
326		LLMimeIndex mime_plain(mime.subPart(0));
327		ensure_equals(
328			"first part type",
329			mime_plain.contentType(),
330			"text/plain");
331		ensure_equals(
332			"first part content length",
333			mime_plain.contentLength(),
334			55);
335		ensure_equals("first part offset", mime_plain.offset(), 131);
336
337		LLMimeIndex mime_xml(mime.subPart(1));
338		ensure_equals(
339			"second part type",
340			mime_xml.contentType(),
341			"text/xml; charset=UTF-8");
342		ensure_equals(
343			"second part content length",
344			mime_xml.contentLength(),
345			22);
346		ensure_equals("second part offset", mime_xml.offset(), 262);
347	}
348
349	template<> template<>
350	void mime_parse_object_t::test<5>()
351	{
352		// test multi-part with multiple params
353		const std::string SERIALIZED_MIME("Content-Type: multipart/mixed; boundary=segment; comment=\"testing multiple params.\"\r\nContent-Length: 220\r\n\r\n--segment\r\nContent-Type: text/plain\r\nContent-Length: 55\r\n\r\nhow are you today?\r\nI do not know. I guess I am:\n'fine'\r\n\r\n--segment\r\nContent-Type: text/xml; charset=UTF-8\r\nContent-Length: 22\r\n\r\n<llsd><undef /></llsd>\r\n\r\n");
354		std::stringstream istr;
355		istr.str(SERIALIZED_MIME);
356		LLMimeIndex mime;
357		LLMimeParser parser;
358		bool ok = parser.parseIndex(istr, mime);
359		ensure("Parse successful.", ok);
360		ensure("is multipart.", mime.isMultipart());
361		ensure_equals("sub-part count", mime.subPartCount(), 2);
362		ensure_equals("content length", mime.contentLength(), 220);
363
364		LLMimeIndex mime_plain(mime.subPart(0));
365		ensure_equals(
366			"first part type",
367			mime_plain.contentType(),
368			"text/plain");
369		ensure_equals(
370			"first part content length",
371			mime_plain.contentLength(),
372			55);
373
374		LLMimeIndex mime_xml(mime.subPart(1));
375		ensure_equals(
376			"second part type",
377			mime_xml.contentType(),
378			"text/xml; charset=UTF-8");
379		ensure_equals(
380			"second part content length",
381			mime_xml.contentLength(),
382			22);
383	}
384
385	template<> template<>
386	void mime_parse_object_t::test<6>()
387	{
388		// test multi-part with no specified boundary and eof
389/*
390Content-Type: multipart/relatedrnContent-Length: 220rnrn--rnContent-Type: text/plainrnContent-Length: 55rnrnhow are you today?rnI do not know. I guess I am:n'fine'rnrn--rnContent-Type: text/xml; charset=UTF-8rnContent-Length: 22rnrn<llsd><undef /></llsd>rnrn
391*/
392		const std::string SERIALIZED_MIME("Content-Type: multipart/related\r\nContent-Length: 500\r\n\r\n--\r\nContent-Type: text/plain\r\nContent-Length: 55\r\n\r\nhow are you today?\r\nI do not know. I guess I am:\n'fine'\r\n\r\n--\r\nContent-Type: text/xml; charset=UTF-8\r\nContent-Length: 22\r\n\r\n<llsd><undef /></llsd>\r\n\r\n");
393		std::stringstream istr;
394		istr.str(SERIALIZED_MIME);
395		LLMimeIndex mime;
396		LLMimeParser parser;
397		bool ok = parser.parseIndex(istr, mime);
398		ensure("Parse successful.", ok);
399		ensure("is multipart.", mime.isMultipart());
400		ensure_equals("sub-part count", mime.subPartCount(), 2);
401		ensure_equals("content length", mime.contentLength(), 500);
402		ensure_equals("data offset for multipart", mime.offset(), 56);
403
404		LLMimeIndex mime_plain(mime.subPart(0));
405		ensure_equals(
406			"first part type",
407			mime_plain.contentType(),
408			"text/plain");
409		ensure_equals(
410			"first part content length",
411			mime_plain.contentLength(),
412			55);
413		ensure_equals("first part offset", mime_plain.offset(), 108);
414
415		LLMimeIndex mime_xml(mime.subPart(1));
416		ensure_equals(
417			"second part type",
418			mime_xml.contentType(),
419			"text/xml; charset=UTF-8");
420		ensure_equals(
421			"second part content length",
422			mime_xml.contentLength(),
423			22);
424		ensure_equals("second part offset", mime_xml.offset(), 232);
425	}
426
427/*
428	template<> template<>
429	void mime_parse_object_t::test<>()
430	{
431	}
432	template<> template<>
433	void mime_parse_object_t::test<>()
434	{
435	}
436	template<> template<>
437	void mime_parse_object_t::test<>()
438	{
439	}
440	template<> template<>
441	void mime_parse_object_t::test<>()
442	{
443	}
444*/
445}