|  | /* | 
|  | *  Copyright 2010 The WebRTC Project Authors. All rights reserved. | 
|  | * | 
|  | *  Use of this source code is governed by a BSD-style license | 
|  | *  that can be found in the LICENSE file in the root of the source | 
|  | *  tree. An additional intellectual property rights grant can be found | 
|  | *  in the file PATENTS.  All contributing project authors may | 
|  | *  be found in the AUTHORS file in the root of the source tree. | 
|  | */ | 
|  |  | 
|  | #include <string> | 
|  |  | 
|  | #include "webrtc/base/gunit.h" | 
|  | #include "webrtc/base/helpers.h" | 
|  | #include "webrtc/base/logging.h" | 
|  | #include "webrtc/base/pathutils.h" | 
|  | #include "webrtc/base/scoped_ptr.h" | 
|  | #include "webrtc/base/multipart.h" | 
|  |  | 
|  | namespace rtc { | 
|  |  | 
|  | static const std::string kTestMultipartBoundary = "123456789987654321"; | 
|  | static const std::string kTestContentType = | 
|  | "multipart/form-data; boundary=123456789987654321"; | 
|  | static const char kTestData[] = "This is a test."; | 
|  | static const char kTestStreamContent[] = "This is a test stream."; | 
|  |  | 
|  | TEST(MultipartTest, TestBasicOperations) { | 
|  | MultipartStream multipart("multipart/form-data", kTestMultipartBoundary); | 
|  | std::string content_type; | 
|  | multipart.GetContentType(&content_type); | 
|  | EXPECT_EQ(kTestContentType, content_type); | 
|  |  | 
|  | EXPECT_EQ(rtc::SS_OPENING, multipart.GetState()); | 
|  |  | 
|  | // The multipart stream contains only --boundary--\r\n | 
|  | size_t end_part_size = multipart.GetEndPartSize(); | 
|  | multipart.EndParts(); | 
|  | EXPECT_EQ(rtc::SS_OPEN, multipart.GetState()); | 
|  | size_t size; | 
|  | EXPECT_TRUE(multipart.GetSize(&size)); | 
|  | EXPECT_EQ(end_part_size, size); | 
|  |  | 
|  | // Write is not supported. | 
|  | EXPECT_EQ(rtc::SR_ERROR, | 
|  | multipart.Write(kTestData, sizeof(kTestData), NULL, NULL)); | 
|  |  | 
|  | multipart.Close(); | 
|  | EXPECT_EQ(rtc::SS_CLOSED, multipart.GetState()); | 
|  | EXPECT_TRUE(multipart.GetSize(&size)); | 
|  | EXPECT_EQ(0U, size); | 
|  | } | 
|  |  | 
|  | TEST(MultipartTest, TestAddAndRead) { | 
|  | MultipartStream multipart("multipart/form-data", kTestMultipartBoundary); | 
|  |  | 
|  | size_t part_size = | 
|  | multipart.GetPartSize(kTestData, "form-data; name=\"text\"", "text"); | 
|  | EXPECT_TRUE(multipart.AddPart(kTestData, "form-data; name=\"text\"", "text")); | 
|  | size_t size; | 
|  | EXPECT_TRUE(multipart.GetSize(&size)); | 
|  | EXPECT_EQ(part_size, size); | 
|  |  | 
|  | rtc::scoped_ptr<rtc::MemoryStream> stream( | 
|  | new rtc::MemoryStream(kTestStreamContent)); | 
|  | size_t stream_size = 0; | 
|  | EXPECT_TRUE(stream->GetSize(&stream_size)); | 
|  | part_size += | 
|  | multipart.GetPartSize("", "form-data; name=\"stream\"", "stream"); | 
|  | part_size += stream_size; | 
|  |  | 
|  | EXPECT_TRUE(multipart.AddPart( | 
|  | new rtc::MemoryStream(kTestStreamContent), | 
|  | "form-data; name=\"stream\"", | 
|  | "stream")); | 
|  | EXPECT_TRUE(multipart.GetSize(&size)); | 
|  | EXPECT_EQ(part_size, size); | 
|  |  | 
|  | // In adding state, block read. | 
|  | char buffer[1024]; | 
|  | EXPECT_EQ(rtc::SR_BLOCK, | 
|  | multipart.Read(buffer, sizeof(buffer), NULL, NULL)); | 
|  | // Write is not supported. | 
|  | EXPECT_EQ(rtc::SR_ERROR, | 
|  | multipart.Write(buffer, sizeof(buffer), NULL, NULL)); | 
|  |  | 
|  | part_size += multipart.GetEndPartSize(); | 
|  | multipart.EndParts(); | 
|  | EXPECT_TRUE(multipart.GetSize(&size)); | 
|  | EXPECT_EQ(part_size, size); | 
|  |  | 
|  | // Read the multipart stream into StringStream | 
|  | std::string str; | 
|  | rtc::StringStream str_stream(&str); | 
|  | EXPECT_EQ(rtc::SR_SUCCESS, | 
|  | Flow(&multipart, buffer, sizeof(buffer), &str_stream)); | 
|  | EXPECT_EQ(size, str.length()); | 
|  |  | 
|  | // Search three boundaries and two parts in the order. | 
|  | size_t pos = 0; | 
|  | pos = str.find(kTestMultipartBoundary); | 
|  | EXPECT_NE(std::string::npos, pos); | 
|  | pos += kTestMultipartBoundary.length(); | 
|  |  | 
|  | pos = str.find(kTestData, pos); | 
|  | EXPECT_NE(std::string::npos, pos); | 
|  | pos += sizeof(kTestData); | 
|  |  | 
|  | pos = str.find(kTestMultipartBoundary, pos); | 
|  | EXPECT_NE(std::string::npos, pos); | 
|  | pos += kTestMultipartBoundary.length(); | 
|  |  | 
|  | pos = str.find(kTestStreamContent, pos); | 
|  | EXPECT_NE(std::string::npos, pos); | 
|  | pos += sizeof(kTestStreamContent); | 
|  |  | 
|  | pos = str.find(kTestMultipartBoundary, pos); | 
|  | EXPECT_NE(std::string::npos, pos); | 
|  | pos += kTestMultipartBoundary.length(); | 
|  |  | 
|  | pos = str.find(kTestMultipartBoundary, pos); | 
|  | EXPECT_EQ(std::string::npos, pos); | 
|  | } | 
|  |  | 
|  | }  // namespace rtc |