00001 
00034 #include <tut/tut.h>
00035 #include "linden_common.h"
00036 #include "llmime.h"
00037 #include "llsdserialize.h"
00038 
00039 namespace tut
00040 {
00041         struct mime_index
00042         {
00043         };
00044         typedef test_group<mime_index> mime_index_t;
00045         typedef mime_index_t::object mime_index_object_t;
00046         tut::mime_index_t tut_mime_index("mime_index");
00047 
00048         template<> template<>
00049         void mime_index_object_t::test<1>()
00050         {
00051                 LLMimeIndex mime;
00052                 ensure("no headers", mime.headers().isUndefined());
00053                 ensure_equals("invalid offset", mime.offset(), -1);
00054                 ensure_equals("invalid content length", mime.contentLength(), -1);
00055                 ensure("no content type", mime.contentType().empty());
00056                 ensure("not multipart", !mime.isMultipart());
00057                 ensure_equals("no attachments", mime.subPartCount(), 0);
00058         }
00059 
00060         template<> template<>
00061         void mime_index_object_t::test<2>()
00062         {
00063                 const S32 CONTENT_LENGTH = 6000;
00064                 const S32 CONTENT_OFFSET = 100;
00065                 const std::string CONTENT_TYPE = std::string("image/j2c");
00066                 LLSD headers;
00067                 headers["Content-Length"] = CONTENT_LENGTH;
00068                 headers["Content-Type"] = CONTENT_TYPE;
00069                 LLMimeIndex mime(headers, CONTENT_OFFSET);
00070                 ensure("headers are map", mime.headers().isMap());
00071                 ensure_equals("offset", mime.offset(), CONTENT_OFFSET);
00072                 ensure_equals("content length", mime.contentLength(), CONTENT_LENGTH);
00073                 ensure_equals("type is image/j2c", mime.contentType(), CONTENT_TYPE);
00074                 ensure("not multipart", !mime.isMultipart());
00075                 ensure_equals("no attachments", mime.subPartCount(), 0);
00076         }
00077 
00078         template<> template<>
00079         void mime_index_object_t::test<3>()
00080         {
00081                 const S32 MULTI_CONTENT_LENGTH = 8000;
00082                 const S32 MULTI_CONTENT_OFFSET = 100;
00083                 const std::string MULTI_CONTENT_TYPE = std::string("multipart/mixed");
00084                 LLSD headers;
00085                 headers["Content-Length"] = MULTI_CONTENT_LENGTH;
00086                 headers["Content-Type"] = MULTI_CONTENT_TYPE;
00087                 LLMimeIndex mime(headers, MULTI_CONTENT_OFFSET);
00088                 llinfos << "headers: " << LLSDOStreamer<LLSDNotationFormatter>(headers)
00089                         << llendl;
00090 
00091 
00092                 const S32 META_CONTENT_LENGTH = 700;
00093                 const S32 META_CONTENT_OFFSET = 69;
00094                 const std::string META_CONTENT_TYPE = std::string(
00095                         "text/llsd+xml");
00096                 headers = LLSD::emptyMap();
00097                 headers["Content-Length"] = META_CONTENT_LENGTH;
00098                 headers["Content-Type"] = META_CONTENT_TYPE;
00099                 LLMimeIndex meta(headers, META_CONTENT_OFFSET);
00100                 mime.attachSubPart(meta);
00101 
00102                 const S32 IMAGE_CONTENT_LENGTH = 6000;
00103                 const S32 IMAGE_CONTENT_OFFSET = 200;
00104                 const std::string IMAGE_CONTENT_TYPE = std::string("image/j2c");
00105                 headers = LLSD::emptyMap();
00106                 headers["Content-Length"] = IMAGE_CONTENT_LENGTH;
00107                 headers["Content-Type"] = IMAGE_CONTENT_TYPE;
00108                 LLMimeIndex image(headers, IMAGE_CONTENT_OFFSET);
00109                 mime.attachSubPart(image);
00110 
00111                 
00112                 ensure("is multipart", mime.isMultipart());
00113                 ensure_equals("multi offset", mime.offset(), MULTI_CONTENT_OFFSET);
00114                 ensure_equals(
00115                         "multi content length",
00116                         mime.contentLength(),
00117                         MULTI_CONTENT_LENGTH);
00118                 ensure_equals("two attachments", mime.subPartCount(), 2);
00119 
00120                 
00121                 
00122                 LLMimeIndex invalid_child(mime.subPart(-1));
00123                 ensure("no headers", invalid_child.headers().isUndefined());
00124                 ensure_equals("invalid offset", invalid_child.offset(), -1);
00125                 ensure_equals(
00126                         "invalid content length", invalid_child.contentLength(), -1);
00127                 ensure("no content type", invalid_child.contentType().empty());
00128                 ensure("not multipart", !invalid_child.isMultipart());
00129                 ensure_equals("no attachments", invalid_child.subPartCount(), 0);
00130 
00131                 invalid_child = mime.subPart(2);
00132                 ensure("no headers", invalid_child.headers().isUndefined());
00133                 ensure_equals("invalid offset", invalid_child.offset(), -1);
00134                 ensure_equals(
00135                         "invalid content length", invalid_child.contentLength(), -1);
00136                 ensure("no content type", invalid_child.contentType().empty());
00137                 ensure("not multipart", !invalid_child.isMultipart());
00138                 ensure_equals("no attachments", invalid_child.subPartCount(), 0);
00139         }
00140 
00141         template<> template<>
00142         void mime_index_object_t::test<4>()
00143         {
00144                 const S32 MULTI_CONTENT_LENGTH = 8000;
00145                 const S32 MULTI_CONTENT_OFFSET = 100;
00146                 const std::string MULTI_CONTENT_TYPE = std::string("multipart/mixed");
00147                 LLSD headers;
00148                 headers["Content-Length"] = MULTI_CONTENT_LENGTH;
00149                 headers["Content-Type"] = MULTI_CONTENT_TYPE;
00150                 LLMimeIndex mime(headers, MULTI_CONTENT_OFFSET);
00151 
00152                 const S32 META_CONTENT_LENGTH = 700;
00153                 const S32 META_CONTENT_OFFSET = 69;
00154                 const std::string META_CONTENT_TYPE = std::string(
00155                         "application/llsd+xml");
00156                 headers = LLSD::emptyMap();
00157                 headers["Content-Length"] = META_CONTENT_LENGTH;
00158                 headers["Content-Type"] = META_CONTENT_TYPE;
00159                 LLMimeIndex meta(headers, META_CONTENT_OFFSET);
00160                 mime.attachSubPart(meta);
00161 
00162                 const S32 IMAGE_CONTENT_LENGTH = 6000;
00163                 const S32 IMAGE_CONTENT_OFFSET = 200;
00164                 const std::string IMAGE_CONTENT_TYPE = std::string("image/j2c");
00165                 headers = LLSD::emptyMap();
00166                 headers["Content-Length"] = IMAGE_CONTENT_LENGTH;
00167                 headers["Content-Type"] = IMAGE_CONTENT_TYPE;
00168                 LLMimeIndex image(headers, IMAGE_CONTENT_OFFSET);
00169                 mime.attachSubPart(image);
00170 
00171                 
00172                 ensure("is multipart", mime.isMultipart());
00173                 ensure_equals("multi offset", mime.offset(), MULTI_CONTENT_OFFSET);
00174                 ensure_equals(
00175                         "multi content length",
00176                         mime.contentLength(),
00177                         MULTI_CONTENT_LENGTH);
00178                 ensure_equals("two attachments", mime.subPartCount(), 2);
00179 
00180                 LLMimeIndex actual_meta = mime.subPart(0);
00181                 ensure_equals(
00182                         "meta type", actual_meta.contentType(), META_CONTENT_TYPE);
00183                 ensure_equals(
00184                         "meta offset", actual_meta.offset(), META_CONTENT_OFFSET);
00185                 ensure_equals(
00186                         "meta content length",
00187                         actual_meta.contentLength(),
00188                         META_CONTENT_LENGTH);
00189 
00190                 LLMimeIndex actual_image = mime.subPart(1);
00191                 ensure_equals(
00192                         "image type", actual_image.contentType(), IMAGE_CONTENT_TYPE);
00193                 ensure_equals(
00194                         "image offset", actual_image.offset(), IMAGE_CONTENT_OFFSET);
00195                 ensure_equals(
00196                         "image content length",
00197                         actual_image.contentLength(),
00198                         IMAGE_CONTENT_LENGTH);
00199         }
00200 
00201 
00202 
00203 
00204 
00205 
00206 
00207 
00208 
00209 
00210 
00211 
00212 
00213 
00214 
00215 
00216 
00217 
00218 
00219 
00220 
00221 
00222 
00223 }
00224 
00225 
00226 namespace tut
00227 {
00228         struct mime_parse
00229         {
00230         };
00231         typedef test_group<mime_parse> mime_parse_t;
00232         typedef mime_parse_t::object mime_parse_object_t;
00233         tut::mime_parse_t tut_mime_parse("mime_parse");
00234 
00235         template<> template<>
00236         void mime_parse_object_t::test<1>()
00237         {
00238                 
00239                 const std::string SERIALIZED_MIME("Content-Length: 200\r\nContent-Type: text/plain\r\n\r\naaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccc\r\n");
00240                 std::stringstream istr;
00241                 istr.str(SERIALIZED_MIME);
00242                 LLMimeIndex mime;
00243                 LLMimeParser parser;
00244                 bool ok = parser.parseIndex(istr, mime);
00245                 ensure("Parse successful.", ok);
00246                 ensure_equals("content type", mime.contentType(), "text/plain");
00247                 ensure_equals("content length", mime.contentLength(), 200);
00248                 ensure_equals("offset", mime.offset(), 49);
00249         }
00250 
00251         template<> template<>
00252         void mime_parse_object_t::test<2>()
00253         {
00254                 
00255                 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");
00256                 std::stringstream istr;
00257                 istr.str(SERIALIZED_MIME);
00258                 LLMimeIndex mime;
00259                 LLMimeParser parser;
00260                 bool ok = parser.parseIndex(istr, mime);
00261                 ensure("Parse successful.", ok);
00262                 ensure("not multipart.", !mime.isMultipart());
00263                 ensure_equals("content type", mime.contentType(), "text/plain");
00264                 ensure_equals("content length", mime.contentLength(), 200);
00265                 ensure_equals("offset", mime.offset(), 49);
00266         }
00267 
00268         template<> template<>
00269         void mime_parse_object_t::test<3>()
00270         {
00271                 
00272                 
00273 
00274 
00275                 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");
00276                 std::stringstream istr;
00277                 istr.str(SERIALIZED_MIME);
00278                 LLMimeIndex mime;
00279                 LLMimeParser parser;
00280                 bool ok = parser.parseIndex(istr, mime);
00281                 ensure("Parse successful.", ok);
00282                 ensure("is multipart.", mime.isMultipart());
00283                 ensure_equals("sub-part count", mime.subPartCount(), 2);
00284                 ensure_equals("content length", mime.contentLength(), 150);
00285                 ensure_equals("data offset for multipart", mime.offset(), 74);
00286 
00287                 LLMimeIndex mime_plain(mime.subPart(0));
00288                 ensure_equals(
00289                         "first part type",
00290                         mime_plain.contentType(),
00291                         "text/plain");
00292                 ensure_equals(
00293                         "first part content length not known.",
00294                         mime_plain.contentLength(),
00295                         -1);
00296                 ensure_equals("first part offset", mime_plain.offset(), 113);
00297 
00298                 LLMimeIndex mime_xml(mime.subPart(1));
00299                 ensure_equals(
00300                         "second part type",
00301                         mime_xml.contentType(),
00302                         "text/xml; charset=UTF-8");
00303                 ensure_equals(
00304                         "second part content length",
00305                         mime_xml.contentLength(),
00306                         22);
00307                 ensure_equals("second part offset", mime_xml.offset(), 198);
00308         }
00309 
00310         template<> template<>
00311         void mime_parse_object_t::test<4>()
00312         {
00313                 
00314                 
00315 
00316                 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");
00317                 std::stringstream istr;
00318                 istr.str(SERIALIZED_MIME);
00319                 LLMimeIndex mime;
00320                 LLMimeParser parser;
00321                 bool ok = parser.parseIndex(istr, mime);
00322                 ensure("Parse successful.", ok);
00323                 ensure("is multipart.", mime.isMultipart());
00324                 ensure_equals("sub-part count", mime.subPartCount(), 2);
00325                 ensure_equals("content length", mime.contentLength(), 220);
00326                 ensure_equals("data offset for multipart", mime.offset(), 72);
00327 
00328                 LLMimeIndex mime_plain(mime.subPart(0));
00329                 ensure_equals(
00330                         "first part type",
00331                         mime_plain.contentType(),
00332                         "text/plain");
00333                 ensure_equals(
00334                         "first part content length",
00335                         mime_plain.contentLength(),
00336                         55);
00337                 ensure_equals("first part offset", mime_plain.offset(), 131);
00338 
00339                 LLMimeIndex mime_xml(mime.subPart(1));
00340                 ensure_equals(
00341                         "second part type",
00342                         mime_xml.contentType(),
00343                         "text/xml; charset=UTF-8");
00344                 ensure_equals(
00345                         "second part content length",
00346                         mime_xml.contentLength(),
00347                         22);
00348                 ensure_equals("second part offset", mime_xml.offset(), 262);
00349         }
00350 
00351         template<> template<>
00352         void mime_parse_object_t::test<5>()
00353         {
00354                 
00355                 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");
00356                 std::stringstream istr;
00357                 istr.str(SERIALIZED_MIME);
00358                 LLMimeIndex mime;
00359                 LLMimeParser parser;
00360                 bool ok = parser.parseIndex(istr, mime);
00361                 ensure("Parse successful.", ok);
00362                 ensure("is multipart.", mime.isMultipart());
00363                 ensure_equals("sub-part count", mime.subPartCount(), 2);
00364                 ensure_equals("content length", mime.contentLength(), 220);
00365 
00366                 LLMimeIndex mime_plain(mime.subPart(0));
00367                 ensure_equals(
00368                         "first part type",
00369                         mime_plain.contentType(),
00370                         "text/plain");
00371                 ensure_equals(
00372                         "first part content length",
00373                         mime_plain.contentLength(),
00374                         55);
00375 
00376                 LLMimeIndex mime_xml(mime.subPart(1));
00377                 ensure_equals(
00378                         "second part type",
00379                         mime_xml.contentType(),
00380                         "text/xml; charset=UTF-8");
00381                 ensure_equals(
00382                         "second part content length",
00383                         mime_xml.contentLength(),
00384                         22);
00385         }
00386 
00387         template<> template<>
00388         void mime_parse_object_t::test<6>()
00389         {
00390                 
00391 
00392 
00393 
00394                 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");
00395                 std::stringstream istr;
00396                 istr.str(SERIALIZED_MIME);
00397                 LLMimeIndex mime;
00398                 LLMimeParser parser;
00399                 bool ok = parser.parseIndex(istr, mime);
00400                 ensure("Parse successful.", ok);
00401                 ensure("is multipart.", mime.isMultipart());
00402                 ensure_equals("sub-part count", mime.subPartCount(), 2);
00403                 ensure_equals("content length", mime.contentLength(), 500);
00404                 ensure_equals("data offset for multipart", mime.offset(), 56);
00405 
00406                 LLMimeIndex mime_plain(mime.subPart(0));
00407                 ensure_equals(
00408                         "first part type",
00409                         mime_plain.contentType(),
00410                         "text/plain");
00411                 ensure_equals(
00412                         "first part content length",
00413                         mime_plain.contentLength(),
00414                         55);
00415                 ensure_equals("first part offset", mime_plain.offset(), 108);
00416 
00417                 LLMimeIndex mime_xml(mime.subPart(1));
00418                 ensure_equals(
00419                         "second part type",
00420                         mime_xml.contentType(),
00421                         "text/xml; charset=UTF-8");
00422                 ensure_equals(
00423                         "second part content length",
00424                         mime_xml.contentLength(),
00425                         22);
00426                 ensure_equals("second part offset", mime_xml.offset(), 232);
00427         }
00428 
00429 
00430 
00431 
00432 
00433 
00434 
00435 
00436 
00437 
00438 
00439 
00440 
00441 
00442 
00443 
00444 
00445 
00446 
00447 }