Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1000)

Unified Diff: third_party/WebKit/Source/modules/fetch/MultipartParserTest.cpp

Issue 2292763002: [Fetch API] Implement Request.formData and Response.formData. (Closed)
Patch Set: Rebase Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/modules/fetch/MultipartParserTest.cpp
diff --git a/third_party/WebKit/Source/modules/fetch/MultipartParserTest.cpp b/third_party/WebKit/Source/modules/fetch/MultipartParserTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2b2cb271b52144b9cdc811c94700285c49f31f20
--- /dev/null
+++ b/third_party/WebKit/Source/modules/fetch/MultipartParserTest.cpp
@@ -0,0 +1,232 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "modules/fetch/MultipartParser.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+#include <algorithm>
+
+namespace blink {
+
+namespace {
+
+class MockClient final : public GarbageCollectedFinalized<MockClient>, public MultipartParser::Client {
+ USING_GARBAGE_COLLECTED_MIXIN(MockClient);
+public:
+ struct Part {
+ Part() = default;
+ explicit Part(const ResourceResponse& response) : response(response), dataFullyReceived(false) {}
+ ResourceResponse response;
+ Vector<char> data;
+ bool dataFullyReceived;
+ };
+ void partHeaderFieldsInMultipartReceived(const ResourceResponse& response) override
+ {
+ m_parts.append(response);
+ }
+ void partDataInMultipartReceived(const char* bytes, size_t size) override
+ {
+ m_parts.last().data.append(bytes, size);
+ }
+ void partDataInMultipartFullyReceived() override
+ {
+ m_parts.last().dataFullyReceived = true;
+ }
+ size_t numberOfParts() const
+ {
+ return m_parts.size();
+ }
+ const Part& part(size_t partIndex) const
+ {
+ EXPECT_LT(partIndex, numberOfParts());
+ return partIndex < numberOfParts() ? m_parts[partIndex] : m_emptyPart;
+ }
+private:
+ Part m_emptyPart;
+ Vector<Part> m_parts;
+};
+
+const char* kBytes =
+ "preamble"
+ "\r\n--boundary\r\n\r\n"
+ "\r\n--boundary\r\ncontent-type: application/xhtml+xml\r\n\r\n1"
+ "\r\n--boundary\t\r\ncontent-type: text/html\r\n\r\n2\r\n--\r\n--bound--\r\n--\r\n2\r\n"
+ "\r\n--boundary \r\ncontent-type: text/plain\r\n\r\n333"
+ "\r\n--boundary--\t \r\n"
+ "epilogue";
+
+TEST(MultipartParserTest, AppendDataInChunks)
+{
+ const size_t sizes[] = {1u, 2u, strlen(kBytes)};
+
+ Vector<char> boundary;
+ boundary.append("boundary", 8u);
+ for (size_t size : sizes) {
+ MockClient* client = new MockClient;
+ MultipartParser* parser = new MultipartParser(boundary, client);
+
+ for (size_t i = 0u; kBytes[i]; i += size)
+ EXPECT_TRUE(parser->appendData(kBytes + i, std::min(size, strlen(kBytes + i))));
+ EXPECT_TRUE(parser->finish()) << " size=" << size;
+ EXPECT_EQ(4u, client->numberOfParts()) << " size=" << size;
+ EXPECT_EQ(0u, client->part(0).data.size());
+ EXPECT_TRUE(client->part(0).dataFullyReceived);
+ EXPECT_EQ(String("1"), client->part(1).data);
+ EXPECT_TRUE(client->part(1).dataFullyReceived);
+ EXPECT_EQ(String("2\r\n--\r\n--bound--\r\n--\r\n2\r\n"), client->part(2).data);
+ EXPECT_TRUE(client->part(2).dataFullyReceived);
+ EXPECT_EQ(String("333"), client->part(3).data);
+ EXPECT_TRUE(client->part(3).dataFullyReceived);
+ }
+}
+
+TEST(MultipartParserTest, Epilogue)
+{
+ const size_t ends[] = {
+ 0u, // Non-empty epilogue in the end.
+ 8u, // Empty epilogue in the end.
+ 9u, // Partial CRLF after close delimiter in the end.
+ 10u, // No CRLF after close delimiter in the end.
+ 12u, // No transport padding nor CRLF after close delimiter in the end.
+ 13u, // Partial close delimiter in the end.
+ 14u, // No close delimiter but a delimiter in the end.
+ 15u // Partial delimiter in the end.
+ };
+
+ Vector<char> boundary;
+ boundary.append("boundary", 8u);
+ for (size_t end : ends) {
+ MockClient* client = new MockClient;
+ MultipartParser* parser = new MultipartParser(boundary, client);
+
+ EXPECT_TRUE(parser->appendData(kBytes, strlen(kBytes) - end));
+ EXPECT_EQ(end <= 12u, parser->finish()) << " end=" << end;
+ EXPECT_EQ(4u, client->numberOfParts()) << " end=" << end;
+ EXPECT_EQ(0u, client->part(0).data.size());
+ EXPECT_TRUE(client->part(0).dataFullyReceived);
+ EXPECT_EQ(String("1"), client->part(1).data);
+ EXPECT_TRUE(client->part(1).dataFullyReceived);
+ EXPECT_EQ(String("2\r\n--\r\n--bound--\r\n--\r\n2\r\n"), client->part(2).data);
+ EXPECT_TRUE(client->part(2).dataFullyReceived);
+ switch (end) {
+ case 14u:
+ EXPECT_EQ(String("333"), client->part(3).data);
+ EXPECT_TRUE(client->part(3).dataFullyReceived);
+ break;
+ case 15u:
+ EXPECT_EQ(String("333\r\n--boundar"), client->part(3).data);
+ EXPECT_FALSE(client->part(3).dataFullyReceived);
+ break;
+ default:
+ EXPECT_EQ(String("333"), client->part(3).data);
+ EXPECT_TRUE(client->part(3).dataFullyReceived);
+ }
+ }
+}
+
+TEST(MultipartParserTest, NoEndBoundary)
+{
+ const char* bytes = "--boundary\r\ncontent-type: application/xhtml+xml\r\n\r\n1";
+
+ Vector<char> boundary;
+ boundary.append("boundary", 8u);
+ MockClient* client = new MockClient;
+ MultipartParser* parser = new MultipartParser(boundary, client);
+
+ EXPECT_TRUE(parser->appendData(bytes, strlen(bytes)));
+ EXPECT_FALSE(parser->finish()); // No close delimiter.
+ EXPECT_EQ(1u, client->numberOfParts());
+ EXPECT_EQ(String("1"), client->part(0).data);
+ EXPECT_FALSE(client->part(0).dataFullyReceived);
+}
+
+TEST(MultipartParserTest, NoStartBoundary)
+{
+ const char* bytes = "content-type: application/xhtml+xml\r\n\r\n1\r\n--boundary--\r\n";
+
+ Vector<char> boundary;
+ boundary.append("boundary", 8u);
+ MockClient* client = new MockClient;
+ MultipartParser* parser = new MultipartParser(boundary, client);
+
+ EXPECT_FALSE(parser->appendData(bytes, strlen(bytes))); // Close delimiter before delimiter.
+ EXPECT_FALSE(parser->finish()); // No parts.
+ EXPECT_EQ(0u, client->numberOfParts());
+}
+
+TEST(MultipartParserTest, NoStartNorEndBoundary)
+{
+ const char* bytes = "content-type: application/xhtml+xml\r\n\r\n1";
+
+ Vector<char> boundary;
+ boundary.append("boundary", 8u);
+ MockClient* client = new MockClient;
+ MultipartParser* parser = new MultipartParser(boundary, client);
+
+ EXPECT_TRUE(parser->appendData(bytes, strlen(bytes))); // Valid preamble.
+ EXPECT_FALSE(parser->finish()); // No parts.
+ EXPECT_EQ(0u, client->numberOfParts());
+}
+
+const size_t kStarts[] = {
+ 0u, // Non-empty preamble in the beginning.
+ 8u, // Empty preamble in the beginning.
+ 9u, // Truncated delimiter in the beginning.
+ 10u, // No preamble in the beginning.
+ 11u // Truncated dash boundary in the beginning.
+};
+
+TEST(MultipartParserTest, Preamble)
+{
+ Vector<char> boundary;
+ boundary.append("boundary", 8u);
+ for (size_t start : kStarts) {
+ MockClient* client = new MockClient;
+ MultipartParser* parser = new MultipartParser(boundary, client);
+
+ EXPECT_TRUE(parser->appendData(kBytes + start, strlen(kBytes + start)));
+ EXPECT_TRUE(parser->finish());
+ switch (start) {
+ case 9u:
+ case 11u:
+ EXPECT_EQ(3u, client->numberOfParts()) << " start=" << start;
+ EXPECT_EQ(String("1"), client->part(0).data);
+ EXPECT_TRUE(client->part(0).dataFullyReceived);
+ EXPECT_EQ(String("2\r\n--\r\n--bound--\r\n--\r\n2\r\n"), client->part(1).data);
+ EXPECT_TRUE(client->part(1).dataFullyReceived);
+ EXPECT_EQ(String("333"), client->part(2).data);
+ EXPECT_TRUE(client->part(2).dataFullyReceived);
+ break;
+ default:
+ EXPECT_EQ(4u, client->numberOfParts()) << " start=" << start;
+ EXPECT_EQ(0u, client->part(0).data.size());
+ EXPECT_TRUE(client->part(0).dataFullyReceived);
+ EXPECT_EQ(String("1"), client->part(1).data);
+ EXPECT_TRUE(client->part(1).dataFullyReceived);
+ EXPECT_EQ(String("2\r\n--\r\n--bound--\r\n--\r\n2\r\n"), client->part(2).data);
+ EXPECT_TRUE(client->part(2).dataFullyReceived);
+ EXPECT_EQ(String("333"), client->part(3).data);
+ EXPECT_TRUE(client->part(3).dataFullyReceived);
+ }
+ }
+}
+
+TEST(MultipartParserTest, PreambleWithMalformedBoundary)
+{
+ Vector<char> boundary;
+ boundary.append("--boundary", 10u);
+ for (size_t start : kStarts) {
+ MockClient* client = new MockClient;
+ MultipartParser* parser = new MultipartParser(boundary, client);
+
+ EXPECT_TRUE(parser->appendData(kBytes + start, strlen(kBytes + start))); // Valid preamble.
+ EXPECT_FALSE(parser->finish()); // No parts.
+ EXPECT_EQ(0u, client->numberOfParts());
+ }
+}
+
+} // namespace
+
+} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698