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

Side by Side Diff: third_party/crashpad/crashpad/util/net/http_transport_test.cc

Issue 2804713002: Update Crashpad to b4095401639ebe2ad33169e5c1d994065cbff1b8 (Closed)
Patch Set: Created 3 years, 8 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Crashpad Authors. All rights reserved. 1 // Copyright 2014 The Crashpad Authors. All rights reserved.
2 // 2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with 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 5 // You may obtain a copy of the License at
6 // 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
8 // 8 //
9 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
(...skipping 13 matching lines...) Expand all
24 #include <vector> 24 #include <vector>
25 25
26 #include "base/files/file_path.h" 26 #include "base/files/file_path.h"
27 #include "base/format_macros.h" 27 #include "base/format_macros.h"
28 #include "base/logging.h" 28 #include "base/logging.h"
29 #include "base/strings/stringprintf.h" 29 #include "base/strings/stringprintf.h"
30 #include "base/strings/utf_string_conversions.h" 30 #include "base/strings/utf_string_conversions.h"
31 #include "build/build_config.h" 31 #include "build/build_config.h"
32 #include "gtest/gtest.h" 32 #include "gtest/gtest.h"
33 #include "test/multiprocess_exec.h" 33 #include "test/multiprocess_exec.h"
34 #include "test/paths.h" 34 #include "test/test_paths.h"
35 #include "util/file/file_io.h" 35 #include "util/file/file_io.h"
36 #include "util/misc/random_string.h" 36 #include "util/misc/random_string.h"
37 #include "util/net/http_body.h" 37 #include "util/net/http_body.h"
38 #include "util/net/http_headers.h" 38 #include "util/net/http_headers.h"
39 #include "util/net/http_multipart_builder.h" 39 #include "util/net/http_multipart_builder.h"
40 40
41 namespace crashpad { 41 namespace crashpad {
42 namespace test { 42 namespace test {
43 namespace { 43 namespace {
44 44
45 class HTTPTransportTestFixture : public MultiprocessExec { 45 class HTTPTransportTestFixture : public MultiprocessExec {
46 public: 46 public:
47 using RequestValidator = 47 using RequestValidator =
48 void(*)(HTTPTransportTestFixture*, const std::string&); 48 void(*)(HTTPTransportTestFixture*, const std::string&);
49 49
50 HTTPTransportTestFixture(const HTTPHeaders& headers, 50 HTTPTransportTestFixture(const HTTPHeaders& headers,
51 std::unique_ptr<HTTPBodyStream> body_stream, 51 std::unique_ptr<HTTPBodyStream> body_stream,
52 uint16_t http_response_code, 52 uint16_t http_response_code,
53 RequestValidator request_validator) 53 RequestValidator request_validator)
54 : MultiprocessExec(), 54 : MultiprocessExec(),
55 headers_(headers), 55 headers_(headers),
56 body_stream_(std::move(body_stream)), 56 body_stream_(std::move(body_stream)),
57 response_code_(http_response_code), 57 response_code_(http_response_code),
58 request_validator_(request_validator) { 58 request_validator_(request_validator) {
59 base::FilePath server_path = Paths::TestDataRoot().Append( 59 base::FilePath server_path = TestPaths::TestDataRoot().Append(
60 FILE_PATH_LITERAL("util/net/http_transport_test_server.py")); 60 FILE_PATH_LITERAL("util/net/http_transport_test_server.py"));
61 #if defined(OS_POSIX) 61 #if defined(OS_POSIX)
62 SetChildCommand(server_path.value(), nullptr); 62 SetChildCommand(server_path.value(), nullptr);
63 #elif defined(OS_WIN) 63 #elif defined(OS_WIN)
64 // Explicitly invoke a shell and python so that python can be found in the 64 // Explicitly invoke a shell and python so that python can be found in the
65 // path, and run the test script. 65 // path, and run the test script.
66 std::vector<std::string> args; 66 std::vector<std::string> args;
67 args.push_back("/c"); 67 args.push_back("/c");
68 args.push_back("python"); 68 args.push_back("python");
69 args.push_back(base::UTF16ToUTF8(server_path.value())); 69 args.push_back(base::UTF16ToUTF8(server_path.value()));
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 for (const auto& pair : headers_) { 104 for (const auto& pair : headers_) {
105 transport->SetHeader(pair.first, pair.second); 105 transport->SetHeader(pair.first, pair.second);
106 } 106 }
107 transport->SetBodyStream(std::move(body_stream_)); 107 transport->SetBodyStream(std::move(body_stream_));
108 108
109 std::string response_body; 109 std::string response_body;
110 bool success = transport->ExecuteSynchronously(&response_body); 110 bool success = transport->ExecuteSynchronously(&response_body);
111 if (response_code_ == 200) { 111 if (response_code_ == 200) {
112 EXPECT_TRUE(success); 112 EXPECT_TRUE(success);
113 std::string expect_response_body = random_string + "\r\n"; 113 std::string expect_response_body = random_string + "\r\n";
114 EXPECT_EQ(expect_response_body, response_body); 114 EXPECT_EQ(response_body, expect_response_body);
115 } else { 115 } else {
116 EXPECT_FALSE(success); 116 EXPECT_FALSE(success);
117 EXPECT_TRUE(response_body.empty()); 117 EXPECT_TRUE(response_body.empty());
118 } 118 }
119 119
120 // Read until the child's stdout closes. 120 // Read until the child's stdout closes.
121 std::string request; 121 std::string request;
122 char buf[32]; 122 char buf[32];
123 FileOperationResult bytes_read; 123 FileOperationResult bytes_read;
124 while ((bytes_read = ReadFile(ReadPipeHandle(), buf, sizeof(buf))) != 0) { 124 while ((bytes_read = ReadFile(ReadPipeHandle(), buf, sizeof(buf))) != 0) {
(...skipping 10 matching lines...) Expand all
135 uint16_t response_code_; 135 uint16_t response_code_;
136 RequestValidator request_validator_; 136 RequestValidator request_validator_;
137 }; 137 };
138 138
139 const char kMultipartFormData[] = "multipart/form-data"; 139 const char kMultipartFormData[] = "multipart/form-data";
140 140
141 void GetHeaderField(const std::string& request, 141 void GetHeaderField(const std::string& request,
142 const std::string& header, 142 const std::string& header,
143 std::string* value) { 143 std::string* value) {
144 size_t index = request.find(header); 144 size_t index = request.find(header);
145 ASSERT_NE(std::string::npos, index); 145 ASSERT_NE(index, std::string::npos);
146 // Since the header is never the first line of the request, it should always 146 // Since the header is never the first line of the request, it should always
147 // be preceded by a CRLF. 147 // be preceded by a CRLF.
148 EXPECT_EQ('\n', request[index - 1]); 148 EXPECT_EQ(request[index - 1], '\n');
149 EXPECT_EQ('\r', request[index - 2]); 149 EXPECT_EQ(request[index - 2], '\r');
150 150
151 index += header.length(); 151 index += header.length();
152 EXPECT_EQ(':', request[index++]); 152 EXPECT_EQ(request[index++], ':');
153 // Per RFC 7230 §3.2, there can be one or more spaces or horizontal tabs. 153 // Per RFC 7230 §3.2, there can be one or more spaces or horizontal tabs.
154 // For testing purposes, just assume one space. 154 // For testing purposes, just assume one space.
155 EXPECT_EQ(' ', request[index++]); 155 EXPECT_EQ(request[index++], ' ');
156 156
157 size_t header_end = request.find('\r', index); 157 size_t header_end = request.find('\r', index);
158 ASSERT_NE(std::string::npos, header_end); 158 ASSERT_NE(header_end, std::string::npos);
159 159
160 *value = request.substr(index, header_end - index); 160 *value = request.substr(index, header_end - index);
161 } 161 }
162 162
163 void GetMultipartBoundary(const std::string& request, 163 void GetMultipartBoundary(const std::string& request,
164 std::string* multipart_boundary) { 164 std::string* multipart_boundary) {
165 std::string content_type; 165 std::string content_type;
166 GetHeaderField(request, kContentType, &content_type); 166 GetHeaderField(request, kContentType, &content_type);
167 167
168 ASSERT_GE(content_type.length(), strlen(kMultipartFormData)); 168 ASSERT_GE(content_type.length(), strlen(kMultipartFormData));
169 size_t index = strlen(kMultipartFormData); 169 size_t index = strlen(kMultipartFormData);
170 EXPECT_EQ(kMultipartFormData, content_type.substr(0, index)); 170 EXPECT_EQ(content_type.substr(0, index), kMultipartFormData);
171 171
172 EXPECT_EQ(';', content_type[index++]); 172 EXPECT_EQ(content_type[index++], ';');
173 173
174 size_t boundary_begin = content_type.find('=', index); 174 size_t boundary_begin = content_type.find('=', index);
175 ASSERT_NE(std::string::npos, boundary_begin); 175 ASSERT_NE(boundary_begin, std::string::npos);
176 EXPECT_EQ('=', content_type[boundary_begin++]); 176 EXPECT_EQ(content_type[boundary_begin++], '=');
177 if (multipart_boundary) { 177 if (multipart_boundary) {
178 *multipart_boundary = content_type.substr(boundary_begin); 178 *multipart_boundary = content_type.substr(boundary_begin);
179 } 179 }
180 } 180 }
181 181
182 const char kBoundaryEq[] = "boundary="; 182 const char kBoundaryEq[] = "boundary=";
183 183
184 void ValidFormData(HTTPTransportTestFixture* fixture, 184 void ValidFormData(HTTPTransportTestFixture* fixture,
185 const std::string& request) { 185 const std::string& request) {
186 std::string actual_boundary; 186 std::string actual_boundary;
187 GetMultipartBoundary(request, &actual_boundary); 187 GetMultipartBoundary(request, &actual_boundary);
188 188
189 const auto& content_type = fixture->headers().find(kContentType); 189 const auto& content_type = fixture->headers().find(kContentType);
190 ASSERT_NE(fixture->headers().end(), content_type); 190 ASSERT_NE(content_type, fixture->headers().end());
191 191
192 size_t boundary = content_type->second.find(kBoundaryEq); 192 size_t boundary = content_type->second.find(kBoundaryEq);
193 ASSERT_NE(std::string::npos, boundary); 193 ASSERT_NE(boundary, std::string::npos);
194 std::string expected_boundary = 194 std::string expected_boundary =
195 content_type->second.substr(boundary + strlen(kBoundaryEq)); 195 content_type->second.substr(boundary + strlen(kBoundaryEq));
196 EXPECT_EQ(expected_boundary, actual_boundary); 196 EXPECT_EQ(actual_boundary, expected_boundary);
197 197
198 size_t body_start = request.find("\r\n\r\n"); 198 size_t body_start = request.find("\r\n\r\n");
199 ASSERT_NE(std::string::npos, body_start); 199 ASSERT_NE(body_start, std::string::npos);
200 body_start += 4; 200 body_start += 4;
201 201
202 std::string expected = "--" + expected_boundary + "\r\n"; 202 std::string expected = "--" + expected_boundary + "\r\n";
203 expected += "Content-Disposition: form-data; name=\"key1\"\r\n\r\n"; 203 expected += "Content-Disposition: form-data; name=\"key1\"\r\n\r\n";
204 expected += "test\r\n"; 204 expected += "test\r\n";
205 ASSERT_LT(body_start + expected.length(), request.length()); 205 ASSERT_LT(body_start + expected.length(), request.length());
206 EXPECT_EQ(expected, request.substr(body_start, expected.length())); 206 EXPECT_EQ(request.substr(body_start, expected.length()), expected);
207 207
208 body_start += expected.length(); 208 body_start += expected.length();
209 209
210 expected = "--" + expected_boundary + "\r\n"; 210 expected = "--" + expected_boundary + "\r\n";
211 expected += "Content-Disposition: form-data; name=\"key2\"\r\n\r\n"; 211 expected += "Content-Disposition: form-data; name=\"key2\"\r\n\r\n";
212 expected += "--abcdefg123\r\n"; 212 expected += "--abcdefg123\r\n";
213 expected += "--" + expected_boundary + "--\r\n"; 213 expected += "--" + expected_boundary + "--\r\n";
214 ASSERT_EQ(body_start + expected.length(), request.length()); 214 ASSERT_EQ(request.length(), body_start + expected.length());
215 EXPECT_EQ(expected, request.substr(body_start)); 215 EXPECT_EQ(request.substr(body_start), expected);
216 } 216 }
217 217
218 TEST(HTTPTransport, ValidFormData) { 218 TEST(HTTPTransport, ValidFormData) {
219 HTTPMultipartBuilder builder; 219 HTTPMultipartBuilder builder;
220 builder.SetFormData("key1", "test"); 220 builder.SetFormData("key1", "test");
221 builder.SetFormData("key2", "--abcdefg123"); 221 builder.SetFormData("key2", "--abcdefg123");
222 222
223 HTTPHeaders headers; 223 HTTPHeaders headers;
224 builder.PopulateContentHeaders(&headers); 224 builder.PopulateContentHeaders(&headers);
225 225
(...skipping 15 matching lines...) Expand all
241 &ValidFormData); 241 &ValidFormData);
242 test.Run(); 242 test.Run();
243 } 243 }
244 244
245 const char kTextPlain[] = "text/plain"; 245 const char kTextPlain[] = "text/plain";
246 246
247 void ErrorResponse(HTTPTransportTestFixture* fixture, 247 void ErrorResponse(HTTPTransportTestFixture* fixture,
248 const std::string& request) { 248 const std::string& request) {
249 std::string content_type; 249 std::string content_type;
250 GetHeaderField(request, kContentType, &content_type); 250 GetHeaderField(request, kContentType, &content_type);
251 EXPECT_EQ(kTextPlain, content_type); 251 EXPECT_EQ(content_type, kTextPlain);
252 } 252 }
253 253
254 TEST(HTTPTransport, ErrorResponse) { 254 TEST(HTTPTransport, ErrorResponse) {
255 HTTPMultipartBuilder builder; 255 HTTPMultipartBuilder builder;
256 HTTPHeaders headers; 256 HTTPHeaders headers;
257 headers[kContentType] = kTextPlain; 257 headers[kContentType] = kTextPlain;
258 HTTPTransportTestFixture test(headers, builder.GetBodyStream(), 258 HTTPTransportTestFixture test(headers, builder.GetBodyStream(),
259 404, &ErrorResponse); 259 404, &ErrorResponse);
260 test.Run(); 260 test.Run();
261 } 261 }
262 262
263 const char kTextBody[] = "hello world"; 263 const char kTextBody[] = "hello world";
264 264
265 void UnchunkedPlainText(HTTPTransportTestFixture* fixture, 265 void UnchunkedPlainText(HTTPTransportTestFixture* fixture,
266 const std::string& request) { 266 const std::string& request) {
267 std::string header_value; 267 std::string header_value;
268 GetHeaderField(request, kContentType, &header_value); 268 GetHeaderField(request, kContentType, &header_value);
269 EXPECT_EQ(kTextPlain, header_value); 269 EXPECT_EQ(header_value, kTextPlain);
270 270
271 GetHeaderField(request, kContentLength, &header_value); 271 GetHeaderField(request, kContentLength, &header_value);
272 const auto& content_length = fixture->headers().find(kContentLength); 272 const auto& content_length = fixture->headers().find(kContentLength);
273 ASSERT_NE(fixture->headers().end(), content_length); 273 ASSERT_NE(content_length, fixture->headers().end());
274 EXPECT_EQ(content_length->second, header_value); 274 EXPECT_EQ(header_value, content_length->second);
275 275
276 size_t body_start = request.rfind("\r\n"); 276 size_t body_start = request.rfind("\r\n");
277 ASSERT_NE(std::string::npos, body_start); 277 ASSERT_NE(body_start, std::string::npos);
278 278
279 EXPECT_EQ(kTextBody, request.substr(body_start + 2)); 279 EXPECT_EQ(request.substr(body_start + 2), kTextBody);
280 } 280 }
281 281
282 TEST(HTTPTransport, UnchunkedPlainText) { 282 TEST(HTTPTransport, UnchunkedPlainText) {
283 std::unique_ptr<HTTPBodyStream> body_stream( 283 std::unique_ptr<HTTPBodyStream> body_stream(
284 new StringHTTPBodyStream(kTextBody)); 284 new StringHTTPBodyStream(kTextBody));
285 285
286 HTTPHeaders headers; 286 HTTPHeaders headers;
287 headers[kContentType] = kTextPlain; 287 headers[kContentType] = kTextPlain;
288 headers[kContentLength] = base::StringPrintf("%" PRIuS, strlen(kTextBody)); 288 headers[kContentLength] = base::StringPrintf("%" PRIuS, strlen(kTextBody));
289 289
(...skipping 17 matching lines...) Expand all
307 if (has_content_length) { 307 if (has_content_length) {
308 headers[kContentLength] = 308 headers[kContentLength] =
309 base::StringPrintf("%" PRIuS, request_string.size()); 309 base::StringPrintf("%" PRIuS, request_string.size());
310 } 310 }
311 HTTPTransportTestFixture test( 311 HTTPTransportTestFixture test(
312 headers, 312 headers,
313 std::move(body_stream), 313 std::move(body_stream),
314 200, 314 200,
315 [](HTTPTransportTestFixture* fixture, const std::string& request) { 315 [](HTTPTransportTestFixture* fixture, const std::string& request) {
316 size_t body_start = request.rfind("\r\n"); 316 size_t body_start = request.rfind("\r\n");
317 EXPECT_EQ(33 * 1024u + 2, request.size() - body_start); 317 EXPECT_EQ(request.size() - body_start, 33 * 1024u + 2);
318 }); 318 });
319 test.Run(); 319 test.Run();
320 } 320 }
321 321
322 TEST(HTTPTransport, Upload33k) { 322 TEST(HTTPTransport, Upload33k) {
323 RunUpload33k(true); 323 RunUpload33k(true);
324 } 324 }
325 325
326 TEST(HTTPTransport, Upload33k_LengthUnknown) { 326 TEST(HTTPTransport, Upload33k_LengthUnknown) {
327 // The same as Upload33k, but without declaring Content-Length ahead of time. 327 // The same as Upload33k, but without declaring Content-Length ahead of time.
328 RunUpload33k(false); 328 RunUpload33k(false);
329 } 329 }
330 330
331 } // namespace 331 } // namespace
332 } // namespace test 332 } // namespace test
333 } // namespace crashpad 333 } // namespace crashpad
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698