1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/resource_fetcher.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h" 872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" 972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h" 1072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebKitClient.h" 1172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLError.h" 1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLLoader.h" 1372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h" 1472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::TimeDelta; 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebFrame; 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebURLError; 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebURLLoader; 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebURLRequest; 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebURLResponse; 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace webkit_glue { 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochResourceFetcher::ResourceFetcher(const GURL& url, WebFrame* frame, 26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen WebURLRequest::TargetType target_type, 27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen Callback* callback) 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : url_(url), 29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen target_type_(target_type), 3072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen completed_(false), 31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen callback_(callback) { 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Can't do anything without a frame. However, delegate can be NULL (so we 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // can do a http request and ignore the results). 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(frame); 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Start(frame); 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochResourceFetcher::~ResourceFetcher() { 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!completed_ && loader_.get()) 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch loader_->cancel(); 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ResourceFetcher::Cancel() { 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!completed_) { 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch loader_->cancel(); 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch completed_ = true; 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ResourceFetcher::Start(WebFrame* frame) { 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLRequest request(url_); 52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen request.setTargetType(target_type_); 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch frame->dispatchWillSendRequest(request); 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch loader_.reset(WebKit::webKitClient()->createURLLoader()); 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch loader_->loadAsynchronously(request, this); 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ResourceFetcher::RunCallback(const WebURLResponse& response, 6072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::string& data) { 6172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!callback_.get()) 6272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return; 6372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 6472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Take care to clear callback_ before running the callback as it may lead to 6572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // our destruction. 6672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen scoped_ptr<Callback> callback; 6772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen callback.swap(callback_); 6872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen callback->Run(response, data); 6972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 7072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////// 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// WebURLLoaderClient methods 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ResourceFetcher::willSendRequest( 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLLoader* loader, WebURLRequest& new_request, 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const WebURLResponse& redirect_response) { 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ResourceFetcher::didSendData( 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLLoader* loader, unsigned long long bytes_sent, 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unsigned long long total_bytes_to_be_sent) { 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ResourceFetcher::didReceiveResponse( 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLLoader* loader, const WebURLResponse& response) { 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!completed_); 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch response_ = response; 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ResourceFetcher::didReceiveData( 91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen WebURLLoader* loader, const char* data, int data_length, 92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int encoded_data_length) { 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!completed_); 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(data_length > 0); 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data_.append(data, data_length); 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ResourceFetcher::didReceiveCachedMetadata( 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebURLLoader* loader, const char* data, int data_length) { 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!completed_); 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(data_length > 0); 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch metadata_.assign(data, data_length); 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ResourceFetcher::didFinishLoading( 1083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick WebURLLoader* loader, double finishTime) { 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!completed_); 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch completed_ = true; 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 11272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen RunCallback(response_, data_); 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ResourceFetcher::didFail(WebURLLoader* loader, const WebURLError& error) { 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!completed_); 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch completed_ = true; 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Go ahead and tell our delegate that we're done. 12072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen RunCallback(WebURLResponse(), std::string()); 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////// 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// A resource fetcher with a timeout 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochResourceFetcherWithTimeout::ResourceFetcherWithTimeout( 127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const GURL& url, WebFrame* frame, WebURLRequest::TargetType target_type, 128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int timeout_secs, Callback* callback) 129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen : ResourceFetcher(url, frame, target_type, callback) { 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch timeout_timer_.Start(TimeDelta::FromSeconds(timeout_secs), this, 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &ResourceFetcherWithTimeout::TimeoutFired); 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1343345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickResourceFetcherWithTimeout::~ResourceFetcherWithTimeout() { 1353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ResourceFetcherWithTimeout::TimeoutFired() { 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!completed_) { 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch loader_->cancel(); 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch didFail(NULL, WebURLError()); 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace webkit_glue 145