1 // Copyright (c) 2012 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.
5 #ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_DOWNLOADER_H_
6 #define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_DOWNLOADER_H_
10 #include "native_client/src/include/nacl_macros.h"
11 #include "native_client/src/include/nacl_string.h"
12 #include "native_client/src/trusted/validator/nacl_file_info.h"
13 #include "ppapi/c/private/pp_file_handle.h"
14 #include "ppapi/c/trusted/ppb_file_io_trusted.h"
15 #include "ppapi/c/trusted/ppb_url_loader_trusted.h"
16 #include "ppapi/cpp/file_io.h"
17 #include "ppapi/cpp/instance.h"
18 #include "ppapi/cpp/url_loader.h"
19 #include "ppapi/cpp/url_response_info.h"
20 #include "ppapi/native_client/src/trusted/plugin/callback_source.h"
21 #include "ppapi/utility/completion_callback_factory.h"
35 SCHEME_CHROME_EXTENSION
,
40 typedef std::vector
<char>* FileStreamData
;
41 typedef CallbackSource
<FileStreamData
> StreamCallbackSource
;
42 typedef pp::CompletionCallbackWithOutput
<FileStreamData
> StreamCallback
;
44 // A class that wraps PPAPI URLLoader and FileIO functionality for downloading
45 // the url into a file and providing an open file descriptor.
46 class FileDownloader
{
48 // Ctor initializes |instance_| to NULL, be sure to call Initialize() before
49 // calling Open(), or Open() will fail.
52 file_open_notify_callback_(pp::BlockUntilComplete()),
53 stream_finish_callback_(pp::BlockUntilComplete()),
54 file_handle_(PP_kInvalidFileHandle
),
55 file_io_trusted_interface_(NULL
),
56 url_loader_trusted_interface_(NULL
),
59 open_and_stream_(true),
60 url_scheme_(SCHEME_OTHER
),
61 data_stream_callback_source_(NULL
) {}
64 // Initialize() can only be called once during the lifetime of this instance.
65 void Initialize(Plugin
* instance
);
67 // Issues a GET on |url| to start downloading the response into a file,
68 // and finish streaming it. |callback| will be run after streaming is
69 // done or if an error prevents streaming from completing.
70 // Returns true when callback is scheduled to be called on success or failure.
71 // Returns false if callback is NULL, Initialize() has not been called or if
72 // the PPB_FileIO_Trusted interface is not available.
73 // If |record_progress| is true, then download progress will be recorded,
74 // and can be polled through GetDownloadProgress().
75 // If |progress_callback| is not NULL and |record_progress| is true,
76 // then the callback will be invoked for every progress update received
78 bool Open(const nacl::string
& url
,
80 const pp::CompletionCallback
& callback
,
82 PP_URLLoaderTrusted_StatusCallback progress_callback
);
84 // Similar to Open(), but used for streaming the |url| data directly to the
85 // caller without writing to a temporary file. The callbacks provided by
86 // |stream_callback_source| are expected to copy the data before returning.
87 // |callback| is called once the response headers are received,
88 // and streaming must be completed separately via FinishStreaming().
89 bool OpenStream(const nacl::string
& url
,
90 const pp::CompletionCallback
& callback
,
91 StreamCallbackSource
* stream_callback_source
);
93 // Finish streaming the response body for a URL request started by either
94 // Open() or OpenStream(). If DownloadMode is DOWNLOAD_TO_FILE,
95 // then the response body is streamed to a file, the file is opened and
96 // a file descriptor is made available. Runs the given |callback| when
98 void FinishStreaming(const pp::CompletionCallback
& callback
);
100 // Bypasses downloading and takes a handle to the open file. To get the fd,
101 // call GetFileInfo().
102 void OpenFast(const nacl::string
& url
, PP_FileHandle file_handle
,
103 uint64_t file_token_lo
, uint64_t file_token_hi
);
105 // Return a structure describing the file opened, including a file desc.
106 // If downloading and opening succeeded, this returns a valid read-only
107 // POSIX file descriptor. On failure, the return value is an invalid
108 // descriptor. The file descriptor is owned by this instance, so the
109 // delegate does not have to close it.
110 struct NaClFileInfo
GetFileInfo();
112 // Returns the time delta between the call to Open() and this function.
113 int64_t TimeSinceOpenMilliseconds() const;
115 // The value of |url_| changes over the life of this instance. When the file
116 // is first opened, |url_| is a copy of the URL used to open the file, which
117 // can be a relative URL. Once the GET request has finished, and the contents
118 // of the file represented by |url_| are available, |url_| is the full URL
119 // including the scheme, host and full path.
120 const nacl::string
& url() const { return url_
; }
122 // Returns the url passed to Open().
123 const nacl::string
& url_to_open() const { return url_to_open_
; }
125 // Returns the PP_Resource of the active URL loader, or kInvalidResource.
126 PP_Resource
url_loader() const { return url_loader_
.pp_resource(); }
128 // GetDownloadProgress() returns the current download progress, which is
129 // meaningful after Open() has been called. Progress only refers to the
130 // response body and does not include the headers.
132 // This data is only available if the |record_progress| true in the
133 // Open() call. If progress is being recorded, then |bytes_received|
134 // will be set to the number of bytes received thus far,
135 // and |total_bytes_to_be_received| will be set to the total number
136 // of bytes to be received. The total bytes to be received may be unknown,
137 // in which case |total_bytes_to_be_received| will be set to -1.
138 bool GetDownloadProgress(int64_t* bytes_received
,
139 int64_t* total_bytes_to_be_received
) const;
141 // Returns the buffer used for DOWNLOAD_TO_BUFFER mode.
142 const std::deque
<char>& buffer() const { return buffer_
; }
144 bool streaming_to_file() const;
145 bool streaming_to_buffer() const;
146 bool streaming_to_user() const;
147 bool not_streaming() const;
149 int status_code() const { return status_code_
; }
150 nacl::string
GetResponseHeaders() const;
153 NACL_DISALLOW_COPY_AND_ASSIGN(FileDownloader
);
154 // This class loads and opens the file in three steps for DOWNLOAD_TO_FILE:
155 // 1) Ask the browser to start streaming |url_| as a file.
156 // 2) Ask the browser to finish streaming if headers indicate success.
157 // 3) Ask the browser to open the file, so we can get the file descriptor.
158 // For DOWNLOAD_TO_BUFFER, the process is very similar:
159 // 1) Ask the browser to start streaming |url_| to an internal buffer.
160 // 2) Ask the browser to finish streaming to |temp_buffer_| on success.
161 // 3) Wait for streaming to finish, filling |buffer_| incrementally.
162 // Each step is done asynchronously using callbacks. We create callbacks
163 // through a factory to take advantage of ref-counting.
164 // DOWNLOAD_STREAM is similar to DOWNLOAD_TO_BUFFER except the downloaded
165 // data is passed directly to the user instead of saved in a buffer.
166 // The public Open*() functions start step 1), and the public FinishStreaming
167 // function proceeds to step 2) and 3).
168 bool InitialResponseIsValid(int32_t pp_error
);
169 void URLLoadStartNotify(int32_t pp_error
);
170 void URLLoadFinishNotify(int32_t pp_error
);
171 void URLBufferStartNotify(int32_t pp_error
);
172 void URLReadBodyNotify(int32_t pp_error
);
173 void StreamFinishNotify(int32_t pp_error
);
176 nacl::string url_to_open_
;
178 pp::URLResponseInfo url_response_
;
179 pp::CompletionCallback file_open_notify_callback_
;
180 pp::CompletionCallback stream_finish_callback_
;
181 pp::FileIO file_reader_
;
182 PP_FileHandle file_handle_
;
183 struct NaClFileToken file_token_
;
184 const PPB_FileIOTrusted
* file_io_trusted_interface_
;
185 const PPB_URLLoaderTrusted
* url_loader_trusted_interface_
;
186 pp::URLLoader url_loader_
;
187 pp::CompletionCallbackFactory
<FileDownloader
> callback_factory_
;
189 int32_t status_code_
;
191 bool open_and_stream_
;
192 static const uint32_t kTempBufferSize
= 2048;
193 std::vector
<char> temp_buffer_
;
194 std::deque
<char> buffer_
;
195 UrlSchemeType url_scheme_
;
196 StreamCallbackSource
* data_stream_callback_source_
;
198 } // namespace plugin;
199 #endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_DOWNLOADER_H_