embedded_test_server_handlers.cc 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. // Copyright 2018 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. #include "ios/testing/embedded_test_server_handlers.h"
  5. #include <utility>
  6. #include "base/bind.h"
  7. #include "base/strings/escape.h"
  8. #include "base/strings/string_number_conversions.h"
  9. #include "base/strings/string_split.h"
  10. #include "base/strings/stringprintf.h"
  11. #include "base/threading/thread_task_runner_handle.h"
  12. #include "net/test/embedded_test_server/http_request.h"
  13. #include "net/test/embedded_test_server/http_response.h"
  14. #include "url/gurl.h"
  15. namespace testing {
  16. const char kTestFormPage[] = "ios.testing.HandleForm";
  17. const char kTestFormFieldValue[] = "test-value";
  18. const char kTestDownloadMimeType[] = "application/vnd.test";
  19. namespace {
  20. // Extracts and escapes url spec from the query.
  21. std::string ExtractUlrSpecFromQuery(
  22. const net::test_server::HttpRequest& request) {
  23. GURL request_url = request.GetURL();
  24. std::string spec =
  25. base::UnescapeBinaryURLComponent(request_url.query_piece());
  26. // Escape the URL spec.
  27. GURL url(spec);
  28. return url.is_valid() ? base::EscapeForHTML(url.spec()) : spec;
  29. }
  30. // A HttpResponse that responds with |length| zeroes and kTestDownloadMimeType
  31. // MIME Type.
  32. class DownloadResponse : public net::test_server::BasicHttpResponse {
  33. public:
  34. DownloadResponse(int length) : length_(length) {}
  35. DownloadResponse(const DownloadResponse&) = delete;
  36. DownloadResponse& operator=(const DownloadResponse&) = delete;
  37. void SendResponse(
  38. base::WeakPtr<net::test_server::HttpResponseDelegate> delegate) override {
  39. base::StringPairs headers = {
  40. {"content-type", kTestDownloadMimeType},
  41. {"content-length", base::StringPrintf("%d", length_)}};
  42. delegate->SendResponseHeaders(net::HTTP_OK, "OK", headers);
  43. Send(delegate, length_);
  44. }
  45. private:
  46. // Sends "0" |count| times using 1KB blocks. Using blocks with smaller size is
  47. // performance inefficient and can cause unnecessary delays especially when
  48. // multiple tests run in parallel on a single machine.
  49. static void Send(
  50. base::WeakPtr<net::test_server::HttpResponseDelegate> delegate,
  51. int count) {
  52. if (!count) {
  53. if (delegate)
  54. delegate->FinishResponse();
  55. return;
  56. }
  57. int block_size = std::min(count, 1000);
  58. std::string content_block(block_size, 0);
  59. auto next_send =
  60. base::BindOnce(&DownloadResponse::Send, delegate, count - block_size);
  61. base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
  62. FROM_HERE,
  63. base::BindOnce(&net::test_server::HttpResponseDelegate::SendContents,
  64. delegate, content_block, std::move(next_send)),
  65. base::Milliseconds(100));
  66. }
  67. int length_ = 0;
  68. };
  69. } // namespace
  70. std::unique_ptr<net::test_server::HttpResponse> HandleIFrame(
  71. const net::test_server::HttpRequest& request) {
  72. auto http_response = std::make_unique<net::test_server::BasicHttpResponse>();
  73. http_response->set_content_type("text/html");
  74. http_response->set_content(
  75. base::StringPrintf("<html><head></head><body><iframe "
  76. "src='%s'></iframe>Main frame text</body></html>",
  77. ExtractUlrSpecFromQuery(request).c_str()));
  78. return std::move(http_response);
  79. }
  80. // Returns a page with |html|.
  81. std::unique_ptr<net::test_server::HttpResponse> HandlePageWithHtml(
  82. const std::string& html,
  83. const net::test_server::HttpRequest& request) {
  84. auto http_response = std::make_unique<net::test_server::BasicHttpResponse>();
  85. http_response->set_content_type("text/html");
  86. http_response->set_content(html);
  87. return std::move(http_response);
  88. }
  89. std::unique_ptr<net::test_server::HttpResponse> HandlePageWithContents(
  90. const net::test_server::HttpRequest& request) {
  91. auto http_response = std::make_unique<net::test_server::BasicHttpResponse>();
  92. http_response->set_content_type("text/html");
  93. http_response->set_content(request.GetURL().query());
  94. return std::move(http_response);
  95. }
  96. std::unique_ptr<net::test_server::HttpResponse> HandleEchoQueryOrCloseSocket(
  97. const bool& responds_with_content,
  98. const net::test_server::HttpRequest& request) {
  99. if (!responds_with_content) {
  100. return std::make_unique<net::test_server::RawHttpResponse>(
  101. /*headers=*/"", /*contents=*/"");
  102. }
  103. auto response = std::make_unique<net::test_server::BasicHttpResponse>();
  104. response->set_content_type("text/html");
  105. response->set_content(request.GetURL().query());
  106. response->AddCustomHeader("Cache-Control", "no-store");
  107. return std::move(response);
  108. }
  109. std::unique_ptr<net::test_server::HttpResponse> HandleForm(
  110. const net::test_server::HttpRequest& request) {
  111. std::string form_action = ExtractUlrSpecFromQuery(request);
  112. auto response = std::make_unique<net::test_server::BasicHttpResponse>();
  113. response->set_content_type("text/html");
  114. response->set_content(base::StringPrintf(
  115. "<form method='post' id='form' action='%s'>"
  116. " <input type='text' name='test-name' value='%s'>"
  117. "</form>"
  118. "%s",
  119. form_action.c_str(), kTestFormFieldValue, kTestFormPage));
  120. return std::move(response);
  121. }
  122. std::unique_ptr<net::test_server::HttpResponse> HandleDownload(
  123. const net::test_server::HttpRequest& request) {
  124. int length = 0;
  125. if (!base::StringToInt(request.GetURL().query(), &length)) {
  126. length = 1;
  127. }
  128. return std::make_unique<DownloadResponse>(length);
  129. }
  130. } // namespace testing