test_server_helpers.cc 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // Copyright 2021 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 "components/policy/test_support/test_server_helpers.h"
  5. #include <utility>
  6. #include "base/ranges/algorithm.h"
  7. #include "components/policy/core/common/cloud/cloud_policy_constants.h"
  8. #include "net/base/url_util.h"
  9. #include "net/http/http_status_code.h"
  10. #include "net/test/embedded_test_server/http_request.h"
  11. #include "net/test/embedded_test_server/http_response.h"
  12. #include "third_party/re2/src/re2/re2.h"
  13. namespace policy {
  14. using ::net::test_server::BasicHttpResponse;
  15. using ::net::test_server::HttpRequest;
  16. using ::net::test_server::HttpResponse;
  17. namespace {
  18. // C++ does not offer a mechanism to check if a given status code is present in
  19. // net::HttpStatusCode enum. To allow distinguishing standard HTTP status code
  20. // from custom ones, we define this array that will contain all standard codes.
  21. constexpr net::HttpStatusCode kStandardHttpStatusCodes[] = {
  22. #define HTTP_STATUS_ENUM_VALUE(label, code, reason) net::HttpStatusCode(code),
  23. #include "net/http/http_status_code_list.h"
  24. #undef HTTP_STATUS_ENUM_VALUE
  25. };
  26. } // namespace
  27. void CustomHttpResponse::SendResponse(
  28. base::WeakPtr<net::test_server::HttpResponseDelegate> delegate) {
  29. std::string reason = "Custom";
  30. // The implementation of the BasicHttpResponse::reason() calls
  31. // net::GetHttpReasonPhrase, which requires status code to be a standard HTTP
  32. // status code and crashes otherwise. Hence we avoid calling it if a custom
  33. // HTTP code is used.
  34. // TODO(crbug/1280752): Make GetHttpReasonPhrase support custom codes instead.
  35. if (base::ranges::lower_bound(kStandardHttpStatusCodes, code()) !=
  36. base::ranges::end(kStandardHttpStatusCodes)) {
  37. reason = BasicHttpResponse::reason();
  38. }
  39. delegate->SendHeadersContentAndFinish(code(), reason, BuildHeaders(),
  40. content());
  41. }
  42. std::string KeyValueFromUrl(GURL url, const std::string& key) {
  43. std::string value;
  44. return net::GetValueForKeyInQuery(url, key, &value) ? value : std::string();
  45. }
  46. bool MeetsServerSideRequirements(GURL url) {
  47. std::string device_id = KeyValueFromUrl(url, dm_protocol::kParamDeviceID);
  48. return KeyValueFromUrl(url, dm_protocol::kParamDeviceType) ==
  49. dm_protocol::kValueDeviceType &&
  50. KeyValueFromUrl(url, dm_protocol::kParamAppType) ==
  51. dm_protocol::kValueAppType &&
  52. !device_id.empty() && device_id.size() <= 64;
  53. }
  54. bool GetTokenFromAuthorization(const HttpRequest& request,
  55. const std::string& token_header_prefix,
  56. std::string* out) {
  57. auto authorization = request.headers.find(dm_protocol::kAuthHeader);
  58. return authorization != request.headers.end() &&
  59. re2::RE2::FullMatch(authorization->second,
  60. token_header_prefix + "(.+)", out);
  61. }
  62. bool GetEnrollmentTokenFromRequest(const HttpRequest& request,
  63. std::string* out) {
  64. return GetTokenFromAuthorization(
  65. request, dm_protocol::kEnrollmentTokenAuthHeaderPrefix, out);
  66. }
  67. bool GetDeviceTokenFromRequest(const HttpRequest& request, std::string* out) {
  68. return GetTokenFromAuthorization(request,
  69. dm_protocol::kDMTokenAuthHeaderPrefix, out);
  70. }
  71. bool GetGoogleLoginFromRequest(const net::test_server::HttpRequest& request,
  72. std::string* out) {
  73. return net::GetValueForKeyInQuery(request.GetURL(), "oauth_token", out) ||
  74. GetTokenFromAuthorization(
  75. request, dm_protocol::kServiceTokenAuthHeaderPrefix, out) ||
  76. GetTokenFromAuthorization(request,
  77. dm_protocol::kOAuthTokenHeaderPrefix, out);
  78. }
  79. std::unique_ptr<HttpResponse> CreateHttpResponse(net::HttpStatusCode code,
  80. const std::string& content) {
  81. auto response = std::make_unique<CustomHttpResponse>();
  82. response->set_content_type("text/plain");
  83. response->set_code(code);
  84. response->set_content(content);
  85. return response;
  86. }
  87. } // namespace policy