Home | History | Annotate | Download | only in plugin
      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.
      4 
      5 #ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_DOWNLOADER_H_
      6 #define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_DOWNLOADER_H_
      7 
      8 #include <deque>
      9 
     10 #include "native_client/src/include/nacl_macros.h"
     11 #include "native_client/src/include/nacl_string.h"
     12 #include "native_client/src/public/nacl_file_info.h"
     13 #include "ppapi/c/private/ppb_nacl_private.h"
     14 #include "ppapi/cpp/file_io.h"
     15 #include "ppapi/cpp/instance.h"
     16 #include "ppapi/cpp/url_loader.h"
     17 #include "ppapi/cpp/url_response_info.h"
     18 #include "ppapi/native_client/src/trusted/plugin/callback_source.h"
     19 #include "ppapi/utility/completion_callback_factory.h"
     20 
     21 namespace plugin {
     22 
     23 class Plugin;
     24 
     25 typedef enum {
     26   DOWNLOAD_TO_BUFFER_AND_STREAM = 0,
     27   DOWNLOAD_NONE
     28 } DownloadMode;
     29 
     30 typedef std::vector<char>* FileStreamData;
     31 typedef CallbackSource<FileStreamData> StreamCallbackSource;
     32 typedef pp::CompletionCallbackWithOutput<FileStreamData> StreamCallback;
     33 
     34 // A class that wraps PPAPI URLLoader and FileIO functionality for downloading
     35 // the url into a file and providing an open file descriptor.
     36 class FileDownloader {
     37  public:
     38   explicit FileDownloader(Plugin* instance);
     39   ~FileDownloader() {}
     40 
     41   // Issues a GET on |url| to start downloading the response into a file,
     42   // and finish streaming it. |callback| will be run after streaming is
     43   // done or if an error prevents streaming from completing.
     44   // Returns true when callback is scheduled to be called on success or failure.
     45   // Returns false if callback is NULL, or if the PPB_FileIO_Trusted interface
     46   // is not available.
     47   // If |record_progress| is true, then download progress will be recorded,
     48   // and can be polled through GetDownloadProgress().
     49   // If |progress_callback| is not NULL and |record_progress| is true,
     50   // then the callback will be invoked for every progress update received
     51   // by the loader.
     52 
     53   // Similar to Open(), but used for streaming the |url| data directly to the
     54   // caller without writing to a temporary file. The callbacks provided by
     55   // |stream_callback_source| are expected to copy the data before returning.
     56   // |callback| is called once the response headers are received,
     57   // and streaming must be completed separately via BeginStreaming().
     58   bool OpenStream(const nacl::string& url,
     59                   const pp::CompletionCallback& callback,
     60                   StreamCallbackSource* stream_callback_source);
     61 
     62   // Finish streaming the response body for a URL request started by either
     63   // OpenStream(). Runs the given |callback| when streaming is done.
     64   void BeginStreaming(const pp::CompletionCallback& callback);
     65 
     66   // Once the GET request has finished, and the contents of the file
     67   // represented by |url_| are available, |full_url_| is the full URL including
     68   // the scheme, host and full path.
     69   // Returns an empty string before the GET request has finished.
     70   const nacl::string& full_url() const { return full_url_; }
     71 
     72   // GetDownloadProgress() returns the current download progress, which is
     73   // meaningful after Open() has been called. Progress only refers to the
     74   // response body and does not include the headers.
     75   //
     76   // This data is only available if the |record_progress| true in the
     77   // Open() call.  If progress is being recorded, then |bytes_received|
     78   // will be set to the number of bytes received thus far,
     79   // and |total_bytes_to_be_received| will be set to the total number
     80   // of bytes to be received.  The total bytes to be received may be unknown,
     81   // in which case |total_bytes_to_be_received| will be set to -1.
     82   bool GetDownloadProgress(int64_t* bytes_received,
     83                            int64_t* total_bytes_to_be_received) const;
     84 
     85   int status_code() const { return status_code_; }
     86   nacl::string GetResponseHeaders() const;
     87 
     88   void set_request_headers(const nacl::string& extra_request_headers) {
     89     extra_request_headers_ = extra_request_headers;
     90   }
     91 
     92  private:
     93   NACL_DISALLOW_COPY_AND_ASSIGN(FileDownloader);
     94 
     95   // For DOWNLOAD_TO_BUFFER_AND_STREAM, the process is very similar:
     96   //   1) Ask the browser to start streaming |url_| to an internal buffer.
     97   //   2) Ask the browser to finish streaming to |temp_buffer_| on success.
     98   //   3) Wait for streaming to finish, passing the data directly to the user.
     99   // Each step is done asynchronously using callbacks.  We create callbacks
    100   // through a factory to take advantage of ref-counting.
    101   // The public Open*() functions start step 1), and the public BeginStreaming
    102   // function proceeds to step 2) and 3).
    103   bool InitialResponseIsValid();
    104   void URLLoadStartNotify(int32_t pp_error);
    105   void URLReadBodyNotify(int32_t pp_error);
    106 
    107   Plugin* instance_;
    108   nacl::string full_url_;
    109 
    110   nacl::string extra_request_headers_;
    111   pp::URLResponseInfo url_response_;
    112   pp::CompletionCallback file_open_notify_callback_;
    113   pp::CompletionCallback stream_finish_callback_;
    114   pp::URLLoader url_loader_;
    115   pp::CompletionCallbackFactory<FileDownloader> callback_factory_;
    116   int32_t status_code_;
    117   DownloadMode mode_;
    118   static const uint32_t kTempBufferSize = 16384;
    119   std::vector<char> temp_buffer_;
    120   StreamCallbackSource* data_stream_callback_source_;
    121 };
    122 
    123 }  // namespace plugin
    124 
    125 #endif  // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_FILE_DOWNLOADER_H_
    126