report_sender.cc 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  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. #include "net/url_request/report_sender.h"
  5. #include <utility>
  6. #include "net/base/elements_upload_data_stream.h"
  7. #include "net/base/isolation_info.h"
  8. #include "net/base/load_flags.h"
  9. #include "net/base/request_priority.h"
  10. #include "net/base/upload_bytes_element_reader.h"
  11. #include "net/http/http_status_code.h"
  12. #include "net/url_request/url_request_context.h"
  13. #include "url/gurl.h"
  14. namespace {
  15. const void* const kUserDataKey = &kUserDataKey;
  16. class CallbackInfo : public base::SupportsUserData::Data {
  17. public:
  18. CallbackInfo(net::ReportSender::SuccessCallback success_callback,
  19. net::ReportSender::ErrorCallback error_callback)
  20. : success_callback_(std::move(success_callback)),
  21. error_callback_(std::move(error_callback)) {}
  22. ~CallbackInfo() override = default;
  23. void RunSuccessCallback() {
  24. if (!success_callback_.is_null())
  25. std::move(success_callback_).Run();
  26. }
  27. void RunErrorCallback(const GURL& url,
  28. int net_error,
  29. int http_response_code) {
  30. if (!error_callback_.is_null())
  31. std::move(error_callback_).Run(url, net_error, http_response_code);
  32. }
  33. private:
  34. net::ReportSender::SuccessCallback success_callback_;
  35. net::ReportSender::ErrorCallback error_callback_;
  36. };
  37. } // namespace
  38. namespace net {
  39. const int ReportSender::kLoadFlags = LOAD_BYPASS_CACHE | LOAD_DISABLE_CACHE;
  40. ReportSender::ReportSender(URLRequestContext* request_context,
  41. net::NetworkTrafficAnnotationTag traffic_annotation)
  42. : request_context_(request_context),
  43. traffic_annotation_(traffic_annotation) {}
  44. ReportSender::~ReportSender() = default;
  45. void ReportSender::Send(const GURL& report_uri,
  46. base::StringPiece content_type,
  47. base::StringPiece report,
  48. const NetworkIsolationKey& network_isolation_key,
  49. SuccessCallback success_callback,
  50. ErrorCallback error_callback) {
  51. DCHECK(!content_type.empty());
  52. std::unique_ptr<URLRequest> url_request = request_context_->CreateRequest(
  53. report_uri, DEFAULT_PRIORITY, this, traffic_annotation_);
  54. url_request->SetUserData(
  55. &kUserDataKey, std::make_unique<CallbackInfo>(std::move(success_callback),
  56. std::move(error_callback)));
  57. url_request->SetLoadFlags(kLoadFlags);
  58. url_request->set_allow_credentials(false);
  59. url_request->set_isolation_info(IsolationInfo::CreatePartial(
  60. IsolationInfo::RequestType::kOther, network_isolation_key));
  61. HttpRequestHeaders extra_headers;
  62. extra_headers.SetHeader(HttpRequestHeaders::kContentType, content_type);
  63. url_request->SetExtraRequestHeaders(extra_headers);
  64. url_request->set_method("POST");
  65. std::vector<char> report_data(report.begin(), report.end());
  66. auto reader = std::make_unique<UploadOwnedBytesElementReader>(&report_data);
  67. url_request->set_upload(
  68. ElementsUploadDataStream::CreateWithReader(std::move(reader), 0));
  69. URLRequest* raw_url_request = url_request.get();
  70. inflight_requests_[raw_url_request] = std::move(url_request);
  71. raw_url_request->Start();
  72. }
  73. void ReportSender::OnResponseStarted(URLRequest* request, int net_error) {
  74. DCHECK_NE(ERR_IO_PENDING, net_error);
  75. CallbackInfo* callback_info =
  76. static_cast<CallbackInfo*>(request->GetUserData(&kUserDataKey));
  77. DCHECK(callback_info);
  78. if (net_error != OK) {
  79. DVLOG(1) << "Failed to send report for " << request->url().host();
  80. callback_info->RunErrorCallback(request->url(), net_error, -1);
  81. } else if (request->GetResponseCode() != net::HTTP_OK) {
  82. callback_info->RunErrorCallback(request->url(), OK,
  83. request->GetResponseCode());
  84. } else {
  85. callback_info->RunSuccessCallback();
  86. }
  87. CHECK_GT(inflight_requests_.erase(request), 0u);
  88. }
  89. void ReportSender::OnReadCompleted(URLRequest* request, int bytes_read) {
  90. NOTREACHED();
  91. }
  92. } // namespace net