add all
This commit is contained in:
@@ -0,0 +1,332 @@
|
||||
#if UNITY_WEBGL && !UNITY_EDITOR
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
using Best.HTTP.Caching;
|
||||
using Best.HTTP.Hosts.Connections.File;
|
||||
using Best.HTTP.Hosts.Connections.HTTP1;
|
||||
using Best.HTTP.HostSetting;
|
||||
using Best.HTTP.Request.Authentication;
|
||||
using Best.HTTP.Request.Timings;
|
||||
using Best.HTTP.Shared;
|
||||
using Best.HTTP.Shared.PlatformSupport.Memory;
|
||||
using Best.HTTP.Shared.Streams;
|
||||
|
||||
namespace Best.HTTP.Hosts.Connections.WebGL
|
||||
{
|
||||
class PeekableIncomingSegmentContentProviderStream : PeekableContentProviderStream
|
||||
{
|
||||
private int peek_listIdx;
|
||||
private int peek_pos;
|
||||
|
||||
public override void BeginPeek()
|
||||
{
|
||||
peek_listIdx = 0;
|
||||
peek_pos = base.bufferList.Count > 0 ? base.bufferList[0].Offset : 0;
|
||||
}
|
||||
|
||||
public override int PeekByte()
|
||||
{
|
||||
if (base.bufferList.Count == 0)
|
||||
return -1;
|
||||
|
||||
var segment = base.bufferList[this.peek_listIdx];
|
||||
if (peek_pos >= segment.Offset + segment.Count)
|
||||
{
|
||||
if (base.bufferList.Count <= this.peek_listIdx + 1)
|
||||
return -1;
|
||||
|
||||
segment = base.bufferList[++this.peek_listIdx];
|
||||
this.peek_pos = segment.Offset;
|
||||
}
|
||||
|
||||
return segment.Data[this.peek_pos++];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal sealed class WebGLXHRConnection : ConnectionBase
|
||||
{
|
||||
public PeekableContentProviderStream ContentProvider { get; private set; }
|
||||
|
||||
int NativeId;
|
||||
PeekableHTTP1Response _response;
|
||||
|
||||
public WebGLXHRConnection(HostKey hostKey)
|
||||
: base(hostKey, false)
|
||||
{
|
||||
WebGLXHRNativeInterface.XHR_SetLoglevel((byte)HTTPManager.Logger.Level);
|
||||
}
|
||||
|
||||
public override void Shutdown(ShutdownTypes type)
|
||||
{
|
||||
base.Shutdown(type);
|
||||
|
||||
WebGLXHRNativeInterface.XHR_Abort(this.NativeId);
|
||||
}
|
||||
|
||||
protected override void ThreadFunc()
|
||||
{
|
||||
// XmlHttpRequest setup
|
||||
|
||||
CurrentRequest.Prepare();
|
||||
|
||||
Credentials credentials = null;// CurrentRequest.Authenticator?.Credentials;
|
||||
|
||||
this.NativeId = WebGLXHRNativeInterface.XHR_Create(HTTPRequest.MethodNames[(byte)CurrentRequest.MethodType],
|
||||
CurrentRequest.CurrentUri.OriginalString,
|
||||
credentials?.UserName, credentials?.Password, CurrentRequest.WithCredentials ? 1 : 0);
|
||||
WebGLXHRNativeConnectionLayer.Add(NativeId, this);
|
||||
|
||||
CurrentRequest.EnumerateHeaders((header, values) =>
|
||||
{
|
||||
if (!header.Equals("Content-Length"))
|
||||
for (int i = 0; i < values.Count; ++i)
|
||||
WebGLXHRNativeInterface.XHR_SetRequestHeader(NativeId, header, values[i]);
|
||||
}, /*callBeforeSendCallback:*/ true);
|
||||
|
||||
WebGLXHRNativeConnectionLayer.SetupHandlers(NativeId, CurrentRequest);
|
||||
|
||||
WebGLXHRNativeInterface.XHR_SetTimeout(NativeId, (uint)(CurrentRequest.TimeoutSettings.ConnectTimeout.TotalMilliseconds + CurrentRequest.TimeoutSettings.Timeout.TotalMilliseconds));
|
||||
|
||||
Stream upStream = CurrentRequest.UploadSettings.UploadStream;
|
||||
byte[] body = null;
|
||||
int length = 0;
|
||||
bool releaseBodyBuffer = false;
|
||||
|
||||
if (upStream != null)
|
||||
{
|
||||
var internalBuffer = BufferPool.Get(upStream.Length > 0 ? upStream.Length : CurrentRequest.UploadSettings.UploadChunkSize, true);
|
||||
using (BufferPoolMemoryStream ms = new BufferPoolMemoryStream(internalBuffer, 0, internalBuffer.Length, true, true, false, true))
|
||||
{
|
||||
var buffer = BufferPool.Get(CurrentRequest.UploadSettings.UploadChunkSize, true);
|
||||
int readCount = -1;
|
||||
while ((readCount = upStream.Read(buffer, 0, buffer.Length)) > 0)
|
||||
ms.Write(buffer, 0, readCount);
|
||||
|
||||
BufferPool.Release(buffer);
|
||||
|
||||
length = (int)ms.Position;
|
||||
body = ms.GetBuffer();
|
||||
|
||||
releaseBodyBuffer = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (this._response == null)
|
||||
this.CurrentRequest.Response = this._response = new PeekableHTTP1Response(this.CurrentRequest, false, null);
|
||||
|
||||
this.ContentProvider = new PeekableIncomingSegmentContentProviderStream();
|
||||
|
||||
WebGLXHRNativeInterface.XHR_Send(NativeId, body, length);
|
||||
|
||||
if (releaseBodyBuffer)
|
||||
BufferPool.Release(body);
|
||||
|
||||
this.CurrentRequest.TimeoutSettings.QueuedAt = DateTime.MinValue;
|
||||
this.CurrentRequest.TimeoutSettings.ProcessingStarted = DateTime.UtcNow;
|
||||
this.CurrentRequest.OnCancellationRequested += OnCancellationRequested;
|
||||
}
|
||||
|
||||
#region Callback Implementations
|
||||
|
||||
private void OnCancellationRequested(HTTPRequest req)
|
||||
{
|
||||
if (HTTPManager.Logger.IsDiagnostic)
|
||||
HTTPManager.Logger.Verbose(nameof(WebGLXHRConnection), $"{this.NativeId} - OnCancellationRequested()", this.Context);
|
||||
|
||||
Interlocked.Exchange(ref this._response, null);
|
||||
req.OnCancellationRequested -= OnCancellationRequested;
|
||||
|
||||
WebGLXHRNativeInterface.XHR_Abort(this.NativeId);
|
||||
}
|
||||
|
||||
internal void OnBuffer(BufferSegment buffer)
|
||||
{
|
||||
if (HTTPManager.Logger.IsDiagnostic)
|
||||
HTTPManager.Logger.Verbose(nameof(WebGLXHRConnection), $"{this.NativeId} - OnBuffer({buffer})", this.Context);
|
||||
|
||||
try
|
||||
{
|
||||
if (this.CurrentRequest.TimeoutSettings.IsTimedOut(DateTime.UtcNow))
|
||||
throw new TimeoutException();
|
||||
|
||||
if (this.CurrentRequest.IsCancellationRequested)
|
||||
throw new Exception("Cancellation requested!");
|
||||
|
||||
this.ContentProvider?.Write(buffer);
|
||||
this._response?.ProcessPeekable(this.ContentProvider);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
BufferPool.Release(buffer);
|
||||
|
||||
if (this.ShutdownType == ShutdownTypes.Immediate)
|
||||
return;
|
||||
|
||||
FinishedProcessing(e);
|
||||
}
|
||||
|
||||
// After an exception, this._response will be null!
|
||||
if (this._response != null && this._response.ReadState == PeekableHTTP1Response.PeekableReadState.Finished)
|
||||
FinishedProcessing(null);
|
||||
}
|
||||
|
||||
internal void OnError(string error)
|
||||
{
|
||||
if (HTTPManager.Logger.IsDiagnostic)
|
||||
HTTPManager.Logger.Verbose(nameof(WebGLXHRConnection), $"{this.NativeId} - OnError({error})", this.Context);
|
||||
|
||||
FinishedProcessing(new Exception(error));
|
||||
}
|
||||
|
||||
internal void OnResponse(BufferSegment payload)
|
||||
{
|
||||
if (HTTPManager.Logger.IsDiagnostic)
|
||||
HTTPManager.Logger.Verbose(nameof(WebGLXHRConnection), $"{this.NativeId} - OnResponse({payload})", this.Context);
|
||||
|
||||
this._response?.DownStream?.EmergencyIncreaseMaxBuffered();
|
||||
OnBuffer(payload);
|
||||
}
|
||||
|
||||
void FinishedProcessing(Exception ex)
|
||||
{
|
||||
// Warning: FinishedProcessing might be called from different threads in parallel:
|
||||
// - send thread triggered by a write failure
|
||||
// - read thread oncontent/OnError/OnConnectionClosed
|
||||
|
||||
var resp = Interlocked.Exchange(ref this._response, null);
|
||||
if (resp == null)
|
||||
return;
|
||||
|
||||
HTTPManager.Logger.Verbose(nameof(WebGLXHRConnection), $"{nameof(FinishedProcessing)}({resp}, {ex})", this.Context);
|
||||
|
||||
// Unset the consumer, we no longer expect another OnContent call until further notice.
|
||||
this.ContentProvider?.Unbind();
|
||||
this.ContentProvider?.Dispose();
|
||||
this.ContentProvider = null;
|
||||
|
||||
var req = this.CurrentRequest;
|
||||
|
||||
req.OnCancellationRequested -= OnCancellationRequested;
|
||||
|
||||
bool resendRequest = false;
|
||||
HTTPRequestStates requestState = HTTPRequestStates.Finished;
|
||||
HTTPConnectionStates connectionState = HTTPConnectionStates.Recycle;
|
||||
Exception error = ex;
|
||||
|
||||
if (error != null)
|
||||
{
|
||||
// Timeout is a non-retryable error
|
||||
if (ex is TimeoutException)
|
||||
{
|
||||
error = null;
|
||||
requestState = HTTPRequestStates.TimedOut;
|
||||
}
|
||||
else if (ex is HTTPCacheAcquireLockException)
|
||||
{
|
||||
error = null;
|
||||
resendRequest = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (req.RetrySettings.Retries < req.RetrySettings.MaxRetries)
|
||||
{
|
||||
req.RetrySettings.Retries++;
|
||||
error = null;
|
||||
resendRequest = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
requestState = HTTPRequestStates.Error;
|
||||
}
|
||||
}
|
||||
|
||||
// Any exception means that the connection is in an unknown state, we shouldn't try to reuse it.
|
||||
connectionState = HTTPConnectionStates.Closed;
|
||||
|
||||
resp.Dispose();
|
||||
}
|
||||
else
|
||||
{
|
||||
// After HandleResponse connectionState can have the following values:
|
||||
// - Processing: nothing interesting, caller side can decide what happens with the connection (recycle connection).
|
||||
// - Closed: server sent an connection: close header.
|
||||
// - ClosedResendRequest: in this case resendRequest is true, and the connection must not be reused.
|
||||
// In this case we can send only one ConnectionEvent to handle both case and avoid concurrency issues.
|
||||
|
||||
KeepAliveHeader keepAlive = null;
|
||||
error = ConnectionHelper.HandleResponse(req, out resendRequest, out connectionState, ref keepAlive, this.Context);
|
||||
connectionState = HTTPConnectionStates.Recycle;
|
||||
|
||||
if (error != null)
|
||||
requestState = HTTPRequestStates.Error;
|
||||
else if (!resendRequest && resp.IsUpgraded)
|
||||
requestState = HTTPRequestStates.Processing;
|
||||
}
|
||||
|
||||
req.Timing.StartNext(TimingEventNames.Queued);
|
||||
|
||||
HTTPManager.Logger.Verbose(nameof(WebGLXHRConnection), $"{nameof(FinishedProcessing)} final decision. ResendRequest: {resendRequest}, RequestState: {requestState}, ConnectionState: {connectionState}", this.Context);
|
||||
|
||||
// If HandleResponse returned with ClosedResendRequest or there were an error and we can retry the request
|
||||
if (connectionState == HTTPConnectionStates.ClosedResendRequest || (resendRequest && connectionState == HTTPConnectionStates.Closed))
|
||||
{
|
||||
ConnectionHelper.ResendRequestAndCloseConnection(this, req);
|
||||
}
|
||||
else if (resendRequest && requestState == HTTPRequestStates.Finished)
|
||||
{
|
||||
RequestEventHelper.EnqueueRequestEvent(new RequestEventInfo(req, RequestEvents.Resend));
|
||||
ConnectionEventHelper.EnqueueConnectionEvent(new ConnectionEventInfo(this, connectionState));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise set the request's then the connection's state
|
||||
ConnectionHelper.EnqueueEvents(this, connectionState, req, requestState, error);
|
||||
}
|
||||
}
|
||||
|
||||
internal void OnDownloadProgress(int down, int total) => RequestEventHelper.EnqueueRequestEvent(new RequestEventInfo(this.CurrentRequest, RequestEvents.DownloadProgress, down, total));
|
||||
internal void OnUploadProgress(int up, int total) => RequestEventHelper.EnqueueRequestEvent(new RequestEventInfo(this.CurrentRequest, RequestEvents.UploadProgress, up, total));
|
||||
|
||||
internal void OnTimeout()
|
||||
{
|
||||
if (HTTPManager.Logger.IsDiagnostic)
|
||||
HTTPManager.Logger.Verbose(nameof(WebGLXHRConnection), $"{this.NativeId} - OnTimeout", this.Context);
|
||||
|
||||
CurrentRequest.Response = null;
|
||||
CurrentRequest.State = HTTPRequestStates.TimedOut;
|
||||
ConnectionEventHelper.EnqueueConnectionEvent(new ConnectionEventInfo(this, HTTPConnectionStates.Closed));
|
||||
}
|
||||
|
||||
internal void OnAborted()
|
||||
{
|
||||
if (HTTPManager.Logger.IsDiagnostic)
|
||||
HTTPManager.Logger.Verbose(nameof(WebGLXHRConnection), $"{this.NativeId} - OnAborted", this.Context);
|
||||
|
||||
CurrentRequest.Response = null;
|
||||
CurrentRequest.State = HTTPRequestStates.Aborted;
|
||||
ConnectionEventHelper.EnqueueConnectionEvent(new ConnectionEventInfo(this, HTTPConnectionStates.Closed));
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
WebGLXHRNativeConnectionLayer.Remove(NativeId);
|
||||
WebGLXHRNativeInterface.XHR_Release(NativeId);
|
||||
|
||||
this.ContentProvider?.Dispose();
|
||||
this.ContentProvider = null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 678df3294a2b9c64ba56e9dd095f08fe
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,153 @@
|
||||
#if UNITY_WEBGL && !UNITY_EDITOR
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Best.HTTP.Shared;
|
||||
using Best.HTTP.Shared.Extensions;
|
||||
using Best.HTTP.Shared.PlatformSupport.Memory;
|
||||
|
||||
namespace Best.HTTP.Hosts.Connections.WebGL
|
||||
{
|
||||
internal static class WebGLXHRNativeConnectionLayer
|
||||
{
|
||||
static Dictionary<int, WebGLXHRConnection> Connections = new Dictionary<int, WebGLXHRConnection>(1);
|
||||
|
||||
public static void Add(int nativeId, WebGLXHRConnection connection) => Connections.Add(nativeId, connection);
|
||||
public static void Remove(int nativeId) => Connections.Remove(nativeId);
|
||||
|
||||
public static void SetupHandlers(int nativeId, HTTPRequest request)
|
||||
{
|
||||
WebGLXHRNativeInterface.XHR_SetResponseHandler(nativeId, OnResponse, OnError, OnTimeout, OnAborted, OnBufferCallback, OnAllocArray);
|
||||
|
||||
// Setting OnUploadProgress result in an addEventListener("progress", ...) call making the request non-simple.
|
||||
// https://forum.unity.com/threads/best-http-released.200006/page-49#post-3696220
|
||||
WebGLXHRNativeInterface.XHR_SetProgressHandler(nativeId,
|
||||
request.DownloadSettings.OnDownloadProgress == null ? (OnWebGLXHRProgressDelegate)null : OnDownloadProgress,
|
||||
request.UploadSettings.OnUploadProgress == null ? (OnWebGLXHRProgressDelegate)null : OnUploadProgress);
|
||||
}
|
||||
|
||||
[AOT.MonoPInvokeCallback(typeof(OnWebGLXHRAllocArray))]
|
||||
static unsafe IntPtr OnAllocArray(int nativeId, int length)
|
||||
{
|
||||
byte[] buffer = BufferPool.Get(length, true);
|
||||
fixed (byte* ptr = buffer)
|
||||
{
|
||||
var p = (IntPtr)ptr;
|
||||
|
||||
if (HTTPManager.Logger.IsDiagnostic)
|
||||
HTTPManager.Logger.Verbose(nameof(WebGLXHRConnection), $"({p}) <= OnAllocArray({nativeId}, {length})");
|
||||
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
[AOT.MonoPInvokeCallback(typeof(OnWebGLXHRRequestHandlerDelegate))]
|
||||
static void OnResponse(int nativeId, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1, SizeParamIndex = 2)] byte[] pBuffer, int length)
|
||||
{
|
||||
WebGLXHRConnection conn = null;
|
||||
if (!Connections.TryGetValue(nativeId, out conn))
|
||||
{
|
||||
HTTPManager.Logger.Error("WebGLConnection", $"OnResponse({nativeId}, {pBuffer}, {length}): No WebGL connection found for nativeId({nativeId})!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (HTTPManager.Logger.IsDiagnostic)
|
||||
HTTPManager.Logger.Verbose("WebGLConnection", $"OnResponse({nativeId}, {pBuffer}, {length})", conn.Context);
|
||||
|
||||
BufferSegment payload = BufferSegment.Empty;
|
||||
if (length > 0)
|
||||
payload = pBuffer.AsBuffer(length);
|
||||
|
||||
conn.OnResponse(payload);
|
||||
}
|
||||
|
||||
[AOT.MonoPInvokeCallback(typeof(OnWebGLXHRBufferDelegate))]
|
||||
public static void OnBufferCallback(int nativeId, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1, SizeParamIndex = 2)] byte[] pBuffer, int length)
|
||||
{
|
||||
WebGLXHRConnection conn = null;
|
||||
if (!Connections.TryGetValue(nativeId, out conn))
|
||||
{
|
||||
HTTPManager.Logger.Error("WebGLConnection - OnBufferCallback", "No WebGL connection found for nativeId: " + nativeId.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
BufferSegment payload = BufferSegment.Empty;
|
||||
if (length > 0)
|
||||
payload = pBuffer.AsBuffer(length);
|
||||
|
||||
conn.OnBuffer(payload);
|
||||
}
|
||||
|
||||
[AOT.MonoPInvokeCallback(typeof(OnWebGLXHRProgressDelegate))]
|
||||
static void OnDownloadProgress(int nativeId, int downloaded, int total)
|
||||
{
|
||||
WebGLXHRConnection conn = null;
|
||||
if (!Connections.TryGetValue(nativeId, out conn))
|
||||
{
|
||||
HTTPManager.Logger.Error("WebGLConnection - OnDownloadProgress", "No WebGL connection found for nativeId: " + nativeId.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
HTTPManager.Logger.Information(nativeId + " OnDownloadProgress", downloaded.ToString() + " / " + total.ToString(), conn.Context);
|
||||
|
||||
conn.OnDownloadProgress(downloaded, total);
|
||||
}
|
||||
|
||||
[AOT.MonoPInvokeCallback(typeof(OnWebGLXHRProgressDelegate))]
|
||||
static void OnUploadProgress(int nativeId, int uploaded, int total)
|
||||
{
|
||||
WebGLXHRConnection conn = null;
|
||||
if (!Connections.TryGetValue(nativeId, out conn))
|
||||
{
|
||||
HTTPManager.Logger.Error("WebGLConnection - OnUploadProgress", "No WebGL connection found for nativeId: " + nativeId.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
HTTPManager.Logger.Information(nativeId + " OnUploadProgress", uploaded.ToString() + " / " + total.ToString(), conn.Context);
|
||||
|
||||
conn.OnUploadProgress(uploaded, total);
|
||||
}
|
||||
|
||||
[AOT.MonoPInvokeCallback(typeof(OnWebGLXHRErrorDelegate))]
|
||||
static void OnError(int nativeId, string error)
|
||||
{
|
||||
WebGLXHRConnection conn = null;
|
||||
if (!Connections.TryGetValue(nativeId, out conn))
|
||||
{
|
||||
HTTPManager.Logger.Error("WebGLConnection - OnError", "No WebGL connection found for nativeId: " + nativeId.ToString() + " Error: " + error);
|
||||
return;
|
||||
}
|
||||
|
||||
conn.OnError(error);
|
||||
}
|
||||
|
||||
[AOT.MonoPInvokeCallback(typeof(OnWebGLXHRTimeoutDelegate))]
|
||||
static void OnTimeout(int nativeId)
|
||||
{
|
||||
WebGLXHRConnection conn = null;
|
||||
if (!Connections.TryGetValue(nativeId, out conn))
|
||||
{
|
||||
HTTPManager.Logger.Error("WebGLConnection - OnTimeout", "No WebGL connection found for nativeId: " + nativeId.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
conn.OnTimeout();
|
||||
}
|
||||
|
||||
[AOT.MonoPInvokeCallback(typeof(OnWebGLXHRAbortedDelegate))]
|
||||
static void OnAborted(int nativeId)
|
||||
{
|
||||
WebGLXHRConnection conn = null;
|
||||
if (!Connections.TryGetValue(nativeId, out conn))
|
||||
{
|
||||
HTTPManager.Logger.Error("WebGLConnection - OnAborted", "No WebGL connection found for nativeId: " + nativeId.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
conn.OnAborted();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42cfa2a1d7f27744da3528da58df7ef7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,54 @@
|
||||
#if UNITY_WEBGL && !UNITY_EDITOR
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Best.HTTP.Hosts.Connections.WebGL
|
||||
{
|
||||
delegate void OnWebGLXHRRequestHandlerDelegate(int nativeId, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1, SizeParamIndex = 2)] byte[] pBuffer, int length);
|
||||
delegate void OnWebGLXHRBufferDelegate(int nativeId, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1, SizeParamIndex = 2)] byte[] pBuffer, int length);
|
||||
delegate void OnWebGLXHRProgressDelegate(int nativeId, int downloaded, int total);
|
||||
delegate void OnWebGLXHRErrorDelegate(int nativeId, string error);
|
||||
delegate void OnWebGLXHRTimeoutDelegate(int nativeId);
|
||||
delegate void OnWebGLXHRAbortedDelegate(int nativeId);
|
||||
delegate IntPtr OnWebGLXHRAllocArray(int nativeId, int size);
|
||||
|
||||
internal static class WebGLXHRNativeInterface
|
||||
{
|
||||
[DllImport("__Internal")]
|
||||
public static extern int XHR_Create(string method, string url, string userName, string passwd, int withCredentials);
|
||||
|
||||
/// <summary>
|
||||
/// Is an unsigned long representing the number of milliseconds a request can take before automatically being terminated. A value of 0 (which is the default) means there is no timeout.
|
||||
/// </summary>
|
||||
[DllImport("__Internal")]
|
||||
public static extern void XHR_SetTimeout(int nativeId, uint timeout);
|
||||
|
||||
[DllImport("__Internal")]
|
||||
public static extern void XHR_SetRequestHeader(int nativeId, string header, string value);
|
||||
|
||||
[DllImport("__Internal")]
|
||||
public static extern void XHR_SetResponseHandler(int nativeId,
|
||||
OnWebGLXHRRequestHandlerDelegate onresponse,
|
||||
OnWebGLXHRErrorDelegate onerror,
|
||||
OnWebGLXHRTimeoutDelegate ontimeout,
|
||||
OnWebGLXHRAbortedDelegate onabort,
|
||||
OnWebGLXHRBufferDelegate onbuffer,
|
||||
OnWebGLXHRAllocArray onallocArray);
|
||||
|
||||
[DllImport("__Internal")]
|
||||
public static extern void XHR_SetProgressHandler(int nativeId, OnWebGLXHRProgressDelegate onDownloadProgress, OnWebGLXHRProgressDelegate onUploadProgress);
|
||||
|
||||
[DllImport("__Internal")]
|
||||
public static extern void XHR_Send(int nativeId, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1, SizeParamIndex = 2)] byte[] body, int length);
|
||||
|
||||
[DllImport("__Internal")]
|
||||
public static extern void XHR_Abort(int nativeId);
|
||||
|
||||
[DllImport("__Internal")]
|
||||
public static extern void XHR_Release(int nativeId);
|
||||
|
||||
[DllImport("__Internal")]
|
||||
public static extern void XHR_SetLoglevel(int logLevel);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ef4c9a06ea58925459016164ae22bedf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user