chore: 重构网络模块
parent
fdfec81181
commit
d19f389e2a
|
@ -1,7 +1,6 @@
|
|||
using NUnit.Framework;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Runtime.CompilerServices;
|
||||
using LeanCloud;
|
||||
|
||||
namespace LeanCloudTests {
|
||||
|
@ -16,7 +15,6 @@ namespace LeanCloudTests {
|
|||
}
|
||||
|
||||
[Test]
|
||||
[AsyncStateMachine(typeof(ObjectControllerTests))]
|
||||
public async Task TestSave() {
|
||||
TestContext.Out.WriteLine($"before at {Thread.CurrentThread.ManagedThreadId}");
|
||||
var obj = AVObject.Create("Foo");
|
||||
|
@ -26,7 +24,6 @@ namespace LeanCloudTests {
|
|||
Assert.NotNull(obj.ObjectId);
|
||||
Assert.NotNull(obj.CreatedAt);
|
||||
Assert.NotNull(obj.UpdatedAt);
|
||||
await Task.Delay(10000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.Collections.Generic;
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace LeanCloud.Storage.Internal
|
||||
{
|
||||
|
@ -43,7 +44,13 @@ namespace LeanCloud.Storage.Internal
|
|||
string appId = AVClient.CurrentConfiguration.ApplicationId;
|
||||
string url = string.Format("https://app-router.leancloud.cn/2/route?appId={0}", appId);
|
||||
|
||||
var ret = await AVClient.HttpGetAsync(new Uri(url));
|
||||
var request = new HttpRequest {
|
||||
Uri = new Uri(url),
|
||||
Method = HttpMethod.Get,
|
||||
Headers = null,
|
||||
Data = null
|
||||
};
|
||||
var ret = await AVPlugins.Instance.HttpClient.ExecuteAsync(request, null, null, CancellationToken.None);
|
||||
if (ret.Item1 != HttpStatusCode.OK) {
|
||||
throw new AVException(AVException.ErrorCode.ConnectionFailed, "can not reach router.", null);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.IO;
|
|||
using System.Text;
|
||||
using LeanCloud.Storage.Internal;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace LeanCloud.Storage.Internal
|
||||
{
|
||||
|
@ -14,105 +15,154 @@ namespace LeanCloud.Storage.Internal
|
|||
public class AVCommand : HttpRequest
|
||||
{
|
||||
public IDictionary<string, object> DataObject { get; private set; }
|
||||
public override Stream Data
|
||||
{
|
||||
get
|
||||
{
|
||||
if (base.Data != null)
|
||||
{
|
||||
return base.Data;
|
||||
}
|
||||
|
||||
return base.Data = (DataObject != null
|
||||
? new MemoryStream(Encoding.UTF8.GetBytes(Json.Encode(DataObject)))
|
||||
: null);
|
||||
public object Body {
|
||||
get; set;
|
||||
}
|
||||
|
||||
public override Stream Data {
|
||||
get {
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes(Json.Encode(Body)));
|
||||
}
|
||||
set { base.Data = value; }
|
||||
}
|
||||
|
||||
public AVCommand(string relativeUri,
|
||||
string method,
|
||||
string sessionToken = null,
|
||||
IList<KeyValuePair<string, string>> headers = null,
|
||||
IDictionary<string, object> data = null) : this(relativeUri: relativeUri,
|
||||
method: method,
|
||||
sessionToken: sessionToken,
|
||||
headers: headers,
|
||||
stream: null,
|
||||
contentType: data != null ? "application/json" : null)
|
||||
{
|
||||
DataObject = data;
|
||||
}
|
||||
|
||||
public AVCommand(string relativeUri,
|
||||
string method,
|
||||
string sessionToken = null,
|
||||
IList<KeyValuePair<string, string>> headers = null,
|
||||
Stream stream = null,
|
||||
string contentType = null)
|
||||
object data = null)
|
||||
{
|
||||
var state = AVPlugins.Instance.AppRouterController.Get();
|
||||
var urlTemplate = "https://{0}/{1}/{2}";
|
||||
AVClient.Configuration configuration = AVClient.CurrentConfiguration;
|
||||
var apiVersion = "1.1";
|
||||
if (relativeUri.StartsWith("push") || relativeUri.StartsWith("installations"))
|
||||
{
|
||||
if (relativeUri.StartsWith("push") || relativeUri.StartsWith("installations")) {
|
||||
Uri = new Uri(string.Format(urlTemplate, state.PushServer, apiVersion, relativeUri));
|
||||
if (configuration.PushServer != null)
|
||||
{
|
||||
if (configuration.PushServer != null) {
|
||||
Uri = new Uri(string.Format("{0}{1}/{2}", configuration.PushServer, apiVersion, relativeUri));
|
||||
}
|
||||
}
|
||||
else if (relativeUri.StartsWith("stats") || relativeUri.StartsWith("always_collect") || relativeUri.StartsWith("statistics"))
|
||||
{
|
||||
} else if (relativeUri.StartsWith("stats") || relativeUri.StartsWith("always_collect") || relativeUri.StartsWith("statistics")) {
|
||||
Uri = new Uri(string.Format(urlTemplate, state.StatsServer, apiVersion, relativeUri));
|
||||
if (configuration.StatsServer != null)
|
||||
{
|
||||
if (configuration.StatsServer != null) {
|
||||
Uri = new Uri(string.Format("{0}{1}/{2}", configuration.StatsServer, apiVersion, relativeUri));
|
||||
}
|
||||
}
|
||||
else if (relativeUri.StartsWith("functions") || relativeUri.StartsWith("call"))
|
||||
{
|
||||
} else if (relativeUri.StartsWith("functions") || relativeUri.StartsWith("call")) {
|
||||
Uri = new Uri(string.Format(urlTemplate, state.EngineServer, apiVersion, relativeUri));
|
||||
|
||||
if (configuration.EngineServer != null)
|
||||
{
|
||||
if (configuration.EngineServer != null) {
|
||||
Uri = new Uri(string.Format("{0}{1}/{2}", configuration.EngineServer, apiVersion, relativeUri));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Uri = new Uri(string.Format(urlTemplate, state.ApiServer, apiVersion, relativeUri));
|
||||
|
||||
if (configuration.ApiServer != null)
|
||||
{
|
||||
if (configuration.ApiServer != null) {
|
||||
Uri = new Uri(string.Format("{0}{1}/{2}", configuration.ApiServer, apiVersion, relativeUri));
|
||||
}
|
||||
}
|
||||
Method = method;
|
||||
Data = stream;
|
||||
switch (method) {
|
||||
case "GET":
|
||||
Method = HttpMethod.Get;
|
||||
break;
|
||||
case "POST":
|
||||
Method = HttpMethod.Post;
|
||||
break;
|
||||
case "DELETE":
|
||||
Method = HttpMethod.Delete;
|
||||
break;
|
||||
case "PUT":
|
||||
Method = HttpMethod.Put;
|
||||
break;
|
||||
case "HEAD":
|
||||
Method = HttpMethod.Head;
|
||||
break;
|
||||
case "TRACE":
|
||||
Method = HttpMethod.Trace;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Body = data;
|
||||
Headers = new List<KeyValuePair<string, string>>(headers ?? Enumerable.Empty<KeyValuePair<string, string>>());
|
||||
|
||||
string useProduction = AVClient.UseProduction ? "1" : "0";
|
||||
Headers.Add(new KeyValuePair<string, string>("X-LC-Prod", useProduction));
|
||||
|
||||
if (!string.IsNullOrEmpty(sessionToken))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(sessionToken)) {
|
||||
Headers.Add(new KeyValuePair<string, string>("X-LC-Session", sessionToken));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(contentType))
|
||||
{
|
||||
Headers.Add(new KeyValuePair<string, string>("Content-Type", contentType));
|
||||
}
|
||||
|
||||
Headers.Add(new KeyValuePair<string, string>("Content-Type", "application/json"));
|
||||
}
|
||||
|
||||
//public AVCommand(string relativeUri,
|
||||
// string method,
|
||||
// string sessionToken = null,
|
||||
// IList<KeyValuePair<string, string>> headers = null,
|
||||
// Stream stream = null,
|
||||
// string contentType = null)
|
||||
//{
|
||||
// var state = AVPlugins.Instance.AppRouterController.Get();
|
||||
// var urlTemplate = "https://{0}/{1}/{2}";
|
||||
// AVClient.Configuration configuration = AVClient.CurrentConfiguration;
|
||||
// var apiVersion = "1.1";
|
||||
// if (relativeUri.StartsWith("push") || relativeUri.StartsWith("installations"))
|
||||
// {
|
||||
// Uri = new Uri(string.Format(urlTemplate, state.PushServer, apiVersion, relativeUri));
|
||||
// if (configuration.PushServer != null)
|
||||
// {
|
||||
// Uri = new Uri(string.Format("{0}{1}/{2}", configuration.PushServer, apiVersion, relativeUri));
|
||||
// }
|
||||
// }
|
||||
// else if (relativeUri.StartsWith("stats") || relativeUri.StartsWith("always_collect") || relativeUri.StartsWith("statistics"))
|
||||
// {
|
||||
// Uri = new Uri(string.Format(urlTemplate, state.StatsServer, apiVersion, relativeUri));
|
||||
// if (configuration.StatsServer != null)
|
||||
// {
|
||||
// Uri = new Uri(string.Format("{0}{1}/{2}", configuration.StatsServer, apiVersion, relativeUri));
|
||||
// }
|
||||
// }
|
||||
// else if (relativeUri.StartsWith("functions") || relativeUri.StartsWith("call"))
|
||||
// {
|
||||
// Uri = new Uri(string.Format(urlTemplate, state.EngineServer, apiVersion, relativeUri));
|
||||
|
||||
// if (configuration.EngineServer != null)
|
||||
// {
|
||||
// Uri = new Uri(string.Format("{0}{1}/{2}", configuration.EngineServer, apiVersion, relativeUri));
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Uri = new Uri(string.Format(urlTemplate, state.ApiServer, apiVersion, relativeUri));
|
||||
|
||||
// if (configuration.ApiServer != null)
|
||||
// {
|
||||
// Uri = new Uri(string.Format("{0}{1}/{2}", configuration.ApiServer, apiVersion, relativeUri));
|
||||
// }
|
||||
// }
|
||||
// Method = method;
|
||||
// Data = stream;
|
||||
// Headers = new List<KeyValuePair<string, string>>(headers ?? Enumerable.Empty<KeyValuePair<string, string>>());
|
||||
|
||||
// string useProduction = AVClient.UseProduction ? "1" : "0";
|
||||
// Headers.Add(new KeyValuePair<string, string>("X-LC-Prod", useProduction));
|
||||
|
||||
// if (!string.IsNullOrEmpty(sessionToken))
|
||||
// {
|
||||
// Headers.Add(new KeyValuePair<string, string>("X-LC-Session", sessionToken));
|
||||
// }
|
||||
// if (!string.IsNullOrEmpty(contentType))
|
||||
// {
|
||||
// Headers.Add(new KeyValuePair<string, string>("Content-Type", contentType));
|
||||
// }
|
||||
//}
|
||||
|
||||
public AVCommand(AVCommand other)
|
||||
{
|
||||
this.Uri = other.Uri;
|
||||
this.Method = other.Method;
|
||||
this.DataObject = other.DataObject;
|
||||
this.Headers = new List<KeyValuePair<string, string>>(other.Headers);
|
||||
this.Data = other.Data;
|
||||
this.Body = other.Data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace LeanCloud.Storage.Internal
|
|||
/// <param name="downloadProgress"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public Task<Tuple<HttpStatusCode, IDictionary<string, object>>> RunCommandAsync(AVCommand command,
|
||||
public Task<Tuple<HttpStatusCode, IDictionary<string, object>>> RunCommandAsync(HttpRequest command,
|
||||
IProgress<AVUploadProgressEventArgs> uploadProgress = null,
|
||||
IProgress<AVDownloadProgressEventArgs> downloadProgress = null,
|
||||
CancellationToken cancellationToken = default(CancellationToken))
|
||||
|
@ -99,11 +99,11 @@ namespace LeanCloud.Storage.Internal
|
|||
}
|
||||
|
||||
private const string revocableSessionTokenTrueValue = "1";
|
||||
private Task<AVCommand> PrepareCommand(AVCommand command)
|
||||
private Task<HttpRequest> PrepareCommand(HttpRequest command)
|
||||
{
|
||||
AVCommand newCommand = new AVCommand(command);
|
||||
HttpRequest newCommand = command;
|
||||
|
||||
Task<AVCommand> installationIdTask = installationIdController.GetAsync().ContinueWith(t =>
|
||||
Task<HttpRequest> installationIdTask = installationIdController.GetAsync().ContinueWith(t =>
|
||||
{
|
||||
newCommand.Headers.Add(new KeyValuePair<string, string>("X-LC-Installation-Id", t.Result.ToString()));
|
||||
return newCommand;
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace LeanCloud.Storage.Internal
|
|||
/// <param name="downloadProgress">Download progress callback.</param>
|
||||
/// <param name="cancellationToken">The cancellation token for the request.</param>
|
||||
/// <returns></returns>
|
||||
Task<Tuple<HttpStatusCode, IDictionary<string, object>>> RunCommandAsync(AVCommand command,
|
||||
Task<Tuple<HttpStatusCode, IDictionary<string, object>>> RunCommandAsync(HttpRequest command,
|
||||
IProgress<AVUploadProgressEventArgs> uploadProgress = null,
|
||||
IProgress<AVDownloadProgressEventArgs> downloadProgress = null,
|
||||
CancellationToken cancellationToken = default(CancellationToken));
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.Threading;
|
|||
using System.Threading.Tasks;
|
||||
using LeanCloud.Storage.Internal;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
|
@ -32,55 +33,36 @@ namespace LeanCloud.Storage.Internal
|
|||
/// <param name="sessionToken">Session token.</param>
|
||||
/// <param name="progress">Progress.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
public virtual Task<FileState> SaveAsync(FileState state,
|
||||
Stream dataStream,
|
||||
String sessionToken,
|
||||
IProgress<AVUploadProgressEventArgs> progress,
|
||||
CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
if (state.Url != null)
|
||||
{
|
||||
public virtual async Task<FileState> SaveAsync(FileState state,
|
||||
Stream dataStream,
|
||||
String sessionToken,
|
||||
IProgress<AVUploadProgressEventArgs> progress,
|
||||
CancellationToken cancellationToken = default(CancellationToken)) {
|
||||
if (state.Url != null) {
|
||||
// !isDirty
|
||||
return Task<FileState>.FromResult(state);
|
||||
return state;
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
var tcs = new TaskCompletionSource<FileState>();
|
||||
tcs.TrySetCanceled();
|
||||
return tcs.Task;
|
||||
if (cancellationToken.IsCancellationRequested) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var oldPosition = dataStream.Position;
|
||||
var command = new AVCommand("files/" + state.Name,
|
||||
method: "POST",
|
||||
sessionToken: sessionToken,
|
||||
contentType: state.MimeType,
|
||||
stream: dataStream);
|
||||
|
||||
return commandRunner.RunCommandAsync(command,
|
||||
uploadProgress: progress,
|
||||
cancellationToken: cancellationToken).OnSuccess(uploadTask =>
|
||||
{
|
||||
var result = uploadTask.Result;
|
||||
var jsonData = result.Item2;
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
return new FileState
|
||||
{
|
||||
Name = jsonData["name"] as string,
|
||||
Url = new Uri(jsonData["url"] as string, UriKind.Absolute),
|
||||
MimeType = state.MimeType
|
||||
};
|
||||
}).ContinueWith(t =>
|
||||
{
|
||||
// Rewind the stream on failure or cancellation (if possible)
|
||||
if ((t.IsFaulted || t.IsCanceled) && dataStream.CanSeek)
|
||||
{
|
||||
dataStream.Seek(oldPosition, SeekOrigin.Begin);
|
||||
}
|
||||
return t;
|
||||
}).Unwrap();
|
||||
var request = new HttpRequest {
|
||||
Uri = new Uri("files/" + state.Name),
|
||||
Method = HttpMethod.Post,
|
||||
Headers = new List<KeyValuePair<string, string>> {
|
||||
new KeyValuePair<string, string>("Content-Type", state.MimeType)
|
||||
}
|
||||
};
|
||||
var ret = await AVPlugins.Instance.HttpClient.ExecuteAsync(request, null, null, CancellationToken.None);
|
||||
var jsonData = Json.Parse(ret.Item2) as Dictionary<string, object>;
|
||||
return new FileState {
|
||||
Name = jsonData["name"] as string,
|
||||
Url = new Uri(jsonData["url"] as string, UriKind.Absolute),
|
||||
MimeType = state.MimeType
|
||||
};
|
||||
}
|
||||
public Task DeleteAsync(FileState state, string sessionToken, CancellationToken cancellationToken)
|
||||
{
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.Threading;
|
|||
using System.IO;
|
||||
using LeanCloud.Storage.Internal;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace LeanCloud.Storage.Internal
|
||||
{
|
||||
|
@ -40,15 +41,18 @@ namespace LeanCloud.Storage.Internal
|
|||
});
|
||||
}
|
||||
|
||||
internal Task<FileState> PutFile(FileState state, string uploadUrl, Stream dataStream)
|
||||
internal async Task<FileState> PutFile(FileState state, string uploadUrl, Stream dataStream)
|
||||
{
|
||||
IList<KeyValuePair<string, string>> makeBlockHeaders = new List<KeyValuePair<string, string>>();
|
||||
makeBlockHeaders.Add(new KeyValuePair<string, string>("Content-Type", state.MimeType));
|
||||
|
||||
return AVClient.RequestAsync(new Uri(uploadUrl), "PUT", makeBlockHeaders, dataStream, state.MimeType, CancellationToken.None).OnSuccess(t =>
|
||||
{
|
||||
return state;
|
||||
});
|
||||
var request = new HttpRequest {
|
||||
Uri = new Uri(uploadUrl),
|
||||
Method = HttpMethod.Put,
|
||||
Headers = makeBlockHeaders,
|
||||
Data = dataStream
|
||||
};
|
||||
await AVPlugins.Instance.HttpClient.ExecuteAsync(request, null, null, CancellationToken.None);
|
||||
return state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -159,7 +160,7 @@ namespace LeanCloud.Storage.Internal
|
|||
|
||||
return HexStringFromBytes(hashBytes);
|
||||
}
|
||||
Task<Tuple<HttpStatusCode, IDictionary<string, object>>> PostToQCloud(
|
||||
async Task<Tuple<HttpStatusCode, IDictionary<string, object>>> PostToQCloud(
|
||||
Dictionary<string, object> body,
|
||||
byte[] sliceFile,
|
||||
CancellationToken cancellationToken)
|
||||
|
@ -174,14 +175,15 @@ namespace LeanCloud.Storage.Internal
|
|||
|
||||
sliceHeaders.Add(new KeyValuePair<string, string>("Content-Type", contentType));
|
||||
|
||||
var rtn = AVClient.RequestAsync(new Uri(this.uploadUrl), "POST", sliceHeaders, tempStream, null, cancellationToken).OnSuccess(_ =>
|
||||
{
|
||||
var dic = AVClient.ReponseResolve(_.Result, CancellationToken.None);
|
||||
|
||||
return dic;
|
||||
});
|
||||
|
||||
return rtn;
|
||||
var request = new HttpRequest {
|
||||
Uri = new Uri(this.uploadUrl),
|
||||
Method = HttpMethod.Post,
|
||||
Headers = sliceHeaders,
|
||||
Data = tempStream
|
||||
};
|
||||
var ret = await AVPlugins.Instance.HttpClient.ExecuteAsync(request, null, null, CancellationToken.None);
|
||||
var result = new Tuple<HttpStatusCode, IDictionary<string, object>>(ret.Item1, Json.Parse(ret.Item2) as Dictionary<string, object>);
|
||||
return result;
|
||||
}
|
||||
public static Stream HttpUploadFile(byte[] file, string fileName, out string contentType, out long contentLength, IDictionary<string, object> nvc)
|
||||
{
|
||||
|
|
|
@ -6,6 +6,7 @@ using System.Net;
|
|||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace LeanCloud.Storage.Internal
|
||||
{
|
||||
|
@ -173,20 +174,32 @@ namespace LeanCloud.Storage.Internal
|
|||
return makeBlockHeaders;
|
||||
}
|
||||
|
||||
Task<Tuple<HttpStatusCode, string>> MakeBlock(FileState state, byte[] firstChunkBinary, long blcokSize = 4194304)
|
||||
{
|
||||
async Task<Tuple<HttpStatusCode, string>> MakeBlock(FileState state, byte[] firstChunkBinary, long blcokSize = 4194304) {
|
||||
MemoryStream firstChunkData = new MemoryStream(firstChunkBinary, 0, firstChunkBinary.Length);
|
||||
return AVClient.RequestAsync(new Uri(new Uri(UP_HOST) + string.Format("mkblk/{0}", blcokSize)), "POST", GetQiniuRequestHeaders(state), firstChunkData, "application/octet-stream", CancellationToken.None);
|
||||
var headers = GetQiniuRequestHeaders(state);
|
||||
headers.Add(new KeyValuePair<string, string>("Content-Type", "application/octet-stream"));
|
||||
var request = new HttpRequest {
|
||||
Uri = new Uri(new Uri(UP_HOST) + string.Format("mkblk/{0}", blcokSize)),
|
||||
Method = HttpMethod.Post,
|
||||
Headers = headers,
|
||||
Data = firstChunkData
|
||||
};
|
||||
return await AVPlugins.Instance.HttpClient.ExecuteAsync(request, null, null, CancellationToken.None);
|
||||
}
|
||||
Task<Tuple<HttpStatusCode, string>> PutChunk(FileState state, byte[] chunkBinary, string LastChunkctx, long currentChunkOffsetInBlock)
|
||||
{
|
||||
|
||||
async Task<Tuple<HttpStatusCode, string>> PutChunk(FileState state, byte[] chunkBinary, string LastChunkctx, long currentChunkOffsetInBlock) {
|
||||
MemoryStream chunkData = new MemoryStream(chunkBinary, 0, chunkBinary.Length);
|
||||
return AVClient.RequestAsync(new Uri(new Uri(UP_HOST) + string.Format("bput/{0}/{1}", LastChunkctx,
|
||||
currentChunkOffsetInBlock)), "POST",
|
||||
GetQiniuRequestHeaders(state), chunkData,
|
||||
"application/octet-stream", CancellationToken.None);
|
||||
var request = new HttpRequest {
|
||||
Uri = new Uri(new Uri(UP_HOST) + string.Format("bput/{0}/{1}", LastChunkctx, currentChunkOffsetInBlock)),
|
||||
Method = HttpMethod.Post,
|
||||
Headers = GetQiniuRequestHeaders(state),
|
||||
Data = chunkData
|
||||
};
|
||||
var ret = await AVPlugins.Instance.HttpClient.ExecuteAsync(request, null, null, CancellationToken.None);
|
||||
return ret;
|
||||
}
|
||||
internal Task<Tuple<HttpStatusCode, string>> QiniuMakeFile(FileState state, Stream dataStream, string upToken, string key, long fsize, string[] ctxes, CancellationToken cancellationToken)
|
||||
|
||||
internal async Task<Tuple<HttpStatusCode, string>> QiniuMakeFile(FileState state, Stream dataStream, string upToken, string key, long fsize, string[] ctxes, CancellationToken cancellationToken)
|
||||
{
|
||||
StringBuilder urlBuilder = new StringBuilder();
|
||||
urlBuilder.AppendFormat("{0}/mkfile/{1}", UP_HOST, fsize);
|
||||
|
@ -208,6 +221,7 @@ namespace LeanCloud.Storage.Internal
|
|||
|
||||
string authHead = "UpToken " + upToken;
|
||||
headers.Add(new KeyValuePair<string, string>("Authorization", authHead));
|
||||
headers.Add(new KeyValuePair<string, string>("Content-Type", "text/plain"));
|
||||
int proCount = ctxes.Length;
|
||||
Stream body = new MemoryStream();
|
||||
|
||||
|
@ -221,13 +235,14 @@ namespace LeanCloud.Storage.Internal
|
|||
}
|
||||
}
|
||||
body.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
var rtn = AVClient.RequestAsync(new Uri(urlBuilder.ToString()), "POST", headers, body, "text/plain", cancellationToken).OnSuccess(_ =>
|
||||
{
|
||||
var dic = AVClient.ReponseResolve(_.Result, CancellationToken.None);
|
||||
return _.Result;
|
||||
});
|
||||
return rtn;
|
||||
var request = new HttpRequest {
|
||||
Uri = new Uri(urlBuilder.ToString()),
|
||||
Method = HttpMethod.Post,
|
||||
Headers = headers,
|
||||
Data = body
|
||||
};
|
||||
var ret = await AVPlugins.Instance.HttpClient.ExecuteAsync(request, null, null, CancellationToken.None);
|
||||
return ret;
|
||||
}
|
||||
internal void MergeFromJSON(FileState state, IDictionary<string, object> jsonData)
|
||||
{
|
||||
|
|
|
@ -41,18 +41,17 @@ namespace LeanCloud.Storage.Internal {
|
|||
IProgress<AVUploadProgressEventArgs> uploadProgress,
|
||||
IProgress<AVDownloadProgressEventArgs> downloadProgress,
|
||||
CancellationToken cancellationToken) {
|
||||
|
||||
HttpMethod httpMethod = new HttpMethod(httpRequest.Method);
|
||||
|
||||
HttpMethod httpMethod = httpRequest.Method;
|
||||
HttpRequestMessage message = new HttpRequestMessage(httpMethod, httpRequest.Uri);
|
||||
|
||||
// Fill in zero-length data if method is post.
|
||||
Stream data = httpRequest.Data;
|
||||
if (httpRequest.Data == null && httpRequest.Method.ToLower().Equals("post")) {
|
||||
data = new MemoryStream(new byte[0]);
|
||||
if (httpRequest.Data == null && httpRequest.Method == HttpMethod.Post) {
|
||||
message.Content = new StreamContent(new MemoryStream(new byte[0]));
|
||||
}
|
||||
|
||||
if (data != null) {
|
||||
message.Content = new StreamContent(data);
|
||||
if (httpRequest.Data != null) {
|
||||
message.Content = new StreamContent(httpRequest.Data);
|
||||
}
|
||||
|
||||
if (httpRequest.Headers != null) {
|
||||
|
@ -74,6 +73,7 @@ namespace LeanCloud.Storage.Internal {
|
|||
uploadProgress?.Report(new AVUploadProgressEventArgs { Progress = 0 });
|
||||
var response = await client.SendAsync(message, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
|
||||
uploadProgress?.Report(new AVUploadProgressEventArgs { Progress = 1 });
|
||||
message.Dispose();
|
||||
|
||||
var resultString = await response.Content.ReadAsStringAsync();
|
||||
response.Dispose();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace LeanCloud.Storage.Internal
|
||||
{
|
||||
|
@ -10,16 +11,12 @@ namespace LeanCloud.Storage.Internal
|
|||
public class HttpRequest
|
||||
{
|
||||
public Uri Uri { get; set; }
|
||||
|
||||
public IList<KeyValuePair<string, string>> Headers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Data stream to be uploaded.
|
||||
/// </summary>
|
||||
public virtual Stream Data { get; set; }
|
||||
// HttpMethod
|
||||
public HttpMethod Method { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// HTTP method. One of <c>DELETE</c>, <c>GET</c>, <c>HEAD</c>, <c>POST</c> or <c>PUT</c>
|
||||
/// </summary>
|
||||
public string Method { get; set; }
|
||||
public virtual Stream Data { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace LeanCloud
|
|||
/// AVClient contains static functions that handle global
|
||||
/// configuration for the LeanCloud library.
|
||||
/// </summary>
|
||||
public static partial class AVClient
|
||||
public static class AVClient
|
||||
{
|
||||
public static readonly string[] DateFormatStrings = {
|
||||
// Official ISO format
|
||||
|
@ -367,37 +367,37 @@ namespace LeanCloud
|
|||
return Json.Encode(jsonData);
|
||||
}
|
||||
|
||||
public static Task<Tuple<HttpStatusCode, string>> HttpGetAsync(Uri uri)
|
||||
{
|
||||
return RequestAsync(uri, "GET", null, body: null, contentType: null, cancellationToken: CancellationToken.None);
|
||||
}
|
||||
//public static Task<Tuple<HttpStatusCode, string>> HttpGetAsync(Uri uri)
|
||||
//{
|
||||
// return RequestAsync(uri, "GET", null, body: null, contentType: null, cancellationToken: CancellationToken.None);
|
||||
//}
|
||||
|
||||
public static Task<Tuple<HttpStatusCode, string>> RequestAsync(Uri uri, string method, IList<KeyValuePair<string, string>> headers, IDictionary<string, object> body, string contentType, CancellationToken cancellationToken)
|
||||
{
|
||||
var dataStream = body != null ? new MemoryStream(Encoding.UTF8.GetBytes(Json.Encode(body))) : null;
|
||||
return AVClient.RequestAsync(uri, method, headers, dataStream, contentType, cancellationToken);
|
||||
//return AVPlugins.Instance.HttpClient.ExecuteAsync(request, null, null, cancellationToken);
|
||||
}
|
||||
//public static Task<Tuple<HttpStatusCode, string>> RequestAsync(Uri uri, string method, IList<KeyValuePair<string, string>> headers, IDictionary<string, object> body, string contentType, CancellationToken cancellationToken)
|
||||
//{
|
||||
// var dataStream = body != null ? new MemoryStream(Encoding.UTF8.GetBytes(Json.Encode(body))) : null;
|
||||
// return AVClient.RequestAsync(uri, method, headers, dataStream, contentType, cancellationToken);
|
||||
// //return AVPlugins.Instance.HttpClient.ExecuteAsync(request, null, null, cancellationToken);
|
||||
//}
|
||||
|
||||
public static Task<Tuple<HttpStatusCode, string>> RequestAsync(Uri uri, string method, IList<KeyValuePair<string, string>> headers, Stream data, string contentType, CancellationToken cancellationToken)
|
||||
{
|
||||
HttpRequest request = new HttpRequest()
|
||||
{
|
||||
Data = data != null ? data : null,
|
||||
Headers = headers,
|
||||
Method = method,
|
||||
Uri = uri
|
||||
};
|
||||
return AVPlugins.Instance.HttpClient.ExecuteAsync(request, null, null, cancellationToken).OnSuccess(t =>
|
||||
{
|
||||
var response = t.Result;
|
||||
var contentString = response.Item2;
|
||||
int responseCode = (int)response.Item1;
|
||||
var responseLog = responseCode + ";" + contentString;
|
||||
PrintLog(responseLog);
|
||||
return response;
|
||||
});
|
||||
}
|
||||
//public static Task<Tuple<HttpStatusCode, string>> RequestAsync(Uri uri, string method, IList<KeyValuePair<string, string>> headers, Stream data, string contentType, CancellationToken cancellationToken)
|
||||
//{
|
||||
// HttpRequest request = new HttpRequest()
|
||||
// {
|
||||
// Data = data != null ? data : null,
|
||||
// Headers = headers,
|
||||
// Method = method,
|
||||
// Uri = uri
|
||||
// };
|
||||
// return AVPlugins.Instance.HttpClient.ExecuteAsync(request, null, null, cancellationToken).OnSuccess(t =>
|
||||
// {
|
||||
// var response = t.Result;
|
||||
// var contentString = response.Item2;
|
||||
// int responseCode = (int)response.Item1;
|
||||
// var responseLog = responseCode + ";" + contentString;
|
||||
// PrintLog(responseLog);
|
||||
// return response;
|
||||
// });
|
||||
//}
|
||||
|
||||
internal static Tuple<HttpStatusCode, IDictionary<string, object>> ReponseResolve(Tuple<HttpStatusCode, string> response, CancellationToken cancellationToken)
|
||||
{
|
||||
|
@ -477,21 +477,8 @@ namespace LeanCloud
|
|||
|
||||
try
|
||||
{
|
||||
if (request is AVCommand)
|
||||
{
|
||||
var command = (AVCommand)request;
|
||||
if (command.DataObject != null)
|
||||
{
|
||||
var bodyLog = "Body:" + Json.Encode(command.DataObject);
|
||||
sb.AppendLine(bodyLog);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
StreamReader reader = new StreamReader(request.Data);
|
||||
string bodyLog = reader.ReadToEnd();
|
||||
sb.AppendLine(bodyLog);
|
||||
}
|
||||
var bodyLog = "Body:" + Json.Encode(request.Data);
|
||||
sb.AppendLine(bodyLog);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
|
|
@ -211,9 +211,7 @@ namespace LeanCloud {
|
|||
if (overwrite) {
|
||||
path = string.Format("{0}?overwrite=1", path);
|
||||
}
|
||||
var dataStr = Json.Encode(data);
|
||||
var dataStream = new MemoryStream(Encoding.UTF8.GetBytes(dataStr));
|
||||
var command = new AVCommand(path, "POST", contentType: "application/json", sessionToken: user.SessionToken, stream: dataStream);
|
||||
var command = new AVCommand(path, "POST", user.SessionToken, data: data);
|
||||
return AVPlugins.Instance.CommandRunner.RunCommandAsync(command).OnSuccess(t => {
|
||||
try {
|
||||
List<AVStatistic> statisticList = new List<AVStatistic>();
|
||||
|
|
Loading…
Reference in New Issue