| // Copyright 2012 The Emscripten Authors. All rights reserved. |
| // Emscripten is available under two separate licenses, the MIT license and the |
| // University of Illinois/NCSA Open Source License. Both these licenses can be |
| // found in the LICENSE file. |
| |
| // |
| // 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(unsigned handle, void* parent, const char * file) { |
| http* req = reinterpret_cast<http*>(parent); |
| req->onLoaded(file); |
| } |
| |
| void http::onError(unsigned handle, void* parent, int statuserror) { |
| http* req = reinterpret_cast<http*>(parent); |
| req->onError(statuserror); |
| } |
| |
| void http::onProgress(unsigned handle, 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); |
| } |
| |
| _handle = 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; |
| } |
| } |
| |
| /** |
| * Abort the request |
| */ |
| void http::abortRequest() { |
| emscripten_async_wget2_abort(_handle); |
| _status = ST_ABORTED; |
| } |
| |
| /** |
| * 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(); |
| REPORT_RESULT(0); |
| } |
| } |
| |
| 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 if (req->getStatus() == http::ST_ABORTED) { |
| printf("Aborted Request n°%d", req->getId()); |
| } 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("/emscripten-core/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); |
| http2->abortRequest(); |
| |
| http* http3 = new http("https://raw.github.com",http::REQUEST_GET); |
| http3->runRequest("/emscripten-core/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); |
| } |