PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/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
Possible License(s): LGPL-2.1
  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. #include "linden_common.h"
  29. #include "llsdserialize.h"
  30. #include "../llmime.h"
  31. #include "../test/lltut.h"
  32. namespace tut
  33. {
  34. struct mime_index
  35. {
  36. };
  37. typedef test_group<mime_index> mime_index_t;
  38. typedef mime_index_t::object mime_index_object_t;
  39. tut::mime_index_t tut_mime_index("LLMime");
  40. template<> template<>
  41. void mime_index_object_t::test<1>()
  42. {
  43. LLMimeIndex mime;
  44. ensure("no headers", mime.headers().isUndefined());
  45. ensure_equals("invalid offset", mime.offset(), -1);
  46. ensure_equals("invalid content length", mime.contentLength(), -1);
  47. ensure("no content type", mime.contentType().empty());
  48. ensure("not multipart", !mime.isMultipart());
  49. ensure_equals("no attachments", mime.subPartCount(), 0);
  50. }
  51. template<> template<>
  52. void mime_index_object_t::test<2>()
  53. {
  54. const S32 CONTENT_LENGTH = 6000;
  55. const S32 CONTENT_OFFSET = 100;
  56. const std::string CONTENT_TYPE = std::string("image/j2c");
  57. LLSD headers;
  58. headers["Content-Length"] = CONTENT_LENGTH;
  59. headers["Content-Type"] = CONTENT_TYPE;
  60. LLMimeIndex mime(headers, CONTENT_OFFSET);
  61. ensure("headers are map", mime.headers().isMap());
  62. ensure_equals("offset", mime.offset(), CONTENT_OFFSET);
  63. ensure_equals("content length", mime.contentLength(), CONTENT_LENGTH);
  64. ensure_equals("type is image/j2c", mime.contentType(), CONTENT_TYPE);
  65. ensure("not multipart", !mime.isMultipart());
  66. ensure_equals("no attachments", mime.subPartCount(), 0);
  67. }
  68. template<> template<>
  69. void mime_index_object_t::test<3>()
  70. {
  71. const S32 MULTI_CONTENT_LENGTH = 8000;
  72. const S32 MULTI_CONTENT_OFFSET = 100;
  73. const std::string MULTI_CONTENT_TYPE = std::string("multipart/mixed");
  74. LLSD headers;
  75. headers["Content-Length"] = MULTI_CONTENT_LENGTH;
  76. headers["Content-Type"] = MULTI_CONTENT_TYPE;
  77. LLMimeIndex mime(headers, MULTI_CONTENT_OFFSET);
  78. llinfos << "headers: " << LLSDOStreamer<LLSDNotationFormatter>(headers)
  79. << llendl;
  80. const S32 META_CONTENT_LENGTH = 700;
  81. const S32 META_CONTENT_OFFSET = 69;
  82. const std::string META_CONTENT_TYPE = std::string(
  83. "text/llsd+xml");
  84. headers = LLSD::emptyMap();
  85. headers["Content-Length"] = META_CONTENT_LENGTH;
  86. headers["Content-Type"] = META_CONTENT_TYPE;
  87. LLMimeIndex meta(headers, META_CONTENT_OFFSET);
  88. mime.attachSubPart(meta);
  89. const S32 IMAGE_CONTENT_LENGTH = 6000;
  90. const S32 IMAGE_CONTENT_OFFSET = 200;
  91. const std::string IMAGE_CONTENT_TYPE = std::string("image/j2c");
  92. headers = LLSD::emptyMap();
  93. headers["Content-Length"] = IMAGE_CONTENT_LENGTH;
  94. headers["Content-Type"] = IMAGE_CONTENT_TYPE;
  95. LLMimeIndex image(headers, IMAGE_CONTENT_OFFSET);
  96. mime.attachSubPart(image);
  97. // make sure we have a valid multi-part
  98. ensure("is multipart", mime.isMultipart());
  99. ensure_equals("multi offset", mime.offset(), MULTI_CONTENT_OFFSET);
  100. ensure_equals(
  101. "multi content length",
  102. mime.contentLength(),
  103. MULTI_CONTENT_LENGTH);
  104. ensure_equals("two attachments", mime.subPartCount(), 2);
  105. // make sure ranged gets do the right thing with out of bounds
  106. // sub-parts.
  107. LLMimeIndex invalid_child(mime.subPart(-1));
  108. ensure("no headers", invalid_child.headers().isUndefined());
  109. ensure_equals("invalid offset", invalid_child.offset(), -1);
  110. ensure_equals(
  111. "invalid content length", invalid_child.contentLength(), -1);
  112. ensure("no content type", invalid_child.contentType().empty());
  113. ensure("not multipart", !invalid_child.isMultipart());
  114. ensure_equals("no attachments", invalid_child.subPartCount(), 0);
  115. invalid_child = mime.subPart(2);
  116. ensure("no headers", invalid_child.headers().isUndefined());
  117. ensure_equals("invalid offset", invalid_child.offset(), -1);
  118. ensure_equals(
  119. "invalid content length", invalid_child.contentLength(), -1);
  120. ensure("no content type", invalid_child.contentType().empty());
  121. ensure("not multipart", !invalid_child.isMultipart());
  122. ensure_equals("no attachments", invalid_child.subPartCount(), 0);
  123. }
  124. template<> template<>
  125. void mime_index_object_t::test<4>()
  126. {
  127. const S32 MULTI_CONTENT_LENGTH = 8000;
  128. const S32 MULTI_CONTENT_OFFSET = 100;
  129. const std::string MULTI_CONTENT_TYPE = std::string("multipart/mixed");
  130. LLSD headers;
  131. headers["Content-Length"] = MULTI_CONTENT_LENGTH;
  132. headers["Content-Type"] = MULTI_CONTENT_TYPE;
  133. LLMimeIndex mime(headers, MULTI_CONTENT_OFFSET);
  134. const S32 META_CONTENT_LENGTH = 700;
  135. const S32 META_CONTENT_OFFSET = 69;
  136. const std::string META_CONTENT_TYPE = std::string(
  137. "application/llsd+xml");
  138. headers = LLSD::emptyMap();
  139. headers["Content-Length"] = META_CONTENT_LENGTH;
  140. headers["Content-Type"] = META_CONTENT_TYPE;
  141. LLMimeIndex meta(headers, META_CONTENT_OFFSET);
  142. mime.attachSubPart(meta);
  143. const S32 IMAGE_CONTENT_LENGTH = 6000;
  144. const S32 IMAGE_CONTENT_OFFSET = 200;
  145. const std::string IMAGE_CONTENT_TYPE = std::string("image/j2c");
  146. headers = LLSD::emptyMap();
  147. headers["Content-Length"] = IMAGE_CONTENT_LENGTH;
  148. headers["Content-Type"] = IMAGE_CONTENT_TYPE;
  149. LLMimeIndex image(headers, IMAGE_CONTENT_OFFSET);
  150. mime.attachSubPart(image);
  151. // check what we have
  152. ensure("is multipart", mime.isMultipart());
  153. ensure_equals("multi offset", mime.offset(), MULTI_CONTENT_OFFSET);
  154. ensure_equals(
  155. "multi content length",
  156. mime.contentLength(),
  157. MULTI_CONTENT_LENGTH);
  158. ensure_equals("two attachments", mime.subPartCount(), 2);
  159. LLMimeIndex actual_meta = mime.subPart(0);
  160. ensure_equals(
  161. "meta type", actual_meta.contentType(), META_CONTENT_TYPE);
  162. ensure_equals(
  163. "meta offset", actual_meta.offset(), META_CONTENT_OFFSET);
  164. ensure_equals(
  165. "meta content length",
  166. actual_meta.contentLength(),
  167. META_CONTENT_LENGTH);
  168. LLMimeIndex actual_image = mime.subPart(1);
  169. ensure_equals(
  170. "image type", actual_image.contentType(), IMAGE_CONTENT_TYPE);
  171. ensure_equals(
  172. "image offset", actual_image.offset(), IMAGE_CONTENT_OFFSET);
  173. ensure_equals(
  174. "image content length",
  175. actual_image.contentLength(),
  176. IMAGE_CONTENT_LENGTH);
  177. }
  178. /*
  179. template<> template<>
  180. void mime_index_object_t::test<5>()
  181. {
  182. }
  183. template<> template<>
  184. void mime_index_object_t::test<6>()
  185. {
  186. }
  187. template<> template<>
  188. void mime_index_object_t::test<7>()
  189. {
  190. }
  191. template<> template<>
  192. void mime_index_object_t::test<8>()
  193. {
  194. }
  195. template<> template<>
  196. void mime_index_object_t::test<>()
  197. {
  198. }
  199. */
  200. }
  201. namespace tut
  202. {
  203. struct mime_parse
  204. {
  205. };
  206. typedef test_group<mime_parse> mime_parse_t;
  207. typedef mime_parse_t::object mime_parse_object_t;
  208. tut::mime_parse_t tut_mime_parse("LLMimeParse");
  209. template<> template<>
  210. void mime_parse_object_t::test<1>()
  211. {
  212. // parse one mime object
  213. const std::string SERIALIZED_MIME("Content-Length: 200\r\nContent-Type: text/plain\r\n\r\naaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccc\r\n");
  214. std::stringstream istr;
  215. istr.str(SERIALIZED_MIME);
  216. LLMimeIndex mime;
  217. LLMimeParser parser;
  218. bool ok = parser.parseIndex(istr, mime);
  219. ensure("Parse successful.", ok);
  220. ensure_equals("content type", mime.contentType(), "text/plain");
  221. ensure_equals("content length", mime.contentLength(), 200);
  222. ensure_equals("offset", mime.offset(), 49);
  223. }
  224. template<> template<>
  225. void mime_parse_object_t::test<2>()
  226. {
  227. // make sure we only parse one.
  228. 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");
  229. std::stringstream istr;
  230. istr.str(SERIALIZED_MIME);
  231. LLMimeIndex mime;
  232. LLMimeParser parser;
  233. bool ok = parser.parseIndex(istr, mime);
  234. ensure("Parse successful.", ok);
  235. ensure("not multipart.", !mime.isMultipart());
  236. ensure_equals("content type", mime.contentType(), "text/plain");
  237. ensure_equals("content length", mime.contentLength(), 200);
  238. ensure_equals("offset", mime.offset(), 49);
  239. }
  240. template<> template<>
  241. void mime_parse_object_t::test<3>()
  242. {
  243. // test multi-part and lack of content length for some of it.
  244. /*
  245. Content-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
  246. */
  247. 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");
  248. std::stringstream istr;
  249. istr.str(SERIALIZED_MIME);
  250. LLMimeIndex mime;
  251. LLMimeParser parser;
  252. bool ok = parser.parseIndex(istr, mime);
  253. ensure("Parse successful.", ok);
  254. ensure("is multipart.", mime.isMultipart());
  255. ensure_equals("sub-part count", mime.subPartCount(), 2);
  256. ensure_equals("content length", mime.contentLength(), 150);
  257. ensure_equals("data offset for multipart", mime.offset(), 74);
  258. LLMimeIndex mime_plain(mime.subPart(0));
  259. ensure_equals(
  260. "first part type",
  261. mime_plain.contentType(),
  262. "text/plain");
  263. ensure_equals(
  264. "first part content length not known.",
  265. mime_plain.contentLength(),
  266. -1);
  267. ensure_equals("first part offset", mime_plain.offset(), 113);
  268. LLMimeIndex mime_xml(mime.subPart(1));
  269. ensure_equals(
  270. "second part type",
  271. mime_xml.contentType(),
  272. "text/xml; charset=UTF-8");
  273. ensure_equals(
  274. "second part content length",
  275. mime_xml.contentLength(),
  276. 22);
  277. ensure_equals("second part offset", mime_xml.offset(), 198);
  278. }
  279. template<> template<>
  280. void mime_parse_object_t::test<4>()
  281. {
  282. // test multi-part, unquoted separator, and premature eof conditions
  283. /*
  284. Content-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 */
  285. 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");
  286. std::stringstream istr;
  287. istr.str(SERIALIZED_MIME);
  288. LLMimeIndex mime;
  289. LLMimeParser parser;
  290. bool ok = parser.parseIndex(istr, mime);
  291. ensure("Parse successful.", ok);
  292. ensure("is multipart.", mime.isMultipart());
  293. ensure_equals("sub-part count", mime.subPartCount(), 2);
  294. ensure_equals("content length", mime.contentLength(), 220);
  295. ensure_equals("data offset for multipart", mime.offset(), 72);
  296. LLMimeIndex mime_plain(mime.subPart(0));
  297. ensure_equals(
  298. "first part type",
  299. mime_plain.contentType(),
  300. "text/plain");
  301. ensure_equals(
  302. "first part content length",
  303. mime_plain.contentLength(),
  304. 55);
  305. ensure_equals("first part offset", mime_plain.offset(), 131);
  306. LLMimeIndex mime_xml(mime.subPart(1));
  307. ensure_equals(
  308. "second part type",
  309. mime_xml.contentType(),
  310. "text/xml; charset=UTF-8");
  311. ensure_equals(
  312. "second part content length",
  313. mime_xml.contentLength(),
  314. 22);
  315. ensure_equals("second part offset", mime_xml.offset(), 262);
  316. }
  317. template<> template<>
  318. void mime_parse_object_t::test<5>()
  319. {
  320. // test multi-part with multiple params
  321. 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");
  322. std::stringstream istr;
  323. istr.str(SERIALIZED_MIME);
  324. LLMimeIndex mime;
  325. LLMimeParser parser;
  326. bool ok = parser.parseIndex(istr, mime);
  327. ensure("Parse successful.", ok);
  328. ensure("is multipart.", mime.isMultipart());
  329. ensure_equals("sub-part count", mime.subPartCount(), 2);
  330. ensure_equals("content length", mime.contentLength(), 220);
  331. LLMimeIndex mime_plain(mime.subPart(0));
  332. ensure_equals(
  333. "first part type",
  334. mime_plain.contentType(),
  335. "text/plain");
  336. ensure_equals(
  337. "first part content length",
  338. mime_plain.contentLength(),
  339. 55);
  340. LLMimeIndex mime_xml(mime.subPart(1));
  341. ensure_equals(
  342. "second part type",
  343. mime_xml.contentType(),
  344. "text/xml; charset=UTF-8");
  345. ensure_equals(
  346. "second part content length",
  347. mime_xml.contentLength(),
  348. 22);
  349. }
  350. template<> template<>
  351. void mime_parse_object_t::test<6>()
  352. {
  353. // test multi-part with no specified boundary and eof
  354. /*
  355. Content-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
  356. */
  357. 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");
  358. std::stringstream istr;
  359. istr.str(SERIALIZED_MIME);
  360. LLMimeIndex mime;
  361. LLMimeParser parser;
  362. bool ok = parser.parseIndex(istr, mime);
  363. ensure("Parse successful.", ok);
  364. ensure("is multipart.", mime.isMultipart());
  365. ensure_equals("sub-part count", mime.subPartCount(), 2);
  366. ensure_equals("content length", mime.contentLength(), 500);
  367. ensure_equals("data offset for multipart", mime.offset(), 56);
  368. LLMimeIndex mime_plain(mime.subPart(0));
  369. ensure_equals(
  370. "first part type",
  371. mime_plain.contentType(),
  372. "text/plain");
  373. ensure_equals(
  374. "first part content length",
  375. mime_plain.contentLength(),
  376. 55);
  377. ensure_equals("first part offset", mime_plain.offset(), 108);
  378. LLMimeIndex mime_xml(mime.subPart(1));
  379. ensure_equals(
  380. "second part type",
  381. mime_xml.contentType(),
  382. "text/xml; charset=UTF-8");
  383. ensure_equals(
  384. "second part content length",
  385. mime_xml.contentLength(),
  386. 22);
  387. ensure_equals("second part offset", mime_xml.offset(), 232);
  388. }
  389. /*
  390. template<> template<>
  391. void mime_parse_object_t::test<>()
  392. {
  393. }
  394. template<> template<>
  395. void mime_parse_object_t::test<>()
  396. {
  397. }
  398. template<> template<>
  399. void mime_parse_object_t::test<>()
  400. {
  401. }
  402. template<> template<>
  403. void mime_parse_object_t::test<>()
  404. {
  405. }
  406. */
  407. }