Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / native_client_sdk / doc_generated / devguide / coding / url-loading.html
1 {{+bindTo:partials.standard_nacl_article}}
2
3 <section id="url-loading">
4 <span id="devguide-coding-url-loading"></span><h1 id="url-loading"><span id="devguide-coding-url-loading"></span>URL Loading</h1>
5 <div class="contents local" id="contents" style="display: none">
6 <ul class="small-gap">
7 <li><a class="reference internal" href="#introduction" id="id1">Introduction</a></li>
8 <li><a class="reference internal" href="#reference-information" id="id2">Reference information</a></li>
9 <li><a class="reference internal" href="#background" id="id3">Background</a></li>
10 <li><p class="first"><a class="reference internal" href="#the-url-loader-example" id="id4">The <code>url_loader</code> example</a></p>
11 <ul class="small-gap">
12 <li><a class="reference internal" href="#url-loading-overview" id="id5">URL loading overview</a></li>
13 </ul>
14 </li>
15 <li><p class="first"><a class="reference internal" href="#url-loader-deep-dive" id="id6"><code>url_loader</code> deep dive</a></p>
16 <ul class="small-gap">
17 <li><a class="reference internal" href="#setting-up-the-request" id="id7">Setting up the request</a></li>
18 <li><a class="reference internal" href="#downloading-the-data" id="id8">Downloading the data</a></li>
19 <li><a class="reference internal" href="#displaying-a-result" id="id9">Displaying a result</a></li>
20 </ul>
21 </li>
22 </ul>
23
24 </div><h2 id="introduction">Introduction</h2>
25 <p>This section describes how to use the <a class="reference external" href="/native-client/pepper_stable/cpp/classpp_1_1_u_r_l_loader">URLLoader API</a> to load resources
26 such as images and sound files from a server into your application.</p>
27 <p>The example discussed in this section is included in the SDK in the directory
28 <code>examples/api/url_loader</code>.</p>
29 <h2 id="reference-information">Reference information</h2>
30 <p>For reference information related to loading data from URLs, see the
31 following documentation:</p>
32 <ul class="small-gap">
33 <li><a class="reference external" href="/native-client/pepper_stable/cpp/url__loader_8h">url_loader.h</a> - Contains
34 <code>URLLoader</code> class for loading data from URLs</li>
35 <li><a class="reference external" href="/native-client/pepper_stable/cpp/url__request__info_8h">url_request_info.h</a> - Contains
36 <code>URLRequest</code> class for creating and manipulating URL requests</li>
37 <li><a class="reference external" href="/native-client/pepper_stable/cpp/url__response__info_8h">url_response_info.h</a> - Contains
38 <code>URLResponse</code> class for examaning URL responses</li>
39 </ul>
40 <h2 id="background">Background</h2>
41 <p>When a user launches your Native Client web application, Chrome downloads and
42 caches your application&#8217;s HTML file, manifest file (.nmf), and Native Client
43 module (.pexe or .nexe). If your application needs additional assets, such as
44 images and sound files, it must explicitly load those assets. You can use the
45 Pepper APIs described in this section to load assets from a URL into your
46 application.</p>
47 <p>After you&#8217;ve loaded assets into your application, Chrome will cache those
48 assets. To avoid being at the whim of the Chrome cache, however, you may want
49 to use the <a class="reference external" href="/native-client/pepper_stable/cpp/classpp_1_1_file_i_o">Pepper FileIO API</a> to write those assets
50 to a persistent, sandboxed location on the user&#8217;s file system.</p>
51 <h2 id="the-url-loader-example">The <code>url_loader</code> example</h2>
52 <p>The SDK includes an example called <code>url_loader</code> demonstrating downloading
53 files from a server. This example has these primary files:</p>
54 <ul class="small-gap">
55 <li><code>index.html</code> - The HTML code that launches the Native Client module.</li>
56 <li><code>example.js</code> - The JavaScript file for index.html. It has code that sends
57 a PostMessage request to the Native Client module when the &#8220;Get URL&#8221; button
58 is clicked.</li>
59 <li><code>url_loader_success.html</code> - An HTML file on the server whose contents are
60 being retrieved using the <code>URLLoader</code> API.</li>
61 <li><code>url_loader.cc</code> - The code that sets up and provides and entry point into
62 the Native client module.</li>
63 <li><code>url_loader_handler.cc</code> - The code that retrieves the contents of the
64 url_loader_success.html file and returns the results (this is where the
65 bulk of the work is done).</li>
66 </ul>
67 <p>The remainder of this document covers the code in the <code>url_loader.cc</code> and
68 <code>url_loader_handler.cc</code> files.</p>
69 <h3 id="url-loading-overview">URL loading overview</h3>
70 <p>Like many Pepper APIs, the <code>URLLoader</code> API includes a set of methods that
71 execute asynchronously and that invoke callback functions in your Native Client
72 module. The high-level flow for the <code>url_loader</code> example is described below.
73 Note that methods in the namespace <code>pp::URLLoader</code> are part of the Pepper
74 <code>URLLoader</code> API, while the rest of the functions are part of the code in the
75 Native Client module (specifically in the file <code>url_loader_handler.cc</code>). The
76 following image shows the flow of the <code>url_loader_handler</code> code:</p>
77 <img alt="/native-client/images/pepper-urlloader-api.png" src="/native-client/images/pepper-urlloader-api.png" />
78 <p>Following are the high-level steps involved in URL loading.</p>
79 <ol class="arabic simple">
80 <li>The Native Client module calls <code>pp::URLLoader::Open</code> to begin opening the
81 URL.</li>
82 <li>When <code>Open</code> completes, it invokes a callback function in the Native Client
83 module (in this case, <code>OnOpen</code>).</li>
84 <li>The Native Client module calls the Pepper function
85 <code>URLLoader::ReadResponseBody</code> to begin reading the response body with the
86 data. <code>ReadResponseBody</code> is passed an optional callback function in the
87 Native Client module (in this case, On <code>Read</code>). The callback function is
88 an optional callback because <code>ReadResponseBody</code> may read data and return
89 synchronously if data is available (this improves performance for large
90 files and fast connections).</li>
91 </ol>
92 <p>The remainder of this document demonstrates how the previous steps are
93 implemented in the <code>url_loader</code> example.</p>
94 <h2 id="url-loader-deep-dive"><code>url_loader</code> deep dive</h2>
95 <h3 id="setting-up-the-request">Setting up the request</h3>
96 <p><code>HandleMessage</code> in <code>url_loader.cc</code> creates a <code>URLLoaderHandler</code> instance
97 and passes it the URL of the asset to be retrieved. Then <code>HandleMessage</code>
98 calls <code>Start</code> to start retrieving the asset from the server:</p>
99 <pre class="prettyprint">
100 void URLLoaderInstance::HandleMessage(const pp::Var&amp; var_message) {
101   if (!var_message.is_string()) {
102     return;
103   }
104   std::string message = var_message.AsString();
105   if (message.find(kLoadUrlMethodId) == 0) {
106     // The argument to getUrl is everything after the first ':'.
107     size_t sep_pos = message.find_first_of(kMessageArgumentSeparator);
108     if (sep_pos != std::string::npos) {
109       std::string url = message.substr(sep_pos + 1);
110       printf(&quot;URLLoaderInstance::HandleMessage('%s', '%s')\n&quot;,
111              message.c_str(),
112              url.c_str());
113       fflush(stdout);
114       URLLoaderHandler* handler = URLLoaderHandler::Create(this, url);
115       if (handler != NULL) {
116         // Starts asynchronous download. When download is finished or when an
117         // error occurs, |handler| posts the results back to the browser
118         // vis PostMessage and self-destroys.
119         handler-&gt;Start();
120       }
121     }
122   }
123 }
124 </pre>
125 <p>Notice that the constructor for <code>URLLoaderHandler</code> in
126 <code>url_loader_handler.cc</code> sets up the parameters of the URL request (using
127 <code>SetURL,</code> <code>SetMethod</code>, and <code>SetRecordDownloadProgress</code>):</p>
128 <pre class="prettyprint">
129 URLLoaderHandler::URLLoaderHandler(pp::Instance* instance,
130                                    const std::string&amp; url)
131     : instance_(instance),
132       url_(url),
133       url_request_(instance),
134       url_loader_(instance),
135       buffer_(new char[READ_BUFFER_SIZE]),
136       cc_factory_(this) {
137   url_request_.SetURL(url);
138   url_request_.SetMethod(&quot;GET&quot;);
139   url_request_.SetRecordDownloadProgress(true);
140 }
141 </pre>
142 <h3 id="downloading-the-data">Downloading the data</h3>
143 <p><code>Start</code> in <code>url_loader_handler.cc</code> creates a callback (<code>cc</code>) using a
144 <code>CompletionCallbackFactory</code>. The callback is passed to <code>Open</code> to be called
145 upon its completion. <code>Open</code> begins loading the <code>URLRequestInfo</code>.</p>
146 <pre class="prettyprint">
147 void URLLoaderHandler::Start() {
148   pp::CompletionCallback cc =
149       cc_factory_.NewCallback(&amp;URLLoaderHandler::OnOpen);
150   url_loader_.Open(url_request_, cc);
151 }
152 </pre>
153 <p><code>OnOpen</code> ensures that the Open call was successful and, if so, calls
154 <code>GetDownloadProgress</code> to determine the amount of data to be downloaded so it
155 can allocate memory for the response body.</p>
156 <p>Note that the amount of data to be downloaded may be unknown, in which case
157 <code>GetDownloadProgress</code> sets <code>total_bytes_to_be_received</code> to -1. It is not a
158 problem if <code>total_bytes_to_be_received</code> is set to -1 or if
159 <code>GetDownloadProgress</code> fails; in these scenarios memory for the read buffer
160 can&#8217;t be allocated in advance and must be allocated as data is received.</p>
161 <p>Finally, <code>OnOpen</code> calls <code>ReadBody.</code></p>
162 <pre class="prettyprint">
163 void URLLoaderHandler::OnOpen(int32_t result) {
164   if (result != PP_OK) {
165     ReportResultAndDie(url_, &quot;pp::URLLoader::Open() failed&quot;, false);
166     return;
167   }
168   int64_t bytes_received = 0;
169   int64_t total_bytes_to_be_received = 0;
170   if (url_loader_.GetDownloadProgress(&amp;bytes_received,
171                                       &amp;total_bytes_to_be_received)) {
172     if (total_bytes_to_be_received &gt; 0) {
173       url_response_body_.reserve(total_bytes_to_be_received);
174     }
175   }
176   url_request_.SetRecordDownloadProgress(false);
177   ReadBody();
178 }
179 </pre>
180 <p><code>ReadBody</code> creates another <code>CompletionCallback</code> (a <code>NewOptionalCallback</code>)
181 and passes it to <code>ReadResponseBody,</code> which reads the response body, and
182 <code>AppendDataBytes,</code> which appends the resulting data to the previously read
183 data.</p>
184 <pre class="prettyprint">
185 void URLLoaderHandler::ReadBody() {
186   pp::CompletionCallback cc =
187       cc_factory_.NewOptionalCallback(&amp;URLLoaderHandler::OnRead);
188   int32_t result = PP_OK;
189   do {
190     result = url_loader_.ReadResponseBody(buffer_, READ_BUFFER_SIZE, cc);
191     if (result &gt; 0) {
192       AppendDataBytes(buffer_, result);
193     }
194   } while (result &gt; 0);
195
196   if (result != PP_OK_COMPLETIONPENDING) {
197     cc.Run(result);
198   }
199 }
200
201 void URLLoaderHandler::AppendDataBytes(const char* buffer, int32_t num_bytes) {
202   if (num_bytes &lt;= 0)
203     return;
204   num_bytes = std::min(READ_BUFFER_SIZE, num_bytes);
205   url_response_body_.insert(
206       url_response_body_.end(), buffer, buffer + num_bytes);
207 }
208 </pre>
209 <p>Eventually either all the bytes have been read for the entire file (resulting
210 in <code>PP_OK</code> or 0), all the bytes have been read for what has been
211 downloaded, but more is to be downloaded (<code>PP_OK_COMPLETIONPENDING</code> or -1),
212 or there is an error (less than -1). <code>OnRead</code> is called in the event of an
213 error or <code>PP_OK</code>.</p>
214 <h3 id="displaying-a-result">Displaying a result</h3>
215 <p>OnRead calls <code>ReportResultAndDie</code> when either an error or <code>PP_OK</code> is
216 returned to indicate streaming of file is complete. <code>ReportResultAndDie</code> then
217 calls <code>ReportResult,</code> which calls <code>PostMessage</code> to send the result back to
218 the HTML page.</p>
219 </section>
220
221 {{/partials.standard_nacl_article}}