17d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch/* 27d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch * Copyright 2010, The Android Open Source Project 37d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch * 47d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch * Redistribution and use in source and binary forms, with or without 57d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch * modification, are permitted provided that the following conditions 67d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch * are met: 77d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch * * Redistributions of source code must retain the above copyright 87d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch * notice, this list of conditions and the following disclaimer. 97d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch * * Redistributions in binary form must reproduce the above copyright 107d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch * notice, this list of conditions and the following disclaimer in the 117d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch * documentation and/or other materials provided with the distribution. 127d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch * 137d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 147d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 157d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 167d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 177d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 187d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 197d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 207d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 217d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 227d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 237d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 247d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch */ 257d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch#ifndef URL_FETCHER_PROXY_H_ 267d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch#define URL_FETCHER_PROXY_H_ 277d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch 287d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch#include "android/autofill/android_url_request_context_getter.h" 297d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch#include "android/autofill/profile_android.h" 306662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block#include "base/scoped_ptr.h" 319aa5f8b435409e063e76e6e4f12f5c4e85997e0aKristian Monsen#include "base/threading/thread.h" 327d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch#include "common/net/url_fetcher.h" 337d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch#include "net/url_request/url_request_status.h" 347d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch 357d214dfa174224b459660971e5b5cce2e06be02aBen Murdochclass URLFetcherProxy; 367d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch 377d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch// The URLFetcherProxy uses RunnableMethod to call functions on it in 387d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch// another thread, but (since it's trying to behave like a URLFetcher) 397d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch// isn't reference counted. This specialisation makes RunnableMethod 407d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch// work with a non-reference-counted object by not manipulating the 417d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch// reference counts. 427d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch// TODO: Investigate alternatives to using RunnableMethod that don't 437d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch// expect a ref counted object so we can remove this if possible. 447d214dfa174224b459660971e5b5cce2e06be02aBen Murdochtemplate <> 457d214dfa174224b459660971e5b5cce2e06be02aBen Murdochstruct RunnableMethodTraits<class URLFetcherProxy> { 467d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch void RetainCallee(URLFetcherProxy* obj) { 477d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch } 487d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch 497d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch void ReleaseCallee(URLFetcherProxy* obj) { 507d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch } 517d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch}; 527d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch 537d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch// A class that implements the same API as URLFetcher but instead of 547d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch// assuming that the calling thread is a chrome thread with a message 556662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block// loop, it assumes the calling thread is WebKit's main thread. 566662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block// 576662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block// It extends URLFetcher so as to minimise the diff in other code when 586662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block// using this class in place of URLFetcher. It uses a private 596662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block// URLFetcher instance to do the network request and thus implements 60851c24f8cc7438c16c50ead815bde972a60b4a18Steve Block// URLFetcher::Delegate. We always use 61851c24f8cc7438c16c50ead815bde972a60b4a18Steve Block// ProfileImplAndroid::GetDefaultRequestContext() as the request 62851c24f8cc7438c16c50ead815bde972a60b4a18Steve Block// context. 636662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block// 646662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block// Note that we overide the minimum number of methods to allow this 656662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block// class to be used by AutoFillDownloadManager ... 666662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block// - set_upload_data() 67dbeb7bfd58939b6a020a91552afd12c32108a7c7Iain Merrick// - set_automatically_retry_on_5xx() 686662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block// - Start() 696662b631f1f14f6db83e053e0dd7887bb18adb91Steve Blockclass URLFetcherProxy : public URLFetcher, public URLFetcher::Delegate { 707d214dfa174224b459660971e5b5cce2e06be02aBen Murdochpublic: 716662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block URLFetcherProxy(const GURL& url, 726662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block URLFetcher::RequestType request_type, 736662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block URLFetcher::Delegate* d) 746662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block : URLFetcher(url /*unused*/, URLFetcher::POST /*unused*/, d), 756662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block request_type_(request_type), 76c5a01be107ec80b0d7062dcc836c0608dd467f17Ben Murdoch retry_(true), 77c5a01be107ec80b0d7062dcc836c0608dd467f17Ben Murdoch url_(url) 786662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block { 796662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block } 807d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch 816662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block virtual ~URLFetcherProxy() 826662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block { 83164f7496de0fbee436b385a79ead9e3cb81a50c1Ben Murdoch pending_callbacks_.erase(this); 846662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block } 857d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch 86dbeb7bfd58939b6a020a91552afd12c32108a7c7Iain Merrick virtual void set_automatically_retry_on_5xx(bool retry) 876662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block { 886662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block retry_ = retry; 896662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block } 907d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch 916662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block virtual void set_upload_data(const std::string& upload_content_type, 926662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block const std::string& upload_content) 937d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch { 946662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block upload_content_type_ = upload_content_type; 956662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block upload_content_ = upload_content; 967d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch } 977d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch 986662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block virtual void Start() 996662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block { 1008474bd350e233cca45dcbfe5f8e4f542675c4c66Kristian Monsen scoped_refptr<net::URLRequestContextGetter> con = request_context(); 10140eae52c5e5dbf475a0cf368c9ccbb7f8a0653f4Ben Murdoch CHECK(con.get()) << "No URLRequestContextGetter!"; 1026662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block scoped_refptr<base::MessageLoopProxy> mlp = con->GetIOMessageLoopProxy(); 1036662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block // TODO: See the template specialisation at the top of the file. Can we use 1046662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block // an alternative to RunnableMethod that doesn't expect a ref counted object? 1056662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block mlp->PostTask(FROM_HERE, NewRunnableMethod(this, &URLFetcherProxy::DoStart)); 1066662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block }; 1076662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block 1087d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch virtual void OnURLFetchComplete(const URLFetcher* source, 1097d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch const GURL& url, 110532b5811cf4c192c4333b19108d6a303edb23691Kristian Monsen const net::URLRequestStatus& status, 1117d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch int response_code, 1127d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch const ResponseCookies& cookies, 1137d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch const std::string& data) 1147d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch { 1157d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch url_ = url; 1167d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch status_ = status; 1177d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch response_code_ = response_code; 1187d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch cookies_ = cookies; 1197d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch data_ = data; 120164f7496de0fbee436b385a79ead9e3cb81a50c1Ben Murdoch pending_callbacks_[this] = true; 121cecae02673edd6b4cee88a9b87a61055a91f70bbKristian Monsen DoComplete(this); 1227d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch } 1237d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch 1247d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch net::HttpResponseHeaders* response_headers() const {return real_fetcher_->response_headers();}; 1257d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch 1267d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch // Returns the back-off delay before the request will be retried, 1277d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch // when a 5xx response was received. 1287d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch base::TimeDelta backoff_delay() const { return real_fetcher_->backoff_delay();}; 1297d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch 1307d214dfa174224b459660971e5b5cce2e06be02aBen Murdochprivate: 1317d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch void DoStart() 1327d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch { 133c5a01be107ec80b0d7062dcc836c0608dd467f17Ben Murdoch real_fetcher_.reset(new URLFetcher(url_, request_type_, this)); 134dbeb7bfd58939b6a020a91552afd12c32108a7c7Iain Merrick real_fetcher_->set_automatically_retry_on_5xx(retry_); 1356662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block // We expect set_upload_data() to have been called on this object. 1366662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block real_fetcher_->set_upload_data(upload_content_type_, upload_content_); 13740eae52c5e5dbf475a0cf368c9ccbb7f8a0653f4Ben Murdoch real_fetcher_->set_request_context(request_context()); 1387d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch real_fetcher_->Start(); 1397d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch }; 1407d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch 1417d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch static void DoComplete(void* context) 1427d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch { 1436662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block URLFetcherProxy* that = static_cast<URLFetcherProxy*>(context); 144164f7496de0fbee436b385a79ead9e3cb81a50c1Ben Murdoch if (pending_callbacks_[that]) { 145164f7496de0fbee436b385a79ead9e3cb81a50c1Ben Murdoch that->DoCompleteImpl(); 146164f7496de0fbee436b385a79ead9e3cb81a50c1Ben Murdoch } 1477d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch } 1487d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch 1496662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block void DoCompleteImpl() 1506662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block { 1516662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block delegate()->OnURLFetchComplete(this, url_, status_, response_code_, cookies_, data_); 1526662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block } 1536662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block 1546662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block scoped_ptr<URLFetcher> real_fetcher_; 1556662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block URLFetcher::RequestType request_type_; 1566662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block 1576662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block bool retry_; 1586662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block std::string upload_content_type_; 1597d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch std::string upload_content_; 1607d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch 1616662b631f1f14f6db83e053e0dd7887bb18adb91Steve Block GURL url_; 162532b5811cf4c192c4333b19108d6a303edb23691Kristian Monsen net::URLRequestStatus status_; 1637d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch int response_code_; 1647d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch ResponseCookies cookies_; 1657d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch std::string data_; 1667d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch 167164f7496de0fbee436b385a79ead9e3cb81a50c1Ben Murdoch static std::map<URLFetcherProxy*, bool> pending_callbacks_; 168164f7496de0fbee436b385a79ead9e3cb81a50c1Ben Murdoch 1697d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch DISALLOW_EVIL_CONSTRUCTORS(URLFetcherProxy); 1707d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch}; 1717d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch 1727d214dfa174224b459660971e5b5cce2e06be02aBen Murdoch#endif // URL_FETCHER_PROXY_H_ 173