| 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 #include "update_engine/download_action.h" | 5 #include "update_engine/download_action.h" |
| 6 #include <errno.h> | 6 #include <errno.h> |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <glib.h> | 8 #include <glib.h> |
| 9 #include "update_engine/action_pipe.h" | 9 #include "update_engine/action_pipe.h" |
| 10 | 10 |
| 11 using std::min; | 11 using std::min; |
| 12 | 12 |
| 13 namespace chromeos_update_engine { | 13 namespace chromeos_update_engine { |
| 14 | 14 |
| 15 DownloadAction::DownloadAction(HttpFetcher* http_fetcher) | 15 DownloadAction::DownloadAction(HttpFetcher* http_fetcher) |
| 16 : size_(0), | 16 : writer_(NULL), |
| 17 should_decompress_(false), | |
| 18 writer_(NULL), | |
| 19 http_fetcher_(http_fetcher) {} | 17 http_fetcher_(http_fetcher) {} |
| 20 | 18 |
| 21 DownloadAction::~DownloadAction() {} | 19 DownloadAction::~DownloadAction() {} |
| 22 | 20 |
| 23 void DownloadAction::PerformAction() { | 21 void DownloadAction::PerformAction() { |
| 24 http_fetcher_->set_delegate(this); | 22 http_fetcher_->set_delegate(this); |
| 25 CHECK(!writer_); | |
| 26 direct_file_writer_.reset(new DirectFileWriter); | |
| 27 | 23 |
| 28 // Get the InstallPlan and read it | 24 // Get the InstallPlan and read it |
| 29 CHECK(HasInputObject()); | 25 CHECK(HasInputObject()); |
| 30 InstallPlan install_plan(GetInputObject()); | 26 install_plan_ = GetInputObject(); |
| 31 | 27 |
| 32 should_decompress_ = install_plan.is_full_update; | 28 install_plan_.Dump(); |
| 33 url_ = install_plan.download_url; | |
| 34 output_path_ = install_plan.install_path; | |
| 35 hash_ = install_plan.download_hash; | |
| 36 install_plan.Dump(); | |
| 37 | 29 |
| 38 if (should_decompress_) { | 30 if (writer_) { |
| 39 decompressing_file_writer_.reset( | 31 LOG(INFO) << "Using writer for test."; |
| 40 new GzipDecompressingFileWriter(direct_file_writer_.get())); | |
| 41 writer_ = decompressing_file_writer_.get(); | |
| 42 } else { | 32 } else { |
| 43 writer_ = direct_file_writer_.get(); | 33 if (install_plan_.is_full_update) { |
| 34 kernel_file_writer_.reset(new DirectFileWriter); |
| 35 rootfs_file_writer_.reset(new DirectFileWriter); |
| 36 split_file_writer_.reset(new SplitFileWriter(kernel_file_writer_.get(), |
| 37 rootfs_file_writer_.get())); |
| 38 split_file_writer_->SetFirstOpenArgs( |
| 39 install_plan_.kernel_install_path.c_str(), |
| 40 O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, |
| 41 0644); |
| 42 decompressing_file_writer_.reset( |
| 43 new GzipDecompressingFileWriter(split_file_writer_.get())); |
| 44 writer_ = decompressing_file_writer_.get(); |
| 45 } else { |
| 46 delta_performer_.reset(new DeltaPerformer); |
| 47 writer_ = delta_performer_.get(); |
| 48 } |
| 44 } | 49 } |
| 45 int rc = writer_->Open(output_path_.c_str(), | 50 int rc = writer_->Open(install_plan_.install_path.c_str(), |
| 46 O_TRUNC | O_WRONLY | O_CREAT | O_LARGEFILE, 0644); | 51 O_TRUNC | O_WRONLY | O_CREAT | O_LARGEFILE, |
| 52 0644); |
| 47 if (rc < 0) { | 53 if (rc < 0) { |
| 48 LOG(ERROR) << "Unable to open output file " << output_path_; | 54 LOG(ERROR) << "Unable to open output file " << install_plan_.install_path; |
| 49 // report error to processor | 55 // report error to processor |
| 50 processor_->ActionComplete(this, false); | 56 processor_->ActionComplete(this, false); |
| 51 return; | 57 return; |
| 52 } | 58 } |
| 53 http_fetcher_->BeginTransfer(url_); | 59 if (!install_plan_.is_full_update) { |
| 60 if (!delta_performer_->OpenKernel( |
| 61 install_plan_.kernel_install_path.c_str())) { |
| 62 LOG(ERROR) << "Unable to open kernel file " |
| 63 << install_plan_.kernel_install_path.c_str(); |
| 64 writer_->Close(); |
| 65 processor_->ActionComplete(this, false); |
| 66 return; |
| 67 } |
| 68 } |
| 69 http_fetcher_->BeginTransfer(install_plan_.download_url); |
| 54 } | 70 } |
| 55 | 71 |
| 56 void DownloadAction::TerminateProcessing() { | 72 void DownloadAction::TerminateProcessing() { |
| 57 CHECK(writer_); | 73 CHECK(writer_); |
| 58 CHECK_EQ(writer_->Close(), 0); | 74 CHECK_EQ(writer_->Close(), 0); |
| 59 writer_ = NULL; | 75 writer_ = NULL; |
| 60 http_fetcher_->TerminateTransfer(); | 76 http_fetcher_->TerminateTransfer(); |
| 61 } | 77 } |
| 62 | 78 |
| 63 void DownloadAction::ReceivedBytes(HttpFetcher *fetcher, | 79 void DownloadAction::ReceivedBytes(HttpFetcher *fetcher, |
| 64 const char* bytes, | 80 const char* bytes, |
| 65 int length) { | 81 int length) { |
| 66 int rc = writer_->Write(bytes, length); | 82 int rc = writer_->Write(bytes, length); |
| 67 TEST_AND_RETURN(rc >= 0); | 83 TEST_AND_RETURN(rc >= 0); |
| 68 omaha_hash_calculator_.Update(bytes, length); | 84 omaha_hash_calculator_.Update(bytes, length); |
| 69 } | 85 } |
| 70 | 86 |
| 71 void DownloadAction::TransferComplete(HttpFetcher *fetcher, bool successful) { | 87 void DownloadAction::TransferComplete(HttpFetcher *fetcher, bool successful) { |
| 72 if (writer_) { | 88 if (writer_) { |
| 73 CHECK_EQ(writer_->Close(), 0) << errno; | 89 CHECK_EQ(writer_->Close(), 0) << errno; |
| 74 writer_ = NULL; | 90 writer_ = NULL; |
| 75 } | 91 } |
| 76 if (successful) { | 92 if (successful) { |
| 77 // Make sure hash is correct | 93 // Make sure hash is correct |
| 78 omaha_hash_calculator_.Finalize(); | 94 omaha_hash_calculator_.Finalize(); |
| 79 if (omaha_hash_calculator_.hash() != hash_) { | 95 if (omaha_hash_calculator_.hash() != install_plan_.download_hash) { |
| 80 LOG(ERROR) << "Download of " << url_ << " failed. Expect hash " | 96 LOG(ERROR) << "Download of " << install_plan_.download_url |
| 81 << hash_ << " but got hash " << omaha_hash_calculator_.hash(); | 97 << " failed. Expect hash " << install_plan_.download_hash |
| 98 << " but got hash " << omaha_hash_calculator_.hash(); |
| 82 successful = false; | 99 successful = false; |
| 83 } | 100 } |
| 84 } | 101 } |
| 85 | 102 |
| 86 // Write the path to the output pipe if we're successful | 103 // Write the path to the output pipe if we're successful |
| 87 if (successful && HasOutputPipe()) | 104 if (successful && HasOutputPipe()) |
| 88 SetOutputObject(GetInputObject()); | 105 SetOutputObject(GetInputObject()); |
| 89 processor_->ActionComplete(this, successful); | 106 processor_->ActionComplete(this, successful); |
| 90 } | 107 } |
| 91 | 108 |
| 92 }; // namespace {} | 109 }; // namespace {} |
| OLD | NEW |