blob: 2e1186529a8c72abc2b67e903ddf75fe01786020 [file] [log] [blame]
rspangler@google.com49fdf182009-10-10 00:57:34 +00001// 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
3// found in the LICENSE file.
4
rspangler@google.com49fdf182009-10-10 00:57:34 +00005#include "update_engine/mock_http_fetcher.h"
adlr@google.comc98a7ed2009-12-04 18:54:03 +00006#include <algorithm>
Chris Masone790e62e2010-08-12 10:41:18 -07007#include "base/logging.h"
rspangler@google.com49fdf182009-10-10 00:57:34 +00008
9// This is a mac implementation of HttpFetcher which is useful for testing.
10
adlr@google.comc98a7ed2009-12-04 18:54:03 +000011using std::min;
12
rspangler@google.com49fdf182009-10-10 00:57:34 +000013namespace chromeos_update_engine {
14
15MockHttpFetcher::~MockHttpFetcher() {
16 CHECK(!timeout_source_) << "Call TerminateTransfer() before dtor.";
17}
18
19void MockHttpFetcher::BeginTransfer(const std::string& url) {
Darin Petkovcb466212010-08-26 09:40:11 -070020 http_response_code_ = 0;
rspangler@google.com49fdf182009-10-10 00:57:34 +000021 if (sent_size_ < data_.size())
22 SendData(true);
23}
24
25// Returns false on one condition: If timeout_source_ was already set
26// and it needs to be deleted by the caller. If timeout_source_ is NULL
27// when this function is called, this function will always return true.
28bool MockHttpFetcher::SendData(bool skip_delivery) {
29 CHECK_LT(sent_size_, data_.size());
30 if (!skip_delivery) {
31 const size_t chunk_size = min(kMockHttpFetcherChunkSize,
32 data_.size() - sent_size_);
33 CHECK(delegate_);
34 delegate_->ReceivedBytes(this, &data_[sent_size_], chunk_size);
35 sent_size_ += chunk_size;
36 CHECK_LE(sent_size_, data_.size());
37 if (sent_size_ == data_.size()) {
Darin Petkovcb466212010-08-26 09:40:11 -070038 // We've sent all the data. Notify of success.
39 http_response_code_ = 200;
rspangler@google.com49fdf182009-10-10 00:57:34 +000040 delegate_->TransferComplete(this, true);
41 }
42 }
43
44 if (paused_) {
45 // If we're paused, we should return true if timeout_source_ is set,
46 // since we need the caller to delete it.
47 return timeout_source_;
48 }
49
50 if (timeout_source_) {
51 // we still need a timeout if there's more data to send
52 return sent_size_ < data_.size();
53 } else if (sent_size_ < data_.size()) {
54 // we don't have a timeout source and we need one
55 timeout_source_ = g_timeout_source_new(10);
56 CHECK(timeout_source_);
57 g_source_set_callback(timeout_source_, StaticTimeoutCallback, this,
58 NULL);
59 timout_tag_ = g_source_attach(timeout_source_, NULL);
60 }
61 return true;
62}
63
64bool MockHttpFetcher::TimeoutCallback() {
65 CHECK(!paused_);
66 bool ret = SendData(false);
67 if (false == ret) {
68 timeout_source_ = NULL;
69 }
70 return ret;
71}
72
73// If the transfer is in progress, aborts the transfer early.
74// The transfer cannot be resumed.
75void MockHttpFetcher::TerminateTransfer() {
76 sent_size_ = data_.size();
77 // kill any timeout
78 if (timeout_source_) {
79 g_source_remove(timout_tag_);
80 g_source_destroy(timeout_source_);
81 timeout_source_ = NULL;
82 }
83}
84
85void MockHttpFetcher::Pause() {
86 CHECK(!paused_);
87 paused_ = true;
88 if (timeout_source_) {
89 g_source_remove(timout_tag_);
90 g_source_destroy(timeout_source_);
91 timeout_source_ = NULL;
92 }
93
94}
95
96void MockHttpFetcher::Unpause() {
97 CHECK(paused_) << "You must pause before unpause.";
98 paused_ = false;
99 if (sent_size_ < data_.size()) {
100 SendData(false);
101 }
102}
103
104} // namespace chromeos_update_engine