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