• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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 COMPONENTS_RAPPOR_LOG_UPLOADER_H_
6 #define COMPONENTS_RAPPOR_LOG_UPLOADER_H_
7 
8 #include <queue>
9 #include <string>
10 
11 #include "base/compiler_specific.h"
12 #include "base/macros.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/time/time.h"
15 #include "base/timer/timer.h"
16 #include "net/url_request/url_fetcher_delegate.h"
17 #include "net/url_request/url_request_context_getter.h"
18 #include "url/gurl.h"
19 
20 namespace net {
21 class URLFetcher;
22 }
23 
24 namespace rappor {
25 
26 // Uploads logs from RapporService.  Logs are passed in via QueueLog(), stored
27 // internally, and uploaded one at a time.  A queued log will be uploaded at a
28 // fixed interval after the successful upload of the previous logs.  If an
29 // upload fails, the uploader will keep retrying the upload with an exponential
30 // backoff interval.
31 class LogUploader : public net::URLFetcherDelegate {
32  public:
33   // Constructor takes the |server_url| that logs should be uploaded to, the
34   // |mime_type| of the uploaded data, and |request_context| to create uploads
35   // with.
36   LogUploader(const GURL& server_url,
37               const std::string& mime_type,
38               net::URLRequestContextGetter* request_context);
39 
40   // If the object is destroyed (or the program terminates) while logs are
41   // queued, the logs are lost.
42   virtual ~LogUploader();
43 
44   // Adds an entry to the queue of logs to be uploaded to the server.  The
45   // uploader makes no assumptions about the format of |log| and simply sends
46   // it verbatim to the server.
47   void QueueLog(const std::string& log);
48 
49  protected:
50   // Checks if an upload has been scheduled.
51   virtual bool IsUploadScheduled() const;
52 
53   // Schedules a future call to StartScheduledUpload if one isn't already
54   // pending.  Can be overridden for testing.
55   virtual void ScheduleNextUpload(base::TimeDelta interval);
56 
57   // Starts transmission of the next log. Exposed for tests.
58   void StartScheduledUpload();
59 
60   // Increases the upload interval each time it's called, to handle the case
61   // where the server is having issues. Exposed for tests.
62   static base::TimeDelta BackOffUploadInterval(base::TimeDelta);
63 
64  private:
65   // Implements net::URLFetcherDelegate. Called after transmission completes
66   // (whether successful or not).
67   virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
68 
69   // Called when the upload is completed.
70   void OnUploadFinished(bool server_is_healthy, bool more_logs_remaining);
71 
72   // The server URL to upload logs to.
73   const GURL server_url_;
74 
75   // The mime type to specify on uploaded logs.
76   const std::string mime_type_;
77 
78   // The request context used to send uploads.
79   scoped_refptr<net::URLRequestContextGetter> request_context_;
80 
81   // The outstanding transmission that appears as a URL Fetch operation.
82   scoped_ptr<net::URLFetcher> current_fetch_;
83 
84   // The logs that still need to be uploaded.
85   std::queue<std::string> queued_logs_;
86 
87   // A timer used to delay before attempting another upload.
88   base::OneShotTimer<LogUploader> upload_timer_;
89 
90   // Indicates that the last triggered upload hasn't resolved yet.
91   bool has_callback_pending_;
92 
93   // The interval to wait after an upload's URLFetcher completion before
94   // starting the next upload attempt.
95   base::TimeDelta upload_interval_;
96 
97   DISALLOW_COPY_AND_ASSIGN(LogUploader);
98 };
99 
100 }  // namespace rappor
101 
102 #endif  // COMPONENTS_RAPPOR_LOG_UPLOADER_H_
103