diff options
author | Joel Croteau <jcroteau@gmail.com> | 2014-03-03 16:24:43 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2014-03-07 18:09:28 -0800 |
commit | 4d32fb5e5b361dca5d72ed7892f3315eb70edcc1 (patch) | |
tree | 822f150fbe71f8f68296ad7f21d59202ed9b913f | |
parent | e351933a7ae98cd190cb023284cec66dd7cfb7f1 (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.js | 55 | ||||
-rw-r--r-- | system/include/emscripten/emscripten.h | 22 |
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 |