OLD | NEW |
1 // Copyright (c) 2009 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium OS Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_LIBCURL_HTTP_FETCHER_H__ | 5 #ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_LIBCURL_HTTP_FETCHER_H__ |
6 #define CHROMEOS_PLATFORM_UPDATE_ENGINE_LIBCURL_HTTP_FETCHER_H__ | 6 #define CHROMEOS_PLATFORM_UPDATE_ENGINE_LIBCURL_HTTP_FETCHER_H__ |
7 | 7 |
8 #include <map> | 8 #include <map> |
9 #include <string> | 9 #include <string> |
10 #include <curl/curl.h> | 10 #include <curl/curl.h> |
11 #include <glib.h> | 11 #include <glib.h> |
12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "update_engine/http_fetcher.h" | 14 #include "update_engine/http_fetcher.h" |
15 | 15 |
16 // This is a concrete implementation of HttpFetcher that uses libcurl to do the | 16 // This is a concrete implementation of HttpFetcher that uses libcurl to do the |
17 // http work. | 17 // http work. |
18 | 18 |
19 namespace chromeos_update_engine { | 19 namespace chromeos_update_engine { |
20 | 20 |
21 class LibcurlHttpFetcher : public HttpFetcher { | 21 class LibcurlHttpFetcher : public HttpFetcher { |
22 public: | 22 public: |
23 LibcurlHttpFetcher() | 23 LibcurlHttpFetcher() |
24 : curl_multi_handle_(NULL), curl_handle_(NULL), | 24 : curl_multi_handle_(NULL), |
25 timeout_source_(NULL), transfer_in_progress_(false), | 25 curl_handle_(NULL), |
26 retry_count_(0), idle_ms_(1000) {} | 26 timeout_source_(NULL), |
| 27 transfer_in_progress_(false), |
| 28 retry_count_(0), |
| 29 retry_seconds_(60), |
| 30 idle_seconds_(1) {} |
27 | 31 |
28 // Cleans up all internal state. Does not notify delegate | 32 // Cleans up all internal state. Does not notify delegate |
29 ~LibcurlHttpFetcher(); | 33 ~LibcurlHttpFetcher(); |
30 | 34 |
31 // Begins the transfer if it hasn't already begun. | 35 // Begins the transfer if it hasn't already begun. |
32 virtual void BeginTransfer(const std::string& url); | 36 virtual void BeginTransfer(const std::string& url); |
33 | 37 |
34 // If the transfer is in progress, aborts the transfer early. | 38 // If the transfer is in progress, aborts the transfer early. |
35 // The transfer cannot be resumed. | 39 // The transfer cannot be resumed. |
36 virtual void TerminateTransfer(); | 40 virtual void TerminateTransfer(); |
37 | 41 |
38 // Suspend the transfer by calling curl_easy_pause(CURLPAUSE_ALL). | 42 // Suspend the transfer by calling curl_easy_pause(CURLPAUSE_ALL). |
39 virtual void Pause(); | 43 virtual void Pause(); |
40 | 44 |
41 // Resume the transfer by calling curl_easy_pause(CURLPAUSE_CONT). | 45 // Resume the transfer by calling curl_easy_pause(CURLPAUSE_CONT). |
42 virtual void Unpause(); | 46 virtual void Unpause(); |
43 | 47 |
44 // Libcurl sometimes asks to be called back after some time while | 48 // Libcurl sometimes asks to be called back after some time while |
45 // leaving that time unspecified. In that case, we pick a reasonable | 49 // leaving that time unspecified. In that case, we pick a reasonable |
46 // default of one second, but it can be overridden here. This is | 50 // default of one second, but it can be overridden here. This is |
47 // primarily useful for testing. | 51 // primarily useful for testing. |
48 // From http://curl.haxx.se/libcurl/c/curl_multi_timeout.html: | 52 // From http://curl.haxx.se/libcurl/c/curl_multi_timeout.html: |
49 // if libcurl returns a -1 timeout here, it just means that libcurl | 53 // if libcurl returns a -1 timeout here, it just means that libcurl |
50 // currently has no stored timeout value. You must not wait too long | 54 // currently has no stored timeout value. You must not wait too long |
51 // (more than a few seconds perhaps) before you call | 55 // (more than a few seconds perhaps) before you call |
52 // curl_multi_perform() again. | 56 // curl_multi_perform() again. |
53 void set_idle_ms(long ms) { | 57 void set_idle_seconds(int seconds) { idle_seconds_ = seconds; } |
54 idle_ms_ = ms; | 58 |
55 } | 59 // Sets the retry timeout. Useful for testing. |
| 60 void set_retry_seconds(int seconds) { retry_seconds_ = seconds; } |
| 61 |
56 private: | 62 private: |
57 // Resumes a transfer where it left off. This will use the | 63 // Resumes a transfer where it left off. This will use the |
58 // HTTP Range: header to make a new connection from where the last | 64 // HTTP Range: header to make a new connection from where the last |
59 // left off. | 65 // left off. |
60 virtual void ResumeTransfer(const std::string& url); | 66 virtual void ResumeTransfer(const std::string& url); |
61 | 67 |
62 // These two methods are for glib main loop callbacks. They are called | 68 // These two methods are for glib main loop callbacks. They are called |
63 // when either a file descriptor is ready for work or when a timer | 69 // when either a file descriptor is ready for work or when a timer |
64 // has fired. The static versions are shims for libcurl which has a C API. | 70 // has fired. The static versions are shims for libcurl which has a C API. |
65 bool FDCallback(GIOChannel *source, GIOCondition condition); | 71 bool FDCallback(GIOChannel *source, GIOCondition condition); |
66 static gboolean StaticFDCallback(GIOChannel *source, | 72 static gboolean StaticFDCallback(GIOChannel *source, |
67 GIOCondition condition, | 73 GIOCondition condition, |
68 gpointer data) { | 74 gpointer data) { |
69 return reinterpret_cast<LibcurlHttpFetcher*>(data)->FDCallback(source, | 75 return reinterpret_cast<LibcurlHttpFetcher*>(data)->FDCallback(source, |
70 condition); | 76 condition); |
71 } | 77 } |
72 gboolean TimeoutCallback(); | 78 gboolean TimeoutCallback(); |
73 static gboolean StaticTimeoutCallback(gpointer data) { | 79 static gboolean StaticTimeoutCallback(gpointer data) { |
74 return reinterpret_cast<LibcurlHttpFetcher*>(data)->TimeoutCallback(); | 80 return reinterpret_cast<LibcurlHttpFetcher*>(data)->TimeoutCallback(); |
75 } | 81 } |
76 | 82 |
77 gboolean RetryTimeoutCallback(); | 83 gboolean RetryTimeoutCallback(); |
78 static gboolean StaticRetryTimeoutCallback(void* arg) { | 84 static gboolean StaticRetryTimeoutCallback(void* arg) { |
79 return static_cast<LibcurlHttpFetcher*>(arg)->RetryTimeoutCallback(); | 85 return static_cast<LibcurlHttpFetcher*>(arg)->RetryTimeoutCallback(); |
80 } | 86 } |
81 | 87 |
82 // Calls into curl_multi_perform to let libcurl do its work. Returns after | 88 // Calls into curl_multi_perform to let libcurl do its work. Returns after |
83 // curl_multi_perform is finished, which may actually be after more than | 89 // curl_multi_perform is finished, which may actually be after more than |
84 // one call to curl_multi_perform. This method will set up the glib run | 90 // one call to curl_multi_perform. This method will set up the glib run |
85 // loop with sources for future work that libcurl will do. | 91 // loop with sources for future work that libcurl will do. |
86 // This method will not block. | 92 // This method will not block. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 | 127 |
122 // The transfer size. -1 if not known. | 128 // The transfer size. -1 if not known. |
123 off_t transfer_size_; | 129 off_t transfer_size_; |
124 | 130 |
125 // How many bytes have been downloaded and sent to the delegate. | 131 // How many bytes have been downloaded and sent to the delegate. |
126 off_t bytes_downloaded_; | 132 off_t bytes_downloaded_; |
127 | 133 |
128 // If we resumed an earlier transfer, data offset that we used for the | 134 // If we resumed an earlier transfer, data offset that we used for the |
129 // new connection. 0 otherwise. | 135 // new connection. 0 otherwise. |
130 off_t resume_offset_; | 136 off_t resume_offset_; |
131 | 137 |
132 // Number of resumes performed. | 138 // Number of resumes performed. |
133 int retry_count_; | 139 int retry_count_; |
134 | 140 |
135 long idle_ms_; | 141 // Seconds to wait before retrying a resume. |
| 142 int retry_seconds_; |
| 143 |
| 144 // Seconds to wait before asking libcurl to "perform". |
| 145 int idle_seconds_; |
| 146 |
136 DISALLOW_COPY_AND_ASSIGN(LibcurlHttpFetcher); | 147 DISALLOW_COPY_AND_ASSIGN(LibcurlHttpFetcher); |
137 }; | 148 }; |
138 | 149 |
139 } // namespace chromeos_update_engine | 150 } // namespace chromeos_update_engine |
140 | 151 |
141 #endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_LIBCURL_HTTP_FETCHER_H__ | 152 #endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_LIBCURL_HTTP_FETCHER_H__ |
OLD | NEW |