11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved. 21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be 31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file. 41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "mojo/tools/package_manager/package_fetcher.h" 61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/bind.h" 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_path.h" 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "mojo/services/public/interfaces/network/url_loader.mojom.h" 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace mojo { 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciPackageFetcher::PackageFetcher(NetworkService* network_service, 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PackageFetcherDelegate* delegate, 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const GURL& url) 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : delegate_(delegate), 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci url_(url) { 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci network_service->CreateURLLoader(Get(&loader_)); 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci URLRequestPtr request(URLRequest::New()); 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request->url = url.spec(); 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request->auto_follow_redirects = true; 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci loader_->Start(request.Pass(), 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&PackageFetcher::OnReceivedResponse, 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Unretained(this))); 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciPackageFetcher::~PackageFetcher() { 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PackageFetcher::OnReceivedResponse(URLResponsePtr response) { 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (response->error) { 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci printf("Got error %d (%s) for %s\n", 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci response->error->code, 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci response->error->description.get().c_str(), 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci url_.spec().c_str()); 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci delegate_->FetchFailed(url_); 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!base::CreateTemporaryFile(&output_file_name_)) { 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci delegate_->FetchFailed(url_); 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci output_file_.Initialize(output_file_name_, 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!output_file_.IsValid()) { 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::DeleteFile(output_file_name_, false); 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci delegate_->FetchFailed(url_); 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Danger: may be deleted now. 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci body_ = response->body.Pass(); 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ReadData(MOJO_RESULT_OK); 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Danger: may be deleted now. 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PackageFetcher::ReadData(MojoResult) { 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci char buf[4096]; 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci uint32_t num_bytes = sizeof(buf); 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MojoResult result = ReadDataRaw(body_.get(), buf, &num_bytes, 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MOJO_READ_DATA_FLAG_NONE); 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (result == MOJO_RESULT_SHOULD_WAIT) { 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WaitToReadMore(); 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else if (result == MOJO_RESULT_OK) { 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (output_file_.WriteAtCurrentPos(buf, num_bytes) != 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci static_cast<int>(num_bytes)) { 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Clean up the output file. 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci output_file_.Close(); 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::DeleteFile(output_file_name_, false); 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci delegate_->FetchFailed(url_); 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Danger: may be deleted now. 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WaitToReadMore(); 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else if (result == MOJO_RESULT_FAILED_PRECONDITION) { 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Done. 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci output_file_.Close(); 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci delegate_->FetchSucceeded(url_, output_file_name_); 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Danger: may be deleted now. 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PackageFetcher::WaitToReadMore() { 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci handle_watcher_.Start( 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci body_.get(), 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MOJO_HANDLE_SIGNAL_READABLE, 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MOJO_DEADLINE_INDEFINITE, 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&PackageFetcher::ReadData, base::Unretained(this))); 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace mojo 97