446 lines
16 KiB
C++
446 lines
16 KiB
C++
/**
|
|
* @file llmime_test.cpp
|
|
* @author Phoenix
|
|
* @date 2006-12-24
|
|
* @brief BRIEF_DESC of llmime_test.cpp
|
|
*
|
|
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
|
|
* Second Life Viewer Source Code
|
|
* Copyright (C) 2010, Linden Research, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation;
|
|
* version 2.1 of the License only.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*
|
|
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
|
* $/LicenseInfo$
|
|
*/
|
|
|
|
#include "linden_common.h"
|
|
|
|
#include "llsdserialize.h"
|
|
|
|
#include "../llmime.h"
|
|
|
|
#include "../test/lltut.h"
|
|
|
|
namespace tut
|
|
{
|
|
struct mime_index
|
|
{
|
|
};
|
|
typedef test_group<mime_index> mime_index_t;
|
|
typedef mime_index_t::object mime_index_object_t;
|
|
tut::mime_index_t tut_mime_index("LLMime");
|
|
|
|
template<> template<>
|
|
void mime_index_object_t::test<1>()
|
|
{
|
|
LLMimeIndex mime;
|
|
ensure("no headers", mime.headers().isUndefined());
|
|
ensure_equals("invalid offset", mime.offset(), -1);
|
|
ensure_equals("invalid content length", mime.contentLength(), -1);
|
|
ensure("no content type", mime.contentType().empty());
|
|
ensure("not multipart", !mime.isMultipart());
|
|
ensure_equals("no attachments", mime.subPartCount(), 0);
|
|
}
|
|
|
|
template<> template<>
|
|
void mime_index_object_t::test<2>()
|
|
{
|
|
const S32 CONTENT_LENGTH = 6000;
|
|
const S32 CONTENT_OFFSET = 100;
|
|
const std::string CONTENT_TYPE = std::string("image/j2c");
|
|
LLSD headers;
|
|
headers["Content-Length"] = CONTENT_LENGTH;
|
|
headers["Content-Type"] = CONTENT_TYPE;
|
|
LLMimeIndex mime(headers, CONTENT_OFFSET);
|
|
ensure("headers are map", mime.headers().isMap());
|
|
ensure_equals("offset", mime.offset(), CONTENT_OFFSET);
|
|
ensure_equals("content length", mime.contentLength(), CONTENT_LENGTH);
|
|
ensure_equals("type is image/j2c", mime.contentType(), CONTENT_TYPE);
|
|
ensure("not multipart", !mime.isMultipart());
|
|
ensure_equals("no attachments", mime.subPartCount(), 0);
|
|
}
|
|
|
|
template<> template<>
|
|
void mime_index_object_t::test<3>()
|
|
{
|
|
const S32 MULTI_CONTENT_LENGTH = 8000;
|
|
const S32 MULTI_CONTENT_OFFSET = 100;
|
|
const std::string MULTI_CONTENT_TYPE = std::string("multipart/mixed");
|
|
LLSD headers;
|
|
headers["Content-Length"] = MULTI_CONTENT_LENGTH;
|
|
headers["Content-Type"] = MULTI_CONTENT_TYPE;
|
|
LLMimeIndex mime(headers, MULTI_CONTENT_OFFSET);
|
|
LL_INFOS() << "headers: " << LLSDOStreamer<LLSDNotationFormatter>(headers)
|
|
<< LL_ENDL;
|
|
|
|
|
|
const S32 META_CONTENT_LENGTH = 700;
|
|
const S32 META_CONTENT_OFFSET = 69;
|
|
const std::string META_CONTENT_TYPE = std::string(
|
|
"text/llsd+xml");
|
|
headers = LLSD::emptyMap();
|
|
headers["Content-Length"] = META_CONTENT_LENGTH;
|
|
headers["Content-Type"] = META_CONTENT_TYPE;
|
|
LLMimeIndex meta(headers, META_CONTENT_OFFSET);
|
|
mime.attachSubPart(meta);
|
|
|
|
const S32 IMAGE_CONTENT_LENGTH = 6000;
|
|
const S32 IMAGE_CONTENT_OFFSET = 200;
|
|
const std::string IMAGE_CONTENT_TYPE = std::string("image/j2c");
|
|
headers = LLSD::emptyMap();
|
|
headers["Content-Length"] = IMAGE_CONTENT_LENGTH;
|
|
headers["Content-Type"] = IMAGE_CONTENT_TYPE;
|
|
LLMimeIndex image(headers, IMAGE_CONTENT_OFFSET);
|
|
mime.attachSubPart(image);
|
|
|
|
// make sure we have a valid multi-part
|
|
ensure("is multipart", mime.isMultipart());
|
|
ensure_equals("multi offset", mime.offset(), MULTI_CONTENT_OFFSET);
|
|
ensure_equals(
|
|
"multi content length",
|
|
mime.contentLength(),
|
|
MULTI_CONTENT_LENGTH);
|
|
ensure_equals("two attachments", mime.subPartCount(), 2);
|
|
|
|
// make sure ranged gets do the right thing with out of bounds
|
|
// sub-parts.
|
|
LLMimeIndex invalid_child(mime.subPart(-1));
|
|
ensure("no headers", invalid_child.headers().isUndefined());
|
|
ensure_equals("invalid offset", invalid_child.offset(), -1);
|
|
ensure_equals(
|
|
"invalid content length", invalid_child.contentLength(), -1);
|
|
ensure("no content type", invalid_child.contentType().empty());
|
|
ensure("not multipart", !invalid_child.isMultipart());
|
|
ensure_equals("no attachments", invalid_child.subPartCount(), 0);
|
|
|
|
invalid_child = mime.subPart(2);
|
|
ensure("no headers", invalid_child.headers().isUndefined());
|
|
ensure_equals("invalid offset", invalid_child.offset(), -1);
|
|
ensure_equals(
|
|
"invalid content length", invalid_child.contentLength(), -1);
|
|
ensure("no content type", invalid_child.contentType().empty());
|
|
ensure("not multipart", !invalid_child.isMultipart());
|
|
ensure_equals("no attachments", invalid_child.subPartCount(), 0);
|
|
}
|
|
|
|
template<> template<>
|
|
void mime_index_object_t::test<4>()
|
|
{
|
|
const S32 MULTI_CONTENT_LENGTH = 8000;
|
|
const S32 MULTI_CONTENT_OFFSET = 100;
|
|
const std::string MULTI_CONTENT_TYPE = std::string("multipart/mixed");
|
|
LLSD headers;
|
|
headers["Content-Length"] = MULTI_CONTENT_LENGTH;
|
|
headers["Content-Type"] = MULTI_CONTENT_TYPE;
|
|
LLMimeIndex mime(headers, MULTI_CONTENT_OFFSET);
|
|
|
|
const S32 META_CONTENT_LENGTH = 700;
|
|
const S32 META_CONTENT_OFFSET = 69;
|
|
const std::string META_CONTENT_TYPE = std::string(
|
|
"application/llsd+xml");
|
|
headers = LLSD::emptyMap();
|
|
headers["Content-Length"] = META_CONTENT_LENGTH;
|
|
headers["Content-Type"] = META_CONTENT_TYPE;
|
|
LLMimeIndex meta(headers, META_CONTENT_OFFSET);
|
|
mime.attachSubPart(meta);
|
|
|
|
const S32 IMAGE_CONTENT_LENGTH = 6000;
|
|
const S32 IMAGE_CONTENT_OFFSET = 200;
|
|
const std::string IMAGE_CONTENT_TYPE = std::string("image/j2c");
|
|
headers = LLSD::emptyMap();
|
|
headers["Content-Length"] = IMAGE_CONTENT_LENGTH;
|
|
headers["Content-Type"] = IMAGE_CONTENT_TYPE;
|
|
LLMimeIndex image(headers, IMAGE_CONTENT_OFFSET);
|
|
mime.attachSubPart(image);
|
|
|
|
// check what we have
|
|
ensure("is multipart", mime.isMultipart());
|
|
ensure_equals("multi offset", mime.offset(), MULTI_CONTENT_OFFSET);
|
|
ensure_equals(
|
|
"multi content length",
|
|
mime.contentLength(),
|
|
MULTI_CONTENT_LENGTH);
|
|
ensure_equals("two attachments", mime.subPartCount(), 2);
|
|
|
|
LLMimeIndex actual_meta = mime.subPart(0);
|
|
ensure_equals(
|
|
"meta type", actual_meta.contentType(), META_CONTENT_TYPE);
|
|
ensure_equals(
|
|
"meta offset", actual_meta.offset(), META_CONTENT_OFFSET);
|
|
ensure_equals(
|
|
"meta content length",
|
|
actual_meta.contentLength(),
|
|
META_CONTENT_LENGTH);
|
|
|
|
LLMimeIndex actual_image = mime.subPart(1);
|
|
ensure_equals(
|
|
"image type", actual_image.contentType(), IMAGE_CONTENT_TYPE);
|
|
ensure_equals(
|
|
"image offset", actual_image.offset(), IMAGE_CONTENT_OFFSET);
|
|
ensure_equals(
|
|
"image content length",
|
|
actual_image.contentLength(),
|
|
IMAGE_CONTENT_LENGTH);
|
|
}
|
|
|
|
/*
|
|
template<> template<>
|
|
void mime_index_object_t::test<5>()
|
|
{
|
|
}
|
|
template<> template<>
|
|
void mime_index_object_t::test<6>()
|
|
{
|
|
}
|
|
template<> template<>
|
|
void mime_index_object_t::test<7>()
|
|
{
|
|
}
|
|
template<> template<>
|
|
void mime_index_object_t::test<8>()
|
|
{
|
|
}
|
|
template<> template<>
|
|
void mime_index_object_t::test<>()
|
|
{
|
|
}
|
|
*/
|
|
}
|
|
|
|
|
|
namespace tut
|
|
{
|
|
struct mime_parse
|
|
{
|
|
};
|
|
typedef test_group<mime_parse> mime_parse_t;
|
|
typedef mime_parse_t::object mime_parse_object_t;
|
|
tut::mime_parse_t tut_mime_parse("LLMimeParse");
|
|
|
|
template<> template<>
|
|
void mime_parse_object_t::test<1>()
|
|
{
|
|
// parse one mime object
|
|
const std::string SERIALIZED_MIME("Content-Length: 200\r\nContent-Type: text/plain\r\n\r\naaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccc\r\n");
|
|
std::stringstream istr;
|
|
istr.str(SERIALIZED_MIME);
|
|
LLMimeIndex mime;
|
|
LLMimeParser parser;
|
|
bool ok = parser.parseIndex(istr, mime);
|
|
ensure("Parse successful.", ok);
|
|
ensure_equals("content type", mime.contentType(), "text/plain");
|
|
ensure_equals("content length", mime.contentLength(), 200);
|
|
ensure_equals("offset", mime.offset(), 49);
|
|
}
|
|
|
|
template<> template<>
|
|
void mime_parse_object_t::test<2>()
|
|
{
|
|
// make sure we only parse one.
|
|
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");
|
|
std::stringstream istr;
|
|
istr.str(SERIALIZED_MIME);
|
|
LLMimeIndex mime;
|
|
LLMimeParser parser;
|
|
bool ok = parser.parseIndex(istr, mime);
|
|
ensure("Parse successful.", ok);
|
|
ensure("not multipart.", !mime.isMultipart());
|
|
ensure_equals("content type", mime.contentType(), "text/plain");
|
|
ensure_equals("content length", mime.contentLength(), 200);
|
|
ensure_equals("offset", mime.offset(), 49);
|
|
}
|
|
|
|
template<> template<>
|
|
void mime_parse_object_t::test<3>()
|
|
{
|
|
// test multi-part and lack of content length for some of it.
|
|
/*
|
|
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
|
|
*/
|
|
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");
|
|
std::stringstream istr;
|
|
istr.str(SERIALIZED_MIME);
|
|
LLMimeIndex mime;
|
|
LLMimeParser parser;
|
|
bool ok = parser.parseIndex(istr, mime);
|
|
ensure("Parse successful.", ok);
|
|
ensure("is multipart.", mime.isMultipart());
|
|
ensure_equals("sub-part count", mime.subPartCount(), 2);
|
|
ensure_equals("content length", mime.contentLength(), 150);
|
|
ensure_equals("data offset for multipart", mime.offset(), 74);
|
|
|
|
LLMimeIndex mime_plain(mime.subPart(0));
|
|
ensure_equals(
|
|
"first part type",
|
|
mime_plain.contentType(),
|
|
"text/plain");
|
|
ensure_equals(
|
|
"first part content length not known.",
|
|
mime_plain.contentLength(),
|
|
-1);
|
|
ensure_equals("first part offset", mime_plain.offset(), 113);
|
|
|
|
LLMimeIndex mime_xml(mime.subPart(1));
|
|
ensure_equals(
|
|
"second part type",
|
|
mime_xml.contentType(),
|
|
"text/xml; charset=UTF-8");
|
|
ensure_equals(
|
|
"second part content length",
|
|
mime_xml.contentLength(),
|
|
22);
|
|
ensure_equals("second part offset", mime_xml.offset(), 198);
|
|
}
|
|
|
|
template<> template<>
|
|
void mime_parse_object_t::test<4>()
|
|
{
|
|
// test multi-part, unquoted separator, and premature eof conditions
|
|
/*
|
|
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 */
|
|
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");
|
|
std::stringstream istr;
|
|
istr.str(SERIALIZED_MIME);
|
|
LLMimeIndex mime;
|
|
LLMimeParser parser;
|
|
bool ok = parser.parseIndex(istr, mime);
|
|
ensure("Parse successful.", ok);
|
|
ensure("is multipart.", mime.isMultipart());
|
|
ensure_equals("sub-part count", mime.subPartCount(), 2);
|
|
ensure_equals("content length", mime.contentLength(), 220);
|
|
ensure_equals("data offset for multipart", mime.offset(), 72);
|
|
|
|
LLMimeIndex mime_plain(mime.subPart(0));
|
|
ensure_equals(
|
|
"first part type",
|
|
mime_plain.contentType(),
|
|
"text/plain");
|
|
ensure_equals(
|
|
"first part content length",
|
|
mime_plain.contentLength(),
|
|
55);
|
|
ensure_equals("first part offset", mime_plain.offset(), 131);
|
|
|
|
LLMimeIndex mime_xml(mime.subPart(1));
|
|
ensure_equals(
|
|
"second part type",
|
|
mime_xml.contentType(),
|
|
"text/xml; charset=UTF-8");
|
|
ensure_equals(
|
|
"second part content length",
|
|
mime_xml.contentLength(),
|
|
22);
|
|
ensure_equals("second part offset", mime_xml.offset(), 262);
|
|
}
|
|
|
|
template<> template<>
|
|
void mime_parse_object_t::test<5>()
|
|
{
|
|
// test multi-part with multiple params
|
|
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");
|
|
std::stringstream istr;
|
|
istr.str(SERIALIZED_MIME);
|
|
LLMimeIndex mime;
|
|
LLMimeParser parser;
|
|
bool ok = parser.parseIndex(istr, mime);
|
|
ensure("Parse successful.", ok);
|
|
ensure("is multipart.", mime.isMultipart());
|
|
ensure_equals("sub-part count", mime.subPartCount(), 2);
|
|
ensure_equals("content length", mime.contentLength(), 220);
|
|
|
|
LLMimeIndex mime_plain(mime.subPart(0));
|
|
ensure_equals(
|
|
"first part type",
|
|
mime_plain.contentType(),
|
|
"text/plain");
|
|
ensure_equals(
|
|
"first part content length",
|
|
mime_plain.contentLength(),
|
|
55);
|
|
|
|
LLMimeIndex mime_xml(mime.subPart(1));
|
|
ensure_equals(
|
|
"second part type",
|
|
mime_xml.contentType(),
|
|
"text/xml; charset=UTF-8");
|
|
ensure_equals(
|
|
"second part content length",
|
|
mime_xml.contentLength(),
|
|
22);
|
|
}
|
|
|
|
template<> template<>
|
|
void mime_parse_object_t::test<6>()
|
|
{
|
|
// test multi-part with no specified boundary and eof
|
|
/*
|
|
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
|
|
*/
|
|
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");
|
|
std::stringstream istr;
|
|
istr.str(SERIALIZED_MIME);
|
|
LLMimeIndex mime;
|
|
LLMimeParser parser;
|
|
bool ok = parser.parseIndex(istr, mime);
|
|
ensure("Parse successful.", ok);
|
|
ensure("is multipart.", mime.isMultipart());
|
|
ensure_equals("sub-part count", mime.subPartCount(), 2);
|
|
ensure_equals("content length", mime.contentLength(), 500);
|
|
ensure_equals("data offset for multipart", mime.offset(), 56);
|
|
|
|
LLMimeIndex mime_plain(mime.subPart(0));
|
|
ensure_equals(
|
|
"first part type",
|
|
mime_plain.contentType(),
|
|
"text/plain");
|
|
ensure_equals(
|
|
"first part content length",
|
|
mime_plain.contentLength(),
|
|
55);
|
|
ensure_equals("first part offset", mime_plain.offset(), 108);
|
|
|
|
LLMimeIndex mime_xml(mime.subPart(1));
|
|
ensure_equals(
|
|
"second part type",
|
|
mime_xml.contentType(),
|
|
"text/xml; charset=UTF-8");
|
|
ensure_equals(
|
|
"second part content length",
|
|
mime_xml.contentLength(),
|
|
22);
|
|
ensure_equals("second part offset", mime_xml.offset(), 232);
|
|
}
|
|
|
|
/*
|
|
template<> template<>
|
|
void mime_parse_object_t::test<>()
|
|
{
|
|
}
|
|
template<> template<>
|
|
void mime_parse_object_t::test<>()
|
|
{
|
|
}
|
|
template<> template<>
|
|
void mime_parse_object_t::test<>()
|
|
{
|
|
}
|
|
template<> template<>
|
|
void mime_parse_object_t::test<>()
|
|
{
|
|
}
|
|
*/
|
|
}
|