Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / mojo / tools / package_manager / package_fetcher.cc
1 // Copyright 2014 The Chromium 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 "mojo/tools/package_manager/package_fetcher.h"
6
7 #include "base/bind.h"
8 #include "base/files/file_path.h"
9 #include "base/files/file_util.h"
10 #include "mojo/services/public/interfaces/network/url_loader.mojom.h"
11
12 namespace mojo {
13
14 PackageFetcher::PackageFetcher(NetworkService* network_service,
15                                PackageFetcherDelegate* delegate,
16                                const GURL& url)
17     : delegate_(delegate),
18       url_(url) {
19   network_service->CreateURLLoader(Get(&loader_));
20
21   URLRequestPtr request(URLRequest::New());
22   request->url = url.spec();
23   request->auto_follow_redirects = true;
24
25   loader_->Start(request.Pass(),
26                  base::Bind(&PackageFetcher::OnReceivedResponse,
27                             base::Unretained(this)));
28 }
29
30 PackageFetcher::~PackageFetcher() {
31 }
32
33 void PackageFetcher::OnReceivedResponse(URLResponsePtr response) {
34   if (response->error) {
35     printf("Got error %d (%s) for %s\n",
36            response->error->code,
37            response->error->description.get().c_str(),
38            url_.spec().c_str());
39     delegate_->FetchFailed(url_);
40     return;
41   }
42
43   if (!base::CreateTemporaryFile(&output_file_name_)) {
44     delegate_->FetchFailed(url_);
45     return;
46   }
47   output_file_.Initialize(output_file_name_,
48       base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
49   if (!output_file_.IsValid()) {
50     base::DeleteFile(output_file_name_, false);
51     delegate_->FetchFailed(url_);
52     // Danger: may be deleted now.
53     return;
54   }
55
56   body_ = response->body.Pass();
57   ReadData(MOJO_RESULT_OK);
58   // Danger: may be deleted now.
59 }
60
61 void PackageFetcher::ReadData(MojoResult) {
62   char buf[4096];
63   uint32_t num_bytes = sizeof(buf);
64   MojoResult result = ReadDataRaw(body_.get(), buf, &num_bytes,
65                                   MOJO_READ_DATA_FLAG_NONE);
66   if (result == MOJO_RESULT_SHOULD_WAIT) {
67     WaitToReadMore();
68   } else if (result == MOJO_RESULT_OK) {
69     if (output_file_.WriteAtCurrentPos(buf, num_bytes) !=
70         static_cast<int>(num_bytes)) {
71       // Clean up the output file.
72       output_file_.Close();
73       base::DeleteFile(output_file_name_, false);
74
75       delegate_->FetchFailed(url_);
76       // Danger: may be deleted now.
77       return;
78     }
79     WaitToReadMore();
80   } else if (result == MOJO_RESULT_FAILED_PRECONDITION) {
81     // Done.
82     output_file_.Close();
83     delegate_->FetchSucceeded(url_, output_file_name_);
84     // Danger: may be deleted now.
85   }
86 }
87
88 void PackageFetcher::WaitToReadMore() {
89   handle_watcher_.Start(
90       body_.get(),
91       MOJO_HANDLE_SIGNAL_READABLE,
92       MOJO_DEADLINE_INDEFINITE,
93       base::Bind(&PackageFetcher::ReadData, base::Unretained(this)));
94 }
95
96 }  // namespace mojo