172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian 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 "chrome/browser/sync/glue/http_bridge.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop_proxy.h"
93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h"
10dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/cookie_monster.h"
123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/base/host_resolver.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/load_flags.h"
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/base/net_errors.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_cache.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_network_layer.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_response_headers.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/proxy/proxy_service.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/url_request/url_request_context.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/url_request/url_request_status.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/webkit_glue.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace browser_sync {
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpBridge::RequestContextGetter::RequestContextGetter(
26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    net::URLRequestContextGetter* baseline_context_getter)
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : baseline_context_getter_(baseline_context_getter) {
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsennet::URLRequestContext*
3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenHttpBridge::RequestContextGetter::GetURLRequestContext() {
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Lazily create the context.
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!context_) {
3472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    net::URLRequestContext* baseline_context =
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        baseline_context_getter_->GetURLRequestContext();
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    context_ = new RequestContext(baseline_context);
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    baseline_context_getter_ = NULL;
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Apply the user agent which was set earlier.
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (is_user_agent_set())
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    context_->set_user_agent(user_agent_);
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return context_;
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochscoped_refptr<base::MessageLoopProxy>
48513209b27ff55e2841eac0e4120199c23acce758Ben MurdochHttpBridge::RequestContextGetter::GetIOMessageLoopProxy() const {
49731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpBridgeFactory::HttpBridgeFactory(
53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    net::URLRequestContextGetter* baseline_context_getter) {
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(baseline_context_getter != NULL);
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  request_context_getter_ =
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new HttpBridge::RequestContextGetter(baseline_context_getter);
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpBridgeFactory::~HttpBridgeFactory() {
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochsync_api::HttpPostProviderInterface* HttpBridgeFactory::Create() {
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HttpBridge* http = new HttpBridge(request_context_getter_);
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  http->AddRef();
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return http;
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpBridgeFactory::Destroy(sync_api::HttpPostProviderInterface* http) {
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static_cast<HttpBridge*>(http)->Release();
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenHttpBridge::RequestContext::RequestContext(
7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    net::URLRequestContext* baseline_context)
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : baseline_context_(baseline_context) {
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Create empty, in-memory cookie store.
77dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  set_cookie_store(new net::CookieMonster(NULL, NULL));
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We don't use a cache for bridged loads, but we do want to share proxy info.
80dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  set_host_resolver(baseline_context->host_resolver());
81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  set_proxy_service(baseline_context->proxy_service());
82dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  set_ssl_config_service(baseline_context->ssl_config_service());
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We want to share the HTTP session data with the network layer factory,
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // which includes auth_cache for proxies.
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Session is not refcounted so we need to be careful to not lose the parent
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // context.
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  net::HttpNetworkSession* session =
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      baseline_context->http_transaction_factory()->GetSession();
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(session);
91dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  set_http_transaction_factory(new net::HttpNetworkLayer(session));
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(timsteele): We don't currently listen for pref changes of these
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // fields or CookiePolicy; I'm not sure we want to strictly follow the
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // default settings, since for example if the user chooses to block all
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // cookies, sync will start failing. Also it seems like accept_lang/charset
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // should be tied to whatever the sync servers expect (if anything). These
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // fields should probably just be settable by sync backend; though we should
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // figure out if we need to give the user explicit control over policies etc.
100dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  set_accept_language(baseline_context->accept_language());
101dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  set_accept_charset(baseline_context->accept_charset());
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We default to the browser's user agent. This can (and should) be overridden
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // with set_user_agent.
105dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  set_user_agent(webkit_glue::GetUserAgent(GURL()));
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
107dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  set_net_log(baseline_context->net_log());
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpBridge::RequestContext::~RequestContext() {
111731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
112dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  delete http_transaction_factory();
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenHttpBridge::URLFetchState::URLFetchState() : url_poster(NULL),
116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                             aborted(false),
117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                             request_completed(false),
118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                             request_succeeded(false),
119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                             http_response_code(-1),
120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                             os_error_code(-1) {}
121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenHttpBridge::URLFetchState::~URLFetchState() {}
122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpBridge::HttpBridge(HttpBridge::RequestContextGetter* context_getter)
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : context_getter_for_request_(context_getter),
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      created_on_loop_(MessageLoop::current()),
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      http_post_completed_(false, false) {
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpBridge::~HttpBridge() {
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpBridge::SetUserAgent(const char* user_agent) {
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK_EQ(MessageLoop::current(), created_on_loop_);
134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (DCHECK_IS_ON()) {
135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::AutoLock lock(fetch_state_lock_);
136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(!fetch_state_.request_completed);
137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  context_getter_for_request_->set_user_agent(user_agent);
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpBridge::SetExtraRequestHeaders(const char * headers) {
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(extra_headers_.empty())
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      << "HttpBridge::SetExtraRequestHeaders called twice.";
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extra_headers_.assign(headers);
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpBridge::SetURL(const char* url, int port) {
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK_EQ(MessageLoop::current(), created_on_loop_);
149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (DCHECK_IS_ON()) {
150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::AutoLock lock(fetch_state_lock_);
151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(!fetch_state_.request_completed);
152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(url_for_request_.is_empty())
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      << "HttpBridge::SetURL called more than once?!";
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL temp(url);
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL::Replacements replacements;
1573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string port_str = base::IntToString(port);
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  replacements.SetPort(port_str.c_str(),
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       url_parse::Component(0, port_str.length()));
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  url_for_request_ = temp.ReplaceComponents(replacements);
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpBridge::SetPostPayload(const char* content_type,
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                int content_length,
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                const char* content) {
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK_EQ(MessageLoop::current(), created_on_loop_);
167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (DCHECK_IS_ON()) {
168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::AutoLock lock(fetch_state_lock_);
169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(!fetch_state_.request_completed);
170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(content_type_.empty()) << "Bridge payload already set.";
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK_GE(content_length, 0) << "Content length < 0";
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  content_type_ = content_type;
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!content || (content_length == 0)) {
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK_EQ(content_length, 0);
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    request_content_ = " ";  // TODO(timsteele): URLFetcher requires non-empty
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             // content for POSTs whereas CURL does not, for now
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             // we hack this to support the sync backend.
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    request_content_.assign(content, content_length);
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool HttpBridge::MakeSynchronousPost(int* os_error_code, int* response_code) {
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK_EQ(MessageLoop::current(), created_on_loop_);
186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (DCHECK_IS_ON()) {
187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    base::AutoLock lock(fetch_state_lock_);
188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(!fetch_state_.request_completed);
189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(url_for_request_.is_valid()) << "Invalid URL for request";
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(!content_type_.empty()) << "Payload not set";
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!BrowserThread::PostTask(
194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          BrowserThread::IO, FROM_HERE,
195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          NewRunnableMethod(this, &HttpBridge::CallMakeAsynchronousPost))) {
196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // This usually happens when we're in a unit test.
197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    LOG(WARNING) << "Could not post CallMakeAsynchronousPost task";
198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return false;
199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!http_post_completed_.Wait())  // Block until network request completes
202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    NOTREACHED();                    // or is aborted. See OnURLFetchComplete
203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                     // and Abort.
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::AutoLock lock(fetch_state_lock_);
206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(fetch_state_.request_completed || fetch_state_.aborted);
207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  *os_error_code = fetch_state_.os_error_code;
208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  *response_code = fetch_state_.http_response_code;
209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return fetch_state_.request_succeeded;
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpBridge::MakeAsynchronousPost() {
213731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::AutoLock lock(fetch_state_lock_);
215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(!fetch_state_.request_completed);
216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (fetch_state_.aborted)
217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  fetch_state_.url_poster = new URLFetcher(url_for_request_,
220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                           URLFetcher::POST, this);
221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  fetch_state_.url_poster->set_request_context(context_getter_for_request_);
222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  fetch_state_.url_poster->set_upload_data(content_type_, request_content_);
223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  fetch_state_.url_poster->set_extra_request_headers(extra_headers_);
224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  fetch_state_.url_poster->set_load_flags(net::LOAD_DO_NOT_SEND_COOKIES);
225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  fetch_state_.url_poster->Start();
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint HttpBridge::GetResponseContentLength() const {
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK_EQ(MessageLoop::current(), created_on_loop_);
230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::AutoLock lock(fetch_state_lock_);
231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(fetch_state_.request_completed);
232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return fetch_state_.response_content.size();
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char* HttpBridge::GetResponseContent() const {
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK_EQ(MessageLoop::current(), created_on_loop_);
237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::AutoLock lock(fetch_state_lock_);
238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(fetch_state_.request_completed);
239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return fetch_state_.response_content.data();
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst std::string HttpBridge::GetResponseHeaderValue(
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& name) const {
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK_EQ(MessageLoop::current(), created_on_loop_);
246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::AutoLock lock(fetch_state_lock_);
247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(fetch_state_.request_completed);
248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string value;
250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  fetch_state_.response_headers->EnumerateHeader(NULL, name, &value);
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return value;
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid HttpBridge::Abort() {
255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::AutoLock lock(fetch_state_lock_);
256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(!fetch_state_.aborted);
257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (fetch_state_.aborted || fetch_state_.request_completed)
258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  fetch_state_.aborted = true;
261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE,
262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            fetch_state_.url_poster);
263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  fetch_state_.url_poster = NULL;
264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  fetch_state_.os_error_code = net::ERR_ABORTED;
265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  http_post_completed_.Signal();
266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
26872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid HttpBridge::OnURLFetchComplete(const URLFetcher *source,
26972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                    const GURL &url,
27072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                    const net::URLRequestStatus &status,
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    int response_code,
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    const ResponseCookies &cookies,
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    const std::string &data) {
274731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  base::AutoLock lock(fetch_state_lock_);
276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (fetch_state_.aborted)
277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  fetch_state_.request_completed = true;
280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  fetch_state_.request_succeeded =
281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      (net::URLRequestStatus::SUCCESS == status.status());
282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  fetch_state_.http_response_code = response_code;
283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  fetch_state_.os_error_code = status.os_error();
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
285ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  fetch_state_.response_content = data;
286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  fetch_state_.response_headers = source->response_headers();
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // End of the line for url_poster_. It lives only on the IO loop.
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We defer deletion because we're inside a callback from a component of the
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // URLFetcher, so it seems most natural / "polite" to let the stack unwind.
291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MessageLoop::current()->DeleteSoon(FROM_HERE, fetch_state_.url_poster);
292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  fetch_state_.url_poster = NULL;
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Wake the blocked syncer thread in MakeSynchronousPost.
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // WARNING: DONT DO ANYTHING AFTER THIS CALL! |this| may be deleted!
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  http_post_completed_.Signal();
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace browser_sync
300