diff options
-rw-r--r-- | src/library_browser.js | 50 | ||||
-rw-r--r-- | system/include/emscripten/emscripten.h | 2 | ||||
-rw-r--r-- | tests/http.cpp | 284 | ||||
-rw-r--r-- | tests/http.h | 151 |
4 files changed, 487 insertions, 0 deletions
diff --git a/src/library_browser.js b/src/library_browser.js index 00ee158c..c18edf4a 100644 --- a/src/library_browser.js +++ b/src/library_browser.js @@ -385,6 +385,56 @@ mergeInto(LibraryManager.library, { ); }, + emscripten_async_wget2: function(url, file, request, param, arg, onload, onerror, onprogress) { + var _url = Pointer_stringify(url); + var _file = Pointer_stringify(file); + var _request = Pointer_stringify(request); + var _param = Pointer_stringify(param); + var index = _file.lastIndexOf('/'); + + var http = new XMLHttpRequest(); + http.open(_request, _url, true); + http.responseType = 'arraybuffer'; + + // LOAD + http.onload = function(e) { + if (http.status == 200) { + FS.createDataFile( _file.substr(0, index), _file.substr(index +1), new Uint8Array(http.response), true, true); + if (onload) FUNCTION_TABLE[onload](arg,file); + } else { + if (onerror) FUNCTION_TABLE[onerror](arg,http.status); + } + }; + + // ERROR + http.onerror = function(e) { + if (onerror) FUNCTION_TABLE[onerror](arg,http.status); + }; + + // PROGRESS + http.onprogress = function(e) { + var percentComplete = (e.position / e.totalSize)*100; + if (onprogress) FUNCTION_TABLE[onprogress](arg,percentComplete); + }; + + 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_prepare: function(file, onload, onerror) { var _file = Pointer_stringify(file); var data = FS.analyzePath(_file); diff --git a/system/include/emscripten/emscripten.h b/system/include/emscripten/emscripten.h index 3eefe0b8..fb63384b 100644 --- a/system/include/emscripten/emscripten.h +++ b/system/include/emscripten/emscripten.h @@ -186,6 +186,8 @@ float emscripten_random(); */ void emscripten_async_wget(const char* url, const char* file, void (*onload)(const char*), void (*onerror)(const char*)); +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)); + /* * Prepare a file in asynchronous way. This does just the * preparation part of emscripten_async_wget, that is, it diff --git a/tests/http.cpp b/tests/http.cpp new file mode 100644 index 00000000..623709bf --- /dev/null +++ b/tests/http.cpp @@ -0,0 +1,284 @@ +// +// http.cpp +// Player Javascript +// +// Created by Anthony Liot on 23/11/12. +// + +#include "http.h" +#include <emscripten/emscripten.h> +#include <stdio.h> +#include <stdlib.h> + +int http::uid = 0; + +/* +- Useful for download an url on other domain +<?php +header("Access-Control-Allow-Origin: *"); +// verifie si on a les bons parametres +if( isset($_GET['url']) ) { + + $fileName = $_GET['url']; + if($f = fopen($fileName,'rb') ){ + $fSize = 0; + while(!feof($f)){ + ++$fSize; + $data = fread($f,1); + } + fclose($f); + if( $fSize < 1 ) { + header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found'); + echo 'For empty file ' . $fileName; + die(); + } else { + header("POST ".$fileName." HTTP/1.1\r\n"); + header('Content-Description: File Transfer'); + header('Content-Transfer-Encoding: binary'); + header('Content-Disposition: attachment; filename="' . basename($fileName) . "\";"); + header('Content-Type: application/octet-stream'); + header('Content-Length: '.$fSize); + + header('Expires: 0'); + header('Cache-Control: must-revalidate'); + header('Pragma: public'); + ob_clean(); + flush(); + readfile($fileName); + exit; + } + } else { + header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found'); + echo 'For filename ' . $fileName; + } +} else { + header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden'); +} +?> +*/ +// http://..../download.php?url= +std::string http::cross_domain = ""; + + +//---------------------------------------------------------------------------------------- +// HTTP CLASS +//---------------------------------------------------------------------------------------- + +void http::onLoaded(void* parent, const char * file) { + http* req = reinterpret_cast<http*>(parent); + req->onLoaded(file); +} + +void http::onError(void* parent, int statuserror) { + http* req = reinterpret_cast<http*>(parent); + req->onError(statuserror); +} + +void http::onProgress(void* parent, int progress) { + http* req = reinterpret_cast<http*>(parent); + req->onProgress(progress); +} + +/** +* Constructeur +*/ +http::http(const char* hostname, int requestType, const char* targetFilename) : _hostname(hostname), _page(""), _targetFileName(targetFilename), _param(""), _content(""), _error(""), _request((RequestType)requestType), _status(ST_PENDING), _assync(ASSYNC_THREAD) { + _progressValue = -1; + _uid = uid++; +} + + +/** +* Destructeur +*/ +http::~http() { +} + +/** +* Effectue la requete +*/ +void http::runRequest(const char* page, int assync) { + _page = page; + _status = ST_PENDING; + _assync = (AssyncMode)assync; + _progressValue = 0; + + std::string url = cross_domain; + url += _hostname + _page; + + if (_hostname.size() > 0 && _page.size() > 0) { + + printf("URL : %s\n",url.c_str()); + printf("REQUEST : %s\n",(_request==REQUEST_GET) ? "GET":"POST"); + printf("PARAMS : %s\n",_param.c_str()); + + if (_targetFileName.size() == 0 ) { + _targetFileName = format("prepare%d",_uid); + } + + emscripten_async_wget2(url.c_str(), _targetFileName.c_str(), (_request==REQUEST_GET) ? "GET":"POST", _param.c_str(), this, http::onLoaded, http::onError, http::onProgress); + + } else { + _error = format("malformed url : %s\n",url.c_str()); + _content = ""; + _status = ST_FAILED; + _progressValue = -1; + } +} + +/** +* Accede a la reponse +*/ +const char* http::getContent() { + return _content.c_str(); +} + +/** +* Accede a l'erreur +*/ +const char* http::getError() { + return _error.c_str(); +} + +/** +* Accede au status +*/ +int http::getStatus() { + return _status; +} + +/** +* Accede a la progression between 0 & 100 +*/ +float http::getProgress() { + return (float)_progressValue; +} + +/** +* Accede a la progression between 0 & 100 +*/ +int http::getId() { + return _uid; +} + +/** +* Post +*/ +void http::addValue(const char* key, const char* value) { + if (_param.size() > 0) { + _param += "&"; + _param += key; + _param += "="; + _param += value; + } else { + _param += key; + _param += "="; + _param += value; + } +} + +void http::onProgress(int progress) { + _progressValue = progress; +} + +void http::onLoaded(const char* file) { + + if (strstr(file,"prepare")) { + FILE* f = fopen(file,"rb"); + if (f) { + fseek (f, 0, SEEK_END); + int size=ftell (f); + fseek (f, 0, SEEK_SET); + + char* data = new char[size]; + fread(data,size,1,f); + _content = data; + delete data; + fclose(f); + } else { + _content = file; + } + + } else { + _content = file; + } + + _progressValue = 100; + _status = ST_OK; +} + +void http::onError(int error) { + + printf("Error status : %d\n",error); + + _error = ""; + _content = ""; + _status = ST_FAILED; + _progressValue = -1; +} + +/// TEST +int num_request = 0; +float time_elapsed = 0.0f; + +void wait_https() { + if (num_request == 0) { + printf("End of all download ... %fs\n",(emscripten_get_now() - time_elapsed) / 1000.f); + emscripten_cancel_main_loop(); + } +} + +void wait_http(void* request) { + http* req = reinterpret_cast<http*>(request); + if (req != 0) { + if (req->getStatus() == http::ST_PENDING) { + if ((int)req->getProgress()>0) { + printf("Progress Request n°%d : %d\n",req->getId(),(int)req->getProgress()); + } + emscripten_async_call(wait_http,request,500); + + } else { + if (req->getStatus() == http::ST_OK) { + printf("Success Request n°%d : %s\n",req->getId(),req->getContent()); + + } else { + printf("Error Request n°%d : %s\n",req->getId(), req->getError()); + } + + num_request --; + } + } else { + num_request --; + } +} + + +int main() { + time_elapsed = emscripten_get_now(); + + http* http1 = new http("https://github.com",http::REQUEST_GET,"emscripten_master.zip"); + http1->runRequest("/kripken/emscripten/archive/master.zip",http::ASSYNC_THREAD); + + http* http2 = new http("https://github.com",http::REQUEST_GET,"wolfviking_master.zip"); + http2->runRequest("/wolfviking0/image.js/archive/master.zip",http::ASSYNC_THREAD); + + http* http3 = new http("https://raw.github.com",http::REQUEST_GET); + http3->runRequest("/kripken/emscripten/master/LICENSE",http::ASSYNC_THREAD); + + num_request ++; + emscripten_async_call(wait_http,http1,500); + num_request ++; + emscripten_async_call(wait_http,http2,500); + num_request ++; + emscripten_async_call(wait_http,http3,500); + + /* + Http* http4 = new Http("http://www.---.com",Http::REQUEST_POST); + http4->addValue("app","123"); + http4->runRequest("/test.php",Http::ASSYNC_THREAD); + num_request ++; + emscripten_async_call(wait_http,http4,500); + */ + + emscripten_set_main_loop(wait_https, 0, 0); +}
\ No newline at end of file diff --git a/tests/http.h b/tests/http.h new file mode 100644 index 00000000..7eff7013 --- /dev/null +++ b/tests/http.h @@ -0,0 +1,151 @@ +// +// Http.h +// Player Javascript +// +// Created by Anthony Liot on 23/11/12. +// + +#ifndef __HTTP_H__ +#define __HTTP_H__ + +#include <string> + + +/* + */ +class http { + + public: + + enum Status { + ST_PENDING = 0, + ST_FAILED, + ST_OK + }; + + enum RequestType { + REQUEST_GET = 0, + REQUEST_POST , + }; + + enum AssyncMode { + ASSYNC_THREAD + }; + + // enregistrement sur unigine + static void RegisterAsExtension(bool regis); + + // Callback + static void onLoaded(void* parent, const char * file); + static void onError(void* parent, int statuserror); + static void onProgress(void* parent, int progress); + + // Constructeur + http(const char* hostname, int requestType, const char* targetFileName = ""); + + //Destructeur + virtual ~http(); + + /** + * Effectue la requete + */ + void runRequest(const char* page, int assync); + + /** + * Accede a la reponse + */ + const char* getContent(); + + /** + * Accede a l'erreur + */ + const char* getError(); + + /** + * Accede au status + */ + int getStatus(); + + /** + * Accede a la progression + */ + float getProgress(); + + /** + * Get Id of http Class + */ + int getId(); + + /** + * + */ + void addValue(const char* key, const char* value); + + /** + * Callback + */ + void onProgress(int progress); + void onLoaded(const char* file); + void onError(int error); + + // Static parameter + static int uid; + static std::string cross_domain ; + + private: + + // Id of request + int _uid; + + // nom de l'hote + std::string _hostname; + + // nom de la page + std::string _page; + + // target filename + std::string _targetFileName; + + // param + std::string _param; + + // resultat + std::string _content; + + // probleme + std::string _error; + + // request type + RequestType _request; + + // status + int _status; + + // progress value + int _progressValue; + + // mode assyncrone courant + AssyncMode _assync; + +}; + +//this is safe and convenient but not exactly efficient +inline std::string format(const char* fmt, ...){ + int size = 512; + char* buffer = 0; + buffer = new char[size]; + va_list vl; + va_start(vl,fmt); + int nsize = vsnprintf(buffer,size,fmt,vl); + if(size<=nsize){//fail delete buffer and try again + delete buffer; buffer = 0; + buffer = new char[nsize+1];//+1 for /0 + nsize = vsnprintf(buffer,size,fmt,vl); + } + std::string ret(buffer); + va_end(vl); + delete buffer; + return ret; +} + +#endif /* __HTTP_H__ */ |