public ParseCommand(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 : data != null ? new MemoryStream(UTF8Encoding.UTF8.GetBytes(Json.Encode(data))) : null, contentType : data != null ? "application/json" : null) { }
public Task <Tuple <HttpStatusCode, string> > ExecuteAsync(HttpRequest httpRequest, IProgress <ParseUploadProgressEventArgs> uploadProgress, IProgress <ParseDownloadProgressEventArgs> downloadProgress, CancellationToken cancellationToken) { var tcs = new TaskCompletionSource <Tuple <HttpStatusCode, string> >(); cancellationToken.Register(() => tcs.TrySetCanceled()); uploadProgress = uploadProgress ?? new Progress <ParseUploadProgressEventArgs>(); downloadProgress = downloadProgress ?? new Progress <ParseDownloadProgressEventArgs>(); var headerTable = new Hashtable(); // Fill in the headers if (httpRequest.Headers != null) { foreach (var pair in httpRequest.Headers) { headerTable[pair.Key] = pair.Value; } } // Explicitly assume a JSON content. if (!headerTable.ContainsKey("Content-Type")) { headerTable["Content-Type"] = "application/json"; } Task readBytesTask = null; IDisposable toDisposeAfterReading = null; byte[] bytes = null; if (!httpRequest.Method.Equals("POST") || httpRequest.Data == null) { bool noBody = httpRequest.Data == null; Stream data = httpRequest.Data ?? new MemoryStream(UTF8Encoding.UTF8.GetBytes("{}")); var reader = new StreamReader(data); toDisposeAfterReading = reader; Task <string> streamReaderTask; if (PlatformHooks.IsCompiledByIL2CPP) { streamReaderTask = Task.FromResult(reader.ReadToEnd()); } else { streamReaderTask = reader.ReadToEndAsync(); } readBytesTask = streamReaderTask.OnSuccess(t => { var parsed = Json.Parse(t.Result) as IDictionary <string, object>; // Inject the method parsed["_method"] = httpRequest.Method; parsed["_noBody"] = noBody; bytes = UTF8Encoding.UTF8.GetBytes(Json.Encode(parsed)); }); } else { var ms = new MemoryStream(); toDisposeAfterReading = ms; readBytesTask = httpRequest.Data.CopyToAsync(ms).OnSuccess(_ => { bytes = ms.ToArray(); }); } readBytesTask.Safe().ContinueWith(t => { if (toDisposeAfterReading != null) { toDisposeAfterReading.Dispose(); } return(t); }).Unwrap() .OnSuccess(_ => { float oldDownloadProgress = 0; float oldUploadProgress = 0; PlatformHooks.RunOnMainThread(() => { PlatformHooks.RegisterNetworkRequest(GenerateWWWInstance(httpRequest.Uri.AbsoluteUri, bytes, headerTable), www => { if (cancellationToken.IsCancellationRequested) { tcs.TrySetCanceled(); return; } if (www.isDone) { uploadProgress.Report(new ParseUploadProgressEventArgs { Progress = 1 }); downloadProgress.Report(new ParseDownloadProgressEventArgs { Progress = 1 }); var statusCode = GetStatusCode(www); // Returns HTTP error if that's the only info we have. if (!String.IsNullOrEmpty(www.error) && String.IsNullOrEmpty(www.text)) { var errorString = string.Format("{{\"error\":\"{0}\"}}", www.error); tcs.TrySetResult(new Tuple <HttpStatusCode, string>(statusCode, errorString)); } else { tcs.TrySetResult(new Tuple <HttpStatusCode, string>(statusCode, www.text)); } } else { // Update upload progress var newUploadProgress = www.uploadProgress; if (oldUploadProgress < newUploadProgress) { uploadProgress.Report(new ParseUploadProgressEventArgs { Progress = newUploadProgress }); } oldUploadProgress = newUploadProgress; // Update download progress var newDownloadProgress = www.progress; if (oldDownloadProgress < newDownloadProgress) { downloadProgress.Report(new ParseDownloadProgressEventArgs { Progress = newDownloadProgress }); } oldDownloadProgress = newDownloadProgress; } }); }); }); // Get off of the main thread for further processing. return(tcs.Task.ContinueWith(t => { var dispatchTcs = new TaskCompletionSource <object>(); // ThreadPool doesn't work well in IL2CPP environment, but Thread does! if (PlatformHooks.IsCompiledByIL2CPP) { var thread = new Thread(_ => { dispatchTcs.TrySetResult(null); }); thread.Start(); } else { ThreadPool.QueueUserWorkItem(_ => dispatchTcs.TrySetResult(null)); } return dispatchTcs.Task; }).Unwrap() .ContinueWith(_ => tcs.Task).Unwrap()); }