1// Copyright 2012 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#ifndef SYNC_INTERNAL_API_PUBLIC_HTTP_BRIDGE_H_
6#define SYNC_INTERNAL_API_PUBLIC_HTTP_BRIDGE_H_
7
8#include <string>
9
10#include "base/basictypes.h"
11#include "base/compiler_specific.h"
12#include "base/gtest_prod_util.h"
13#include "base/memory/ref_counted.h"
14#include "base/synchronization/lock.h"
15#include "base/synchronization/waitable_event.h"
16#include "net/url_request/url_fetcher_delegate.h"
17#include "net/url_request/url_request_context.h"
18#include "net/url_request/url_request_context_getter.h"
19#include "sync/base/sync_export.h"
20#include "sync/internal_api/public/base/cancelation_observer.h"
21#include "sync/internal_api/public/http_post_provider_factory.h"
22#include "sync/internal_api/public/http_post_provider_interface.h"
23#include "sync/internal_api/public/network_time_update_callback.h"
24#include "url/gurl.h"
25
26class HttpBridgeTest;
27
28namespace base {
29class MessageLoop;
30}
31
32namespace net {
33class HttpResponseHeaders;
34class HttpUserAgentSettings;
35class URLFetcher;
36class URLRequestJobFactory;
37}
38
39namespace syncer {
40
41class CancelationSignal;
42
43// A bridge between the syncer and Chromium HTTP layers.
44// Provides a way for the sync backend to use Chromium directly for HTTP
45// requests rather than depending on a third party provider (e.g libcurl).
46// This is a one-time use bridge. Create one for each request you want to make.
47// It is RefCountedThreadSafe because it can PostTask to the io loop, and thus
48// needs to stick around across context switches, etc.
49class SYNC_EXPORT_PRIVATE HttpBridge
50    : public base::RefCountedThreadSafe<HttpBridge>,
51      public HttpPostProviderInterface,
52      public net::URLFetcherDelegate {
53 public:
54  // A request context used for HTTP requests bridged from the sync backend.
55  // A bridged RequestContext has a dedicated in-memory cookie store and does
56  // not use a cache. Thus the same type can be used for incognito mode.
57  class RequestContext : public net::URLRequestContext {
58   public:
59    // |baseline_context| is used to obtain the accept-language
60    // and proxy service information for bridged requests.
61    // Typically |baseline_context| should be the net::URLRequestContext of the
62    // currently active profile.
63    RequestContext(
64        net::URLRequestContext* baseline_context,
65        const scoped_refptr<base::SingleThreadTaskRunner>&
66            network_task_runner,
67        const std::string& user_agent);
68
69    // The destructor MUST be called on the IO thread.
70    virtual ~RequestContext();
71
72   private:
73    net::URLRequestContext* const baseline_context_;
74    const scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
75    scoped_ptr<net::HttpUserAgentSettings> http_user_agent_settings_;
76    scoped_ptr<net::URLRequestJobFactory> job_factory_;
77
78    DISALLOW_COPY_AND_ASSIGN(RequestContext);
79  };
80
81  // Lazy-getter for RequestContext objects.
82  class SYNC_EXPORT_PRIVATE RequestContextGetter
83      : public net::URLRequestContextGetter {
84   public:
85    RequestContextGetter(
86        net::URLRequestContextGetter* baseline_context_getter,
87        const std::string& user_agent);
88
89    // net::URLRequestContextGetter implementation.
90    virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE;
91    virtual scoped_refptr<base::SingleThreadTaskRunner>
92        GetNetworkTaskRunner() const OVERRIDE;
93
94   protected:
95    virtual ~RequestContextGetter();
96
97   private:
98    scoped_refptr<net::URLRequestContextGetter> baseline_context_getter_;
99    const scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
100    // User agent to apply to the net::URLRequestContext.
101    const std::string user_agent_;
102
103    // Lazily initialized by GetURLRequestContext().
104    scoped_ptr<RequestContext> context_;
105
106    DISALLOW_COPY_AND_ASSIGN(RequestContextGetter);
107  };
108
109  HttpBridge(RequestContextGetter* context,
110             const NetworkTimeUpdateCallback& network_time_update_callback);
111
112  // HttpPostProvider implementation.
113  virtual void SetExtraRequestHeaders(const char* headers) OVERRIDE;
114  virtual void SetURL(const char* url, int port) OVERRIDE;
115  virtual void SetPostPayload(const char* content_type, int content_length,
116                              const char* content) OVERRIDE;
117  virtual bool MakeSynchronousPost(int* error_code,
118                                   int* response_code) OVERRIDE;
119  virtual void Abort() OVERRIDE;
120
121  // WARNING: these response content methods are used to extract plain old data
122  // and not null terminated strings, so you should make sure you have read
123  // GetResponseContentLength() characters when using GetResponseContent. e.g
124  // string r(b->GetResponseContent(), b->GetResponseContentLength()).
125  virtual int GetResponseContentLength() const OVERRIDE;
126  virtual const char* GetResponseContent() const OVERRIDE;
127  virtual const std::string GetResponseHeaderValue(
128      const std::string& name) const OVERRIDE;
129
130  // net::URLFetcherDelegate implementation.
131  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
132
133  net::URLRequestContextGetter* GetRequestContextGetterForTest() const;
134
135 protected:
136  friend class base::RefCountedThreadSafe<HttpBridge>;
137
138  virtual ~HttpBridge();
139
140  // Protected virtual so the unit test can override to shunt network requests.
141  virtual void MakeAsynchronousPost();
142
143 private:
144  friend class SyncHttpBridgeTest;
145  friend class ::HttpBridgeTest;
146
147  // Called on the IO loop to issue the network request. The extra level
148  // of indirection is so that the unit test can override this behavior but we
149  // still have a function to statically pass to PostTask.
150  void CallMakeAsynchronousPost() { MakeAsynchronousPost(); }
151
152  // Used to destroy a fetcher when the bridge is Abort()ed, to ensure that
153  // a reference to |this| is held while flushing any pending fetch completion
154  // callbacks coming from the IO thread en route to finally destroying the
155  // fetcher.
156  void DestroyURLFetcherOnIOThread(net::URLFetcher* fetcher);
157
158  void UpdateNetworkTime();
159
160  // The message loop of the thread we were created on. This is the thread that
161  // will block on MakeSynchronousPost while the IO thread fetches data from
162  // the network.
163  // This should be the main syncer thread (SyncerThread) which is what blocks
164  // on network IO through curl_easy_perform.
165  base::MessageLoop* const created_on_loop_;
166
167  // The URL to POST to.
168  GURL url_for_request_;
169
170  // POST payload information.
171  std::string content_type_;
172  std::string request_content_;
173  std::string extra_headers_;
174
175  // A waitable event we use to provide blocking semantics to
176  // MakeSynchronousPost. We block created_on_loop_ while the IO loop fetches
177  // network request.
178  base::WaitableEvent http_post_completed_;
179
180  struct URLFetchState {
181    URLFetchState();
182    ~URLFetchState();
183    // Our hook into the network layer is a URLFetcher. USED ONLY ON THE IO
184    // LOOP, so we can block created_on_loop_ while the fetch is in progress.
185    // NOTE: This is not a scoped_ptr for a reason. It must be deleted on the
186    // same thread that created it, which isn't the same thread |this| gets
187    // deleted on. We must manually delete url_poster_ on the IO loop.
188    net::URLFetcher* url_poster;
189
190    // Start and finish time of request. Set immediately before sending
191    // request and after receiving response.
192    base::Time start_time;
193    base::Time end_time;
194
195    // Used to support 'Abort' functionality.
196    bool aborted;
197
198    // Cached response data.
199    bool request_completed;
200    bool request_succeeded;
201    int http_response_code;
202    int error_code;
203    std::string response_content;
204    scoped_refptr<net::HttpResponseHeaders> response_headers;
205  };
206
207  // This lock synchronizes use of state involved in the flow to fetch a URL
208  // using URLFetcher, including |fetch_state_| and
209  // |context_getter_for_request_| on any thread, for example, this flow needs
210  // to be synchronized to gracefully clean up URLFetcher and return
211  // appropriate values in |error_code|.
212  mutable base::Lock fetch_state_lock_;
213  URLFetchState fetch_state_;
214
215  // Gets a customized net::URLRequestContext for bridged requests. See
216  // RequestContext definition for details.
217  scoped_refptr<RequestContextGetter> context_getter_for_request_;
218
219  const scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
220
221  // Callback for updating network time.
222  NetworkTimeUpdateCallback network_time_update_callback_;
223
224  DISALLOW_COPY_AND_ASSIGN(HttpBridge);
225};
226
227class SYNC_EXPORT HttpBridgeFactory : public HttpPostProviderFactory,
228                                      public CancelationObserver {
229 public:
230  HttpBridgeFactory(
231      net::URLRequestContextGetter* baseline_context_getter,
232      const NetworkTimeUpdateCallback& network_time_update_callback,
233      CancelationSignal* cancelation_signal);
234  virtual ~HttpBridgeFactory();
235
236  // HttpPostProviderFactory:
237  virtual void Init(const std::string& user_agent) OVERRIDE;
238  virtual HttpPostProviderInterface* Create() OVERRIDE;
239  virtual void Destroy(HttpPostProviderInterface* http) OVERRIDE;
240
241  // CancelationObserver implementation:
242  virtual void OnSignalReceived() OVERRIDE;
243
244 private:
245  // Protects |request_context_getter_| and |baseline_request_context_getter_|.
246  base::Lock context_getter_lock_;
247
248  // This request context is the starting point for the request_context_getter_
249  // that we eventually use to make requests.  During shutdown we must drop all
250  // references to it before the ProfileSyncService's Shutdown() call is
251  // complete.
252  scoped_refptr<net::URLRequestContextGetter> baseline_request_context_getter_;
253
254  // This request context is built on top of the baseline context and shares
255  // common components. Takes a reference to the
256  // baseline_request_context_getter_.  It's mostly used on sync thread when
257  // creating connection but is released as soon as possible during shutdown.
258  // Protected by |context_getter_lock_|.
259  scoped_refptr<HttpBridge::RequestContextGetter> request_context_getter_;
260
261  NetworkTimeUpdateCallback network_time_update_callback_;
262
263  CancelationSignal* const cancelation_signal_;
264
265  DISALLOW_COPY_AND_ASSIGN(HttpBridgeFactory);
266};
267
268}  //  namespace syncer
269
270#endif  // SYNC_INTERNAL_API_PUBLIC_HTTP_BRIDGE_H_
271