316 lines
10 KiB
JavaScript
316 lines
10 KiB
JavaScript
// https://docs.unity3d.com/6000.0/Documentation/Manual/web-interacting-browser-deprecated.html
|
|
// Deprecated code | Replacement code
|
|
// -----------------+-----------------
|
|
// dynCall() | makeDynCall()
|
|
|
|
var Lib_BEST_HTTP_WebGL_HTTP_Bridge =
|
|
{
|
|
/*LogLevels: {
|
|
All: 0,
|
|
Information: 1,
|
|
Warning: 2,
|
|
Error: 3,
|
|
Exception: 4,
|
|
None: 5
|
|
}*/
|
|
|
|
$_best_http_request_bridge_global: {
|
|
requestInstances: {},
|
|
nextRequestId: 1,
|
|
loglevel: 2,
|
|
|
|
SendTextToCSharpSide: function(request, onbuffer, text)
|
|
{
|
|
const encoder = new TextEncoder();
|
|
const byteArray = encoder.encode(text);
|
|
|
|
const array = {{{ makeDynCall('iii', '_best_http_request_bridge_global.onallocbuffer') }}}(request, byteArray.length);
|
|
|
|
HEAPU8.set(byteArray, array);
|
|
|
|
{{{ makeDynCall('viii', 'onbuffer') }}}(request, array, byteArray.length);
|
|
},
|
|
|
|
GetResponseHeaders: function(request, callback)
|
|
{
|
|
if (_best_http_request_bridge_global.loglevel <= 1) /*information*/
|
|
console.log(`GetResponseHeaders(${request})`);
|
|
|
|
var headers = '';
|
|
|
|
if (document && document.cookie)
|
|
{
|
|
var cookies = document.cookie.split(';');
|
|
for(var i = 0; i < cookies.length; ++i) {
|
|
const cookie = cookies[i].trim();
|
|
|
|
if (cookie.length > 0)
|
|
headers += "Set-Cookie:" + cookie + "\n";
|
|
}
|
|
}
|
|
|
|
const arr = _best_http_request_bridge_global.requestInstances[request].getAllResponseHeaders().trim().split(/[\r\n]+/);
|
|
|
|
arr.forEach((line) => {
|
|
if (line == null || line == undefined || line.length === 0)
|
|
return;
|
|
|
|
const parts = line.split(": ");
|
|
const header = parts.shift();
|
|
const value = parts.join(": ");
|
|
|
|
// Skip 'content-length' header. If there's any content-encoding (gzip for example),
|
|
// the actual content accessible through XHR's response will have different length (it's uncompressed).
|
|
// So we have to remove the header here, and reconstruct it later when the actual content size is known.
|
|
if (header !== 'content-length')
|
|
headers += `${header}:${value}\n`;
|
|
});
|
|
|
|
_best_http_request_bridge_global.SendTextToCSharpSide(request, callback, headers);
|
|
},
|
|
},
|
|
|
|
XHR_Create: function(method, url, user, passwd, withCredentials)
|
|
{
|
|
var _url = new URL(UTF8ToString(url));
|
|
var _method = UTF8ToString(method);
|
|
|
|
if (_best_http_request_bridge_global.loglevel <= 1) /*information*/
|
|
console.log(`XHR_Create (${_best_http_request_bridge_global.nextRequestId}, ${_method}, ${_url.toString()}, ${withCredentials})`);
|
|
|
|
var http = new XMLHttpRequest();
|
|
|
|
if (user && passwd)
|
|
{
|
|
var u = UTF8ToString(user);
|
|
var p = UTF8ToString(passwd);
|
|
|
|
// https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials
|
|
http.withCredentials = true;
|
|
http.open(_method, _url.toString(), /*async:*/ true , u, p);
|
|
}
|
|
else {
|
|
http.withCredentials = withCredentials;
|
|
http.open(_method, _url.toString(), /*async:*/ true);
|
|
}
|
|
|
|
http.responseType = 'arraybuffer';
|
|
|
|
_best_http_request_bridge_global.requestInstances[_best_http_request_bridge_global.nextRequestId] = http;
|
|
return _best_http_request_bridge_global.nextRequestId++;
|
|
},
|
|
|
|
XHR_SetTimeout: function (request, timeout)
|
|
{
|
|
if (_best_http_request_bridge_global.loglevel <= 1) /*information*/
|
|
console.log(`XHR_SetTimeout(${request}, ${timeout})`);
|
|
|
|
_best_http_request_bridge_global.requestInstances[request].timeout = timeout;
|
|
},
|
|
|
|
XHR_SetRequestHeader: function (request, header, value)
|
|
{
|
|
var _header = UTF8ToString(header);
|
|
var _value = UTF8ToString(value);
|
|
|
|
if (_best_http_request_bridge_global.loglevel <= 1) /*information*/
|
|
console.log(`XHR_SetRequestHeader(${_header}, ${_value})`);
|
|
|
|
if (_header != 'Cookie')
|
|
_best_http_request_bridge_global.requestInstances[request].setRequestHeader(_header, _value);
|
|
else {
|
|
var cookies = _value.split(';');
|
|
for (var i = 0; i < cookies.length; i++) {
|
|
document.cookie = cookies[i];
|
|
}
|
|
}
|
|
},
|
|
|
|
XHR_SetResponseHandler: function (request, onresponse, onerror, ontimeout, onaborted, onbuffer, onallocbuffer)
|
|
{
|
|
if (_best_http_request_bridge_global.loglevel <= 1) /*information*/
|
|
console.log(`XHR_SetResponseHandler(${request})`);
|
|
|
|
_best_http_request_bridge_global.onallocbuffer = onallocbuffer;
|
|
|
|
var http = _best_http_request_bridge_global.requestInstances[request];
|
|
|
|
// https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/readystatechange_event
|
|
// The readystatechange event is fired whenever the readyState property of the XMLHttpRequest changes.
|
|
// https://xhr.spec.whatwg.org/#dom-xmlhttprequest-readystate
|
|
http.onreadystatechange = (event) => {
|
|
|
|
if (_best_http_request_bridge_global.loglevel <= 1) /*information*/
|
|
console.log(`${request} onreadystatechange(${http.readyState})`);
|
|
|
|
switch (http.readyState){
|
|
// The object has been constructed.
|
|
case XMLHttpRequest.UNSENT: break;
|
|
|
|
// The open() method has been successfully invoked. During this state request headers can be set using setRequestHeader() and the fetch can be initiated using the send() method.
|
|
case XMLHttpRequest.OPENED: break;
|
|
|
|
// All redirects (if any) have been followed and all headers of a response have been received.
|
|
case XMLHttpRequest.HEADERS_RECEIVED: {
|
|
_best_http_request_bridge_global.SendTextToCSharpSide(request, onbuffer, `HTTP/1.1 ${http.status} ${http.statusText}\n`);
|
|
|
|
_best_http_request_bridge_global.GetResponseHeaders(request, onbuffer);
|
|
break;
|
|
}
|
|
|
|
// The response body is being received.
|
|
case XMLHttpRequest.LOADING: break;
|
|
|
|
// The data transfer has been completed or something went wrong during the transfer (e.g., infinite redirects).
|
|
case XMLHttpRequest.DONE: break;
|
|
}
|
|
};
|
|
|
|
http.onloadstart = (event) => {
|
|
if (_best_http_request_bridge_global.loglevel <= 1) /*information*/
|
|
console.log(`${request} onloadstart: ${event}`);
|
|
};
|
|
|
|
// https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/load_event
|
|
// Fired when an XMLHttpRequest transaction completes successfully. Also available via the onload event handler property.
|
|
http.onload = function http_onload(e) {
|
|
if (_best_http_request_bridge_global.loglevel <= 1) /*information*/
|
|
console.log(`${request} onload(${http.status}, ${http.statusText})`);
|
|
|
|
if (onresponse)
|
|
{
|
|
var responseLength = 0;
|
|
var array = 0;
|
|
|
|
if (!!http.response) {
|
|
var response = http.response;
|
|
responseLength = response.byteLength;
|
|
|
|
_best_http_request_bridge_global.SendTextToCSharpSide(request, onbuffer, `content-length:${responseLength}\n\n`);
|
|
|
|
array = {{{ makeDynCall('iii', 'onallocbuffer') }}}(request, responseLength);
|
|
|
|
var responseBytes = new Uint8Array(response);
|
|
var buffer = HEAPU8.subarray(array, array + responseLength);
|
|
buffer.set(responseBytes)
|
|
}
|
|
else {
|
|
_best_http_request_bridge_global.SendTextToCSharpSide(request, onbuffer, `content-length:0\n\n`);
|
|
}
|
|
|
|
{{{ makeDynCall('viii', 'onresponse') }}}(request, array, responseLength);
|
|
}
|
|
};
|
|
|
|
if (onerror)
|
|
{
|
|
http.onerror = function http_onerror(e) {
|
|
function HandleError(err)
|
|
{
|
|
var length = lengthBytesUTF8(err) + 1;
|
|
var buffer = _malloc(length);
|
|
|
|
stringToUTF8Array(err, HEAPU8, buffer, length);
|
|
|
|
{{{ makeDynCall('vii', 'onerror') }}}(request, buffer);
|
|
|
|
_free(buffer);
|
|
}
|
|
|
|
if (e.error)
|
|
HandleError(e.error);
|
|
else
|
|
HandleError("Unknown Error! Maybe a CORS problem?");
|
|
};
|
|
}
|
|
|
|
if (ontimeout)
|
|
http.ontimeout = function http_onerror(e) {
|
|
{{{ makeDynCall('vi', 'ontimeout') }}}(request);
|
|
};
|
|
|
|
if (onaborted)
|
|
http.onabort = function http_onerror(e) {
|
|
{{{ makeDynCall('vi', 'onaborted') }}}(request);
|
|
};
|
|
},
|
|
|
|
XHR_SetProgressHandler: function (request, onprogress, onuploadprogress)
|
|
{
|
|
if (_best_http_request_bridge_global.loglevel <= 1) /*information*/
|
|
console.log(`XHR_SetProgressHandler(${request})`);
|
|
|
|
var http = _best_http_request_bridge_global.requestInstances[request];
|
|
if (http)
|
|
{
|
|
if (onprogress)
|
|
http.onprogress = function http_onprogress(e) {
|
|
if (_best_http_request_bridge_global.loglevel <= 1) /*information*/
|
|
console.log(`XHR_SetProgressHandler download(${request}, ${e.loaded}, ${e.total})`);
|
|
|
|
if (e.lengthComputable) {
|
|
{{{ makeDynCall('viii', 'onprogress') }}}(request, e.loaded, e.total);
|
|
}
|
|
};
|
|
|
|
if (onuploadprogress)
|
|
http.upload.addEventListener("progress", function http_onprogress(e) {
|
|
if (_best_http_request_bridge_global.loglevel <= 1) /*information*/
|
|
console.log(`XHR_SetProgressHandler upload(${request}, ${e.loaded}, ${e.total})`);
|
|
|
|
if (e.lengthComputable) {
|
|
{{{ makeDynCall('viii', 'onuploadprogress') }}}(request, e.loaded, e.total);
|
|
}
|
|
}, true);
|
|
}
|
|
},
|
|
|
|
XHR_Send: function (request, ptr, length)
|
|
{
|
|
if (_best_http_request_bridge_global.loglevel <= 1) /*information*/
|
|
console.log(`XHR_Send(${request}, ${ptr}, ${length})`);
|
|
|
|
var http = _best_http_request_bridge_global.requestInstances[request];
|
|
|
|
try {
|
|
if (length > 0){
|
|
#if USE_PTHREADS
|
|
http.send(new Uint8Array(HEAPU8.subarray(ptr, ptr+length)));
|
|
#else
|
|
http.send(HEAPU8.subarray(ptr, ptr+length));
|
|
#endif
|
|
}
|
|
else
|
|
http.send();
|
|
}
|
|
catch(e) {
|
|
if (_best_http_request_bridge_global.loglevel <= 4) /*exception*/
|
|
console.error(`XHR_Send(${request}): ${e.name} : ${e.message}`);
|
|
}
|
|
},
|
|
|
|
XHR_Abort: function (request)
|
|
{
|
|
if (_best_http_request_bridge_global.loglevel <= 1) /*information*/
|
|
console.log(`XHR_Abort(${request})`);
|
|
|
|
_best_http_request_bridge_global.requestInstances[request].abort();
|
|
},
|
|
|
|
XHR_Release: function (request)
|
|
{
|
|
if (_best_http_request_bridge_global.loglevel <= 1) /*information*/
|
|
console.log(`XHR_Release(${request})`);
|
|
|
|
delete _best_http_request_bridge_global.requestInstances[request];
|
|
},
|
|
|
|
XHR_SetLoglevel: function (level)
|
|
{
|
|
_best_http_request_bridge_global.loglevel = level;
|
|
}
|
|
};
|
|
|
|
autoAddDeps(Lib_BEST_HTTP_WebGL_HTTP_Bridge, '$_best_http_request_bridge_global');
|
|
mergeInto(LibraryManager.library, Lib_BEST_HTTP_WebGL_HTTP_Bridge);
|