protected virtual void ApiAsync(HttpMethod httpMethod, string path, object parameters, Type resultType, object userState) { Stream input; bool containsEtag; IList<int> batchEtags = null; var httpHelper = PrepareRequest(httpMethod, path, parameters, resultType, out input, out containsEtag, out batchEtags); _httpWebRequest = httpHelper.HttpWebRequest; #if FLUENTHTTP_CORE_TPL if (HttpWebRequestWrapperCreated != null) HttpWebRequestWrapperCreated(this, new HttpWebRequestCreatedEventArgs(userState, httpHelper.HttpWebRequest)); #endif var uploadProgressChanged = UploadProgressChanged; bool notifyUploadProgressChanged = uploadProgressChanged != null && httpHelper.HttpWebRequest.Method == "POST"; httpHelper.OpenReadCompleted += (o, e) => { FuntownApiEventArgs args; if (e.Cancelled) { args = new FuntownApiEventArgs(e.Error, true, userState, null); } else if (e.Error == null) { string responseString = null; try { using (var stream = e.Result) { #if NETFX_CORE bool compressed = false; var contentEncoding = httpHelper.HttpWebResponse.Headers.AllKeys.Contains("Content-Encoding") ? httpHelper.HttpWebResponse.Headers["Content-Encoding"] : null; if (contentEncoding != null) { if (contentEncoding.IndexOf("gzip") != -1) { using (var uncompressedStream = new System.IO.Compression.GZipStream(stream, System.IO.Compression.CompressionMode.Decompress)) { using (var reader = new StreamReader(uncompressedStream)) { responseString = reader.ReadToEnd(); } } compressed = true; } else if (contentEncoding.IndexOf("deflate") != -1) { using (var uncompressedStream = new System.IO.Compression.DeflateStream(stream, System.IO.Compression.CompressionMode.Decompress)) { using (var reader = new StreamReader(uncompressedStream)) { responseString = reader.ReadToEnd(); } } compressed = true; } } if (!compressed) { using (var reader = new StreamReader(stream)) { responseString = reader.ReadToEnd(); } } #else var response = httpHelper.HttpWebResponse; if (response != null && response.StatusCode == HttpStatusCode.NotModified) { var jsonObject = new JsonObject(); var headers = new JsonObject(); foreach (var headerName in response.Headers.AllKeys) headers[headerName] = response.Headers[headerName]; jsonObject["headers"] = headers; args = new FuntownApiEventArgs(null, false, userState, jsonObject); OnCompleted(httpMethod, args); return; } using (var reader = new StreamReader(stream)) { responseString = reader.ReadToEnd(); } #endif } try { object result = ProcessResponse(httpHelper, responseString, resultType, containsEtag, batchEtags); args = new FuntownApiEventArgs(null, false, userState, result); } catch (Exception ex) { args = new FuntownApiEventArgs(ex, false, userState, null); } } catch (Exception ex) { args = httpHelper.HttpWebRequest.IsCancelled ? new FuntownApiEventArgs(ex, true, userState, null) : new FuntownApiEventArgs(ex, false, userState, null); } } else { var webEx = e.Error as WebExceptionWrapper; if (webEx == null) { args = new FuntownApiEventArgs(e.Error, httpHelper.HttpWebRequest.IsCancelled, userState, null); } else { if (webEx.GetResponse() == null) { args = new FuntownApiEventArgs(webEx, false, userState, null); } else { var response = httpHelper.HttpWebResponse; if (response.StatusCode == HttpStatusCode.NotModified) { var jsonObject = new JsonObject(); var headers = new JsonObject(); foreach (var headerName in response.Headers.AllKeys) headers[headerName] = response.Headers[headerName]; jsonObject["headers"] = headers; args = new FuntownApiEventArgs(null, false, userState, jsonObject); } else { httpHelper.OpenReadAsync(); return; } } } } OnCompleted(httpMethod, args); }; if (input == null) { httpHelper.OpenReadAsync(); } else { // we have a request body so write httpHelper.OpenWriteCompleted += (o, e) => { FuntownApiEventArgs args; if (e.Cancelled) { input.Dispose(); args = new FuntownApiEventArgs(e.Error, true, userState, null); } else if (e.Error == null) { try { using (var stream = e.Result) { // write input to requestStream var buffer = new byte[BufferSize]; int nread; if (notifyUploadProgressChanged) { long totalBytesToSend = input.Length; long bytesSent = 0; while ((nread = input.Read(buffer, 0, buffer.Length)) != 0) { stream.Write(buffer, 0, nread); stream.Flush(); // notify upload progress changed bytesSent += nread; OnUploadProgressChanged(new FuntownUploadProgressChangedEventArgs(0, 0, bytesSent, totalBytesToSend, ((int)(bytesSent * 100 / totalBytesToSend)), userState)); } } else { while ((nread = input.Read(buffer, 0, buffer.Length)) != 0) { stream.Write(buffer, 0, nread); stream.Flush(); } } } httpHelper.OpenReadAsync(); return; } catch (Exception ex) { args = new FuntownApiEventArgs(ex, httpHelper.HttpWebRequest.IsCancelled, userState, null); } finally { input.Dispose(); } } else { input.Dispose(); var webExceptionWrapper = e.Error as WebExceptionWrapper; if (webExceptionWrapper != null) { var ex = webExceptionWrapper; if (ex.GetResponse() != null) { httpHelper.OpenReadAsync(); return; } } args = new FuntownApiEventArgs(e.Error, false, userState, null); } OnCompleted(httpMethod, args); }; httpHelper.OpenWriteAsync(); } }
protected virtual void OnDeleteCompleted(FuntownApiEventArgs args) { if (DeleteCompleted != null) DeleteCompleted(this, args); }
private void OnCompleted(HttpMethod httpMethod, FuntownApiEventArgs args) { switch (httpMethod) { case HttpMethod.Get: OnGetCompleted(args); break; case HttpMethod.Post: OnPostCompleted(args); break; case HttpMethod.Delete: OnDeleteCompleted(args); break; default: throw new ArgumentOutOfRangeException("httpMethod"); } }
protected virtual void OnPostCompleted(FuntownApiEventArgs args) { if (PostCompleted != null) PostCompleted(this, args); }