1 : // Copyright 2014 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #include "syzygy/kasko/internet_helpers.h"
16 :
17 : #include <string>
18 :
19 : #include "base/strings/string16.h"
20 : #include "base/strings/utf_string_conversions.h"
21 : #include "gtest/gtest.h"
22 : #include "syzygy/kasko/internet_unittest_helpers.h"
23 :
24 : namespace kasko {
25 :
26 E : TEST(InternetHelpersTest, ParseContentType) {
27 : const struct {
28 : const base::char16* content_type;
29 : const base::char16* expected_mime_type;
30 : const base::char16* expected_charset;
31 : const bool expected_had_charset;
32 : const base::char16* expected_boundary;
33 : } tests[] = {
34 : { L"text/html; charset=utf-8",
35 : L"text/html",
36 : L"utf-8",
37 : true,
38 : L""
39 : },
40 : { L"text/html; charset=",
41 : L"text/html",
42 : L"",
43 : true,
44 : L""
45 : },
46 : { L"text/html; charset",
47 : L"text/html",
48 : L"",
49 : false,
50 : L""
51 : },
52 : { L"text/html; charset='",
53 : L"text/html",
54 : L"",
55 : true,
56 : L""
57 : },
58 : { L"text/html; charset='utf-8'",
59 : L"text/html",
60 : L"utf-8",
61 : true,
62 : L""
63 : },
64 : { L"text/html; charset=\"utf-8\"",
65 : L"text/html",
66 : L"utf-8",
67 : true,
68 : L""
69 : },
70 : { L"text/html; charset =utf-8",
71 : L"text/html",
72 : L"utf-8",
73 : true,
74 : L""
75 : },
76 : { L"text/html; charset= utf-8",
77 : L"text/html",
78 : L"utf-8",
79 : true,
80 : L""
81 : },
82 : { L"text/html; charset=utf-8 ",
83 : L"text/html",
84 : L"utf-8",
85 : true,
86 : L""
87 : },
88 : { L"text/html; boundary=\"WebKit-ada-df-dsf-adsfadsfs\"",
89 : L"text/html",
90 : L"",
91 : false,
92 : L"\"WebKit-ada-df-dsf-adsfadsfs\""
93 : },
94 : { L"text/html; boundary =\"WebKit-ada-df-dsf-adsfadsfs\"",
95 : L"text/html",
96 : L"",
97 : false,
98 : L"\"WebKit-ada-df-dsf-adsfadsfs\""
99 : },
100 : { L"text/html; boundary= \"WebKit-ada-df-dsf-adsfadsfs\"",
101 : L"text/html",
102 : L"",
103 : false,
104 : L"\"WebKit-ada-df-dsf-adsfadsfs\""
105 : },
106 : { L"text/html; boundary= \"WebKit-ada-df-dsf-adsfadsfs\" ",
107 : L"text/html",
108 : L"",
109 : false,
110 : L"\"WebKit-ada-df-dsf-adsfadsfs\""
111 : },
112 : { L"text/html; boundary=\"WebKit-ada-df-dsf-adsfadsfs \"",
113 : L"text/html",
114 : L"",
115 : false,
116 : L"\"WebKit-ada-df-dsf-adsfadsfs \""
117 : },
118 : { L"text/html; boundary=WebKit-ada-df-dsf-adsfadsfs",
119 : L"text/html",
120 : L"",
121 : false,
122 : L"WebKit-ada-df-dsf-adsfadsfs"
123 : },
124 E : };
125 E : for (size_t i = 0; i < arraysize(tests); ++i) {
126 E : base::string16 mime_type;
127 E : base::string16 charset;
128 E : bool had_charset = false;
129 E : base::string16 boundary;
130 : ParseContentType(tests[i].content_type, &mime_type, &charset, &had_charset,
131 E : &boundary);
132 E : EXPECT_EQ(tests[i].expected_mime_type, mime_type) << "i=" << i;
133 E : EXPECT_EQ(tests[i].expected_charset, charset) << "i=" << i;
134 E : EXPECT_EQ(tests[i].expected_had_charset, had_charset) << "i=" << i;
135 E : EXPECT_EQ(tests[i].expected_boundary, boundary) << "i=" << i;
136 E : }
137 E : }
138 :
139 E : TEST(InternetHelpersTest, ComposeAndDecomposeUrl) {
140 : const struct {
141 : const base::char16* url;
142 : const base::char16* scheme;
143 : const base::char16* host;
144 : uint16_t port;
145 : const base::char16* path;
146 : } tests[] = {
147 : {L"http://example.com/", L"http", L"example.com", 80, L"/"},
148 : {L"https://example.com/", L"https", L"example.com", 443, L"/"},
149 : {L"https://sub.example.com/", L"https", L"sub.example.com", 443, L"/"},
150 : {L"https://example.com:9999/", L"https", L"example.com", 9999, L"/"},
151 : {L"http://example.com/a/b/c", L"http", L"example.com", 80, L"/a/b/c"},
152 E : };
153 E : for (size_t i = 0; i < arraysize(tests); ++i) {
154 E : base::string16 scheme, host, path;
155 E : uint16_t port = 0;
156 E : EXPECT_TRUE(DecomposeUrl(tests[i].url, &scheme, &host, &port, &path))
157 : << "i=" << i;
158 E : EXPECT_EQ(tests[i].scheme, scheme) << "i=" << i;
159 E : EXPECT_EQ(tests[i].host, host) << "i=" << i;
160 E : EXPECT_EQ(tests[i].port, port) << "i=" << i;
161 E : EXPECT_EQ(tests[i].path, path) << "i=" << i;
162 : EXPECT_EQ(tests[i].url,
163 : ComposeUrl(tests[i].host, tests[i].port, tests[i].path,
164 E : tests[i].scheme == base::string16(L"https")));
165 E : }
166 :
167 : const base::char16* invalid_urls[] = {L"",
168 : L"example.com",
169 : L"example.com/foo",
170 : L"/foo/bar",
171 : L"example.com:80",
172 : L"http://",
173 : L"http:",
174 : L"http:/example.com",
175 E : L"http:example.com"};
176 :
177 E : for (size_t i = 0; i < arraysize(invalid_urls); ++i) {
178 E : base::string16 scheme, host, path;
179 E : uint16_t port = 0;
180 E : EXPECT_FALSE(DecomposeUrl(invalid_urls[i], &scheme, &host, &port, &path))
181 : << "i=" << i;
182 E : }
183 E : }
184 :
185 E : TEST(InternetHelpersTest, GenerateMultipartHttpRequestBoundary) {
186 E : base::string16 boundary1 = GenerateMultipartHttpRequestBoundary();
187 E : base::string16 boundary2 = GenerateMultipartHttpRequestBoundary();
188 E : EXPECT_FALSE(boundary1.empty());
189 E : EXPECT_FALSE(boundary2.empty());
190 E : EXPECT_NE(boundary1, boundary2);
191 : ASSERT_EQ(base::string16::npos,
192 E : boundary1.find_first_not_of(L"-0123456789abcdefABCDEF"));
193 E : }
194 :
195 :
196 E : TEST(InternetHelpersTest, GenerateMultipartHttpRequestContentTypeHeader) {
197 E : base::string16 boundary = GenerateMultipartHttpRequestBoundary();
198 : base::string16 content_type_header =
199 E : GenerateMultipartHttpRequestContentTypeHeader(boundary);
200 :
201 E : size_t semicolon = content_type_header.find(L':');
202 E : ASSERT_NE(base::string16::npos, semicolon);
203 :
204 E : base::string16 mime_type, charset, parsed_boundary;
205 E : bool had_charset = false;
206 : ParseContentType(base::string16(content_type_header.begin() + semicolon + 1,
207 : content_type_header.end()),
208 E : &mime_type, &charset, &had_charset, &parsed_boundary);
209 E : EXPECT_EQ(boundary, parsed_boundary);
210 E : EXPECT_TRUE(charset.empty());
211 E : EXPECT_FALSE(had_charset);
212 E : EXPECT_EQ(L"multipart/form-data", mime_type);
213 E : }
214 :
215 E : TEST(InternetHelpersTest, GenerateMultipartHttpRequestBody) {
216 E : std::map<base::string16, base::string16> parameters;
217 E : parameters[L"param"] = L"value";
218 E : base::string16 boundary = GenerateMultipartHttpRequestBoundary();
219 E : std::string file = "file contents";
220 E : base::string16 file_part_name = L"file_name";
221 :
222 : std::string body = GenerateMultipartHttpRequestBody(parameters, file,
223 E : file_part_name, boundary);
224 : ExpectMultipartMimeMessageIsPlausible(boundary, parameters, file,
225 E : base::WideToUTF8(file_part_name), body);
226 E : }
227 :
228 : } // namespace kasko
|