AU: Restrict to HTTPS for official builds.
Also, fix multi http fetcher unit tests to predictably force non-expensive
connections.
BUG=7945
TEST=unit tests; tested on device with dev server as well as with
no /root/.dev_mode, dev server, omaha update
Change-Id: Iacc0188b464ec018fc0dbbc8d7d447386113ceb7
Review URL: http://codereview.chromium.org/4004004
diff --git a/http_fetcher_unittest.cc b/http_fetcher_unittest.cc
index bd16768..6c420a0 100644
--- a/http_fetcher_unittest.cc
+++ b/http_fetcher_unittest.cc
@@ -136,6 +136,7 @@
ret->set_idle_seconds(1);
ret->set_retry_seconds(1);
ret->SetConnectionAsExpensive(false);
+ ret->SetBuildType(false);
return ret;
}
HttpFetcher* NewSmallFetcher() {
@@ -169,6 +170,8 @@
// Speed up test execution.
ret->set_idle_seconds(1);
ret->set_retry_seconds(1);
+ ret->SetConnectionAsExpensive(false);
+ ret->SetBuildType(false);
return ret;
}
bool IsMulti() const { return true; }
@@ -613,6 +616,8 @@
dynamic_cast<MultiHttpFetcher<LibcurlHttpFetcher>*>(fetcher.get());
ASSERT_TRUE(multi_fetcher);
multi_fetcher->set_ranges(ranges);
+ multi_fetcher->SetConnectionAsExpensive(false);
+ multi_fetcher->SetBuildType(false);
fetcher->set_delegate(&delegate);
StartTransferArgs start_xfer_args = {fetcher.get(), url};
@@ -698,7 +703,7 @@
}
namespace {
-class ExpensiveConnectionTestDelegate : public HttpFetcherDelegate {
+class BlockedTransferTestDelegate : public HttpFetcherDelegate {
public:
virtual void ReceivedBytes(HttpFetcher* fetcher,
const char* bytes, int length) {
@@ -713,28 +718,37 @@
} // namespace
-TYPED_TEST(HttpFetcherTest, ExpensiveConnectionTest) {
+TYPED_TEST(HttpFetcherTest, BlockedTransferTest) {
if (this->IsMock() || this->IsMulti())
return;
- typename TestFixture::HttpServer server;
-
- ASSERT_TRUE(server.started_);
- GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
- ExpensiveConnectionTestDelegate delegate;
- delegate.loop_ = loop;
+ for (int i = 0; i < 2; i++) {
+ typename TestFixture::HttpServer server;
- scoped_ptr<HttpFetcher> fetcher(this->NewLargeFetcher());
- dynamic_cast<LibcurlHttpFetcher*>(
- fetcher.get())->SetConnectionAsExpensive(true);
- fetcher->set_delegate(&delegate);
+ ASSERT_TRUE(server.started_);
- StartTransferArgs start_xfer_args =
- { fetcher.get(), LocalServerUrlForPath(this->SmallUrl()) };
+ GMainLoop* loop = g_main_loop_new(g_main_context_default(), FALSE);
+ BlockedTransferTestDelegate delegate;
+ delegate.loop_ = loop;
- g_timeout_add(0, StartTransfer, &start_xfer_args);
- g_main_loop_run(loop);
- g_main_loop_unref(loop);
+ scoped_ptr<HttpFetcher> fetcher(this->NewLargeFetcher());
+ LibcurlHttpFetcher* curl_fetcher =
+ dynamic_cast<LibcurlHttpFetcher*>(fetcher.get());
+ bool is_expensive_connection = (i == 0);
+ bool is_official_build = (i == 1);
+ LOG(INFO) << "is_expensive_connection: " << is_expensive_connection;
+ LOG(INFO) << "is_official_build: " << is_official_build;
+ curl_fetcher->SetConnectionAsExpensive(is_expensive_connection);
+ curl_fetcher->SetBuildType(is_official_build);
+ fetcher->set_delegate(&delegate);
+
+ StartTransferArgs start_xfer_args =
+ { fetcher.get(), LocalServerUrlForPath(this->SmallUrl()) };
+
+ g_timeout_add(0, StartTransfer, &start_xfer_args);
+ g_main_loop_run(loop);
+ g_main_loop_unref(loop);
+ }
}
} // namespace chromeos_update_engine
diff --git a/libcurl_http_fetcher.cc b/libcurl_http_fetcher.cc
index 9cacf86..a921725 100644
--- a/libcurl_http_fetcher.cc
+++ b/libcurl_http_fetcher.cc
@@ -43,6 +43,10 @@
return FlimFlamProxy::IsExpensiveConnectionType(type);
}
+bool LibcurlHttpFetcher::IsOfficialBuild() const {
+ return force_build_type_ ? forced_official_build_ : utils::IsOfficialBuild();
+}
+
void LibcurlHttpFetcher::ResumeTransfer(const std::string& url) {
LOG(INFO) << "Starting/Resuming transfer";
CHECK(!transfer_in_progress_);
@@ -82,9 +86,7 @@
url_to_use = ""; // Sabotage the URL
}
- CHECK_EQ(curl_easy_setopt(curl_handle_,
- CURLOPT_URL,
- url_to_use.c_str()),
+ CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_URL, url_to_use.c_str()),
CURLE_OK);
// If the connection drops under 10 bytes/sec for 3 minutes, reconnect.
@@ -105,6 +107,16 @@
CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_CAPATH, kCACertificatesPath),
CURLE_OK);
+ // Restrict protocols to HTTPS in official builds.
+ if (IsOfficialBuild()) {
+ CHECK_EQ(curl_easy_setopt(curl_handle_, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS),
+ CURLE_OK);
+ CHECK_EQ(curl_easy_setopt(curl_handle_,
+ CURLOPT_REDIR_PROTOCOLS,
+ CURLPROTO_HTTPS),
+ CURLE_OK);
+ }
+
CHECK_EQ(curl_multi_add_handle(curl_multi_handle_, curl_handle_), CURLM_OK);
transfer_in_progress_ = true;
}
diff --git a/libcurl_http_fetcher.h b/libcurl_http_fetcher.h
index 2628ecc..25c4e49 100644
--- a/libcurl_http_fetcher.h
+++ b/libcurl_http_fetcher.h
@@ -35,6 +35,8 @@
idle_seconds_(1),
force_connection_type_(false),
forced_expensive_connection_(false),
+ force_build_type_(false),
+ forced_official_build_(false),
in_write_callback_(false),
terminate_requested_(false) {}
@@ -69,12 +71,17 @@
// Sets the retry timeout. Useful for testing.
void set_retry_seconds(int seconds) { retry_seconds_ = seconds; }
-
+
void SetConnectionAsExpensive(bool is_expensive) {
force_connection_type_ = true;
forced_expensive_connection_ = is_expensive;
}
+ void SetBuildType(bool is_official) {
+ force_build_type_ = true;
+ forced_official_build_ = is_official;
+ }
+
private:
// Asks libcurl for the http response code and stores it in the object.
void GetHttpResponseCode();
@@ -133,6 +140,9 @@
// expensive.
bool ConnectionIsExpensive() const;
+ // Returns whether or not the current build is official.
+ bool IsOfficialBuild() const;
+
// Handles for the libcurl library
CURLM *curl_multi_handle_;
CURL *curl_handle_;
@@ -168,15 +178,20 @@
// Seconds to wait before asking libcurl to "perform".
int idle_seconds_;
-
+
// If true, assume the network is expensive or not, according to
// forced_expensive_connection_. (Useful for testing).
bool force_connection_type_;
bool forced_expensive_connection_;
+ // If true, assume the build is official or not, according to
+ // forced_official_build_. Useful for testing.
+ bool force_build_type_;
+ bool forced_official_build_;
+
// If true, we are currently performing a write callback on the delegate.
bool in_write_callback_;
-
+
// We can't clean everything up while we're in a write callback, so
// if we get a terminate request, queue it until we can handle it.
bool terminate_requested_;
diff --git a/multi_http_fetcher.h b/multi_http_fetcher.h
index 1972347..4328199 100644
--- a/multi_http_fetcher.h
+++ b/multi_http_fetcher.h
@@ -73,8 +73,7 @@
fetchers_[current_index_]->Unpause();
}
- // These two function are overloaded in LibcurlHttp fetcher to speed
- // testing.
+ // These functions are overloaded in LibcurlHttp fetcher for testing purposes.
void set_idle_seconds(int seconds) {
for (typename std::vector<std::tr1::shared_ptr<BaseHttpFetcher> >::iterator
it = fetchers_.begin(),
@@ -89,6 +88,20 @@
(*it)->set_retry_seconds(seconds);
}
}
+ void SetConnectionAsExpensive(bool is_expensive) {
+ for (typename std::vector<std::tr1::shared_ptr<BaseHttpFetcher> >::iterator
+ it = fetchers_.begin(),
+ e = fetchers_.end(); it != e; ++it) {
+ (*it)->SetConnectionAsExpensive(is_expensive);
+ }
+ }
+ void SetBuildType(bool is_official) {
+ for (typename std::vector<std::tr1::shared_ptr<BaseHttpFetcher> >::iterator
+ it = fetchers_.begin(),
+ e = fetchers_.end(); it != e; ++it) {
+ (*it)->SetBuildType(is_official);
+ }
+ }
private:
void SendTransferComplete(HttpFetcher* fetcher, bool successful) {
@@ -173,7 +186,7 @@
}
// If true, do not send any more data or TransferComplete to the delegate.
- bool sent_transfer_complete_;
+ bool sent_transfer_complete_;
RangesVect ranges_;
std::vector<std::tr1::shared_ptr<BaseHttpFetcher> > fetchers_;