aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Croteau <jcroteau@gmail.com>2014-03-03 16:24:43 -0800
committerAlon Zakai <alonzakai@gmail.com>2014-03-07 18:09:28 -0800
commit4d32fb5e5b361dca5d72ed7892f3315eb70edcc1 (patch)
tree822f150fbe71f8f68296ad7f21d59202ed9b913f
parente351933a7ae98cd190cb023284cec66dd7cfb7f1 (diff)
Implement emscripten_async_wget2_data
This adds the new function emscripten_async_wget2_data to read from an XMLHTTPRequest directly into memory while supporting advanced features.
-rw-r--r--src/library_browser.js55
-rw-r--r--system/include/emscripten/emscripten.h22
2 files changed, 75 insertions, 2 deletions
diff --git a/src/library_browser.js b/src/library_browser.js
index a280d1b2..0808b9f0 100644
--- a/src/library_browser.js
+++ b/src/library_browser.js
@@ -723,8 +723,59 @@ mergeInto(LibraryManager.library, {
// PROGRESS
http.onprogress = function http_onprogress(e) {
- var percentComplete = (e.position / e.totalSize)*100;
- if (onprogress) Runtime.dynCall('vii', onprogress, [arg, percentComplete]);
+ if (e.lengthComputable || (e.lengthComputable === undefined && e.totalSize != 0)) {
+ var percentComplete = (e.position / e.totalSize)*100;
+ if (onprogress) Runtime.dynCall('vii', onprogress, [arg, percentComplete]);
+ }
+ };
+
+ // Useful because the browser can limit the number of redirection
+ try {
+ if (http.channel instanceof Ci.nsIHttpChannel)
+ http.channel.redirectionLimit = 0;
+ } catch (ex) { /* whatever */ }
+
+ if (_request == "POST") {
+ //Send the proper header information along with the request
+ http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
+ http.setRequestHeader("Content-length", _param.length);
+ http.setRequestHeader("Connection", "close");
+ http.send(_param);
+ } else {
+ http.send(null);
+ }
+ },
+
+ emscripten_async_wget2_data: function(url, request, param, arg, free, onload, onerror, onprogress) {
+ var _url = Pointer_stringify(url);
+ var _request = Pointer_stringify(request);
+ var _param = Pointer_stringify(param);
+
+ var http = new XMLHttpRequest();
+ http.open(_request, _url, true);
+ http.responseType = 'arraybuffer';
+
+ // LOAD
+ http.onload = function http_onload(e) {
+ if (http.status == 200 || _url.substr(0,4).toLowerCase() != "http") {
+ var byteArray = new Uint8Array(http.response);
+ var buffer = _malloc(byteArray.length);
+ HEAPU8.set(byteArray, buffer);
+ if (onload) Runtime.dynCall('viii', onload, [arg, buffer, byteArray.length]);
+ if (free) _free(buffer);
+ } else {
+ if (onerror) Runtime.dynCall('viii', onerror, [arg, http.status, http.statusText]);
+ }
+ };
+
+ // ERROR
+ http.onerror = function http_onerror(e) {
+ if (onerror) Runtime.dynCall('viii', onerror, [arg, http.status, http.statusText]);
+ };
+
+ // PROGRESS
+ http.onprogress = function http_onprogress(e) {
+ if (onprogress) Runtime.dynCall('viii', onprogress, [arg, e.loaded, e.lengthComputable || e.lengthComputable === undefined ? e.total : 0]);
};
// Useful because the browser can limit the number of redirection
diff --git a/system/include/emscripten/emscripten.h b/system/include/emscripten/emscripten.h
index 9bd3ca69..2b883f93 100644
--- a/system/include/emscripten/emscripten.h
+++ b/system/include/emscripten/emscripten.h
@@ -323,6 +323,28 @@ void emscripten_async_wget_data(const char* url, void *arg, void (*onload)(void*
void emscripten_async_wget2(const char* url, const char* file, const char* requesttype, const char* param, void *arg, void (*onload)(void*, const char*), void (*onerror)(void*, int), void (*onprogress)(void*, int));
/*
+ * More feature-complete version of emscripten_async_wget_data. Note:
+ * this version is experimental.
+ *
+ * The requesttype is 'GET' or 'POST',
+ * If is post request, param is the post parameter
+ * like key=value&key2=value2.
+ * The param 'arg' is a pointer will be pass to the callback
+ * The free param tells the runtime whether to free the returned buffer
+ after onload is complete. If false freeing the buffer is the receiver's
+ responsibility.
+ * The callbacks are called with an object pointer give in parameter.
+ * When file is ready then 'onload' callback will called with a pointer to
+ the buffer in memory and the size in bytes.
+ * During the download 'onprogress' callback will called. The first argument is
+ the number of bytes loaded. The second argument is the total size in bytes,
+ or zero if the size is unavailable.
+ * If any error occurred 'onerror' will called with the HTTP status code
+ and a string with the status description.
+ */
+void emscripten_async_wget2_data(const char* url, const char* requesttype, const char* param, void *arg, int free, void (*onload)(void*, void*, unsigned), void (*onerror)(void*, int, const char*), void (*onprogress)(void*, int, int));
+
+/*
* Prepare a file in asynchronous way. This does just the
* preparation part of emscripten_async_wget, that is, it
* works on file data already present, and asynchronously