diff --git a/RestSharp/Enum.cs b/RestSharp/Enum.cs
index ad62429e3..942dac2e3 100644
--- a/RestSharp/Enum.cs
+++ b/RestSharp/Enum.cs
@@ -49,7 +49,8 @@ public enum Method
DELETE,
HEAD,
OPTIONS,
- PATCH
+ PATCH,
+ MERGE,
}
///
diff --git a/RestSharp/Http.Async.cs b/RestSharp/Http.Async.cs
index 9d1c5f867..4ccc7ed11 100644
--- a/RestSharp/Http.Async.cs
+++ b/RestSharp/Http.Async.cs
@@ -31,425 +31,430 @@
#if (FRAMEWORK && !MONOTOUCH && !MONODROID && !PocketPC)
using System.Web;
-#endif
-
-namespace RestSharp
-{
- ///
- /// HttpWebRequest wrapper (async methods)
- ///
- public partial class Http
- {
- private TimeOutState _timeoutState;
-
- public HttpWebRequest DeleteAsync(Action action)
- {
- return GetStyleMethodInternalAsync("DELETE", action);
- }
-
- public HttpWebRequest GetAsync(Action action)
- {
- return GetStyleMethodInternalAsync("GET", action);
- }
-
- public HttpWebRequest HeadAsync(Action action)
- {
- return GetStyleMethodInternalAsync("HEAD", action);
- }
-
- public HttpWebRequest OptionsAsync(Action action)
- {
- return GetStyleMethodInternalAsync("OPTIONS", action);
- }
-
- public HttpWebRequest PostAsync(Action action)
- {
- return PutPostInternalAsync("POST", action);
- }
-
- public HttpWebRequest PutAsync(Action action)
- {
- return PutPostInternalAsync("PUT", action);
- }
-
- public HttpWebRequest PatchAsync(Action action)
- {
- return PutPostInternalAsync("PATCH", action);
- }
-
- ///
- /// Execute an async POST-style request with the specified HTTP Method.
- ///
- /// The HTTP method to execute.
- ///
- public HttpWebRequest AsPostAsync(Action action, string httpMethod)
- {
+#endif
+
+namespace RestSharp
+{
+ ///
+ /// HttpWebRequest wrapper (async methods)
+ ///
+ public partial class Http
+ {
+ private TimeOutState _timeoutState;
+
+ public HttpWebRequest DeleteAsync(Action action)
+ {
+ return GetStyleMethodInternalAsync("DELETE", action);
+ }
+
+ public HttpWebRequest GetAsync(Action action)
+ {
+ return GetStyleMethodInternalAsync("GET", action);
+ }
+
+ public HttpWebRequest HeadAsync(Action action)
+ {
+ return GetStyleMethodInternalAsync("HEAD", action);
+ }
+
+ public HttpWebRequest OptionsAsync(Action action)
+ {
+ return GetStyleMethodInternalAsync("OPTIONS", action);
+ }
+
+ public HttpWebRequest PostAsync(Action action)
+ {
+ return PutPostInternalAsync("POST", action);
+ }
+
+ public HttpWebRequest PutAsync(Action action)
+ {
+ return PutPostInternalAsync("PUT", action);
+ }
+
+ public HttpWebRequest PatchAsync(Action action)
+ {
+ return PutPostInternalAsync("PATCH", action);
+ }
+
+ public HttpWebRequest MergeAsync(Action action)
+ {
+ return PutPostInternalAsync("MERGE", action);
+ }
+
+ ///
+ /// Execute an async POST-style request with the specified HTTP Method.
+ ///
+ /// The HTTP method to execute.
+ ///
+ public HttpWebRequest AsPostAsync(Action action, string httpMethod)
+ {
#if PocketPC
return PutPostInternalAsync(httpMethod.ToUpper(), action);
-#else
- return PutPostInternalAsync(httpMethod.ToUpperInvariant(), action);
-#endif
- }
-
- ///
- /// Execute an async GET-style request with the specified HTTP Method.
- ///
- /// The HTTP method to execute.
- ///
- public HttpWebRequest AsGetAsync(Action action, string httpMethod)
- {
+#else
+ return PutPostInternalAsync(httpMethod.ToUpperInvariant(), action);
+#endif
+ }
+
+ ///
+ /// Execute an async GET-style request with the specified HTTP Method.
+ ///
+ /// The HTTP method to execute.
+ ///
+ public HttpWebRequest AsGetAsync(Action action, string httpMethod)
+ {
#if PocketPC
return GetStyleMethodInternalAsync(httpMethod.ToUpper(), action);
-#else
- return GetStyleMethodInternalAsync(httpMethod.ToUpperInvariant(), action);
-#endif
- }
-
- private HttpWebRequest GetStyleMethodInternalAsync(string method, Action callback)
- {
- HttpWebRequest webRequest = null;
- try
- {
- var url = Url;
- webRequest = ConfigureAsyncWebRequest(method, url);
- if (HasBody && (method == "DELETE" || method == "OPTIONS"))
- {
- webRequest.ContentType = RequestContentType;
- WriteRequestBodyAsync(webRequest, callback);
- }
- else
- {
- _timeoutState = new TimeOutState { Request = webRequest };
- var asyncResult = webRequest.BeginGetResponse(result => ResponseCallback(result, callback), webRequest);
- SetTimeout(asyncResult, _timeoutState);
- }
- }
- catch(Exception ex)
- {
- ExecuteCallback(CreateErrorResponse(ex), callback);
- }
- return webRequest;
- }
-
- private HttpResponse CreateErrorResponse(Exception ex)
- {
- var response = new HttpResponse();
- var webException = ex as WebException;
- if (webException != null && webException.Status == WebExceptionStatus.RequestCanceled)
- {
- response.ResponseStatus = _timeoutState.TimedOut ? ResponseStatus.TimedOut : ResponseStatus.Aborted;
- return response;
- }
-
- response.ErrorMessage = ex.Message;
- response.ErrorException = ex;
- response.ResponseStatus = ResponseStatus.Error;
- return response;
- }
-
- private HttpWebRequest PutPostInternalAsync(string method, Action callback)
- {
- HttpWebRequest webRequest = null;
- try
- {
- webRequest = ConfigureAsyncWebRequest(method, Url);
- PreparePostBody(webRequest);
- WriteRequestBodyAsync(webRequest, callback);
- }
- catch(Exception ex)
- {
- ExecuteCallback(CreateErrorResponse(ex), callback);
- }
-
- return webRequest;
- }
-
- private void WriteRequestBodyAsync(HttpWebRequest webRequest, Action callback)
- {
- IAsyncResult asyncResult;
- _timeoutState = new TimeOutState { Request = webRequest };
-
- if (HasBody || HasFiles || AlwaysMultipartFormData)
- {
-#if !WINDOWS_PHONE && !PocketPC
- webRequest.ContentLength = CalculateContentLength();
-#endif
- asyncResult = webRequest.BeginGetRequestStream(result => RequestStreamCallback(result, callback), webRequest);
- }
-
- else
- {
- asyncResult = webRequest.BeginGetResponse(r => ResponseCallback(r, callback), webRequest);
- }
-
- SetTimeout(asyncResult, _timeoutState);
- }
-
- private long CalculateContentLength()
- {
- if (RequestBodyBytes != null)
- return RequestBodyBytes.Length;
-
- if (!HasFiles && !AlwaysMultipartFormData)
- {
- return _defaultEncoding.GetByteCount(RequestBody);
- }
-
- // calculate length for multipart form
- long length = 0;
- foreach (var file in Files)
- {
- length += _defaultEncoding.GetByteCount(GetMultipartFileHeader(file));
- length += file.ContentLength;
- length += _defaultEncoding.GetByteCount(_lineBreak);
- }
-
- foreach (var param in Parameters)
- {
- length += _defaultEncoding.GetByteCount(GetMultipartFormData(param));
- }
-
- length += _defaultEncoding.GetByteCount(GetMultipartFooter());
- return length;
- }
-
- private void RequestStreamCallback(IAsyncResult result, Action callback)
- {
- var webRequest = (HttpWebRequest)result.AsyncState;
-
- if (_timeoutState.TimedOut)
- {
- var response = new HttpResponse {ResponseStatus = ResponseStatus.TimedOut};
- ExecuteCallback(response, callback);
- return;
- }
-
- // write body to request stream
- try
- {
- using(var requestStream = webRequest.EndGetRequestStream(result))
- {
- if(HasFiles || AlwaysMultipartFormData)
- {
- WriteMultipartFormData(requestStream);
- }
- else if (RequestBodyBytes != null)
- {
- requestStream.Write(RequestBodyBytes, 0, RequestBodyBytes.Length);
- }
- else
- {
- WriteStringTo(requestStream, RequestBody);
- }
- }
- }
- catch (Exception ex)
- {
- ExecuteCallback(CreateErrorResponse(ex), callback);
- return;
- }
-
- IAsyncResult asyncResult = webRequest.BeginGetResponse(r => ResponseCallback(r, callback), webRequest);
- SetTimeout(asyncResult, _timeoutState);
- }
-
- private void SetTimeout(IAsyncResult asyncResult, TimeOutState timeOutState)
- {
-#if FRAMEWORK && !PocketPC
- if (Timeout != 0)
- {
- ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), timeOutState, Timeout, true);
- }
-#endif
- }
-
- private static void TimeoutCallback(object state, bool timedOut)
- {
- if (!timedOut)
- return;
-
- var timeoutState = state as TimeOutState;
-
- if (timeoutState == null)
- {
- return;
- }
-
- lock (timeoutState)
- {
- timeoutState.TimedOut = true;
- }
-
- if (timeoutState.Request != null)
- {
- timeoutState.Request.Abort();
- }
- }
-
- private static void GetRawResponseAsync(IAsyncResult result, Action callback)
- {
- var response = new HttpResponse();
- response.ResponseStatus = ResponseStatus.None;
-
- HttpWebResponse raw = null;
-
- try
- {
- var webRequest = (HttpWebRequest)result.AsyncState;
- raw = webRequest.EndGetResponse(result) as HttpWebResponse;
- }
- catch(WebException ex)
- {
- if(ex.Status == WebExceptionStatus.RequestCanceled)
- {
- throw ex;
- }
-
- // Check to see if this is an HTTP error or a transport error.
- // In cases where an HTTP error occurs ( status code >= 400 )
- // return the underlying HTTP response, otherwise assume a
- // transport exception (ex: connection timeout) and
- // rethrow the exception
-
- if (ex.Response is HttpWebResponse)
- {
- raw = ex.Response as HttpWebResponse;
- }
- else
- {
- throw ex;
- }
- }
-
- callback(raw);
- raw.Close();
- }
-
- private void ResponseCallback(IAsyncResult result, Action callback)
- {
- var response = new HttpResponse {ResponseStatus = ResponseStatus.None};
-
- try
- {
- if(_timeoutState.TimedOut)
- {
- response.ResponseStatus = ResponseStatus.TimedOut;
- ExecuteCallback(response, callback);
- return;
- }
-
- GetRawResponseAsync(result, webResponse =>
- {
- ExtractResponseData(response, webResponse);
- ExecuteCallback(response, callback);
- });
- }
- catch(Exception ex)
- {
- ExecuteCallback(CreateErrorResponse(ex), callback);
- }
- }
-
- private static void ExecuteCallback(HttpResponse response, Action callback)
- {
- callback(response);
- }
-
- partial void AddAsyncHeaderActions()
- {
+#else
+ return GetStyleMethodInternalAsync(httpMethod.ToUpperInvariant(), action);
+#endif
+ }
+
+ private HttpWebRequest GetStyleMethodInternalAsync(string method, Action callback)
+ {
+ HttpWebRequest webRequest = null;
+ try
+ {
+ var url = Url;
+ webRequest = ConfigureAsyncWebRequest(method, url);
+ if (HasBody && (method == "DELETE" || method == "OPTIONS"))
+ {
+ webRequest.ContentType = RequestContentType;
+ WriteRequestBodyAsync(webRequest, callback);
+ }
+ else
+ {
+ _timeoutState = new TimeOutState { Request = webRequest };
+ var asyncResult = webRequest.BeginGetResponse(result => ResponseCallback(result, callback), webRequest);
+ SetTimeout(asyncResult, _timeoutState);
+ }
+ }
+ catch (Exception ex)
+ {
+ ExecuteCallback(CreateErrorResponse(ex), callback);
+ }
+ return webRequest;
+ }
+
+ private HttpResponse CreateErrorResponse(Exception ex)
+ {
+ var response = new HttpResponse();
+ var webException = ex as WebException;
+ if (webException != null && webException.Status == WebExceptionStatus.RequestCanceled)
+ {
+ response.ResponseStatus = _timeoutState.TimedOut ? ResponseStatus.TimedOut : ResponseStatus.Aborted;
+ return response;
+ }
+
+ response.ErrorMessage = ex.Message;
+ response.ErrorException = ex;
+ response.ResponseStatus = ResponseStatus.Error;
+ return response;
+ }
+
+ private HttpWebRequest PutPostInternalAsync(string method, Action callback)
+ {
+ HttpWebRequest webRequest = null;
+ try
+ {
+ webRequest = ConfigureAsyncWebRequest(method, Url);
+ PreparePostBody(webRequest);
+ WriteRequestBodyAsync(webRequest, callback);
+ }
+ catch (Exception ex)
+ {
+ ExecuteCallback(CreateErrorResponse(ex), callback);
+ }
+
+ return webRequest;
+ }
+
+ private void WriteRequestBodyAsync(HttpWebRequest webRequest, Action callback)
+ {
+ IAsyncResult asyncResult;
+ _timeoutState = new TimeOutState { Request = webRequest };
+
+ if (HasBody || HasFiles || AlwaysMultipartFormData)
+ {
+#if !WINDOWS_PHONE && !PocketPC
+ webRequest.ContentLength = CalculateContentLength();
+#endif
+ asyncResult = webRequest.BeginGetRequestStream(result => RequestStreamCallback(result, callback), webRequest);
+ }
+
+ else
+ {
+ asyncResult = webRequest.BeginGetResponse(r => ResponseCallback(r, callback), webRequest);
+ }
+
+ SetTimeout(asyncResult, _timeoutState);
+ }
+
+ private long CalculateContentLength()
+ {
+ if (RequestBodyBytes != null)
+ return RequestBodyBytes.Length;
+
+ if (!HasFiles && !AlwaysMultipartFormData)
+ {
+ return _defaultEncoding.GetByteCount(RequestBody);
+ }
+
+ // calculate length for multipart form
+ long length = 0;
+ foreach (var file in Files)
+ {
+ length += _defaultEncoding.GetByteCount(GetMultipartFileHeader(file));
+ length += file.ContentLength;
+ length += _defaultEncoding.GetByteCount(_lineBreak);
+ }
+
+ foreach (var param in Parameters)
+ {
+ length += _defaultEncoding.GetByteCount(GetMultipartFormData(param));
+ }
+
+ length += _defaultEncoding.GetByteCount(GetMultipartFooter());
+ return length;
+ }
+
+ private void RequestStreamCallback(IAsyncResult result, Action callback)
+ {
+ var webRequest = (HttpWebRequest)result.AsyncState;
+
+ if (_timeoutState.TimedOut)
+ {
+ var response = new HttpResponse { ResponseStatus = ResponseStatus.TimedOut };
+ ExecuteCallback(response, callback);
+ return;
+ }
+
+ // write body to request stream
+ try
+ {
+ using (var requestStream = webRequest.EndGetRequestStream(result))
+ {
+ if (HasFiles || AlwaysMultipartFormData)
+ {
+ WriteMultipartFormData(requestStream);
+ }
+ else if (RequestBodyBytes != null)
+ {
+ requestStream.Write(RequestBodyBytes, 0, RequestBodyBytes.Length);
+ }
+ else
+ {
+ WriteStringTo(requestStream, RequestBody);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ ExecuteCallback(CreateErrorResponse(ex), callback);
+ return;
+ }
+
+ IAsyncResult asyncResult = webRequest.BeginGetResponse(r => ResponseCallback(r, callback), webRequest);
+ SetTimeout(asyncResult, _timeoutState);
+ }
+
+ private void SetTimeout(IAsyncResult asyncResult, TimeOutState timeOutState)
+ {
+#if FRAMEWORK && !PocketPC
+ if (Timeout != 0)
+ {
+ ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), timeOutState, Timeout, true);
+ }
+#endif
+ }
+
+ private static void TimeoutCallback(object state, bool timedOut)
+ {
+ if (!timedOut)
+ return;
+
+ var timeoutState = state as TimeOutState;
+
+ if (timeoutState == null)
+ {
+ return;
+ }
+
+ lock (timeoutState)
+ {
+ timeoutState.TimedOut = true;
+ }
+
+ if (timeoutState.Request != null)
+ {
+ timeoutState.Request.Abort();
+ }
+ }
+
+ private static void GetRawResponseAsync(IAsyncResult result, Action callback)
+ {
+ var response = new HttpResponse();
+ response.ResponseStatus = ResponseStatus.None;
+
+ HttpWebResponse raw = null;
+
+ try
+ {
+ var webRequest = (HttpWebRequest)result.AsyncState;
+ raw = webRequest.EndGetResponse(result) as HttpWebResponse;
+ }
+ catch (WebException ex)
+ {
+ if (ex.Status == WebExceptionStatus.RequestCanceled)
+ {
+ throw ex;
+ }
+
+ // Check to see if this is an HTTP error or a transport error.
+ // In cases where an HTTP error occurs ( status code >= 400 )
+ // return the underlying HTTP response, otherwise assume a
+ // transport exception (ex: connection timeout) and
+ // rethrow the exception
+
+ if (ex.Response is HttpWebResponse)
+ {
+ raw = ex.Response as HttpWebResponse;
+ }
+ else
+ {
+ throw ex;
+ }
+ }
+
+ callback(raw);
+ raw.Close();
+ }
+
+ private void ResponseCallback(IAsyncResult result, Action callback)
+ {
+ var response = new HttpResponse { ResponseStatus = ResponseStatus.None };
+
+ try
+ {
+ if (_timeoutState.TimedOut)
+ {
+ response.ResponseStatus = ResponseStatus.TimedOut;
+ ExecuteCallback(response, callback);
+ return;
+ }
+
+ GetRawResponseAsync(result, webResponse =>
+ {
+ ExtractResponseData(response, webResponse);
+ ExecuteCallback(response, callback);
+ });
+ }
+ catch (Exception ex)
+ {
+ ExecuteCallback(CreateErrorResponse(ex), callback);
+ }
+ }
+
+ private static void ExecuteCallback(HttpResponse response, Action callback)
+ {
+ callback(response);
+ }
+
+ partial void AddAsyncHeaderActions()
+ {
#if SILVERLIGHT
_restrictedHeaderActions.Add("Content-Length", (r, v) => r.ContentLength = Convert.ToInt64(v));
-#endif
+#endif
#if WINDOWS_PHONE
// WP7 doesn't as of Beta doesn't support a way to set Content-Length either directly
// or indirectly
_restrictedHeaderActions.Add("Content-Length", (r, v) => { });
-#endif
- }
-
- // TODO: Try to merge the shared parts between ConfigureWebRequest and ConfigureAsyncWebRequest (quite a bit of code
- // TODO: duplication at the moment).
- private HttpWebRequest ConfigureAsyncWebRequest(string method, Uri url)
- {
+#endif
+ }
+
+ // TODO: Try to merge the shared parts between ConfigureWebRequest and ConfigureAsyncWebRequest (quite a bit of code
+ // TODO: duplication at the moment).
+ private HttpWebRequest ConfigureAsyncWebRequest(string method, Uri url)
+ {
#if SILVERLIGHT
WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
WebRequest.RegisterPrefix("https://", WebRequestCreator.ClientHttp);
-#endif
- var webRequest = (HttpWebRequest)WebRequest.Create(url);
-#if !PocketPC
- webRequest.UseDefaultCredentials = UseDefaultCredentials;
-#endif
-
-#if !WINDOWS_PHONE && !SILVERLIGHT
- webRequest.PreAuthenticate = PreAuthenticate;
-#endif
- AppendHeaders(webRequest);
- AppendCookies(webRequest);
-
- webRequest.Method = method;
-
- // make sure Content-Length header is always sent since default is -1
-#if !WINDOWS_PHONE && !PocketPC
- // WP7 doesn't as of Beta doesn't support a way to set this value either directly
- // or indirectly
- if(!HasFiles && !AlwaysMultipartFormData)
- {
- webRequest.ContentLength = 0;
- }
-#endif
-
- if(Credentials != null)
- {
- webRequest.Credentials = Credentials;
- }
-
-#if !SILVERLIGHT
- if(UserAgent.HasValue())
- {
- webRequest.UserAgent = UserAgent;
- }
-#endif
-
-#if FRAMEWORK
- if(ClientCertificates != null)
- {
- webRequest.ClientCertificates.AddRange(ClientCertificates);
- }
-
- webRequest.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip | DecompressionMethods.None;
- ServicePointManager.Expect100Continue = false;
-
- if (Timeout != 0)
- {
- webRequest.Timeout = Timeout;
- }
-
- if (ReadWriteTimeout != 0)
- {
- webRequest.ReadWriteTimeout = ReadWriteTimeout;
- }
-
- if (Proxy != null)
- {
- webRequest.Proxy = Proxy;
- }
-
- if (FollowRedirects && MaxRedirects.HasValue)
- {
- webRequest.MaximumAutomaticRedirections = MaxRedirects.Value;
- }
-#endif
-
-#if !SILVERLIGHT
- webRequest.AllowAutoRedirect = FollowRedirects;
-#endif
- return webRequest;
- }
-
- private class TimeOutState
- {
- public bool TimedOut { get; set; }
- public HttpWebRequest Request { get; set; }
- }
- }
-}
+#endif
+ var webRequest = (HttpWebRequest)WebRequest.Create(url);
+#if !PocketPC
+ webRequest.UseDefaultCredentials = UseDefaultCredentials;
+#endif
+
+#if !WINDOWS_PHONE && !SILVERLIGHT
+ webRequest.PreAuthenticate = PreAuthenticate;
+#endif
+ AppendHeaders(webRequest);
+ AppendCookies(webRequest);
+
+ webRequest.Method = method;
+
+ // make sure Content-Length header is always sent since default is -1
+#if !WINDOWS_PHONE && !PocketPC
+ // WP7 doesn't as of Beta doesn't support a way to set this value either directly
+ // or indirectly
+ if (!HasFiles && !AlwaysMultipartFormData)
+ {
+ webRequest.ContentLength = 0;
+ }
+#endif
+
+ if (Credentials != null)
+ {
+ webRequest.Credentials = Credentials;
+ }
+
+#if !SILVERLIGHT
+ if (UserAgent.HasValue())
+ {
+ webRequest.UserAgent = UserAgent;
+ }
+#endif
+
+#if FRAMEWORK
+ if (ClientCertificates != null)
+ {
+ webRequest.ClientCertificates.AddRange(ClientCertificates);
+ }
+
+ webRequest.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip | DecompressionMethods.None;
+ ServicePointManager.Expect100Continue = false;
+
+ if (Timeout != 0)
+ {
+ webRequest.Timeout = Timeout;
+ }
+
+ if (ReadWriteTimeout != 0)
+ {
+ webRequest.ReadWriteTimeout = ReadWriteTimeout;
+ }
+
+ if (Proxy != null)
+ {
+ webRequest.Proxy = Proxy;
+ }
+
+ if (FollowRedirects && MaxRedirects.HasValue)
+ {
+ webRequest.MaximumAutomaticRedirections = MaxRedirects.Value;
+ }
+#endif
+
+#if !SILVERLIGHT
+ webRequest.AllowAutoRedirect = FollowRedirects;
+#endif
+ return webRequest;
+ }
+
+ private class TimeOutState
+ {
+ public bool TimedOut { get; set; }
+ public HttpWebRequest Request { get; set; }
+ }
+ }
+}
\ No newline at end of file
diff --git a/RestSharp/Http.Sync.cs b/RestSharp/Http.Sync.cs
index 72c354d0f..09a3acf49 100644
--- a/RestSharp/Http.Sync.cs
+++ b/RestSharp/Http.Sync.cs
@@ -22,280 +22,288 @@
using System.Web;
#endif
-using RestSharp.Extensions;
-
-namespace RestSharp
-{
- ///
- /// HttpWebRequest wrapper (sync methods)
- ///
- public partial class Http
- {
- ///
- /// Execute a POST request
- ///
- public HttpResponse Post()
- {
- return PostPutInternal("POST");
- }
-
- ///
- /// Execute a PUT request
- ///
- public HttpResponse Put()
- {
- return PostPutInternal("PUT");
- }
-
- ///
- /// Execute a GET request
- ///
- public HttpResponse Get()
- {
- return GetStyleMethodInternal("GET");
- }
-
- ///
- /// Execute a HEAD request
- ///
- public HttpResponse Head()
- {
- return GetStyleMethodInternal("HEAD");
- }
-
- ///
- /// Execute an OPTIONS request
- ///
- public HttpResponse Options()
- {
- return GetStyleMethodInternal("OPTIONS");
- }
-
- ///
- /// Execute a DELETE request
- ///
- public HttpResponse Delete()
- {
- return GetStyleMethodInternal("DELETE");
- }
-
- ///
- /// Execute a PATCH request
- ///
- public HttpResponse Patch()
- {
- return PostPutInternal("PATCH");
- }
-
- ///
- /// Execute a GET-style request with the specified HTTP Method.
- ///
- /// The HTTP method to execute.
- ///
- public HttpResponse AsGet(string httpMethod)
- {
+using RestSharp.Extensions;
+
+namespace RestSharp
+{
+ ///
+ /// HttpWebRequest wrapper (sync methods)
+ ///
+ public partial class Http
+ {
+ ///
+ /// Execute a POST request
+ ///
+ public HttpResponse Post()
+ {
+ return PostPutInternal("POST");
+ }
+
+ ///
+ /// Execute a PUT request
+ ///
+ public HttpResponse Put()
+ {
+ return PostPutInternal("PUT");
+ }
+
+ ///
+ /// Execute a GET request
+ ///
+ public HttpResponse Get()
+ {
+ return GetStyleMethodInternal("GET");
+ }
+
+ ///
+ /// Execute a HEAD request
+ ///
+ public HttpResponse Head()
+ {
+ return GetStyleMethodInternal("HEAD");
+ }
+
+ ///
+ /// Execute an OPTIONS request
+ ///
+ public HttpResponse Options()
+ {
+ return GetStyleMethodInternal("OPTIONS");
+ }
+
+ ///
+ /// Execute a DELETE request
+ ///
+ public HttpResponse Delete()
+ {
+ return GetStyleMethodInternal("DELETE");
+ }
+
+ ///
+ /// Execute a PATCH request
+ ///
+ public HttpResponse Patch()
+ {
+ return PostPutInternal("PATCH");
+ }
+
+ ///
+ /// Execute a MERGE request
+ ///
+ public HttpResponse Merge()
+ {
+ return PostPutInternal("MERGE");
+ }
+
+ ///
+ /// Execute a GET-style request with the specified HTTP Method.
+ ///
+ /// The HTTP method to execute.
+ ///
+ public HttpResponse AsGet(string httpMethod)
+ {
#if PocketPC
return GetStyleMethodInternal(httpMethod.ToUpper());
-#else
- return GetStyleMethodInternal(httpMethod.ToUpperInvariant());
-#endif
- }
-
- ///
- /// Execute a POST-style request with the specified HTTP Method.
- ///
- /// The HTTP method to execute.
- ///
- public HttpResponse AsPost(string httpMethod)
- {
+#else
+ return GetStyleMethodInternal(httpMethod.ToUpperInvariant());
+#endif
+ }
+
+ ///
+ /// Execute a POST-style request with the specified HTTP Method.
+ ///
+ /// The HTTP method to execute.
+ ///
+ public HttpResponse AsPost(string httpMethod)
+ {
#if PocketPC
return PostPutInternal(httpMethod.ToUpper());
-#else
- return PostPutInternal(httpMethod.ToUpperInvariant());
-#endif
- }
-
- private HttpResponse GetStyleMethodInternal(string method)
- {
- var webRequest = ConfigureWebRequest(method, Url);
-
- if (HasBody && (method == "DELETE" || method == "OPTIONS"))
- {
- webRequest.ContentType = RequestContentType;
- WriteRequestBody(webRequest);
- }
-
- return GetResponse(webRequest);
- }
-
- private HttpResponse PostPutInternal(string method)
- {
- var webRequest = ConfigureWebRequest(method, Url);
-
- PreparePostData(webRequest);
-
- WriteRequestBody(webRequest);
- return GetResponse(webRequest);
- }
-
- partial void AddSyncHeaderActions()
- {
- _restrictedHeaderActions.Add("Connection", (r, v) => r.Connection = v);
- _restrictedHeaderActions.Add("Content-Length", (r, v) => r.ContentLength = Convert.ToInt64(v));
- _restrictedHeaderActions.Add("Expect", (r, v) => r.Expect = v);
- _restrictedHeaderActions.Add("If-Modified-Since", (r, v) => r.IfModifiedSince = Convert.ToDateTime(v));
- _restrictedHeaderActions.Add("Referer", (r, v) => r.Referer = v);
- _restrictedHeaderActions.Add("Transfer-Encoding", (r, v) => { r.TransferEncoding = v; r.SendChunked = true; });
- _restrictedHeaderActions.Add("User-Agent", (r, v) => r.UserAgent = v);
- }
-
- private void ExtractErrorResponse(HttpResponse httpResponse, Exception ex)
- {
- var webException = ex as WebException;
-
- if (webException != null && webException.Status == WebExceptionStatus.Timeout)
- {
- httpResponse.ResponseStatus = ResponseStatus.TimedOut;
- httpResponse.ErrorMessage = ex.Message;
- httpResponse.ErrorException = webException;
- return;
- }
-
- httpResponse.ErrorMessage = ex.Message;
- httpResponse.ErrorException = ex;
- httpResponse.ResponseStatus = ResponseStatus.Error;
- }
-
- private HttpResponse GetResponse(HttpWebRequest request)
- {
- var response = new HttpResponse { ResponseStatus = ResponseStatus.None };
-
- try
- {
- var webResponse = GetRawResponse(request);
- ExtractResponseData(response, webResponse);
- }
- catch (Exception ex)
- {
- ExtractErrorResponse(response, ex);
- }
-
- return response;
- }
-
- private static HttpWebResponse GetRawResponse(HttpWebRequest request)
- {
- try
- {
- return (HttpWebResponse)request.GetResponse();
- }
- catch (WebException ex)
- {
- // Check to see if this is an HTTP error or a transport error.
- // In cases where an HTTP error occurs ( status code >= 400 )
- // return the underlying HTTP response, otherwise assume a
- // transport exception (ex: connection timeout) and
- // rethrow the exception
-
- if (ex.Response is HttpWebResponse)
- {
- return ex.Response as HttpWebResponse;
- }
- throw;
- }
- }
-
- private void PreparePostData(HttpWebRequest webRequest)
- {
- if (HasFiles || AlwaysMultipartFormData)
- {
- webRequest.ContentType = GetMultipartFormContentType();
- using (var requestStream = webRequest.GetRequestStream())
- {
- WriteMultipartFormData(requestStream);
- }
- }
-
- PreparePostBody(webRequest);
- }
-
- private void WriteRequestBody(HttpWebRequest webRequest)
- {
- if (!HasBody)
- return;
-
- var bytes = RequestBodyBytes == null ? _defaultEncoding.GetBytes(RequestBody) : RequestBodyBytes;
-
- webRequest.ContentLength = bytes.Length;
-
- using (var requestStream = webRequest.GetRequestStream())
- {
- requestStream.Write(bytes, 0, bytes.Length);
- }
- }
-
- // TODO: Try to merge the shared parts between ConfigureWebRequest and ConfigureAsyncWebRequest (quite a bit of code
- // TODO: duplication at the moment).
- private HttpWebRequest ConfigureWebRequest(string method, Uri url)
- {
- var webRequest = (HttpWebRequest)WebRequest.Create(url);
-#if !PocketPC
- webRequest.UseDefaultCredentials = UseDefaultCredentials;
-#endif
- webRequest.PreAuthenticate = PreAuthenticate;
- ServicePointManager.Expect100Continue = false;
-
- AppendHeaders(webRequest);
- AppendCookies(webRequest);
-
- webRequest.Method = method;
-
- // make sure Content-Length header is always sent since default is -1
- if (!HasFiles && !AlwaysMultipartFormData)
- {
- webRequest.ContentLength = 0;
- }
-
- webRequest.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip | DecompressionMethods.None;
-#if FRAMEWORK
- if(ClientCertificates != null)
- {
- webRequest.ClientCertificates.AddRange(ClientCertificates);
- }
-#endif
- if(UserAgent.HasValue())
- {
- webRequest.UserAgent = UserAgent;
- }
-
- if(Timeout != 0)
- {
- webRequest.Timeout = Timeout;
- }
-
- if (ReadWriteTimeout != 0)
- {
- webRequest.ReadWriteTimeout = ReadWriteTimeout;
- }
-
- if(Credentials != null)
- {
- webRequest.Credentials = Credentials;
- }
-
- if(Proxy != null)
- {
- webRequest.Proxy = Proxy;
- }
-
- webRequest.AllowAutoRedirect = FollowRedirects;
- if(FollowRedirects && MaxRedirects.HasValue)
- {
- webRequest.MaximumAutomaticRedirections = MaxRedirects.Value;
- }
-
- return webRequest;
- }
- }
+#else
+ return PostPutInternal(httpMethod.ToUpperInvariant());
+#endif
+ }
+
+ private HttpResponse GetStyleMethodInternal(string method)
+ {
+ var webRequest = ConfigureWebRequest(method, Url);
+
+ if (HasBody && (method == "DELETE" || method == "OPTIONS"))
+ {
+ webRequest.ContentType = RequestContentType;
+ WriteRequestBody(webRequest);
+ }
+
+ return GetResponse(webRequest);
+ }
+
+ private HttpResponse PostPutInternal(string method)
+ {
+ var webRequest = ConfigureWebRequest(method, Url);
+
+ PreparePostData(webRequest);
+
+ WriteRequestBody(webRequest);
+ return GetResponse(webRequest);
+ }
+
+ partial void AddSyncHeaderActions()
+ {
+ _restrictedHeaderActions.Add("Connection", (r, v) => r.Connection = v);
+ _restrictedHeaderActions.Add("Content-Length", (r, v) => r.ContentLength = Convert.ToInt64(v));
+ _restrictedHeaderActions.Add("Expect", (r, v) => r.Expect = v);
+ _restrictedHeaderActions.Add("If-Modified-Since", (r, v) => r.IfModifiedSince = Convert.ToDateTime(v));
+ _restrictedHeaderActions.Add("Referer", (r, v) => r.Referer = v);
+ _restrictedHeaderActions.Add("Transfer-Encoding", (r, v) => { r.TransferEncoding = v; r.SendChunked = true; });
+ _restrictedHeaderActions.Add("User-Agent", (r, v) => r.UserAgent = v);
+ }
+
+ private void ExtractErrorResponse(HttpResponse httpResponse, Exception ex)
+ {
+ var webException = ex as WebException;
+
+ if (webException != null && webException.Status == WebExceptionStatus.Timeout)
+ {
+ httpResponse.ResponseStatus = ResponseStatus.TimedOut;
+ httpResponse.ErrorMessage = ex.Message;
+ httpResponse.ErrorException = webException;
+ return;
+ }
+
+ httpResponse.ErrorMessage = ex.Message;
+ httpResponse.ErrorException = ex;
+ httpResponse.ResponseStatus = ResponseStatus.Error;
+ }
+
+ private HttpResponse GetResponse(HttpWebRequest request)
+ {
+ var response = new HttpResponse { ResponseStatus = ResponseStatus.None };
+
+ try
+ {
+ var webResponse = GetRawResponse(request);
+ ExtractResponseData(response, webResponse);
+ }
+ catch (Exception ex)
+ {
+ ExtractErrorResponse(response, ex);
+ }
+
+ return response;
+ }
+
+ private static HttpWebResponse GetRawResponse(HttpWebRequest request)
+ {
+ try
+ {
+ return (HttpWebResponse)request.GetResponse();
+ }
+ catch (WebException ex)
+ {
+ // Check to see if this is an HTTP error or a transport error.
+ // In cases where an HTTP error occurs ( status code >= 400 )
+ // return the underlying HTTP response, otherwise assume a
+ // transport exception (ex: connection timeout) and
+ // rethrow the exception
+
+ if (ex.Response is HttpWebResponse)
+ {
+ return ex.Response as HttpWebResponse;
+ }
+ throw;
+ }
+ }
+
+ private void PreparePostData(HttpWebRequest webRequest)
+ {
+ if (HasFiles || AlwaysMultipartFormData)
+ {
+ webRequest.ContentType = GetMultipartFormContentType();
+ using (var requestStream = webRequest.GetRequestStream())
+ {
+ WriteMultipartFormData(requestStream);
+ }
+ }
+
+ PreparePostBody(webRequest);
+ }
+
+ private void WriteRequestBody(HttpWebRequest webRequest)
+ {
+ if (!HasBody)
+ return;
+
+ var bytes = RequestBodyBytes == null ? _defaultEncoding.GetBytes(RequestBody) : RequestBodyBytes;
+
+ webRequest.ContentLength = bytes.Length;
+
+ using (var requestStream = webRequest.GetRequestStream())
+ {
+ requestStream.Write(bytes, 0, bytes.Length);
+ }
+ }
+
+ // TODO: Try to merge the shared parts between ConfigureWebRequest and ConfigureAsyncWebRequest (quite a bit of code
+ // TODO: duplication at the moment).
+ private HttpWebRequest ConfigureWebRequest(string method, Uri url)
+ {
+ var webRequest = (HttpWebRequest)WebRequest.Create(url);
+#if !PocketPC
+ webRequest.UseDefaultCredentials = UseDefaultCredentials;
+#endif
+ webRequest.PreAuthenticate = PreAuthenticate;
+ ServicePointManager.Expect100Continue = false;
+
+ AppendHeaders(webRequest);
+ AppendCookies(webRequest);
+
+ webRequest.Method = method;
+
+ // make sure Content-Length header is always sent since default is -1
+ if (!HasFiles && !AlwaysMultipartFormData)
+ {
+ webRequest.ContentLength = 0;
+ }
+
+ webRequest.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip | DecompressionMethods.None;
+#if FRAMEWORK
+ if (ClientCertificates != null)
+ {
+ webRequest.ClientCertificates.AddRange(ClientCertificates);
+ }
+#endif
+ if (UserAgent.HasValue())
+ {
+ webRequest.UserAgent = UserAgent;
+ }
+
+ if (Timeout != 0)
+ {
+ webRequest.Timeout = Timeout;
+ }
+
+ if (ReadWriteTimeout != 0)
+ {
+ webRequest.ReadWriteTimeout = ReadWriteTimeout;
+ }
+
+ if (Credentials != null)
+ {
+ webRequest.Credentials = Credentials;
+ }
+
+ if (Proxy != null)
+ {
+ webRequest.Proxy = Proxy;
+ }
+
+ webRequest.AllowAutoRedirect = FollowRedirects;
+ if (FollowRedirects && MaxRedirects.HasValue)
+ {
+ webRequest.MaximumAutomaticRedirections = MaxRedirects.Value;
+ }
+
+ return webRequest;
+ }
+ }
}
#endif
\ No newline at end of file
diff --git a/RestSharp/Http.cs b/RestSharp/Http.cs
index 7c6763807..136f1ca1f 100644
--- a/RestSharp/Http.cs
+++ b/RestSharp/Http.cs
@@ -94,7 +94,6 @@ protected bool HasFiles
/// Always send a multipart/form-data request - even when no Files are present.
///
public bool AlwaysMultipartFormData { get; set; }
-
///
/// UserAgent to be sent with request
///
@@ -138,7 +137,7 @@ protected bool HasFiles
public X509CertificateCollection ClientCertificates { get; set; }
#endif
#if FRAMEWORK || PocketPC
- ///
+ ///
/// Maximum number of automatic redirects to follow if FollowRedirects is true
///
public int? MaxRedirects { get; set; }
@@ -177,8 +176,10 @@ protected bool HasFiles
///
/// URL to call for this request
///
- public Uri Url { get; set; }
-
+ public Uri Url { get; set; }
+ ///
+ /// Flag to send authorisation header with the HttpWebRequest
+ ///
public bool PreAuthenticate { get; set; }
#if FRAMEWORK || PocketPC
diff --git a/RestSharp/IHttp.cs b/RestSharp/IHttp.cs
index f43bfdc33..8857f2bc1 100644
--- a/RestSharp/IHttp.cs
+++ b/RestSharp/IHttp.cs
@@ -69,7 +69,8 @@ public interface IHttp
HttpWebRequest OptionsAsync(Action action);
HttpWebRequest PostAsync(Action action);
HttpWebRequest PutAsync(Action action);
- HttpWebRequest PatchAsync(Action action);
+ HttpWebRequest PatchAsync(Action action);
+ HttpWebRequest MergeAsync(Action action);
HttpWebRequest AsPostAsync(Action action, string httpMethod);
HttpWebRequest AsGetAsync(Action action, string httpMethod);
@@ -80,7 +81,8 @@ public interface IHttp
HttpResponse Options();
HttpResponse Post();
HttpResponse Put();
- HttpResponse Patch();
+ HttpResponse Patch();
+ HttpResponse Merge();
HttpResponse AsPost(string httpMethod);
HttpResponse AsGet(string httpMethod);
diff --git a/RestSharp/RestClient.Async.cs b/RestSharp/RestClient.Async.cs
index 73fa13144..670420cc5 100644
--- a/RestSharp/RestClient.Async.cs
+++ b/RestSharp/RestClient.Async.cs
@@ -34,23 +34,24 @@ public partial class RestClient
/// Executes the request and callback asynchronously, authenticating if needed
///
/// Request to be executed
- /// Callback function to be executed upon completion providing access to the async handle.
- public virtual RestRequestAsyncHandle ExecuteAsync(IRestRequest request, Action callback)
- {
+ /// Callback function to be executed upon completion providing access to the async handle.
+ public virtual RestRequestAsyncHandle ExecuteAsync(IRestRequest request, Action callback)
+ {
#if PocketPC
- string method = request.Method.ToString();
-#else
- string method = Enum.GetName(typeof (Method), request.Method);
-#endif
- switch (request.Method)
- {
- case Method.PATCH:
- case Method.POST:
- case Method.PUT:
- return ExecuteAsync(request, callback, method, DoAsPostAsync);
- default:
- return ExecuteAsync(request, callback, method, DoAsGetAsync);
- }
+ string method = request.Method.ToString();
+#else
+ string method = Enum.GetName(typeof(Method), request.Method);
+#endif
+ switch (request.Method)
+ {
+ case Method.MERGE:
+ case Method.PATCH:
+ case Method.POST:
+ case Method.PUT:
+ return ExecuteAsync(request, callback, method, DoAsPostAsync);
+ default:
+ return ExecuteAsync(request, callback, method, DoAsGetAsync);
+ }
}
///
diff --git a/RestSharp/RestClient.Sync.cs b/RestSharp/RestClient.Sync.cs
index 6351c3942..6a079c519 100644
--- a/RestSharp/RestClient.Sync.cs
+++ b/RestSharp/RestClient.Sync.cs
@@ -27,23 +27,24 @@ public byte[] DownloadData(IRestRequest request)
/// Executes the request and returns a response, authenticating if needed
///
/// Request to be executed
- /// RestResponse
- public virtual IRestResponse Execute(IRestRequest request)
- {
+ /// RestResponse
+ public virtual IRestResponse Execute(IRestRequest request)
+ {
#if PocketPC
var method = request.Method.ToString();
-#else
- var method = Enum.GetName(typeof(Method), request.Method);
-#endif
- switch (request.Method)
- {
- case Method.POST:
- case Method.PUT:
- case Method.PATCH:
- return Execute(request, method, DoExecuteAsPost);
- default:
- return Execute(request, method, DoExecuteAsGet);
- }
+#else
+ var method = Enum.GetName(typeof(Method), request.Method);
+#endif
+ switch (request.Method)
+ {
+ case Method.POST:
+ case Method.PUT:
+ case Method.PATCH:
+ case Method.MERGE:
+ return Execute(request, method, DoExecuteAsPost);
+ default:
+ return Execute(request, method, DoExecuteAsGet);
+ }
}
public IRestResponse ExecuteAsGet(IRestRequest request, string httpMethod)