| OLD | NEW | 
| (Empty) |  | 
 |    1 // Copyright 2017 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 "content/child/throttling_url_loader.h" | 
 |    6  | 
 |    7 namespace content { | 
 |    8  | 
 |    9 // static | 
 |   10 std::unique_ptr<ThrottlingURLLoader> ThrottlingURLLoader::CreateLoaderAndStart( | 
 |   11     mojom::URLLoaderFactory* factory, | 
 |   12     std::vector<std::unique_ptr<URLLoaderThrottle>> throttles, | 
 |   13     int32_t routing_id, | 
 |   14     int32_t request_id, | 
 |   15     uint32_t options, | 
 |   16     std::unique_ptr<ResourceRequest> url_request, | 
 |   17     mojom::URLLoaderClient* client) { | 
 |   18   std::unique_ptr<ThrottlingURLLoader> loader( | 
 |   19       new ThrottlingURLLoader(std::move(throttles), client)); | 
 |   20   loader->Start(factory, routing_id, request_id, options, | 
 |   21                 std::move(url_request)); | 
 |   22   return loader; | 
 |   23 } | 
 |   24  | 
 |   25 ThrottlingURLLoader::~ThrottlingURLLoader() {} | 
 |   26  | 
 |   27 void ThrottlingURLLoader::FollowRedirect() { | 
 |   28   if (url_loader_) | 
 |   29     url_loader_->FollowRedirect(); | 
 |   30 } | 
 |   31  | 
 |   32 void ThrottlingURLLoader::SetPriority(net::RequestPriority priority, | 
 |   33                                       int32_t intra_priority_value) { | 
 |   34   if (!url_loader_ && !cancelled_by_throttle_) { | 
 |   35     DCHECK_EQ(DEFERRED_START, deferred_stage_); | 
 |   36     set_priority_cached_ = true; | 
 |   37     priority_ = priority; | 
 |   38     intra_priority_value_ = intra_priority_value; | 
 |   39     return; | 
 |   40   } | 
 |   41  | 
 |   42   url_loader_->SetPriority(priority, intra_priority_value); | 
 |   43 } | 
 |   44  | 
 |   45 ThrottlingURLLoader::ThrottlingURLLoader( | 
 |   46     std::vector<std::unique_ptr<URLLoaderThrottle>> throttles, | 
 |   47     mojom::URLLoaderClient* client) | 
 |   48     : forwarding_client_(client), client_binding_(this) { | 
 |   49   if (throttles.size() > 0) { | 
 |   50     // TODO(yzshen): Implement a URLLoaderThrottle subclass which handles a list | 
 |   51     // of URLLoaderThrottles. | 
 |   52     CHECK_EQ(1u, throttles.size()); | 
 |   53     throttle_ = std::move(throttles[0]); | 
 |   54     throttle_->set_delegate(this); | 
 |   55   } | 
 |   56 } | 
 |   57  | 
 |   58 void ThrottlingURLLoader::Start(mojom::URLLoaderFactory* factory, | 
 |   59                                 int32_t routing_id, | 
 |   60                                 int32_t request_id, | 
 |   61                                 uint32_t options, | 
 |   62                                 std::unique_ptr<ResourceRequest> url_request) { | 
 |   63   DCHECK_EQ(DEFERRED_NONE, deferred_stage_); | 
 |   64   DCHECK(!cancelled_by_throttle_); | 
 |   65  | 
 |   66   if (throttle_) { | 
 |   67     bool deferred = false; | 
 |   68     throttle_->WillStartRequest(url_request->url, url_request->load_flags, | 
 |   69                                 url_request->resource_type, &deferred); | 
 |   70     if (cancelled_by_throttle_) | 
 |   71       return; | 
 |   72  | 
 |   73     if (deferred) { | 
 |   74       deferred_stage_ = DEFERRED_START; | 
 |   75       url_loader_factory_ = factory; | 
 |   76       routing_id_ = routing_id; | 
 |   77       request_id_ = request_id; | 
 |   78       options_ = options; | 
 |   79       url_request_ = std::move(url_request); | 
 |   80       return; | 
 |   81     } | 
 |   82   } | 
 |   83  | 
 |   84   factory->CreateLoaderAndStart(mojo::MakeRequest(&url_loader_), routing_id, | 
 |   85                                 request_id, options, *url_request, | 
 |   86                                 client_binding_.CreateInterfacePtrAndBind()); | 
 |   87 } | 
 |   88  | 
 |   89 void ThrottlingURLLoader::OnReceiveResponse( | 
 |   90     const ResourceResponseHead& response_head, | 
 |   91     const base::Optional<net::SSLInfo>& ssl_info, | 
 |   92     mojom::DownloadedTempFilePtr downloaded_file) { | 
 |   93   DCHECK_EQ(DEFERRED_NONE, deferred_stage_); | 
 |   94   DCHECK(!cancelled_by_throttle_); | 
 |   95  | 
 |   96   if (throttle_) { | 
 |   97     bool deferred = false; | 
 |   98     throttle_->WillProcessResponse(&deferred); | 
 |   99     if (cancelled_by_throttle_) | 
 |  100       return; | 
 |  101  | 
 |  102     if (deferred) { | 
 |  103       deferred_stage_ = DEFERRED_RESPONSE; | 
 |  104       response_head_ = response_head; | 
 |  105       ssl_info_ = ssl_info; | 
 |  106       downloaded_file_ = std::move(downloaded_file); | 
 |  107       client_binding_.PauseIncomingMethodCallProcessing(); | 
 |  108       return; | 
 |  109     } | 
 |  110   } | 
 |  111  | 
 |  112   forwarding_client_->OnReceiveResponse(response_head, ssl_info, | 
 |  113                                         std::move(downloaded_file)); | 
 |  114 } | 
 |  115  | 
 |  116 void ThrottlingURLLoader::OnReceiveRedirect( | 
 |  117     const net::RedirectInfo& redirect_info, | 
 |  118     const ResourceResponseHead& response_head) { | 
 |  119   DCHECK_EQ(DEFERRED_NONE, deferred_stage_); | 
 |  120   DCHECK(!cancelled_by_throttle_); | 
 |  121  | 
 |  122   if (throttle_) { | 
 |  123     bool deferred = false; | 
 |  124     throttle_->WillRedirectRequest(redirect_info, &deferred); | 
 |  125     if (cancelled_by_throttle_) | 
 |  126       return; | 
 |  127  | 
 |  128     if (deferred) { | 
 |  129       deferred_stage_ = DEFERRED_REDIRECT; | 
 |  130       redirect_info_ = redirect_info; | 
 |  131       response_head_ = response_head; | 
 |  132       client_binding_.PauseIncomingMethodCallProcessing(); | 
 |  133       return; | 
 |  134     } | 
 |  135   } | 
 |  136  | 
 |  137   forwarding_client_->OnReceiveRedirect(redirect_info, response_head); | 
 |  138 } | 
 |  139  | 
 |  140 void ThrottlingURLLoader::OnDataDownloaded(int64_t data_len, | 
 |  141                                            int64_t encoded_data_len) { | 
 |  142   DCHECK_EQ(DEFERRED_NONE, deferred_stage_); | 
 |  143   DCHECK(!cancelled_by_throttle_); | 
 |  144  | 
 |  145   forwarding_client_->OnDataDownloaded(data_len, encoded_data_len); | 
 |  146 } | 
 |  147  | 
 |  148 void ThrottlingURLLoader::OnUploadProgress( | 
 |  149     int64_t current_position, | 
 |  150     int64_t total_size, | 
 |  151     OnUploadProgressCallback ack_callback) { | 
 |  152   DCHECK_EQ(DEFERRED_NONE, deferred_stage_); | 
 |  153   DCHECK(!cancelled_by_throttle_); | 
 |  154  | 
 |  155   forwarding_client_->OnUploadProgress(current_position, total_size, | 
 |  156                                        std::move(ack_callback)); | 
 |  157 } | 
 |  158  | 
 |  159 void ThrottlingURLLoader::OnReceiveCachedMetadata( | 
 |  160     const std::vector<uint8_t>& data) { | 
 |  161   DCHECK_EQ(DEFERRED_NONE, deferred_stage_); | 
 |  162   DCHECK(!cancelled_by_throttle_); | 
 |  163  | 
 |  164   forwarding_client_->OnReceiveCachedMetadata(data); | 
 |  165 } | 
 |  166  | 
 |  167 void ThrottlingURLLoader::OnTransferSizeUpdated(int32_t transfer_size_diff) { | 
 |  168   DCHECK_EQ(DEFERRED_NONE, deferred_stage_); | 
 |  169   DCHECK(!cancelled_by_throttle_); | 
 |  170  | 
 |  171   forwarding_client_->OnTransferSizeUpdated(transfer_size_diff); | 
 |  172 } | 
 |  173  | 
 |  174 void ThrottlingURLLoader::OnStartLoadingResponseBody( | 
 |  175     mojo::ScopedDataPipeConsumerHandle body) { | 
 |  176   DCHECK_EQ(DEFERRED_NONE, deferred_stage_); | 
 |  177   DCHECK(!cancelled_by_throttle_); | 
 |  178  | 
 |  179   forwarding_client_->OnStartLoadingResponseBody(std::move(body)); | 
 |  180 } | 
 |  181  | 
 |  182 void ThrottlingURLLoader::OnComplete( | 
 |  183     const ResourceRequestCompletionStatus& status) { | 
 |  184   DCHECK_EQ(DEFERRED_NONE, deferred_stage_); | 
 |  185   DCHECK(!cancelled_by_throttle_); | 
 |  186  | 
 |  187   forwarding_client_->OnComplete(status); | 
 |  188 } | 
 |  189  | 
 |  190 void ThrottlingURLLoader::CancelWithError(int error_code) { | 
 |  191   // TODO(yzshen): Support a mode that cancellation also deletes the disk cache | 
 |  192   // entry. | 
 |  193   if (cancelled_by_throttle_) | 
 |  194     return; | 
 |  195  | 
 |  196   cancelled_by_throttle_ = true; | 
 |  197  | 
 |  198   ResourceRequestCompletionStatus request_complete_data; | 
 |  199   request_complete_data.error_code = error_code; | 
 |  200   request_complete_data.completion_time = base::TimeTicks::Now(); | 
 |  201  | 
 |  202   deferred_stage_ = DEFERRED_NONE; | 
 |  203   client_binding_.Close(); | 
 |  204   url_loader_.reset(); | 
 |  205  | 
 |  206   forwarding_client_->OnComplete(request_complete_data); | 
 |  207 } | 
 |  208  | 
 |  209 void ThrottlingURLLoader::Resume() { | 
 |  210   if (cancelled_by_throttle_ || deferred_stage_ == DEFERRED_NONE) | 
 |  211     return; | 
 |  212  | 
 |  213   switch (deferred_stage_) { | 
 |  214     case DEFERRED_START: { | 
 |  215       url_loader_factory_->CreateLoaderAndStart( | 
 |  216           mojo::MakeRequest(&url_loader_), routing_id_, request_id_, options_, | 
 |  217           *url_request_, client_binding_.CreateInterfacePtrAndBind()); | 
 |  218  | 
 |  219       if (set_priority_cached_) { | 
 |  220         set_priority_cached_ = false; | 
 |  221         url_loader_->SetPriority(priority_, intra_priority_value_); | 
 |  222       } | 
 |  223       break; | 
 |  224     } | 
 |  225     case DEFERRED_REDIRECT: { | 
 |  226       client_binding_.ResumeIncomingMethodCallProcessing(); | 
 |  227       forwarding_client_->OnReceiveRedirect(redirect_info_, response_head_); | 
 |  228       break; | 
 |  229     } | 
 |  230     case DEFERRED_RESPONSE: { | 
 |  231       client_binding_.ResumeIncomingMethodCallProcessing(); | 
 |  232       forwarding_client_->OnReceiveResponse(response_head_, ssl_info_, | 
 |  233                                             std::move(downloaded_file_)); | 
 |  234       break; | 
 |  235     } | 
 |  236     default: | 
 |  237       NOTREACHED(); | 
 |  238       break; | 
 |  239   } | 
 |  240   deferred_stage_ = DEFERRED_NONE; | 
 |  241 } | 
 |  242  | 
 |  243 }  // namespace content | 
| OLD | NEW |