Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: chrome/browser/sync/engine/net/server_connection_manager.h

Issue 9699057: [Sync] Move 'sync' target to sync/ (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address Tim's comments Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 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 CHROME_BROWSER_SYNC_ENGINE_NET_SERVER_CONNECTION_MANAGER_H_
6 #define CHROME_BROWSER_SYNC_ENGINE_NET_SERVER_CONNECTION_MANAGER_H_
7 #pragma once
8
9 #include <iosfwd>
10 #include <string>
11
12 #include "base/atomicops.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/observer_list.h"
15 #include "base/string_util.h"
16 #include "base/threading/non_thread_safe.h"
17 #include "base/threading/thread_checker.h"
18 #include "base/synchronization/lock.h"
19 #include "chrome/browser/sync/syncable/syncable_id.h"
20
21 namespace syncable {
22 class Directory;
23 }
24
25 namespace sync_pb {
26 class ClientToServerMessage;
27 }
28
29 namespace browser_sync {
30
31 class ClientToServerMessage;
32
33 static const int32 kUnsetResponseCode = -1;
34 static const int32 kUnsetContentLength = -1;
35 static const int32 kUnsetPayloadLength = -1;
36
37 // HttpResponse gathers the relevant output properties of an HTTP request.
38 // Depending on the value of the server_status code, response_code, and
39 // content_length may not be valid.
40 struct HttpResponse {
41 enum ServerConnectionCode {
42 // For uninitialized state.
43 NONE,
44
45 // CONNECTION_UNAVAILABLE is returned when InternetConnect() fails.
46 CONNECTION_UNAVAILABLE,
47
48 // IO_ERROR is returned when reading/writing to a buffer has failed.
49 IO_ERROR,
50
51 // SYNC_SERVER_ERROR is returned when the HTTP status code indicates that
52 // a non-auth error has occured.
53 SYNC_SERVER_ERROR,
54
55 // SYNC_AUTH_ERROR is returned when the HTTP status code indicates that an
56 // auth error has occured (i.e. a 401 or sync-specific AUTH_INVALID
57 // response)
58 // TODO(tim): Caring about AUTH_INVALID is a layering violation. But
59 // this app-specific logic is being added as a stable branch hotfix so
60 // minimal changes prevail for the moment. Fix this! Bug 35060.
61 SYNC_AUTH_ERROR,
62
63 // All the following connection codes are valid responses from the server.
64 // Means the server is up. If you update this list, be sure to also update
65 // IsGoodReplyFromServer().
66
67 // SERVER_CONNECTION_OK is returned when request was handled correctly.
68 SERVER_CONNECTION_OK,
69
70 // RETRY is returned when a Commit request fails with a RETRY response from
71 // the server.
72 //
73 // TODO(idana): the server no longer returns RETRY so we should remove this
74 // value.
75 RETRY,
76 };
77
78 // The HTTP Status code.
79 int64 response_code;
80
81 // The value of the Content-length header.
82 int64 content_length;
83
84 // The size of a download request's payload.
85 int64 payload_length;
86
87 // Value of the Update-Client-Auth header.
88 std::string update_client_auth_header;
89
90 // Identifies the type of failure, if any.
91 ServerConnectionCode server_status;
92
93 HttpResponse();
94
95 static const char* GetServerConnectionCodeString(
96 ServerConnectionCode code);
97 };
98
99 inline bool IsGoodReplyFromServer(HttpResponse::ServerConnectionCode code) {
100 return code >= HttpResponse::SERVER_CONNECTION_OK;
101 }
102
103 struct ServerConnectionEvent {
104 HttpResponse::ServerConnectionCode connection_code;
105 bool server_reachable;
106 ServerConnectionEvent(HttpResponse::ServerConnectionCode code,
107 bool server_reachable) :
108 connection_code(code), server_reachable(server_reachable) {}
109 };
110
111 class ServerConnectionEventListener {
112 public:
113 virtual void OnServerConnectionEvent(const ServerConnectionEvent& event) = 0;
114 protected:
115 virtual ~ServerConnectionEventListener() {}
116 };
117
118 class ServerConnectionManager;
119 // A helper class that automatically notifies when the status changes.
120 // TODO(tim): This class shouldn't be exposed outside of the implementation,
121 // bug 35060.
122 class ScopedServerStatusWatcher : public base::NonThreadSafe {
123 public:
124 ScopedServerStatusWatcher(ServerConnectionManager* conn_mgr,
125 HttpResponse* response);
126 virtual ~ScopedServerStatusWatcher();
127 private:
128 ServerConnectionManager* const conn_mgr_;
129 HttpResponse* const response_;
130 bool server_reachable_;
131 DISALLOW_COPY_AND_ASSIGN(ScopedServerStatusWatcher);
132 };
133
134 // Use this class to interact with the sync server.
135 // The ServerConnectionManager currently supports POSTing protocol buffers.
136 //
137 class ServerConnectionManager {
138 public:
139 // buffer_in - will be POSTed
140 // buffer_out - string will be overwritten with response
141 struct PostBufferParams {
142 std::string buffer_in;
143 std::string buffer_out;
144 HttpResponse response;
145 };
146
147 // Abstract class providing network-layer functionality to the
148 // ServerConnectionManager. Subclasses implement this using an HTTP stack of
149 // their choice.
150 class Connection {
151 public:
152 explicit Connection(ServerConnectionManager* scm);
153 virtual ~Connection();
154
155 // Called to initialize and perform an HTTP POST.
156 virtual bool Init(const char* path,
157 const std::string& auth_token,
158 const std::string& payload,
159 HttpResponse* response) = 0;
160
161 // Immediately abandons a pending HTTP POST request and unblocks caller
162 // in Init.
163 virtual void Abort() = 0;
164
165 bool ReadBufferResponse(std::string* buffer_out, HttpResponse* response,
166 bool require_response);
167 bool ReadDownloadResponse(HttpResponse* response, std::string* buffer_out);
168
169 protected:
170 std::string MakeConnectionURL(const std::string& sync_server,
171 const std::string& path,
172 bool use_ssl) const;
173
174 void GetServerParams(std::string* server,
175 int* server_port,
176 bool* use_ssl) const {
177 server->assign(scm_->sync_server_);
178 *server_port = scm_->sync_server_port_;
179 *use_ssl = scm_->use_ssl_;
180 }
181
182 std::string buffer_;
183 ServerConnectionManager* scm_;
184
185 private:
186 int ReadResponse(void* buffer, int length);
187 int ReadResponse(std::string* buffer, int length);
188 };
189
190 ServerConnectionManager(const std::string& server,
191 int port,
192 bool use_ssl,
193 const std::string& user_agent);
194
195 virtual ~ServerConnectionManager();
196
197 // POSTS buffer_in and reads a response into buffer_out. Uses our currently
198 // set auth token in our headers.
199 //
200 // Returns true if executed successfully.
201 virtual bool PostBufferWithCachedAuth(PostBufferParams* params,
202 ScopedServerStatusWatcher* watcher);
203
204 // Checks the time on the server. Returns false if the request failed. |time|
205 // is an out parameter that stores the value returned from the server.
206 virtual bool CheckTime(int32* out_time);
207
208 // Returns true if sync_server_ is reachable. This method verifies that the
209 // server is pingable and that traffic can be sent to and from it.
210 virtual bool IsServerReachable();
211
212 // Returns true if user has been successfully authenticated.
213 virtual bool IsUserAuthenticated();
214
215 // Updates status and broadcasts events on change.
216 bool CheckServerReachable();
217
218 void AddListener(ServerConnectionEventListener* listener);
219 void RemoveListener(ServerConnectionEventListener* listener);
220
221 inline std::string user_agent() const { return user_agent_; }
222
223 inline HttpResponse::ServerConnectionCode server_status() const {
224 DCHECK(thread_checker_.CalledOnValidThread());
225 return server_status_;
226 }
227
228 inline bool server_reachable() const { return server_reachable_; }
229
230 const std::string client_id() const { return client_id_; }
231
232 // This changes the server info used by the connection manager. This allows
233 // a single client instance to talk to different backing servers. This is
234 // typically called during / after authentication so that the server url
235 // can be a function of the user's login id.
236 void SetServerParameters(const std::string& server_url,
237 int port,
238 bool use_ssl);
239
240 // Returns the current server parameters in server_url, port and use_ssl.
241 void GetServerParameters(std::string* server_url,
242 int* port,
243 bool* use_ssl) const;
244
245 std::string GetServerHost() const;
246
247 // Factory method to create an Connection object we can use for
248 // communication with the server.
249 virtual Connection* MakeConnection();
250
251 // Aborts any active HTTP POST request.
252 // We expect this to get called on a different thread than the valid
253 // ThreadChecker thread, as we want to kill any pending http traffic without
254 // having to wait for the request to complete.
255 void TerminateAllIO();
256
257 void set_client_id(const std::string& client_id) {
258 DCHECK(thread_checker_.CalledOnValidThread());
259 DCHECK(client_id_.empty());
260 client_id_.assign(client_id);
261 }
262
263 // Returns true if the auth token is succesfully set and false otherwise.
264 bool set_auth_token(const std::string& auth_token) {
265 DCHECK(thread_checker_.CalledOnValidThread());
266 if (previously_invalidated_token != auth_token) {
267 auth_token_.assign(auth_token);
268 previously_invalidated_token = std::string();
269 return true;
270 }
271 return false;
272 }
273
274 void InvalidateAndClearAuthToken() {
275 DCHECK(thread_checker_.CalledOnValidThread());
276 // Copy over the token to previous invalid token.
277 if (!auth_token_.empty()) {
278 previously_invalidated_token.assign(auth_token_);
279 auth_token_ = std::string();
280 }
281 }
282
283 const std::string auth_token() const {
284 DCHECK(thread_checker_.CalledOnValidThread());
285 return auth_token_;
286 }
287
288 protected:
289 inline std::string proto_sync_path() const {
290 return proto_sync_path_;
291 }
292
293 std::string get_time_path() const {
294 return get_time_path_;
295 }
296
297 // NOTE: Tests rely on this protected function being virtual.
298 //
299 // Internal PostBuffer base function.
300 virtual bool PostBufferToPath(PostBufferParams*,
301 const std::string& path,
302 const std::string& auth_token,
303 ScopedServerStatusWatcher* watcher);
304
305 // Helper to check terminated flags and build a Connection object, installing
306 // it as the |active_connection_|. If this ServerConnectionManager has been
307 // terminated, this will return NULL.
308 Connection* MakeActiveConnection();
309
310 // Called by Connection objects as they are destroyed to allow the
311 // ServerConnectionManager to cleanup active connections.
312 void OnConnectionDestroyed(Connection* connection);
313
314 // The sync_server_ is the server that requests will be made to.
315 std::string sync_server_;
316
317 // The sync_server_port_ is the port that HTTP requests will be made on.
318 int sync_server_port_;
319
320 // The unique id of the user's client.
321 std::string client_id_;
322
323 // The user-agent string for HTTP.
324 std::string user_agent_;
325
326 // Indicates whether or not requests should be made using HTTPS.
327 bool use_ssl_;
328
329 // The paths we post to.
330 std::string proto_sync_path_;
331 std::string get_time_path_;
332
333 // The auth token to use in authenticated requests. Set by the AuthWatcher.
334 std::string auth_token_;
335
336 // The previous auth token that is invalid now.
337 std::string previously_invalidated_token;
338
339 ObserverList<ServerConnectionEventListener> listeners_;
340
341 HttpResponse::ServerConnectionCode server_status_;
342 bool server_reachable_;
343
344 base::ThreadChecker thread_checker_;
345
346 // Protects all variables below to allow bailing out of active connections.
347 base::Lock terminate_connection_lock_;
348
349 // If true, we've been told to terminate IO and expect to be destroyed
350 // shortly. No future network requests will be made.
351 bool terminated_;
352
353 // A non-owning pointer to any active http connection, so that we can abort
354 // it if necessary.
355 Connection* active_connection_;
356
357 private:
358 friend class Connection;
359 friend class ScopedServerStatusWatcher;
360
361 // A class to help deal with cleaning up active Connection objects when (for
362 // ex) multiple early-exits are present in some scope. ScopedConnectionHelper
363 // informs the ServerConnectionManager before the Connection object it takes
364 // ownership of is destroyed.
365 class ScopedConnectionHelper {
366 public:
367 // |manager| must outlive this. Takes ownership of |connection|.
368 ScopedConnectionHelper(ServerConnectionManager* manager,
369 Connection* connection);
370 ~ScopedConnectionHelper();
371 Connection* get();
372 private:
373 ServerConnectionManager* manager_;
374 scoped_ptr<Connection> connection_;
375 DISALLOW_COPY_AND_ASSIGN(ScopedConnectionHelper);
376 };
377
378 void NotifyStatusChanged();
379
380 DISALLOW_COPY_AND_ASSIGN(ServerConnectionManager);
381 };
382
383 // Fills a ClientToServerMessage with the appropriate share and birthday
384 // settings.
385 bool FillMessageWithShareDetails(sync_pb::ClientToServerMessage* csm,
386 syncable::Directory* manager,
387 const std::string& share);
388
389 std::ostream& operator<<(std::ostream& s, const struct HttpResponse& hr);
390
391 } // namespace browser_sync
392
393 #endif // CHROME_BROWSER_SYNC_ENGINE_NET_SERVER_CONNECTION_MANAGER_H_
OLDNEW
« no previous file with comments | « chrome/browser/sync/engine/model_safe_worker_unittest.cc ('k') | chrome/browser/sync/engine/net/server_connection_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698