OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 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 "net/test/embedded_test_server/default_handlers.h" | |
6 | |
7 #include <stdlib.h> | |
8 #include <ctime> | |
9 #include <map> | |
10 #include <sstream> | |
11 #include <string> | |
12 | |
13 #include "base/base64.h" | |
14 #include "base/files/file_path.h" | |
15 #include "base/files/file_util.h" | |
16 #include "base/format_macros.h" | |
17 #include "base/md5.h" | |
18 #include "base/path_service.h" | |
19 #include "base/strings/string_split.h" | |
20 #include "base/strings/string_util.h" | |
21 #include "base/strings/stringprintf.h" | |
22 #include "base/thread_task_runner_handle.h" | |
23 #include "base/time/time.h" | |
24 #include "net/base/escape.h" | |
25 #include "net/base/url_util.h" | |
26 #include "net/test/embedded_test_server/http_request.h" | |
27 #include "net/test/embedded_test_server/http_response.h" | |
28 #include "net/test/embedded_test_server/request_handler_util.h" | |
29 | |
30 namespace net { | |
31 namespace test_server { | |
32 namespace { | |
33 | |
34 const UnescapeRule::Type kUnescapeAll = | |
35 UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS | | |
36 UnescapeRule::SPOOFING_AND_CONTROL_CHARS | | |
37 UnescapeRule::REPLACE_PLUS_WITH_SPACE; | |
38 | |
39 const char kDefaultRealm[] = "testrealm"; | |
40 const char kDefaultPassword[] = "secret"; | |
41 const char kEtag[] = "abc"; | |
42 const char kLogoPath[] = "chrome/test/data/google/logo.gif"; | |
43 | |
44 scoped_ptr<HttpResponse> HandleDefaultConnect(const HttpRequest& request) { | |
45 if (request.method != METHOD_CONNECT) | |
46 return nullptr; | |
47 | |
48 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); | |
49 http_response->set_code(HTTP_BAD_REQUEST); | |
50 http_response->set_content( | |
51 "Your client has issued a malformed or illegal request."); | |
52 http_response->set_content_type("text/html"); | |
53 return http_response.Pass(); | |
54 } | |
55 | |
56 scoped_ptr<HttpResponse> HandleCacheTime(const HttpRequest& request) { | |
57 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); | |
58 http_response->set_content( | |
59 "<html><head><title>Cache: max-age=60</title></head></html>"); | |
60 http_response->set_content_type("text/html"); | |
61 http_response->AddCustomHeader("Cache-Control", "max-age=60"); | |
62 return http_response.Pass(); | |
63 } | |
64 | |
65 scoped_ptr<HttpResponse> HandleEchoHeader(const std::string& url, | |
66 const std::string& cache_control, | |
67 const HttpRequest& request) { | |
68 if (!ShouldHandle(request, url)) | |
69 return nullptr; | |
70 | |
71 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); | |
72 | |
73 GURL request_url = request.GetURL(); | |
74 if (request_url.has_query()) { | |
75 std::string header_name = request_url.query(); | |
76 http_response->AddCustomHeader("Vary", header_name); | |
77 if (request.headers.find(header_name) != request.headers.end()) | |
78 http_response->set_content(request.headers.at(header_name)); | |
79 else | |
80 http_response->set_content("None"); | |
81 } | |
82 | |
83 http_response->set_content_type("text/plain"); | |
84 http_response->AddCustomHeader("Cache-Control", cache_control); | |
85 return http_response.Pass(); | |
86 } | |
87 | |
88 scoped_ptr<HttpResponse> HandleEcho(const HttpRequest& request) { | |
89 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); | |
90 | |
91 GURL request_url = request.GetURL(); | |
92 if (request_url.has_query()) { | |
93 RequestQuery query = ParseQuery(request_url); | |
94 if (query.find("status") != query.end()) | |
95 http_response->set_code(static_cast<HttpStatusCode>( | |
96 std::atoi(query["status"].front().c_str()))); | |
97 } | |
98 | |
99 http_response->set_content_type("text/html"); | |
100 if (request.method != METHOD_POST && request.method != METHOD_PUT) | |
101 http_response->set_content("Echo"); | |
102 else | |
103 http_response->set_content(request.content); | |
104 return http_response.Pass(); | |
105 } | |
106 | |
107 scoped_ptr<HttpResponse> HandleEchoTitle(const HttpRequest& request) { | |
108 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); | |
109 http_response->set_content_type("text/html"); | |
110 http_response->set_content("<html><head><title>" + request.content + | |
111 "</title></head></html>"); | |
112 return http_response.Pass(); | |
113 } | |
114 | |
115 scoped_ptr<HttpResponse> HandleEchoAll(const HttpRequest& request) { | |
116 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); | |
117 | |
118 std::string body = | |
119 "<html><head><style>" | |
120 "pre { border: 1px solid black; margin: 5px; padding: 5px }" | |
121 "</style></head><body>" | |
122 "<div style=\"float: right\">" | |
123 "<a href=\"/echo\">back to referring page</a></div>" | |
124 "<h1>Request Body:</h1><pre>"; | |
125 | |
126 if (request.has_content) { | |
127 std::vector<std::string> query_list = base::SplitString( | |
128 request.content, "&", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); | |
129 for (const auto& query : query_list) | |
130 body += query + "\n"; | |
131 } | |
132 | |
133 body += | |
134 "</pre>" | |
135 "<h1>Request Headers:</h1><pre>" + | |
136 request.all_headers + | |
137 "</pre>" | |
138 "</body></html>"; | |
139 | |
140 http_response->set_content_type("text/html"); | |
141 http_response->set_content(body); | |
142 return http_response.Pass(); | |
143 } | |
144 | |
145 scoped_ptr<HttpResponse> HandleSetCookie(const HttpRequest& request) { | |
146 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); | |
147 http_response->set_content_type("text/html"); | |
148 std::string content; | |
149 GURL request_url = request.GetURL(); | |
150 if (request_url.has_query()) { | |
151 std::vector<std::string> cookies = base::SplitString( | |
152 request_url.query(), "&", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); | |
153 for (const auto& cookie : cookies) { | |
154 http_response->AddCustomHeader("Set-Cookie", cookie); | |
155 content += cookie; | |
156 } | |
157 } | |
158 | |
159 http_response->set_content(content); | |
160 return http_response.Pass(); | |
161 } | |
162 | |
163 scoped_ptr<HttpResponse> HandleSetManyCookies(const HttpRequest& request) { | |
164 std::string content; | |
165 | |
166 GURL request_url = request.GetURL(); | |
167 size_t num = 0; | |
168 if (request_url.has_query()) | |
169 num = std::atoi(request_url.query().c_str()); | |
170 | |
171 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); | |
172 http_response->set_content_type("text/html"); | |
173 for (size_t i = 0; i < num; ++i) { | |
174 http_response->AddCustomHeader("Set-Cookie", "a="); | |
175 } | |
176 | |
177 http_response->set_content( | |
178 base::StringPrintf("%" PRIuS " cookies were sent", num)); | |
179 return http_response.Pass(); | |
180 } | |
181 | |
182 scoped_ptr<HttpResponse> HandleExpectAndSetCookie(const HttpRequest& request) { | |
183 std::vector<std::string> received_cookies; | |
184 if (request.headers.find("Cookie") != request.headers.end()) { | |
185 received_cookies = | |
186 base::SplitString(request.headers.at("Cookie"), ";", | |
187 base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); | |
188 } | |
189 | |
190 bool got_all_expected = true; | |
191 GURL request_url = request.GetURL(); | |
192 RequestQuery query_list = ParseQuery(request_url); | |
193 if (query_list.find("expect") != query_list.end()) { | |
194 for (const auto& expected_cookie : query_list.at("expect")) { | |
195 bool found = false; | |
196 for (const auto& received_cookie : received_cookies) { | |
197 if (expected_cookie == received_cookie) | |
198 found = true; | |
199 } | |
200 got_all_expected &= found; | |
201 } | |
202 } | |
203 | |
204 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); | |
205 http_response->set_content_type("text/html"); | |
206 if (got_all_expected) { | |
207 for (const auto& cookie : query_list.at("set")) { | |
208 http_response->AddCustomHeader( | |
209 "Set-Cookie", net::UnescapeURLComponent(cookie, kUnescapeAll)); | |
210 } | |
211 } | |
212 | |
213 std::string content; | |
214 if (query_list.find("data") != query_list.end()) { | |
215 for (const auto& item : query_list.at("data")) | |
216 content += item; | |
217 } | |
218 | |
219 http_response->set_content(content); | |
220 return http_response.Pass(); | |
221 } | |
222 | |
223 scoped_ptr<HttpResponse> HandleSetHeader(const HttpRequest& request) { | |
224 std::string content; | |
225 | |
226 GURL request_url = request.GetURL(); | |
227 | |
228 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); | |
229 http_response->set_content_type("text/html"); | |
230 if (request_url.has_query()) { | |
231 RequestQuery headers = ParseQuery(request_url); | |
232 for (const auto& header : headers) { | |
233 if (header.first.find(": ") == std::string::npos) | |
mmenke
2015/10/30 15:26:35
Suggest just stuffing this in a local. 3 find cal
svaldez
2015/10/30 15:57:40
Done.
| |
234 continue; | |
235 std::string key = header.first.substr(0, header.first.find(": ")); | |
236 std::string value = header.first.substr(header.first.find(": ") + 2); | |
237 http_response->AddCustomHeader(key, value); | |
238 content += header.first; | |
239 } | |
240 } | |
241 | |
242 http_response->set_content(content); | |
243 return http_response.Pass(); | |
244 } | |
245 | |
246 scoped_ptr<HttpResponse> HandleNoContent(const HttpRequest& request) { | |
247 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); | |
248 http_response->set_code(HTTP_NO_CONTENT); | |
249 return http_response.Pass(); | |
250 } | |
251 | |
252 scoped_ptr<HttpResponse> HandleCloseSocket(const HttpRequest& request) { | |
253 scoped_ptr<RawHttpResponse> http_response(new RawHttpResponse("", "")); | |
254 return http_response.Pass(); | |
255 } | |
256 | |
257 scoped_ptr<HttpResponse> HandleAuthBasic(const HttpRequest& request) { | |
258 GURL request_url = request.GetURL(); | |
259 RequestQuery query = ParseQuery(request_url); | |
260 | |
261 std::string expected_password = kDefaultPassword; | |
262 if (query.find("password") != query.end()) | |
263 expected_password = query.at("password").front(); | |
264 std::string realm = kDefaultRealm; | |
265 if (query.find("realm") != query.end()) | |
266 realm = query.at("realm").front(); | |
267 | |
268 bool authed = false; | |
269 std::string error; | |
270 std::string auth; | |
271 std::string username; | |
272 std::string userpass; | |
273 std::string password; | |
274 std::string b64str; | |
275 if (request.headers.find("Authorization") == request.headers.end()) { | |
276 error = "Missing Authorization Header"; | |
277 } else { | |
278 auth = request.headers.at("Authorization"); | |
279 if (auth.find("Basic ") == std::string::npos) { | |
280 error = "Invalid Authorization Header"; | |
281 } else { | |
282 b64str = auth.substr(std::string("Basic ").size()); | |
283 base::Base64Decode(b64str, &userpass); | |
284 if (userpass.find(":") != std::string::npos) { | |
285 username = userpass.substr(0, userpass.find(":")); | |
286 password = userpass.substr(userpass.find(":") + 1); | |
287 if (password == expected_password) | |
288 authed = true; | |
289 else | |
290 error = "Invalid Credentials"; | |
291 } else { | |
292 error = "Invalid Credentials"; | |
293 } | |
294 } | |
295 } | |
296 | |
297 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); | |
298 if (!authed) { | |
299 http_response->set_code(HTTP_UNAUTHORIZED); | |
300 http_response->set_content_type("text/html"); | |
301 http_response->AddCustomHeader("WWW-Authenticate", | |
302 "Basic realm=\"" + realm + "\""); | |
303 if (query.find("set-cookie-if-challenged") != query.end()) | |
304 http_response->AddCustomHeader("Set-Cookie", "got_challenged=true"); | |
305 http_response->set_content(base::StringPrintf( | |
306 "<html><head><title>Denied: %s</title></head>" | |
307 "<body>auth=%s<p>b64str=%s<p>username: %s<p>userpass: %s<p>" | |
308 "password: %s<p>You sent:<br>%s<p></body></html>", | |
309 error.c_str(), auth.c_str(), b64str.c_str(), username.c_str(), | |
310 userpass.c_str(), password.c_str(), request.all_headers.c_str())); | |
311 return http_response.Pass(); | |
312 } | |
313 | |
314 if (request.headers.find("If-None-Match") != request.headers.end() && | |
315 request.headers.at("If-None-Match") == kEtag) { | |
316 http_response->set_code(HTTP_NOT_MODIFIED); | |
317 return http_response.Pass(); | |
318 } | |
319 | |
320 base::FilePath file_path = | |
321 base::FilePath().AppendASCII(request.relative_url.substr(1)); | |
322 if (file_path.FinalExtension() == FILE_PATH_LITERAL("gif")) { | |
323 base::FilePath server_root; | |
324 PathService::Get(base::DIR_SOURCE_ROOT, &server_root); | |
325 base::FilePath gif_path = server_root.AppendASCII(kLogoPath); | |
326 std::string gif_data; | |
327 base::ReadFileToString(gif_path, &gif_data); | |
328 http_response->set_content_type("image/gif"); | |
329 http_response->set_content(gif_data); | |
330 } else { | |
331 http_response->set_content_type("text/html"); | |
332 http_response->set_content( | |
333 base::StringPrintf("<html><head><title>%s/%s</title></head>" | |
334 "<body>auth=%s<p>You sent:<br>%s<p></body></html>", | |
335 username.c_str(), password.c_str(), auth.c_str(), | |
336 request.all_headers.c_str())); | |
337 } | |
338 | |
339 http_response->AddCustomHeader("Cache-Control", "max-age=60000"); | |
340 http_response->AddCustomHeader("Etag", kEtag); | |
341 return http_response.Pass(); | |
342 } | |
343 | |
344 scoped_ptr<HttpResponse> HandleAuthDigest(const HttpRequest& request) { | |
345 std::string nonce = base::MD5String( | |
346 base::StringPrintf("privatekey%s", request.relative_url.c_str())); | |
347 std::string opaque = base::MD5String("opaque"); | |
348 std::string password = kDefaultPassword; | |
349 std::string realm = kDefaultRealm; | |
350 | |
351 bool authed = false; | |
352 std::string error; | |
353 std::string auth; | |
354 std::string digest_str = "Digest"; | |
355 std::string username; | |
356 if (request.headers.find("Authorization") == request.headers.end()) { | |
357 error = "no auth"; | |
358 } else if (request.headers.at("Authorization").substr(0, digest_str.size()) != | |
359 digest_str) { | |
360 error = "not digest"; | |
361 } else { | |
362 auth = request.headers.at("Authorization").substr(digest_str.size() + 1); | |
363 | |
364 std::map<std::string, std::string> auth_pairs; | |
365 base::StringPairs auth_vector; | |
366 base::SplitStringIntoKeyValuePairs(auth, '=', ',', &auth_vector); | |
367 for (const auto& auth_pair : auth_vector) { | |
368 std::string key; | |
369 std::string value; | |
370 base::TrimWhitespaceASCII(auth_pair.first, base::TRIM_ALL, &key); | |
371 base::TrimWhitespaceASCII(auth_pair.second, base::TRIM_ALL, &value); | |
372 if (value.substr(0, 1) == "\"" && value.substr(value.size() - 1) == "\"") | |
mmenke
2015/10/30 15:26:35
Just use "at" instead of substr?
svaldez
2015/10/30 15:57:40
Done.
| |
373 value = value.substr(1, value.size() - 2); | |
mmenke
2015/10/30 15:26:35
Should handle size() <= 1 here and above (Normally
svaldez
2015/10/30 15:57:40
Done.
| |
374 auth_pairs[key] = value; | |
375 } | |
376 | |
377 if (auth_pairs["nonce"] != nonce) { | |
378 error = "wrong nonce"; | |
379 } else if (auth_pairs["opaque"] != opaque) { | |
380 error = "wrong opaque"; | |
381 } else { | |
382 username = auth_pairs["username"]; | |
383 | |
384 std::string hash1 = base::MD5String( | |
385 base::StringPrintf("%s:%s:%s", auth_pairs["username"].c_str(), | |
386 realm.c_str(), password.c_str())); | |
387 std::string hash2 = base::MD5String(base::StringPrintf( | |
388 "%s:%s", request.method_string.c_str(), auth_pairs["uri"].c_str())); | |
389 | |
390 std::string response; | |
391 if (auth_pairs.find("qop") != auth_pairs.end() && | |
392 auth_pairs.find("nc") != auth_pairs.end() && | |
393 auth_pairs.find("cnonce") != auth_pairs.end()) { | |
394 response = base::MD5String(base::StringPrintf( | |
395 "%s:%s:%s:%s:%s:%s", hash1.c_str(), nonce.c_str(), | |
396 auth_pairs["nc"].c_str(), auth_pairs["cnonce"].c_str(), | |
397 auth_pairs["qop"].c_str(), hash2.c_str())); | |
398 } else { | |
399 response = base::MD5String(base::StringPrintf( | |
400 "%s:%s:%s", hash1.c_str(), nonce.c_str(), hash2.c_str())); | |
401 } | |
402 | |
403 if (auth_pairs["response"] == response) | |
404 authed = true; | |
405 else | |
406 error = "wrong password"; | |
407 } | |
408 } | |
409 | |
410 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); | |
411 if (!authed) { | |
412 http_response->set_code(HTTP_UNAUTHORIZED); | |
413 http_response->set_content_type("text/html"); | |
414 std::string auth_header = base::StringPrintf( | |
415 "Digest realm=\"%s\", " | |
416 "domain=\"/\", qop=\"auth\", algorithm=MD5, nonce=\"%s\", " | |
417 "opaque=\"%s\"", | |
418 realm.c_str(), nonce.c_str(), opaque.c_str()); | |
419 http_response->AddCustomHeader("WWW-Authenticate", auth_header); | |
420 http_response->set_content(base::StringPrintf( | |
421 "<html><head><title>Denied: %s</title></head>" | |
422 "<body>auth=%s<p>" | |
423 "You sent:<br>%s<p>We are replying:<br>%s<p></body></html>", | |
424 error.c_str(), auth.c_str(), request.all_headers.c_str(), | |
425 auth_header.c_str())); | |
426 return http_response.Pass(); | |
427 } | |
428 | |
429 http_response->set_content_type("text/html"); | |
430 http_response->set_content( | |
431 base::StringPrintf("<html><head><title>%s/%s</title></head>" | |
432 "<body>auth=%s<p></body></html>", | |
433 username.c_str(), password.c_str(), auth.c_str())); | |
434 | |
435 return http_response.Pass(); | |
436 } | |
437 | |
438 scoped_ptr<HttpResponse> HandleServerRedirect(const HttpRequest& request) { | |
439 GURL request_url = request.GetURL(); | |
440 std::string dest = | |
441 net::UnescapeURLComponent(request_url.query(), kUnescapeAll); | |
442 | |
443 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); | |
444 http_response->set_code(HTTP_MOVED_PERMANENTLY); | |
445 http_response->AddCustomHeader("Location", dest); | |
446 http_response->set_content_type("text/html"); | |
447 http_response->set_content(base::StringPrintf( | |
448 "<html><head></head><body>Redirecting to %s</body></html>", | |
449 dest.c_str())); | |
450 return http_response.Pass(); | |
451 } | |
452 | |
453 scoped_ptr<HttpResponse> HandleCrossSiteRedirect(EmbeddedTestServer* server, | |
454 const HttpRequest& request) { | |
455 if (!ShouldHandle(request, "/cross-site")) | |
456 return nullptr; | |
457 | |
458 std::string dest_all = net::UnescapeURLComponent( | |
459 request.relative_url.substr(std::string("/cross-site").size() + 1), | |
460 kUnescapeAll); | |
461 | |
462 std::string dest = base::StringPrintf( | |
463 "//%s:%hu/%s", dest_all.substr(0, dest_all.find("/")).c_str(), | |
464 server->port(), dest_all.substr(dest_all.find("/") + 1).c_str()); | |
mmenke
2015/10/30 15:26:35
Again, should handle "/" not appearing in the stri
svaldez
2015/10/30 15:57:40
Done.
| |
465 | |
466 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); | |
467 http_response->set_code(HTTP_MOVED_PERMANENTLY); | |
468 http_response->AddCustomHeader("Location", dest); | |
469 http_response->set_content_type("text/html"); | |
470 http_response->set_content(base::StringPrintf( | |
471 "<html><head></head><body>Redirecting to %s</body></html>", | |
472 dest.c_str())); | |
473 return http_response.Pass(); | |
474 } | |
475 | |
476 scoped_ptr<HttpResponse> HandleClientRedirect(const HttpRequest& request) { | |
477 GURL request_url = request.GetURL(); | |
478 std::string dest = | |
479 net::UnescapeURLComponent(request_url.query(), kUnescapeAll); | |
480 | |
481 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); | |
482 http_response->set_content_type("text/html"); | |
483 http_response->set_content(base::StringPrintf( | |
484 "<html><head><meta http-equiv=\"refresh\" content=\"0;url=%s\"></head>" | |
485 "<body>Redirecting to %s</body></html>", | |
486 dest.c_str(), dest.c_str())); | |
487 return http_response.Pass(); | |
488 } | |
489 | |
490 scoped_ptr<HttpResponse> HandleDefaultResponse(const HttpRequest& request) { | |
491 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse); | |
492 http_response->set_content_type("text/html"); | |
493 http_response->set_content("Default response given for path: " + | |
494 request.relative_url); | |
495 return http_response.Pass(); | |
496 } | |
497 | |
498 class DelayedHttpResponse : public BasicHttpResponse { | |
mmenke
2015/10/30 15:26:35
Think this class is worth a comment.
svaldez
2015/10/30 15:57:40
Done.
| |
499 public: | |
500 DelayedHttpResponse(double delay) : delay_(delay) {} | |
mmenke
2015/10/30 15:26:35
explicit
svaldez
2015/10/30 15:57:40
Done.
| |
501 | |
502 void SendResponse(const SendBytesCallback& send, | |
503 const SendCompleteCallback& done) override { | |
504 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | |
505 FROM_HERE, base::Bind(send, ToResponseString(), done), | |
506 base::TimeDelta::FromSecondsD(delay_)); | |
507 } | |
508 | |
509 private: | |
510 double delay_; | |
mmenke
2015/10/30 15:26:34
nit: const?
mmenke
2015/10/30 15:26:35
DISALLOW_COPY_AND_ASSIGN
svaldez
2015/10/30 15:57:40
Done.
svaldez
2015/10/30 15:57:40
Done.
| |
511 }; | |
512 | |
513 scoped_ptr<HttpResponse> HandleSlowServer(const HttpRequest& request) { | |
mmenke
2015/10/30 15:26:34
Think this method is worth a comment. Should prob
svaldez
2015/10/30 15:57:40
Done.
| |
514 double delay = 1.0f; | |
515 | |
516 GURL request_url = request.GetURL(); | |
517 if (request_url.has_query()) { | |
518 delay = std::atof(request_url.query().c_str()); | |
519 } | |
mmenke
2015/10/30 15:26:35
nit: Remove braces
svaldez
2015/10/30 15:57:40
Done.
| |
520 | |
521 scoped_ptr<BasicHttpResponse> http_response(new DelayedHttpResponse(delay)); | |
522 http_response->set_content_type("text/plain"); | |
523 http_response->set_content(base::StringPrintf("waited %.1f seconds", delay)); | |
524 return http_response.Pass(); | |
525 } | |
526 | |
527 } // namespace anonymous | |
528 | |
529 #define PREFIXED_HANDLER(prefix, handler) \ | |
530 base::Bind(&HandlePrefixedRequest, prefix, base::Bind(handler)) | |
531 | |
532 void RegisterDefaultHandlers(EmbeddedTestServer* server) { | |
533 server->RegisterDefaultHandler(base::Bind(&HandleDefaultConnect)); | |
534 | |
535 server->RegisterDefaultHandler( | |
536 PREFIXED_HANDLER("/cachetime", &HandleCacheTime)); | |
537 server->RegisterDefaultHandler( | |
538 base::Bind(&HandleEchoHeader, "/echoheader", "no-cache")); | |
539 server->RegisterDefaultHandler( | |
540 base::Bind(&HandleEchoHeader, "/echoheadercache", "max-age=60000")); | |
541 server->RegisterDefaultHandler(PREFIXED_HANDLER("/echo", &HandleEcho)); | |
542 server->RegisterDefaultHandler( | |
543 PREFIXED_HANDLER("/echotitle", &HandleEchoTitle)); | |
544 server->RegisterDefaultHandler(PREFIXED_HANDLER("/echoall", &HandleEchoAll)); | |
545 server->RegisterDefaultHandler( | |
546 PREFIXED_HANDLER("/set-cookie", &HandleSetCookie)); | |
547 server->RegisterDefaultHandler( | |
548 PREFIXED_HANDLER("/set-many-cookies", &HandleSetManyCookies)); | |
549 server->RegisterDefaultHandler( | |
550 PREFIXED_HANDLER("/expect-and-set-cookie", &HandleExpectAndSetCookie)); | |
551 server->RegisterDefaultHandler( | |
552 PREFIXED_HANDLER("/set-header", &HandleSetHeader)); | |
553 server->RegisterDefaultHandler( | |
554 PREFIXED_HANDLER("/nocontent", &HandleNoContent)); | |
555 server->RegisterDefaultHandler( | |
556 PREFIXED_HANDLER("/close-socket", &HandleCloseSocket)); | |
557 server->RegisterDefaultHandler( | |
558 PREFIXED_HANDLER("/auth-basic", &HandleAuthBasic)); | |
559 server->RegisterDefaultHandler( | |
560 PREFIXED_HANDLER("/auth-digest", &HandleAuthDigest)); | |
561 server->RegisterDefaultHandler( | |
562 PREFIXED_HANDLER("/server-redirect", &HandleServerRedirect)); | |
563 server->RegisterDefaultHandler(base::Bind(&HandleCrossSiteRedirect, server)); | |
564 server->RegisterDefaultHandler( | |
565 PREFIXED_HANDLER("/client-redirect", &HandleClientRedirect)); | |
566 server->RegisterDefaultHandler( | |
567 PREFIXED_HANDLER("/defaultresponse", &HandleDefaultResponse)); | |
568 server->RegisterDefaultHandler(PREFIXED_HANDLER("/slow", &HandleSlowServer)); | |
569 | |
570 // TODO(svaldez): HandleDownload | |
571 // TODO(svaldez): HandleDownloadFinish | |
572 // TODO(svaldez): HandleZipFile | |
573 // TODO(svaldez): HandleRangeReset | |
574 // TODO(svaldez): HandleSSLManySmallRecords | |
575 // TODO(svaldez): HandleChunkedServer | |
576 // TODO(svaldez): HandleGetSSLSessionCache | |
577 // TODO(svaldez): HandleGetChannelID | |
578 // TODO(svaldez): HandleGetClientCert | |
579 // TODO(svaldez): HandleClientCipherList | |
580 // TODO(svaldez): HandleEchoMultipartPost | |
581 } | |
582 | |
583 #undef PREFIXED_HANDLER | |
584 | |
585 } // namespace test_server | |
586 } // namespace net | |
OLD | NEW |