Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include <algorithm> | |
| 6 | |
| 7 #include "chrome/browser/extensions/api/web_request/post_data_parser.h" | |
| 8 #include "testing/gtest/include/gtest/gtest.h" | |
| 9 | |
| 10 namespace { | |
| 11 | |
| 12 // Attempts to run the parser corresponding to the |content_type_header| | |
| 13 // on the source represented by the concatenation of blocks from |bytes|. | |
| 14 // On success, returns true and the parsed |output|, else false. | |
| 15 // Parsed |output| has keys on even positions (0, 2, ...), values on odd ones. | |
| 16 bool RunParser(const std::string& content_type_header, | |
| 17 const std::vector<const std::vector<char>* >& bytes, | |
| 18 std::vector<std::string>* output) { | |
| 19 if (output == NULL) | |
| 20 return false; | |
| 21 output->clear(); | |
| 22 scoped_ptr<extensions::PostDataParser> parser( | |
| 23 extensions::PostDataParser::CreatePostDataParser(&content_type_header)); | |
| 24 if (parser.get() == NULL) | |
| 25 return false; | |
| 26 extensions::PostDataParser::Result result; | |
| 27 for (size_t block = 0; block < bytes.size(); ++block) { | |
| 28 if (!parser->SetSource(bytes[block])) | |
| 29 return false; | |
| 30 while (parser->GetNextPair(&result)) { | |
| 31 output->push_back(result.get_key()); | |
| 32 output->push_back(result.get_val()); | |
| 33 } | |
| 34 } | |
| 35 return parser->AllDataReadOK(); | |
| 36 } | |
| 37 | |
| 38 } // namespace | |
| 39 | |
| 40 class ExtensionWebRequestPostDataParserTest : public testing::Test { | |
| 41 public: | |
| 42 ExtensionWebRequestPostDataParserTest() {} | |
| 43 | |
| 44 protected: | |
| 45 virtual void SetUp() OVERRIDE {} | |
| 46 }; | |
| 47 | |
| 48 TEST_F(ExtensionWebRequestPostDataParserTest, Parsing) { | |
| 49 // We verify that POST data parsers cope with various formats of POST data. | |
| 50 // Construct the test data. | |
| 51 #define kBoundary "THIS_IS_A_BOUNDARY" | |
| 52 #define kBlockStr1 "--" kBoundary "\r\n" \ | |
| 53 "Content-Disposition: form-data; name=\"text\"\r\n" \ | |
| 54 "\r\n" \ | |
| 55 "test text\r\n" \ | |
| 56 "--" kBoundary "\r\n" \ | |
| 57 "Content-Disposition: form-data; name=\"file\"; filename=\"test\"\r\n" \ | |
| 58 "Content-Type: application/octet-stream\r\n" \ | |
| 59 "\r\n" | |
| 60 #define kBlockStr2 "\r\n" \ | |
| 61 "--" kBoundary "\r\n" \ | |
| 62 "Content-Disposition: form-data; name=\"password\"\r\n" \ | |
| 63 "\r\n" \ | |
| 64 "test password\r\n" \ | |
| 65 "--" kBoundary "\r\n" \ | |
| 66 "Content-Disposition: form-data; name=\"radio\"\r\n" \ | |
| 67 "\r\n" \ | |
| 68 "Yes\r\n" \ | |
| 69 "--" kBoundary "\r\n" \ | |
| 70 "Content-Disposition: form-data; name=\"check\"\r\n" \ | |
| 71 "\r\n" \ | |
| 72 "option A\r\n" \ | |
| 73 "--" kBoundary "\r\n" \ | |
| 74 "Content-Disposition: form-data; name=\"check\"\r\n" \ | |
| 75 "\r\n" \ | |
| 76 "option B\r\n" \ | |
| 77 "--" kBoundary "\r\n" \ | |
| 78 "Content-Disposition: form-data; name=\"txtarea\"\r\n" \ | |
| 79 "\r\n" \ | |
| 80 "Some text.\r\n" \ | |
| 81 "Other.\r\n" \ | |
| 82 "\r\n" \ | |
| 83 "--" kBoundary "\r\n" \ | |
| 84 "Content-Disposition: form-data; name=\"select\"\r\n" \ | |
| 85 "\r\n" \ | |
| 86 "one\r\n" \ | |
| 87 "--" kBoundary "--" | |
| 88 // POST data input. | |
| 89 const char kBigBlock[] = kBlockStr1 kBlockStr2; | |
| 90 const char kBlock1[] = kBlockStr1; | |
| 91 const char kBlock2[] = kBlockStr2; | |
| 92 const char kUrlEncodedBlock[] = "text=test+text&file=test" | |
| 93 "&password=test+password&radio=Yes&check=option+A&check=option+B" | |
| 94 "&txtarea=Some+text.%0D%0AOther.%0D%0A&select=one"; | |
| 95 #define BYTES_FROM_BLOCK(bytes, block) \ | |
| 96 const std::vector<char> bytes(block, block + strlen(block)) | |
| 97 BYTES_FROM_BLOCK(kMultipartBytes, kBigBlock); | |
| 98 BYTES_FROM_BLOCK(kMultipartBytesSplit1, kBlock1); | |
| 99 BYTES_FROM_BLOCK(kMultipartBytesSplit2, kBlock2); | |
| 100 BYTES_FROM_BLOCK(kUrlEncodedBytes, kUrlEncodedBlock); | |
| 101 const std::vector<char> kTextPlainBytes; | |
| 102 #undef BYTES_FROM_BLOCK | |
| 103 // Headers. | |
| 104 const char kUrlEncoded[] = "application/x-www-form-urlencoded"; | |
| 105 const char kTextPlain[] = "text/plain"; | |
| 106 const char kMultipart[] = "multipart/form-data; boundary=" kBoundary; | |
| 107 #undef kBlockStr2 | |
| 108 #undef kBlockStr1 | |
| 109 #undef kBoundary | |
| 110 // Expected output. | |
| 111 const char* kPairs[] = { | |
| 112 "text", "test text", | |
| 113 "file", "test", | |
| 114 "password", "test password", | |
| 115 "radio", "Yes", | |
| 116 "check", "option A", | |
| 117 "check", "option B", | |
| 118 "txtarea", "Some text.\r\nOther.\r\n", | |
| 119 "select", "one" | |
| 120 }; | |
| 121 const std::vector<const char*> kExpected(kPairs, kPairs + arraysize(kPairs)); | |
| 122 | |
| 123 std::vector<const std::vector<char>* > input; | |
| 124 std::vector<std::string> output; | |
| 125 | |
| 126 // First test: multipart POST data in one lump. | |
| 127 input.push_back(&kMultipartBytes); | |
| 128 EXPECT_TRUE(RunParser(kMultipart, input, &output)); | |
| 129 EXPECT_TRUE(std::equal(output.begin(), output.end(), kExpected.begin())); | |
|
battre
2012/07/16 17:39:45
Can you add an ASSERT_LE(output.size(), kExpected.
vabr (Chromium)
2012/07/17 11:11:11
Thanks for catching this!
I avoided the ASSERT by
| |
| 130 | |
| 131 // Second test: multipart POST data in several lumps. | |
| 132 input.clear(); | |
| 133 input.push_back(&kMultipartBytesSplit1); | |
| 134 input.push_back(&kMultipartBytesSplit2); | |
| 135 EXPECT_TRUE(RunParser(kMultipart, input, &output)); | |
| 136 EXPECT_TRUE(std::equal(output.begin(), output.end(), kExpected.begin())); | |
| 137 | |
| 138 // Third test: URL-encoded POST data. | |
| 139 input.clear(); | |
| 140 input.push_back(&kUrlEncodedBytes); | |
| 141 EXPECT_TRUE(RunParser(kUrlEncoded, input, &output)); | |
| 142 EXPECT_TRUE(std::equal(output.begin(), output.end(), kExpected.begin())); | |
| 143 | |
| 144 // Fourth test: text/plain POST data in one lump. | |
| 145 input.clear(); | |
| 146 input.push_back(&kTextPlainBytes); | |
| 147 // This should fail, text/plain is ambiguous and thus unparseable. | |
| 148 EXPECT_FALSE(RunParser(kTextPlain, input, &output)); | |
| 149 } | |
| OLD | NEW |