/// <summary> /// Invoke the specified method against the server /// </summary> /// <typeparam name="TBody">The type of <paramref name="body"/></typeparam> /// <typeparam name="TResult">The expected response type from the server</typeparam> /// <param name="method">The HTTP method to be executed</param> /// <param name="url">The resource URL to be executed against</param> /// <param name="contentType">The content/type of <paramref name="body"/></param> /// <param name="body">The contents of the request to send to the server</param> /// <param name="query">The query to append to the URL</param> /// <returns>The server response</returns> public TResult Invoke <TBody, TResult>(string method, string url, string contentType, TBody body, params KeyValuePair <string, object>[] query) { NameValueCollection parameters = new NameValueCollection(); try { if (query != null) { parameters = new NameValueCollection(query); } var requestEventArgs = new RestRequestEventArgs(method, url, parameters, contentType, body); this.Requesting?.Invoke(this, requestEventArgs); if (requestEventArgs.Cancel) { s_tracer.TraceVerbose("HTTP request cancelled"); return(default(TResult)); } // Invoke WebHeaderCollection responseHeaders = null; var retVal = this.InvokeInternal <TBody, TResult>(requestEventArgs.Method, requestEventArgs.Url, requestEventArgs.ContentType, requestEventArgs.AdditionalHeaders, out responseHeaders, body, requestEventArgs.Query); this.Responded?.Invoke(this, new RestResponseEventArgs(requestEventArgs.Method, requestEventArgs.Url, requestEventArgs.Query, requestEventArgs.ContentType, retVal, 200, 0, this.ConvertHeaders(responseHeaders))); return(retVal); } catch (Exception e) { s_tracer.TraceError("Error invoking HTTP: {0}", e.Message); this.Responded?.Invoke(this, new RestResponseEventArgs(method, url, parameters, contentType, null, 500, 0, null)); throw; } }
/// <summary> /// Patches the specified resource at <paramref name="url"/> with <paramref name="patch"/> when <paramref name="ifMatch"/> is true /// </summary> /// <param name="url">The resource URL to patch</param> /// <param name="contentType">The content/type of the patch (dictates serialization)</param> /// <param name="ifMatch">Identifies the If-Match header</param> /// <param name="patch">The patch contents</param> /// <returns>The new ETAG of the patched resource</returns> public String Patch <TPatch>(string url, string contentType, String ifMatch, TPatch patch) { try { var requestEventArgs = new RestRequestEventArgs("PATCH", url, null, contentType, patch); this.Requesting?.Invoke(this, requestEventArgs); if (requestEventArgs.Cancel) { s_tracer.TraceVerbose("HTTP request cancelled"); return(null); } WebHeaderCollection requestHeaders = requestEventArgs.AdditionalHeaders ?? new WebHeaderCollection(), responseHeaders = null; requestHeaders[HttpRequestHeader.IfMatch] = ifMatch; // Invoke this.InvokeInternal <TPatch, Object>("PATCH", url, contentType, requestHeaders, out responseHeaders, patch, null); // Return the ETag of the return(responseHeaders["ETag"]); } catch (Exception e) { s_tracer.TraceError("Error invoking HTTP: {0}", e.Message); this.Responded?.Invoke(this, new RestResponseEventArgs("PATCH", url, null, contentType, null, 500, 0, null)); throw; } }
/// <summary> /// Perform a head operation against the specified url /// </summary> /// <param name="query">The query to execute</param> /// <param name="resourceName">The name of the resource (url)</param> /// <returns>The HTTP headers (result of the HEAD operation)</returns> public IDictionary <string, string> Head(string resourceName, params KeyValuePair <String, Object>[] query) { NameValueCollection parameters = new NameValueCollection(); try { if (query != null) { parameters = new NameValueCollection(query); } var requestEventArgs = new RestRequestEventArgs("HEAD", resourceName, parameters, null, null); this.Requesting?.Invoke(this, requestEventArgs); if (requestEventArgs.Cancel) { s_tracer.TraceVerbose("HTTP request cancelled"); return(null); } // Invoke var httpWebReq = this.CreateHttpRequest(resourceName, requestEventArgs.Query); httpWebReq.Method = "HEAD"; // Get the responst Dictionary <String, String> retVal = new Dictionary <string, string>(); Exception fault = null; var httpTask = httpWebReq.GetResponseAsync().ContinueWith(o => { if (o.IsFaulted) { fault = o.Exception.InnerExceptions.First(); } else { this.Responding?.Invoke(this, new RestResponseEventArgs("HEAD", resourceName, parameters, null, null, 200, o.Result.ContentLength, this.ConvertHeaders(o.Result.Headers))); foreach (var itm in o.Result.Headers.AllKeys) { retVal.Add(itm, o.Result.Headers[itm]); } } }, TaskContinuationOptions.LongRunning); httpTask.Wait(); if (fault != null) { throw fault; } this.Responded?.Invoke(this, new RestResponseEventArgs("HEAD", resourceName, parameters, null, null, 200, 0, retVal)); return(retVal); } catch (Exception e) { s_tracer.TraceError("Error invoking HTTP: {0}", e.Message); this.Responded?.Invoke(this, new RestResponseEventArgs("HEAD", resourceName, parameters, null, null, 500, 0, null)); throw; } }
/// <summary> /// Retrieves a raw byte array of data from the specified location /// </summary> /// <param name="url">The resource URL to fetch from the server</param> /// <param name="query">The query (as key=value) to send on the GET request</param> public byte[] Get(String url, params KeyValuePair <string, object>[] query) { NameValueCollection parameters = new NameValueCollection(); try { var requestEventArgs = new RestRequestEventArgs("GET", url, new NameValueCollection(query), null, null); this.Requesting?.Invoke(this, requestEventArgs); if (requestEventArgs.Cancel) { s_tracer.TraceVerbose("HTTP request cancelled"); return(null); } // Invoke var httpWebReq = this.CreateHttpRequest(url, requestEventArgs.Query); httpWebReq.Method = "GET"; // Get the responst byte[] retVal = null; WebHeaderCollection headers = null; Exception requestException = null; var httpTask = httpWebReq.GetResponseAsync().ContinueWith(o => { if (o.IsFaulted) { requestException = o.Exception.InnerExceptions.First(); } else { try { headers = o.Result.Headers; this.Responding?.Invoke(this, new RestResponseEventArgs("GET", url, requestEventArgs.Query, o.Result.ContentType, null, 200, o.Result.ContentLength, this.ConvertHeaders(headers))); byte[] buffer = new byte[2048]; int br = 1; using (var ms = new MemoryStream()) using (var httpStream = o.Result.GetResponseStream()) { while (br > 0) { br = httpStream.Read(buffer, 0, 2048); ms.Write(buffer, 0, br); // Raise event this.FireProgressChanged(o.Result.ContentType, ms.Length / (float)o.Result.ContentLength); } ms.Seek(0, SeekOrigin.Begin); switch (o.Result.Headers["Content-Encoding"]) { case "deflate": using (var dfs = new DeflateStream(new NonDisposingStream(ms), CompressionMode.Decompress)) using (var oms = new MemoryStream()) { dfs.CopyTo(oms); retVal = oms.ToArray(); } break; case "gzip": using (var gzs = new GZipStream(new NonDisposingStream(ms), CompressionMode.Decompress)) using (var oms = new MemoryStream()) { gzs.CopyTo(oms); retVal = oms.ToArray(); } break; case "bzip2": using (var lzmas = new BZip2Stream(new NonDisposingStream(ms), CompressionMode.Decompress, false)) using (var oms = new MemoryStream()) { lzmas.CopyTo(oms); retVal = oms.ToArray(); } break; case "lzma": using (var lzmas = new LZipStream(new NonDisposingStream(ms), CompressionMode.Decompress)) using (var oms = new MemoryStream()) { lzmas.CopyTo(oms); retVal = oms.ToArray(); } break; default: retVal = ms.ToArray(); break; } } } catch (Exception e) { s_tracer.TraceError("Error downloading {0}: {1}", url, e.Message); } } }, TaskContinuationOptions.LongRunning); httpTask.Wait(); if (requestException != null) { throw requestException; } this.Responded?.Invoke(this, new RestResponseEventArgs("GET", url, null, null, null, 200, 0, this.ConvertHeaders(headers))); return(retVal); } catch (WebException e) { throw new RestClientException <byte[]>( null, e, e.Status, e.Response); } catch (Exception e) { s_tracer.TraceError("Error invoking HTTP: {0}", e.Message); this.Responded?.Invoke(this, new RestResponseEventArgs("GET", url, null, null, null, 500, 0, null)); throw; } }