blob: 3a039d1af07aaa5170cd907420d36843c4452ea0 [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
5#include <glib.h>
6
7#include "update_engine/action_pipe.h"
8#include "update_engine/download_action.h"
9
10namespace chromeos_update_engine {
11
12DownloadAction::DownloadAction(const std::string& url,
13 const std::string& output_path,
14 off_t size, const std::string& hash,
15 const bool should_decompress,
16 HttpFetcher* http_fetcher)
17 : size_(size),
18 url_(url),
19 output_path_(output_path),
20 hash_(hash),
21 should_decompress_(should_decompress),
22 writer_(NULL),
23 http_fetcher_(http_fetcher) {}
24
25DownloadAction::~DownloadAction() {}
26
27void DownloadAction::PerformAction() {
28 http_fetcher_->set_delegate(this);
29 CHECK(!writer_);
30 direct_file_writer_.reset(new DirectFileWriter);
31
32 if (should_decompress_) {
33 decompressing_file_writer_.reset(
34 new GzipDecompressingFileWriter(direct_file_writer_.get()));
35 writer_ = decompressing_file_writer_.get();
36 } else {
37 writer_ = direct_file_writer_.get();
38 }
39
40 int rc = writer_->Open(output_path_.c_str(),
41 O_TRUNC | O_WRONLY | O_CREAT | O_LARGEFILE, 0644);
42 if (rc < 0) {
43 LOG(ERROR) << "Unable to open output file " << output_path_;
44 // report error to processor
45 processor_->ActionComplete(this, false);
46 return;
47 }
48 http_fetcher_->BeginTransfer(url_);
49}
50
51void DownloadAction::TerminateProcessing() {
52 CHECK(writer_);
53 CHECK_EQ(writer_->Close(), 0);
54 writer_ = NULL;
55 http_fetcher_->TerminateTransfer();
56}
57
58void DownloadAction::ReceivedBytes(HttpFetcher *fetcher,
59 const char* bytes,
60 int length) {
61 int bytes_written = 0;
62 do {
63 CHECK_GT(length, bytes_written);
64 int rc = writer_->Write(bytes + bytes_written, length - bytes_written);
65 // TODO(adlr): handle write error
66 CHECK_GE(rc, 0);
67 bytes_written += rc;
68 } while (length != bytes_written);
69 omaha_hash_calculator_.Update(bytes, length);
70}
71
72void DownloadAction::TransferComplete(HttpFetcher *fetcher, bool successful) {
73 if (writer_) {
74 CHECK_EQ(0, writer_->Close()) << errno;
75 writer_ = NULL;
76 }
77 if (successful) {
78 // Make sure hash is correct
79 omaha_hash_calculator_.Finalize();
80 if (omaha_hash_calculator_.hash() != hash_) {
81 LOG(INFO) << "Download of " << url_ << " failed. Expect hash "
82 << hash_ << " but got hash " << omaha_hash_calculator_.hash();
83 successful = false;
84 }
85 }
86
87 // Write the path to the output pipe if we're successful
88 if (successful && HasOutputPipe())
89 SetOutputObject(output_path_);
90 processor_->ActionComplete(this, successful);
91}
92
93}; // namespace {}