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