File: http_bridge.h

package info (click to toggle)
chromium 139.0.7258.127-2
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 6,122,156 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (189 lines) | stat: -rw-r--r-- 7,040 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_SYNC_ENGINE_NET_HTTP_BRIDGE_H_
#define COMPONENTS_SYNC_ENGINE_NET_HTTP_BRIDGE_H_

#include <stdint.h>

#include <memory>
#include <string>

#include "base/memory/scoped_refptr.h"
#include "base/sequence_checker.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "base/task/sequenced_task_runner.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "components/sync/engine/net/http_post_provider.h"
#include "components/sync/engine/net/http_post_provider_factory.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "url/gurl.h"

namespace net {
class HttpResponseHeaders;
}  // namespace net

namespace network {
class SimpleURLLoader;
}  // namespace network

namespace syncer {

// A bridge between the syncer and Chromium HTTP layers.
// Provides a way for the sync backend to use Chromium directly for HTTP
// requests rather than depending on a third party provider (e.g libcurl).
// This is a one-time use bridge. Create one for each request you want to make.
class HttpBridge : public HttpPostProvider {
 public:
  HttpBridge(const std::string& user_agent,
             scoped_refptr<base::SequencedTaskRunner> network_task_runner,
             std::unique_ptr<network::PendingSharedURLLoaderFactory>
                 pending_url_loader_factory);

  HttpBridge(const HttpBridge&) = delete;
  HttpBridge& operator=(const HttpBridge&) = delete;

  // HttpPostProvider implementation.
  void SetExtraRequestHeaders(const char* headers) override;
  void SetURL(const GURL& url) override;
  void SetPostPayload(const char* content_type,
                      int content_length,
                      const char* content) override;
  bool MakeSynchronousPost(int* net_error_code, int* http_status_code) override;
  void Abort() override;

  // WARNING: these response content methods are used to extract plain old data
  // and not null terminated strings, so you should make sure you have read
  // GetResponseContentLength() characters when using GetResponseContent. e.g
  // string r(b->GetResponseContent(), b->GetResponseContentLength()).
  int GetResponseContentLength() const override;
  const char* GetResponseContent() const override;
  const std::string GetResponseHeaderValue(
      const std::string& name) const override;

  void OnURLLoadComplete(std::unique_ptr<std::string> response_body);
  void OnURLLoadUploadProgress(uint64_t position, uint64_t total);

 protected:
  ~HttpBridge() override;

  // Protected virtual for testing.
  virtual scoped_refptr<network::SharedURLLoaderFactory>
  CreateSharedURLLoader();
  virtual void MakeAsynchronousPost();

 private:
  friend class ShuntedHttpBridge;

  // Called on the IO thread to issue the network request. The extra level
  // of indirection is so that the unit test can override this behavior but we
  // still have a function to statically pass to PostTask.
  void CallMakeAsynchronousPost() { MakeAsynchronousPost(); }

  // Actual implementation of the load complete callback. Called by tests too.
  void OnURLLoadCompleteInternal(int http_status_code,
                                 int net_error_code,
                                 const GURL& final_url,
                                 std::unique_ptr<std::string> response_body);

  // Helper method to abort the request if we timed out.
  void OnURLLoadTimedOut();

  // Used to check whether a method runs on the sequence that this object was
  // created on. This is the sequence that will block on MakeSynchronousPost
  // while the IO thread fetches data from the network. This should be the "sync
  // thread" (really just a SequencedTaskRunner) in practice.
  SEQUENCE_CHECKER(sequence_checker_);

  // The user agent for all requests.
  const std::string user_agent_;

  // The URL to POST to.
  GURL url_for_request_;

  // POST payload information.
  std::string content_type_;
  std::string request_content_;
  std::string extra_headers_;

  // A waitable event we use to provide blocking semantics to
  // MakeSynchronousPost. We block the Sync thread while the IO thread processes
  // the network request.
  base::WaitableEvent http_post_completed_;

  struct URLFetchState {
    URLFetchState();
    ~URLFetchState();
    // Our hook into the network layer is a SimpleURLLoader. USED ONLY ON THE IO
    // THREAD, so we can block the Sync thread while the fetch is in progress.
    // NOTE: This must be deleted on the same thread that created it, which
    // isn't the same thread `this` gets deleted on. We must manually delete
    // url_loader on the IO thread.
    std::unique_ptr<network::SimpleURLLoader> url_loader;

    // Start and finish time of request. Set immediately before sending
    // request and after receiving response.
    base::Time start_time;
    base::Time end_time;

    // Used to support 'Abort' functionality.
    bool aborted = false;

    // Cached response data.
    bool request_completed = false;
    bool request_succeeded = false;
    int http_status_code = -1;
    int net_error_code = -1;
    std::string response_content;
    scoped_refptr<net::HttpResponseHeaders> response_headers;

    // Timer to ensure http requests aren't stalled. Reset every time upload or
    // download progress is made.
    std::unique_ptr<base::DelayTimer> http_request_timeout_timer;
  };

  // This lock synchronizes use of state involved in the flow to load a URL
  // using URLLoader, including `fetch_state_` on any thread, for example,
  // this flow needs to be synchronized to gracefully
  // clean up URLFetcher and return appropriate values in `error_code`.
  //
  // TODO(crbug.com/41390139): Check whether we can get rid of
  // `fetch_state_lock_` altogether after the migration to SimpleURLLoader.
  mutable base::Lock fetch_state_lock_;
  URLFetchState fetch_state_;

  std::unique_ptr<network::PendingSharedURLLoaderFactory>
      pending_url_loader_factory_;
  scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;

  const scoped_refptr<base::SequencedTaskRunner> network_task_runner_;
};

class HttpBridgeFactory : public HttpPostProviderFactory {
 public:
  HttpBridgeFactory(const std::string& user_agent,
                    std::unique_ptr<network::PendingSharedURLLoaderFactory>
                        pending_url_loader_factory);

  HttpBridgeFactory(const HttpBridgeFactory&) = delete;
  HttpBridgeFactory& operator=(const HttpBridgeFactory&) = delete;

  ~HttpBridgeFactory() override;

  // HttpPostProviderFactory:
  scoped_refptr<HttpPostProvider> Create() override;

 private:
  // The user agent to use in all requests.
  const std::string user_agent_;

  // The URL loader factory used for making all requests.
  scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
};

}  //  namespace syncer

#endif  // COMPONENTS_SYNC_ENGINE_NET_HTTP_BRIDGE_H_