This commit is contained in:
2020-07-09 08:50:24 +08:00
parent 13d25f4707
commit c523462b82
1818 changed files with 174940 additions and 582 deletions

View File

@@ -0,0 +1,218 @@
using System;
using System.Threading;
#if NETFX_CORE
using System.Threading.Tasks;
//Disable CD4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
#pragma warning disable 4014
//Disable warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
#pragma warning disable 1998
#endif
namespace BestHTTP
{
internal delegate void HTTPConnectionRecycledDelegate(ConnectionBase conn);
internal abstract class ConnectionBase : IDisposable
{
#region Public Properties
/// <summary>
/// The address of the server that this connection is bound to.
/// </summary>
public string ServerAddress { get; protected set; }
/// <summary>
/// The state of this connection.
/// </summary>
public HTTPConnectionStates State { get; protected set; }
/// <summary>
/// It's true if this connection is available to process a HTTPRequest.
/// </summary>
public bool IsFree { get { return State == HTTPConnectionStates.Initial || State == HTTPConnectionStates.Free; } }
/// <summary>
/// Returns true if it's an active connection.
/// </summary>
public bool IsActive { get { return State > HTTPConnectionStates.Initial && State < HTTPConnectionStates.Free; } }
/// <summary>
/// If the State is HTTPConnectionStates.Processing, then it holds a HTTPRequest instance. Otherwise it's null.
/// </summary>
public HTTPRequest CurrentRequest { get; protected set; }
public virtual bool IsRemovable { get { return IsFree && (DateTime.UtcNow - LastProcessTime) > HTTPManager.MaxConnectionIdleTime; } }
/// <summary>
/// When we start to process the current request. It's set after the connection is established.
/// </summary>
public DateTime StartTime { get; protected set; }
/// <summary>
/// When this connection timed out.
/// </summary>
public DateTime TimedOutStart { get; protected set; }
#if !BESTHTTP_DISABLE_PROXY
protected HTTPProxy Proxy { get; set; }
public bool HasProxy { get { return Proxy != null; } }
#endif
public Uri LastProcessedUri { get; protected set; }
#endregion
#region Protected Fields
protected DateTime LastProcessTime;
protected HTTPConnectionRecycledDelegate OnConnectionRecycled = null;
#endregion
#region Privates
private bool IsThreaded;
#endregion
public ConnectionBase(string serverAddress)
:this(serverAddress, true)
{}
public ConnectionBase(string serverAddress, bool threaded)
{
this.ServerAddress = serverAddress;
this.State = HTTPConnectionStates.Initial;
this.LastProcessTime = DateTime.UtcNow;
this.IsThreaded = threaded;
}
internal abstract void Abort(HTTPConnectionStates hTTPConnectionStates);
internal void Process(HTTPRequest request)
{
if (State == HTTPConnectionStates.Processing)
throw new Exception("Connection already processing a request!");
StartTime = DateTime.MaxValue;
State = HTTPConnectionStates.Processing;
CurrentRequest = request;
if (IsThreaded)
{
#if NETFX_CORE
Windows.System.Threading.ThreadPool.RunAsync(ThreadFunc);
#else
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadFunc));
//new Thread(ThreadFunc)
// .Start();
#endif
}
else
ThreadFunc(null);
}
protected virtual
#if NETFX_CORE
async
#endif
void ThreadFunc(object param)
{
}
internal void HandleProgressCallback()
{
if (CurrentRequest.OnProgress != null && CurrentRequest.DownloadProgressChanged)
{
try
{
CurrentRequest.OnProgress(CurrentRequest, CurrentRequest.Downloaded, CurrentRequest.DownloadLength);
}
catch (Exception ex)
{
HTTPManager.Logger.Exception("ConnectionBase", "HandleProgressCallback - OnProgress", ex);
}
CurrentRequest.DownloadProgressChanged = false;
}
if (CurrentRequest.OnUploadProgress != null && CurrentRequest.UploadProgressChanged)
{
try
{
CurrentRequest.OnUploadProgress(CurrentRequest, CurrentRequest.Uploaded, CurrentRequest.UploadLength);
}
catch (Exception ex)
{
HTTPManager.Logger.Exception("ConnectionBase", "HandleProgressCallback - OnUploadProgress", ex);
}
CurrentRequest.UploadProgressChanged = false;
}
}
internal void HandleCallback()
{
try
{
HandleProgressCallback();
if (State == HTTPConnectionStates.Upgraded)
{
if (CurrentRequest != null && CurrentRequest.Response != null && CurrentRequest.Response.IsUpgraded)
CurrentRequest.UpgradeCallback();
State = HTTPConnectionStates.WaitForProtocolShutdown;
}
else
CurrentRequest.CallCallback();
}
catch (Exception ex)
{
HTTPManager.Logger.Exception("ConnectionBase", "HandleCallback", ex);
}
}
internal void Recycle(HTTPConnectionRecycledDelegate onConnectionRecycled)
{
OnConnectionRecycled = onConnectionRecycled;
if (!(State > HTTPConnectionStates.Initial && State < HTTPConnectionStates.WaitForProtocolShutdown) || State == HTTPConnectionStates.Redirected)
RecycleNow();
}
protected void RecycleNow()
{
if (State == HTTPConnectionStates.TimedOut ||
State == HTTPConnectionStates.Closed)
LastProcessTime = DateTime.MinValue;
State = HTTPConnectionStates.Free;
CurrentRequest = null;
if (OnConnectionRecycled != null)
{
OnConnectionRecycled(this);
OnConnectionRecycled = null;
}
}
#region Dispose Pattern
protected bool IsDisposed { get; private set; }
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
IsDisposed = true;
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 19b89653c6a154828965eb801bae64c7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,311 @@
using System;
using System.Collections.Generic;
#if NETFX_CORE
using FileStream = BestHTTP.PlatformSupport.IO.FileStream;
using FileMode = BestHTTP.PlatformSupport.IO.FileMode;
using FileAccess = BestHTTP.PlatformSupport.IO.FileAccess;
using Directory = BestHTTP.PlatformSupport.IO.Directory;
using File = BestHTTP.PlatformSupport.IO.File;
#else
using FileStream = System.IO.FileStream;
using FileMode = System.IO.FileMode;
using FileAccess = System.IO.FileAccess;
#endif
using BestHTTP.Extensions;
namespace BestHTTP
{
sealed class StreamList : System.IO.Stream
{
private System.IO.Stream[] Streams;
private int CurrentIdx;
public StreamList(params System.IO.Stream[] streams)
{
this.Streams = streams;
this.CurrentIdx = 0;
}
public override bool CanRead
{
get {
if (CurrentIdx >= Streams.Length)
return false;
return Streams[CurrentIdx].CanRead;
}
}
public override bool CanSeek { get { return false; } }
public override bool CanWrite
{
get {
if (CurrentIdx >= Streams.Length)
return false;
return Streams[CurrentIdx].CanWrite;
}
}
public override void Flush()
{
if (CurrentIdx >= Streams.Length)
return;
// We have to call the flush to all previous streams, as we may advanced the CurrentIdx
for (int i = 0; i <= CurrentIdx; ++i)
Streams[i].Flush();
}
public override long Length
{
get {
if (CurrentIdx >= Streams.Length)
return 0;
long length = 0;
for (int i = 0; i < Streams.Length; ++i)
length += Streams[i].Length;
return length;
}
}
public override int Read(byte[] buffer, int offset, int count)
{
if (CurrentIdx >= Streams.Length)
return -1;
int readCount = Streams[CurrentIdx].Read(buffer, offset, count);
while (readCount < count && CurrentIdx++ < Streams.Length)
{
readCount += Streams[CurrentIdx].Read(buffer, offset + readCount, count - readCount);
}
return readCount;
}
public override void Write(byte[] buffer, int offset, int count)
{
if (CurrentIdx >= Streams.Length)
return;
Streams[CurrentIdx].Write(buffer, offset, count);
}
public void Write(string str)
{
byte[] bytes = str.GetASCIIBytes();
this.Write(bytes, 0, bytes.Length);
}
protected override void Dispose(bool disposing)
{
for (int i = 0; i < Streams.Length; ++i)
{
try
{
Streams[i].Dispose();
}
catch(Exception ex)
{
HTTPManager.Logger.Exception("StreamList", "Dispose", ex);
}
}
}
public override long Position
{
get
{
throw new NotImplementedException("Position get");
}
set
{
throw new NotImplementedException("Position set");
}
}
public override long Seek(long offset, System.IO.SeekOrigin origin)
{
if (CurrentIdx >= Streams.Length)
return 0;
return Streams[CurrentIdx].Seek(offset, origin);
}
public override void SetLength(long value)
{
throw new NotImplementedException("SetLength");
}
}
/*public static class AndroidFileHelper
{
// AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
// AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
public static Stream GetAPKFileStream(string path)
{
UnityEngine.AndroidJavaClass up = new UnityEngine.AndroidJavaClass("com.unity3d.player.UnityPlayer");
UnityEngine.AndroidJavaObject cActivity = up.GetStatic<UnityEngine.AndroidJavaObject>("currentActivity");
UnityEngine.AndroidJavaObject assetManager = cActivity.GetStatic<UnityEngine.AndroidJavaObject>("getAssets");
return new AndroidInputStream(assetManager.Call<UnityEngine.AndroidJavaObject>("open", path));
}
}
public sealed class AndroidInputStream : Stream
{
private UnityEngine.AndroidJavaObject baseStream;
public override bool CanRead
{
get { throw new NotImplementedException(); }
}
public override bool CanSeek
{
get { throw new NotImplementedException(); }
}
public override bool CanWrite
{
get { throw new NotImplementedException(); }
}
public override void Flush()
{
throw new NotImplementedException();
}
public override long Length
{
get { throw new NotImplementedException(); }
}
public override long Position
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public AndroidInputStream(UnityEngine.AndroidJavaObject inputStream)
{
this.baseStream = inputStream;
}
public override int Read(byte[] buffer, int offset, int count)
{
return this.baseStream.Call<int>("read", buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotImplementedException();
}
public override void SetLength(long value)
{
throw new NotImplementedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotImplementedException();
}
}*/
internal sealed class FileConnection : ConnectionBase
{
public FileConnection(string serverAddress)
:base(serverAddress)
{ }
internal override void Abort(HTTPConnectionStates newState)
{
State = newState;
switch (State)
{
case HTTPConnectionStates.TimedOut: TimedOutStart = DateTime.UtcNow; break;
}
throw new NotImplementedException();
}
protected override void ThreadFunc(object param)
{
try
{
// Step 1 : create a stream with header information
// Step 2 : create a stream from the file
// Step 3 : create a StreamList
// Step 4 : create a HTTPResponse object
// Step 5 : call the Receive function of the response object
using (FileStream fs = new FileStream(this.CurrentRequest.CurrentUri.LocalPath, FileMode.Open, FileAccess.Read))
//using (Stream fs = AndroidFileHelper.GetAPKFileStream(this.CurrentRequest.CurrentUri.LocalPath))
using (StreamList stream = new StreamList(new System.IO.MemoryStream(), fs))
{
// This will write to the MemoryStream
stream.Write("HTTP/1.1 200 Ok\r\n");
stream.Write("Content-Type: application/octet-stream\r\n");
stream.Write("Content-Length: " + fs.Length.ToString() + "\r\n");
stream.Write("\r\n");
stream.Seek(0, System.IO.SeekOrigin.Begin);
base.CurrentRequest.Response = new HTTPResponse(base.CurrentRequest, stream, base.CurrentRequest.UseStreaming, false);
if (!CurrentRequest.Response.Receive())
CurrentRequest.Response = null;
}
}
catch(Exception ex)
{
if (CurrentRequest != null)
{
// Something gone bad, Response must be null!
CurrentRequest.Response = null;
switch (State)
{
case HTTPConnectionStates.AbortRequested:
CurrentRequest.State = HTTPRequestStates.Aborted;
break;
case HTTPConnectionStates.TimedOut:
CurrentRequest.State = HTTPRequestStates.TimedOut;
break;
default:
CurrentRequest.Exception = ex;
CurrentRequest.State = HTTPRequestStates.Error;
break;
}
}
}
finally
{
State = HTTPConnectionStates.Closed;
if (CurrentRequest.State == HTTPRequestStates.Processing)
{
if (CurrentRequest.Response != null)
CurrentRequest.State = HTTPRequestStates.Finished;
else
CurrentRequest.State = HTTPRequestStates.Error;
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2da61498eefa84751bf83deb77fc1754
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,395 @@
#if UNITY_WEBGL && !UNITY_EDITOR
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using BestHTTP.Authentication;
namespace BestHTTP
{
delegate void OnWebGLRequestHandlerDelegate(int nativeId, int httpStatus, IntPtr pBuffer, int length, int zero);
delegate void OnWebGLBufferDelegate(int nativeId, IntPtr pBuffer, int length);
delegate void OnWebGLProgressDelegate(int nativeId, int downloaded, int total);
delegate void OnWebGLErrorDelegate(int nativeId, string error);
delegate void OnWebGLTimeoutDelegate(int nativeId);
delegate void OnWebGLAbortedDelegate(int nativeId);
internal sealed class WebGLConnection : ConnectionBase
{
static Dictionary<int, WebGLConnection> Connections = new Dictionary<int, WebGLConnection>(4);
int NativeId;
MemoryStream Stream;
public WebGLConnection(string serverAddress)
: base(serverAddress, false)
{
XHR_SetLoglevel((byte)HTTPManager.Logger.Level);
}
internal override void Abort(HTTPConnectionStates newState)
{
State = newState;
switch (State)
{
case HTTPConnectionStates.TimedOut: TimedOutStart = DateTime.UtcNow; break;
}
XHR_Abort(this.NativeId);
}
protected override void ThreadFunc(object param /*null*/)
{
// XmlHttpRequest setup
this.NativeId = XHR_Create(HTTPRequest.MethodNames[(byte)CurrentRequest.MethodType],
CurrentRequest.CurrentUri.OriginalString,
CurrentRequest.Credentials != null ? CurrentRequest.Credentials.UserName : null,
CurrentRequest.Credentials != null ? CurrentRequest.Credentials.Password : null);
Connections.Add(NativeId, this);
CurrentRequest.EnumerateHeaders((header, values) =>
{
if (header != "Content-Length")
for (int i = 0; i < values.Count; ++i)
XHR_SetRequestHeader(NativeId, header, values[i]);
}, /*callBeforeSendCallback:*/ true);
byte[] body = CurrentRequest.GetEntityBody();
XHR_SetResponseHandler(NativeId, WebGLConnection.OnResponse, WebGLConnection.OnError, WebGLConnection.OnTimeout, WebGLConnection.OnAborted);
XHR_SetProgressHandler(NativeId, WebGLConnection.OnDownloadProgress, WebGLConnection.OnUploadProgress);
XHR_SetTimeout(NativeId, (uint)(CurrentRequest.ConnectTimeout.TotalMilliseconds + CurrentRequest.Timeout.TotalMilliseconds));
XHR_Send(NativeId, body, body != null ? body.Length : 0);
}
#region Callback Implementations
void OnResponse(int httpStatus, byte[] buffer)
{
try
{
using (MemoryStream ms = new MemoryStream())
{
Stream = ms;
XHR_GetStatusLine(NativeId, OnBufferCallback);
XHR_GetResponseHeaders(NativeId, OnBufferCallback);
if (buffer != null && buffer.Length > 0)
ms.Write(buffer, 0, buffer.Length);
ms.Seek(0L, SeekOrigin.Begin);
SupportedProtocols protocol = CurrentRequest.ProtocolHandler == SupportedProtocols.Unknown ? HTTPProtocolFactory.GetProtocolFromUri(CurrentRequest.CurrentUri) : CurrentRequest.ProtocolHandler;
CurrentRequest.Response = HTTPProtocolFactory.Get(protocol, CurrentRequest, ms, CurrentRequest.UseStreaming, false);
CurrentRequest.Response.Receive(buffer != null && buffer.Length > 0 ? (int)buffer.Length : -1, true);
}
}
catch (Exception e)
{
HTTPManager.Logger.Exception(this.NativeId + " WebGLConnection", "OnResponse", e);
if (CurrentRequest != null)
{
// Something gone bad, Response must be null!
CurrentRequest.Response = null;
switch (State)
{
case HTTPConnectionStates.AbortRequested:
CurrentRequest.State = HTTPRequestStates.Aborted;
break;
case HTTPConnectionStates.TimedOut:
CurrentRequest.State = HTTPRequestStates.TimedOut;
break;
default:
CurrentRequest.Exception = e;
CurrentRequest.State = HTTPRequestStates.Error;
break;
}
}
}
finally
{
Connections.Remove(NativeId);
Stream = null;
if (CurrentRequest != null)
lock (HTTPManager.Locker)
{
State = HTTPConnectionStates.Closed;
if (CurrentRequest.State == HTTPRequestStates.Processing)
{
if (CurrentRequest.Response != null)
CurrentRequest.State = HTTPRequestStates.Finished;
else
CurrentRequest.State = HTTPRequestStates.Error;
}
}
LastProcessTime = DateTime.UtcNow;
if (OnConnectionRecycled != null)
RecycleNow();
XHR_Release(NativeId);
}
}
void OnBuffer(byte[] buffer)
{
if (Stream != null)
{
Stream.Write(buffer, 0, buffer.Length);
Stream.Write(new byte[2] { HTTPResponse.CR, HTTPResponse.LF }, 0, 2);
}
}
void OnDownloadProgress(int down, int total)
{
CurrentRequest.Downloaded = down;
CurrentRequest.DownloadLength = total;
CurrentRequest.DownloadProgressChanged = true;
}
void OnUploadProgress(int up, int total)
{
CurrentRequest.Uploaded = up;
CurrentRequest.UploadLength = total;
CurrentRequest.UploadProgressChanged = true;
}
void OnError(string error)
{
HTTPManager.Logger.Information(this.NativeId + " WebGLConnection - OnError", error);
Connections.Remove(NativeId);
Stream = null;
if (CurrentRequest != null)
lock (HTTPManager.Locker)
{
State = HTTPConnectionStates.Closed;
CurrentRequest.State = HTTPRequestStates.Error;
CurrentRequest.Exception = new Exception(error);
}
LastProcessTime = DateTime.UtcNow;
if (OnConnectionRecycled != null)
RecycleNow();
XHR_Release(NativeId);
}
void OnTimeout()
{
HTTPManager.Logger.Information(this.NativeId + " WebGLConnection - OnResponse", string.Empty);
Connections.Remove(NativeId);
Stream = null;
if (CurrentRequest != null)
lock (HTTPManager.Locker)
{
State = HTTPConnectionStates.Closed;
CurrentRequest.State = HTTPRequestStates.TimedOut;
}
LastProcessTime = DateTime.UtcNow;
if (OnConnectionRecycled != null)
RecycleNow();
XHR_Release(NativeId);
}
void OnAborted()
{
HTTPManager.Logger.Information(this.NativeId + " WebGLConnection - OnAborted", string.Empty);
Connections.Remove(NativeId);
Stream = null;
if (CurrentRequest != null)
lock (HTTPManager.Locker)
{
State = HTTPConnectionStates.Closed;
CurrentRequest.State = HTTPRequestStates.Aborted;
}
LastProcessTime = DateTime.UtcNow;
if (OnConnectionRecycled != null)
RecycleNow();
XHR_Release(NativeId);
}
#endregion
#region WebGL Static Callbacks
[AOT.MonoPInvokeCallback(typeof(OnWebGLRequestHandlerDelegate))]
static void OnResponse(int nativeId, int httpStatus, IntPtr pBuffer, int length, int err)
{
HTTPManager.Logger.Information("WebGLConnection - OnResponse", string.Format("{0} {1} {2} {3}", nativeId, httpStatus, length, err));
WebGLConnection conn = null;
if (!Connections.TryGetValue(nativeId, out conn))
{
HTTPManager.Logger.Error("WebGLConnection - OnResponse", "No WebGL connection found for nativeId: " + nativeId.ToString());
return;
}
byte[] buffer = new byte[length];
// Copy data from the 'unmanaged' memory to managed memory. Buffer will be reclaimed by the GC.
Marshal.Copy(pBuffer, buffer, 0, length);
conn.OnResponse(httpStatus, buffer);
}
[AOT.MonoPInvokeCallback(typeof(OnWebGLBufferDelegate))]
static void OnBufferCallback(int nativeId, IntPtr pBuffer, int length)
{
WebGLConnection conn = null;
if (!Connections.TryGetValue(nativeId, out conn))
{
HTTPManager.Logger.Error("WebGLConnection - OnBufferCallback", "No WebGL connection found for nativeId: " + nativeId.ToString());
return;
}
byte[] buffer = new byte[length];
// Copy data from the 'unmanaged' memory to managed memory. Buffer will be reclaimed by the GC.
Marshal.Copy(pBuffer, buffer, 0, length);
conn.OnBuffer(buffer);
}
[AOT.MonoPInvokeCallback(typeof(OnWebGLProgressDelegate))]
static void OnDownloadProgress(int nativeId, int downloaded, int total)
{
HTTPManager.Logger.Information(nativeId + " OnDownloadProgress", downloaded.ToString() + " / " + total.ToString());
WebGLConnection conn = null;
if (!Connections.TryGetValue(nativeId, out conn))
{
HTTPManager.Logger.Error("WebGLConnection - OnDownloadProgress", "No WebGL connection found for nativeId: " + nativeId.ToString());
return;
}
conn.OnDownloadProgress(downloaded, total);
}
[AOT.MonoPInvokeCallback(typeof(OnWebGLProgressDelegate))]
static void OnUploadProgress(int nativeId, int uploaded, int total)
{
HTTPManager.Logger.Information(nativeId + " OnUploadProgress", uploaded.ToString() + " / " + total.ToString());
WebGLConnection conn = null;
if (!Connections.TryGetValue(nativeId, out conn))
{
HTTPManager.Logger.Error("WebGLConnection - OnUploadProgress", "No WebGL connection found for nativeId: " + nativeId.ToString());
return;
}
conn.OnUploadProgress(uploaded, total);
}
[AOT.MonoPInvokeCallback(typeof(OnWebGLErrorDelegate))]
static void OnError(int nativeId, string error)
{
WebGLConnection 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(OnWebGLTimeoutDelegate))]
static void OnTimeout(int nativeId)
{
WebGLConnection 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(OnWebGLAbortedDelegate))]
static void OnAborted(int nativeId)
{
WebGLConnection conn = null;
if (!Connections.TryGetValue(nativeId, out conn))
{
HTTPManager.Logger.Error("WebGLConnection - OnAborted", "No WebGL connection found for nativeId: " + nativeId.ToString());
return;
}
conn.OnAborted();
}
#endregion
#region WebGL Interface
[DllImport("__Internal")]
private static extern int XHR_Create(string method, string url, string userName, string passwd);
/// <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")]
private static extern void XHR_SetTimeout(int nativeId, uint timeout);
[DllImport("__Internal")]
private static extern void XHR_SetRequestHeader(int nativeId, string header, string value);
[DllImport("__Internal")]
private static extern void XHR_SetResponseHandler(int nativeId, OnWebGLRequestHandlerDelegate onresponse, OnWebGLErrorDelegate onerror, OnWebGLTimeoutDelegate ontimeout, OnWebGLAbortedDelegate onabort);
[DllImport("__Internal")]
private static extern void XHR_SetProgressHandler(int nativeId, OnWebGLProgressDelegate onDownloadProgress, OnWebGLProgressDelegate onUploadProgress);
[DllImport("__Internal")]
private static extern void XHR_Send(int nativeId, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1, SizeParamIndex = 2)] byte[] body, int length);
[DllImport("__Internal")]
private static extern void XHR_GetResponseHeaders(int nativeId, OnWebGLBufferDelegate callback);
[DllImport("__Internal")]
private static extern void XHR_GetStatusLine(int nativeId, OnWebGLBufferDelegate callback);
[DllImport("__Internal")]
private static extern void XHR_Abort(int nativeId);
[DllImport("__Internal")]
private static extern void XHR_Release(int nativeId);
[DllImport("__Internal")]
private static extern void XHR_SetLoglevel(int logLevel);
#endregion
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c888ab88487f84e229e82f41bcda24a8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: