diff --git a/RestSharp.WindowsPhone8/Properties/AssemblyInfo.cs b/RestSharp.WindowsPhone8/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..9258331a1 --- /dev/null +++ b/RestSharp.WindowsPhone8/Properties/AssemblyInfo.cs @@ -0,0 +1,16 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("RestSharp.WindowsPhone8")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("d6e5e03c-bbac-4d6a-8170-051b8225147c")] \ No newline at end of file diff --git a/RestSharp.WindowsPhone8/RestSharp.WindowsPhone8.csproj b/RestSharp.WindowsPhone8/RestSharp.WindowsPhone8.csproj new file mode 100644 index 000000000..66966882e --- /dev/null +++ b/RestSharp.WindowsPhone8/RestSharp.WindowsPhone8.csproj @@ -0,0 +1,353 @@ + + + + Debug + AnyCPU + 10.0.20506 + 2.0 + {35B2AFEA-0A2A-4E13-B946-60B7DD0D0B34} + {C089C8C0-30E0-4E22-80C0-CE093F111A43};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + RestSharp.WindowsPhone + RestSharp.WindowsPhone8 + v8.0 + + + + + WindowsPhone + false + true + true + ..\ + true + 11.0 + + + true + full + false + Bin\Debug + TRACE;DEBUG;WINDOWS_PHONE;WP8 + true + true + prompt + 4 + Bin\Debug\RestSharp.WindowsPhone8.xml + false + + + pdbonly + true + Bin\Release + TRACE;WINDOWS_PHONE;WP8 + true + true + prompt + 4 + Bin\Release\RestSharp.WindowsPhone8.xml + 1591,1573,1658,1584,1574,1572 + true + false + + + true + Bin\x86\Debug + TRACE;DEBUG;WINDOWS_PHONE;WP8 + Bin\Debug\RestSharp.WindowsPhone.xml + true + full + + + prompt + MinimumRecommendedRules.ruleset + false + + + Bin\x86\Release + TRACE;WINDOWS_PHONE + Bin\Release\RestSharp.WindowsPhone.xml + true + true + 1591,1573,1658,1584,1574,1572 + true + pdbonly + + + prompt + MinimumRecommendedRules.ruleset + + + true + Bin\ARM\Debug + TRACE;DEBUG;WINDOWS_PHONE;WP8 + Bin\Debug\RestSharp.WindowsPhone.xml + true + full + + + prompt + MinimumRecommendedRules.ruleset + false + + + Bin\ARM\Release + TRACE;WINDOWS_PHONE + Bin\Release\RestSharp.WindowsPhone.xml + true + true + 1591,1573,1658,1584,1574,1572 + true + pdbonly + + + prompt + MinimumRecommendedRules.ruleset + + + + Extensions\ResponseStatusExtensions.cs + + + Authenticators\HttpBasicAuthenticator.cs + + + Authenticators\IAuthenticator.cs + + + Authenticators\NtlmAuthenticator.cs + + + Authenticators\OAuth1Authenticator.cs + + + Authenticators\OAuth2Authenticator.cs + + + Authenticators\OAuth\Extensions\CollectionExtensions.cs + + + Authenticators\OAuth\Extensions\OAuthExtensions.cs + + + Authenticators\OAuth\Extensions\StringExtensions.cs + + + Authenticators\OAuth\Extensions\TimeExtensions.cs + + + Authenticators\OAuth\HttpPostParameter.cs + + + Authenticators\OAuth\HttpPostParameterType.cs + + + Authenticators\OAuth\OAuthParameterHandling.cs + + + Authenticators\OAuth\OAuthSignatureMethod.cs + + + Authenticators\OAuth\OAuthSignatureTreatment.cs + + + Authenticators\OAuth\OAuthTools.cs + + + Authenticators\OAuth\OAuthType.cs + + + Authenticators\OAuth\OAuthWebQueryInfo.cs + + + Authenticators\OAuth\OAuthWorkflow.cs + + + Authenticators\OAuth\WebPair.cs + + + Authenticators\OAuth\WebPairCollection.cs + + + Authenticators\OAuth\WebParameter.cs + + + Authenticators\OAuth\WebParameterCollection.cs + + + Authenticators\SimpleAuthenticator.cs + + + Compression\ZLib\Crc32.cs + + + Compression\ZLib\FlushType.cs + + + Compression\ZLib\GZipStream.cs + + + Compression\ZLib\Inflate.cs + + + Compression\ZLib\InfTree.cs + + + Compression\ZLib\ZLib.cs + + + Compression\ZLib\ZLibCodec.cs + + + Compression\ZLib\ZLibConstants.cs + + + Compression\ZLib\ZLibStream.cs + + + Deserializers\DeserializeAsAttribute.cs + + + Deserializers\DotNetXmlDeserializer.cs + + + Deserializers\IDeserializer.cs + + + Deserializers\JsonDeserializer.cs + + + Deserializers\XmlAttributeDeserializer.cs + + + Deserializers\XmlDeserializer.cs + + + Enum.cs + + + Extensions\MiscExtensions.cs + + + Extensions\ReflectionExtensions.cs + + + Extensions\ResponseExtensions.cs + + + Extensions\StringExtensions.cs + + + Extensions\XmlExtensions.cs + + + FileParameter.cs + + + Http.Async.cs + + + Http.cs + + + HttpCookie.cs + + + HttpFile.cs + + + HttpHeader.cs + + + HttpParameter.cs + + + HttpResponse.cs + + + IHttp.cs + + + IHttpFactory.cs + + + IHttpResponse.cs + + + IRestClient.cs + + + IRestRequest.cs + + + IRestResponse.cs + + + Parameter.cs + + + RestClient.Async.cs + + + RestClient.cs + + + RestClientExtensions.cs + + + RestRequest.cs + + + RestResponse.cs + + + Serializers\DotNetXmlSerializer.cs + + + Serializers\ISerializer.cs + + + Serializers\JsonSerializer.cs + + + Serializers\SerializeAsAttribute.cs + + + Serializers\XmlSerializer.cs + + + SharedAssemblyInfo.cs + + + SimpleJson.cs + + + Validation\Require.cs + + + Validation\Validate.cs + + + RestResponseCookie.cs + + + RestRequestAsyncHandle.cs + + + + + + + + + + + + \ No newline at end of file diff --git a/RestSharp.WindowsPhone8/packages.config b/RestSharp.WindowsPhone8/packages.config new file mode 100644 index 000000000..6b8deb9c9 --- /dev/null +++ b/RestSharp.WindowsPhone8/packages.config @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/RestSharp.sln b/RestSharp.sln index ffe12b3a3..a99307932 100644 --- a/RestSharp.sln +++ b/RestSharp.sln @@ -35,87 +35,118 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Meta", "Meta", "{C5B02FAA-6 readme.txt = readme.txt releasenotes.markdown = releasenotes.markdown EndProjectSection +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestSharp.WindowsPhone8", "RestSharp.WindowsPhone8\RestSharp.WindowsPhone8.csproj", "{35B2AFEA-0A2A-4E13-B946-60B7DD0D0B34}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|ARM = Debug|ARM Debug|Mixed Platforms = Debug|Mixed Platforms Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|ARM = Release|ARM Release|Mixed Platforms = Release|Mixed Platforms Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Debug|ARM.ActiveCfg = Debug|Any CPU {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Debug|x86.ActiveCfg = Debug|Any CPU {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Release|Any CPU.ActiveCfg = Release|Any CPU {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Release|Any CPU.Build.0 = Release|Any CPU + {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Release|ARM.ActiveCfg = Release|Any CPU {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Release|Mixed Platforms.Build.0 = Release|Any CPU {2ECECFBF-5F3E-40EE-A963-72336DC7ABE2}.Release|x86.ActiveCfg = Release|Any CPU {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Debug|ARM.ActiveCfg = Debug|Any CPU {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Debug|x86.ActiveCfg = Debug|Any CPU {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Release|Any CPU.ActiveCfg = Release|Any CPU {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Release|Any CPU.Build.0 = Release|Any CPU + {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Release|ARM.ActiveCfg = Release|Any CPU {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Release|Mixed Platforms.Build.0 = Release|Any CPU {1464E4AC-18BB-4F23-8A0B-68196F9E1871}.Release|x86.ActiveCfg = Release|Any CPU {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Debug|Any CPU.Build.0 = Debug|Any CPU + {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Debug|ARM.ActiveCfg = Debug|Any CPU {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Debug|x86.ActiveCfg = Debug|Any CPU {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Release|Any CPU.ActiveCfg = Release|Any CPU {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Release|Any CPU.Build.0 = Release|Any CPU + {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Release|ARM.ActiveCfg = Release|Any CPU {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Release|Mixed Platforms.Build.0 = Release|Any CPU {47D3EBB9-0300-4AF8-BAC5-740D51454A63}.Release|x86.ActiveCfg = Release|Any CPU {11F84600-0978-48B9-A28F-63B3781E54B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {11F84600-0978-48B9-A28F-63B3781E54B3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {11F84600-0978-48B9-A28F-63B3781E54B3}.Debug|ARM.ActiveCfg = Debug|Any CPU {11F84600-0978-48B9-A28F-63B3781E54B3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU {11F84600-0978-48B9-A28F-63B3781E54B3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {11F84600-0978-48B9-A28F-63B3781E54B3}.Debug|x86.ActiveCfg = Debug|Any CPU {11F84600-0978-48B9-A28F-63B3781E54B3}.Release|Any CPU.ActiveCfg = Release|Any CPU {11F84600-0978-48B9-A28F-63B3781E54B3}.Release|Any CPU.Build.0 = Release|Any CPU + {11F84600-0978-48B9-A28F-63B3781E54B3}.Release|ARM.ActiveCfg = Release|Any CPU {11F84600-0978-48B9-A28F-63B3781E54B3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {11F84600-0978-48B9-A28F-63B3781E54B3}.Release|Mixed Platforms.Build.0 = Release|Any CPU {11F84600-0978-48B9-A28F-63B3781E54B3}.Release|x86.ActiveCfg = Release|Any CPU {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Debug|ARM.ActiveCfg = Debug|Any CPU {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Debug|x86.ActiveCfg = Debug|Any CPU {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Release|Any CPU.ActiveCfg = Release|Any CPU {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Release|Any CPU.Build.0 = Release|Any CPU + {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Release|ARM.ActiveCfg = Release|Any CPU {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Release|Mixed Platforms.Build.0 = Release|Any CPU {F4D48DF6-316E-4963-B5C1-59CA39B431B7}.Release|x86.ActiveCfg = Release|Any CPU {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Debug|ARM.ActiveCfg = Debug|Any CPU {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Debug|x86.ActiveCfg = Debug|Any CPU {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Release|Any CPU.ActiveCfg = Release|Any CPU {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Release|Any CPU.Build.0 = Release|Any CPU + {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Release|ARM.ActiveCfg = Release|Any CPU {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Release|Mixed Platforms.Build.0 = Release|Any CPU {5FF943A5-260F-4042-B4CE-C4977BAD4EBB}.Release|x86.ActiveCfg = Release|Any CPU {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Debug|ARM.ActiveCfg = Debug|Any CPU {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Debug|x86.ActiveCfg = Debug|Any CPU {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Release|Any CPU.ActiveCfg = Release|Any CPU {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Release|Any CPU.Build.0 = Release|Any CPU + {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Release|ARM.ActiveCfg = Release|Any CPU {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Release|Mixed Platforms.Build.0 = Release|Any CPU {CCC30138-3D68-44D8-AF1A-D22F769EE8DC}.Release|x86.ActiveCfg = Release|Any CPU + {35B2AFEA-0A2A-4E13-B946-60B7DD0D0B34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {35B2AFEA-0A2A-4E13-B946-60B7DD0D0B34}.Debug|Any CPU.Build.0 = Debug|Any CPU + {35B2AFEA-0A2A-4E13-B946-60B7DD0D0B34}.Debug|ARM.ActiveCfg = Debug|ARM + {35B2AFEA-0A2A-4E13-B946-60B7DD0D0B34}.Debug|ARM.Build.0 = Debug|ARM + {35B2AFEA-0A2A-4E13-B946-60B7DD0D0B34}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {35B2AFEA-0A2A-4E13-B946-60B7DD0D0B34}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {35B2AFEA-0A2A-4E13-B946-60B7DD0D0B34}.Debug|x86.ActiveCfg = Debug|Any CPU + {35B2AFEA-0A2A-4E13-B946-60B7DD0D0B34}.Release|Any CPU.ActiveCfg = Release|Any CPU + {35B2AFEA-0A2A-4E13-B946-60B7DD0D0B34}.Release|Any CPU.Build.0 = Release|Any CPU + {35B2AFEA-0A2A-4E13-B946-60B7DD0D0B34}.Release|ARM.ActiveCfg = Release|ARM + {35B2AFEA-0A2A-4E13-B946-60B7DD0D0B34}.Release|ARM.Build.0 = Release|ARM + {35B2AFEA-0A2A-4E13-B946-60B7DD0D0B34}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {35B2AFEA-0A2A-4E13-B946-60B7DD0D0B34}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {35B2AFEA-0A2A-4E13-B946-60B7DD0D0B34}.Release|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/RestSharp/Http.Async.cs b/RestSharp/Http.Async.cs index 69f4a6a33..4af34028a 100644 --- a/RestSharp/Http.Async.cs +++ b/RestSharp/Http.Async.cs @@ -17,6 +17,7 @@ using System; using System.Net; using System.Threading; +using System.Threading.Tasks; using RestSharp.Extensions; #if SILVERLIGHT @@ -35,255 +36,267 @@ 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) - { - return PutPostInternalAsync(httpMethod.ToUpperInvariant(), action); - } - - /// - /// Execute an async GET-style request with the specified HTTP Method. - /// - /// The HTTP method to execute. - /// - public HttpWebRequest AsGetAsync(Action action, string httpMethod) - { - return GetStyleMethodInternalAsync(httpMethod.ToUpperInvariant(), action); - } - - private HttpWebRequest GetStyleMethodInternalAsync(string method, Action callback) - { - HttpWebRequest webRequest = null; - try - { - var url = Url; - webRequest = ConfigureAsyncWebRequest(method, url); - _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; - } + /// + /// HttpWebRequest wrapper (async methods) + /// + public partial class Http + { + private TimeOutState _timeoutState; + + public async Task DeleteAsync() + { + return await GetStyleMethodInternalAsync("DELETE").ConfigureAwait(false); + } + + public async Task GetAsync() + { + return await GetStyleMethodInternalAsync("GET").ConfigureAwait(false); + } + + public async Task HeadAsync() + { + return await GetStyleMethodInternalAsync("HEAD").ConfigureAwait(false); + } + + public async Task OptionsAsync() + { + return await GetStyleMethodInternalAsync("OPTIONS").ConfigureAwait(false); + } + + public async Task PostAsync() + { + return await PutPostInternalAsync("POST").ConfigureAwait(false); + } + + public async Task PutAsync() + { + return await PutPostInternalAsync("PUT").ConfigureAwait(false); + } + + public async Task PatchAsync() + { + return await PutPostInternalAsync("PATCH").ConfigureAwait(false); + } + + /// + /// Execute an async POST-style request with the specified HTTP Method. + /// + /// The HTTP method to execute. + /// + public async Task AsPostAsync(string httpMethod) + { + return await PutPostInternalAsync(httpMethod.ToUpperInvariant()).ConfigureAwait(false); + } + + /// + /// Execute an async GET-style request with the specified HTTP Method. + /// + /// The HTTP method to execute. + /// + public async Task AsGetAsync(string httpMethod) + { + return await GetStyleMethodInternalAsync(httpMethod.ToUpperInvariant()).ConfigureAwait(false); + } + + private async Task GetStyleMethodInternalAsync(string method) + { + try + { + var url = Url; + HttpWebRequest webRequest = ConfigureAsyncWebRequest(method, url); + _timeoutState = new TimeOutState { Request = webRequest }; + return await Task.Factory.FromAsync(webRequest.BeginGetResponse, result => ResponseCallback(result), webRequest).ConfigureAwait(false); + } + catch (Exception ex) + { + return CreateErrorResponse(ex); + } + } - response.ErrorMessage = ex.Message; - response.ErrorException = ex; - response.ResponseStatus = ResponseStatus.Error; - return response; - } + 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; + } - 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; - } + response.ErrorMessage = ex.Message; + response.ErrorException = ex; + response.ResponseStatus = ResponseStatus.Error; + return response; + } - private void WriteRequestBodyAsync(HttpWebRequest webRequest, Action callback) - { - IAsyncResult asyncResult; - _timeoutState = new TimeOutState { Request = webRequest }; + private async Task PutPostInternalAsync(string method) + { + HttpWebRequest webRequest = null; + try + { + webRequest = ConfigureAsyncWebRequest(method, Url); + PreparePostBody(webRequest); + return await WriteRequestBodyAsync(webRequest).ConfigureAwait(false); + } + catch (Exception ex) + { + return CreateErrorResponse(ex); + } + } - if (HasBody || HasFiles || AlwaysMultipartFormData) - { -#if !WINDOWS_PHONE - webRequest.ContentLength = CalculateContentLength(); -#endif - asyncResult = webRequest.BeginGetRequestStream(result => RequestStreamCallback(result, callback), webRequest); - } + private async Task WriteRequestBodyAsync(HttpWebRequest webRequest) + { + IAsyncResult asyncResult; + _timeoutState = new TimeOutState { Request = webRequest }; - else - { - asyncResult = webRequest.BeginGetResponse(r => ResponseCallback(r, callback), webRequest); - } + if (HasBody || HasFiles || AlwaysMultipartFormData) + { +#if !WINDOWS_PHONE || WP8 + webRequest.ContentLength = CalculateContentLength(); +#endif - SetTimeout(asyncResult, _timeoutState); - } + return await Task.Factory.FromAsync(webRequest.BeginGetRequestStream, result => RequestStreamCallback(result).Result, webRequest).ConfigureAwait(false); + } - private long CalculateContentLength() - { - if (RequestBodyBytes != null) - return RequestBodyBytes.Length; + else + { + webRequest.AllowReadStreamBuffering = false; + var task = Task.Factory.FromAsync(webRequest.BeginGetResponse, r => (HttpWebResponse)webRequest.EndGetResponse(r), null); + try + { + var httpWebResponse = await task.ContinueWith( + t => + { + if (t.Exception == null) + return t.Result; + + // Not the best way to fault "continuation" task + // but you can wrap this into your special exception + // and add original exception as a inner exception + throw t.Exception.InnerException; + + // throw CustomException("The request failed!", t.Exception.InnerException); + }).ConfigureAwait(false); + return ExtractResponseData(httpWebResponse); + } + catch (Exception) + { + throw; + } + } - if (!HasFiles && !AlwaysMultipartFormData) - { - return _defaultEncoding.GetByteCount(RequestBody); - } + SetTimeout(asyncResult, _timeoutState); + } - // 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); - } + private long CalculateContentLength() + { + if (RequestBodyBytes != null) + return RequestBodyBytes.Length; - foreach (var param in Parameters) - { - length += _defaultEncoding.GetByteCount(GetMultipartFormData(param)); - } + if (!HasFiles && !AlwaysMultipartFormData) + { + return _defaultEncoding.GetByteCount(RequestBody); + } - length += _defaultEncoding.GetByteCount(GetMultipartFooter()); - return length; - } + // 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); + } - private void RequestStreamCallback(IAsyncResult result, Action callback) - { - var webRequest = (HttpWebRequest)result.AsyncState; + foreach (var param in Parameters) + { + length += _defaultEncoding.GetByteCount(GetMultipartFormData(param)); + } - if (_timeoutState.TimedOut) - { - var response = new HttpResponse {ResponseStatus = ResponseStatus.TimedOut}; - ExecuteCallback(response, callback); - return; - } + length += _defaultEncoding.GetByteCount(GetMultipartFooter()); + return length; + } - // 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; - } + private async Task RequestStreamCallback(IAsyncResult result) + { + var webRequest = (HttpWebRequest)result.AsyncState; - webRequest.BeginGetResponse(r => ResponseCallback(r, callback), webRequest); - } + if (_timeoutState.TimedOut) + { + var response = new HttpResponse { ResponseStatus = ResponseStatus.TimedOut }; + return response; + } - private void SetTimeout(IAsyncResult asyncResult, TimeOutState timeOutState) - { -#if FRAMEWORK - if (Timeout != 0) - { - ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), timeOutState, Timeout, true); - } -#endif - } + // 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) + { + return CreateErrorResponse(ex); + } + return await Task.Factory.FromAsync(webRequest.BeginGetResponse, r => ResponseCallback(r), webRequest).ConfigureAwait(false); + } - private static void TimeoutCallback(object state, bool timedOut) - { - if (!timedOut) - return; + private void SetTimeout(IAsyncResult asyncResult, TimeOutState timeOutState) + { +#if FRAMEWORK || WP8 + if (Timeout != 0) + { + ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), timeOutState, Timeout, true); + } +#endif + } - var timeoutState = state as TimeOutState; + private static void TimeoutCallback(object state, bool timedOut) + { + if (!timedOut) + return; - if (timeoutState == null) - { - return; - } + var timeoutState = state as TimeOutState; - lock (timeoutState) - { - timeoutState.TimedOut = true; - } + if (timeoutState == null) + { + return; + } - if (timeoutState.Request != null) - { - timeoutState.Request.Abort(); - } - } + lock (timeoutState) + { + timeoutState.TimedOut = true; + } - private static void GetRawResponseAsync(IAsyncResult result, Action callback) - { - var response = new HttpResponse(); - response.ResponseStatus = ResponseStatus.None; + if (timeoutState.Request != null) + { + timeoutState.Request.Abort(); + } + } - HttpWebResponse raw = null; + private static HttpWebResponse GetRawResponseAsync(IAsyncResult result) + { + HttpWebResponse raw = null; try { var webRequest = (HttpWebRequest)result.AsyncState; raw = webRequest.EndGetResponse(result) as HttpWebResponse; } - catch(WebException ex) + catch (WebException ex) { - if(ex.Status == WebExceptionStatus.RequestCanceled) + if (ex.Status == WebExceptionStatus.RequestCanceled) { throw ex; } @@ -303,87 +316,86 @@ private static void GetRawResponseAsync(IAsyncResult result, Action callback) - { - var response = new HttpResponse {ResponseStatus = ResponseStatus.None}; + try + { + if (_timeoutState.TimedOut) + { + response.ResponseStatus = ResponseStatus.TimedOut; + return response; + } - 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); - } - } + var raw = GetRawResponseAsync(result); + return ExtractResponseData(raw); + } + catch (Exception ex) + { + return CreateErrorResponse(ex); + } + } - private static void ExecuteCallback(HttpResponse response, Action callback) - { - callback(response); - } + private static void ExecuteCallback(HttpResponse response, Action callback) + { + callback(response); + } - partial void AddAsyncHeaderActions() - { + partial void AddAsyncHeaderActions() + { #if SILVERLIGHT _restrictedHeaderActions.Add("Content-Length", (r, v) => r.ContentLength = Convert.ToInt64(v)); #endif -#if WINDOWS_PHONE +#if WINDOWS_PHONE && !WP8 // 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 - } + } - private HttpWebRequest ConfigureAsyncWebRequest(string method, Uri url) - { + 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); - webRequest.UseDefaultCredentials = false; + var webRequest = (HttpWebRequest)WebRequest.Create(url); + webRequest.UseDefaultCredentials = false; - AppendHeaders(webRequest); - AppendCookies(webRequest); + AppendHeaders(webRequest); + AppendCookies(webRequest); - webRequest.Method = method; + webRequest.Method = method; - // make sure Content-Length header is always sent since default is -1 -#if !WINDOWS_PHONE - // 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; - } + // make sure Content-Length header is always sent since default is -1 +#if !WINDOWS_PHONE || WP8 + // 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 (Credentials != null) + { + webRequest.Credentials = Credentials; + } #if !SILVERLIGHT - if(UserAgent.HasValue()) - { - webRequest.UserAgent = UserAgent; - } + if (UserAgent.HasValue()) + { + webRequest.UserAgent = UserAgent; + } #endif #if FRAMEWORK @@ -412,15 +424,15 @@ private HttpWebRequest ConfigureAsyncWebRequest(string method, Uri url) #endif #if !SILVERLIGHT - webRequest.AllowAutoRedirect = FollowRedirects; + webRequest.AllowAutoRedirect = FollowRedirects; #endif - return webRequest; - } - - private class TimeOutState - { - public bool TimedOut { get; set; } - public HttpWebRequest Request { get; set; } - } - } + return webRequest; + } + + private class TimeOutState + { + public bool TimedOut { get; set; } + public HttpWebRequest Request { get; set; } + } + } } diff --git a/RestSharp/Http.cs b/RestSharp/Http.cs index a1ef10059..659f9a449 100644 --- a/RestSharp/Http.cs +++ b/RestSharp/Http.cs @@ -21,6 +21,7 @@ using System.Net; using System.Security.Cryptography.X509Certificates; using System.Text; +using System.Threading.Tasks; using RestSharp.Extensions; #if WINDOWS_PHONE @@ -29,101 +30,101 @@ namespace RestSharp { - /// - /// HttpWebRequest wrapper - /// - public partial class Http : IHttp, IHttpFactory - { - private const string _lineBreak = "\r\n"; - private static readonly Encoding _defaultEncoding = Encoding.UTF8; - - /// - /// Creates an IHttp - /// - /// - public IHttp Create() - { - return new Http(); - } + /// + /// HttpWebRequest wrapper + /// + public partial class Http : IHttp, IHttpFactory + { + private const string _lineBreak = "\r\n"; + private static readonly Encoding _defaultEncoding = Encoding.UTF8; - /// - /// True if this HTTP request has any HTTP parameters - /// - protected bool HasParameters - { - get - { - return Parameters.Any(); - } - } + /// + /// Creates an IHttp + /// + /// + public IHttp Create() + { + return new Http(); + } - /// - /// True if this HTTP request has any HTTP cookies - /// - protected bool HasCookies - { - get - { - return Cookies.Any(); - } - } + /// + /// True if this HTTP request has any HTTP parameters + /// + protected bool HasParameters + { + get + { + return Parameters.Any(); + } + } - /// - /// True if a request body has been specified - /// - protected bool HasBody - { - get - { - return RequestBodyBytes != null || !string.IsNullOrEmpty(RequestBody); - } - } + /// + /// True if this HTTP request has any HTTP cookies + /// + protected bool HasCookies + { + get + { + return Cookies.Any(); + } + } - /// - /// True if files have been set to be uploaded - /// - protected bool HasFiles - { - get - { - return Files.Any(); - } - } + /// + /// True if a request body has been specified + /// + protected bool HasBody + { + get + { + return RequestBodyBytes != null || !string.IsNullOrEmpty(RequestBody); + } + } - /// - /// Always send a multipart/form-data request - even when no Files are present. - /// - public bool AlwaysMultipartFormData { get; set; } - - /// - /// UserAgent to be sent with request - /// - public string UserAgent { get; set; } - /// - /// Timeout in milliseconds to be used for the request - /// - public int Timeout { get; set; } - /// - /// System.Net.ICredentials to be sent with request - /// - public ICredentials Credentials { get; set; } - /// - /// The System.Net.CookieContainer to be used for the request - /// - public CookieContainer CookieContainer { get; set; } - /// - /// The method to use to write the response instead of reading into RawBytes - /// - public Action ResponseWriter { get; set; } - /// - /// Collection of files to be sent with request - /// - public IList Files { get; private set; } + /// + /// True if files have been set to be uploaded + /// + protected bool HasFiles + { + get + { + return Files.Any(); + } + } + + /// + /// Always send a multipart/form-data request - even when no Files are present. + /// + public bool AlwaysMultipartFormData { get; set; } + + /// + /// UserAgent to be sent with request + /// + public string UserAgent { get; set; } + /// + /// Timeout in milliseconds to be used for the request + /// + public int Timeout { get; set; } + /// + /// System.Net.ICredentials to be sent with request + /// + public ICredentials Credentials { get; set; } + /// + /// The System.Net.CookieContainer to be used for the request + /// + public CookieContainer CookieContainer { get; set; } + /// + /// The method to use to write the response instead of reading into RawBytes + /// + public Action ResponseWriter { get; set; } + /// + /// Collection of files to be sent with request + /// + public IList Files { get; private set; } #if !SILVERLIGHT - /// - /// Whether or not HTTP 3xx response redirects should be automatically followed - /// - public bool FollowRedirects { get; set; } + /// + /// Whether or not HTTP 3xx response redirects should be automatically followed + /// + public bool FollowRedirects { get; set; } #endif #if FRAMEWORK /// @@ -135,34 +136,34 @@ protected bool HasFiles /// public int? MaxRedirects { get; set; } #endif - /// - /// HTTP headers to be sent with request - /// - public IList Headers { get; private set; } - /// - /// HTTP parameters (QueryString or Form values) to be sent with request - /// - public IList Parameters { get; private set; } - /// - /// HTTP cookies to be sent with request - /// - public IList Cookies { get; private set; } - /// - /// Request body to be sent with request - /// - public string RequestBody { get; set; } - /// - /// Content type of the request body. - /// - public string RequestContentType { get; set; } - /// - /// An alternative to RequestBody, for when the caller already has the byte array. - /// - public byte[] RequestBodyBytes { get; set; } - /// - /// URL to call for this request - /// - public Uri Url { get; set; } + /// + /// HTTP headers to be sent with request + /// + public IList Headers { get; private set; } + /// + /// HTTP parameters (QueryString or Form values) to be sent with request + /// + public IList Parameters { get; private set; } + /// + /// HTTP cookies to be sent with request + /// + public IList Cookies { get; private set; } + /// + /// Request body to be sent with request + /// + public string RequestBody { get; set; } + /// + /// Content type of the request body. + /// + public string RequestContentType { get; set; } + /// + /// An alternative to RequestBody, for when the caller already has the byte array. + /// + public byte[] RequestBodyBytes { get; set; } + /// + /// URL to call for this request + /// + public Uri Url { get; set; } #if FRAMEWORK /// @@ -171,28 +172,28 @@ protected bool HasFiles public IWebProxy Proxy { get; set; } #endif - /// - /// Default constructor - /// - public Http() - { - Headers = new List(); - Files = new List(); - Parameters = new List(); - Cookies = new List(); + /// + /// Default constructor + /// + public Http() + { + Headers = new List(); + Files = new List(); + Parameters = new List(); + Cookies = new List(); - _restrictedHeaderActions = new Dictionary>(StringComparer.OrdinalIgnoreCase); + _restrictedHeaderActions = new Dictionary>(StringComparer.OrdinalIgnoreCase); - AddSharedHeaderActions(); - AddSyncHeaderActions(); - } + AddSharedHeaderActions(); + AddSyncHeaderActions(); + } - partial void AddSyncHeaderActions(); - partial void AddAsyncHeaderActions(); - private void AddSharedHeaderActions() - { - _restrictedHeaderActions.Add("Accept", (r, v) => r.Accept = v); - _restrictedHeaderActions.Add("Content-Type", (r, v) => r.ContentType = v); + partial void AddSyncHeaderActions(); + partial void AddAsyncHeaderActions(); + private void AddSharedHeaderActions() + { + _restrictedHeaderActions.Add("Accept", (r, v) => r.Accept = v); + _restrictedHeaderActions.Add("Content-Type", (r, v) => r.ContentType = v); #if NET4 _restrictedHeaderActions.Add("Date", (r, v) => { @@ -204,65 +205,65 @@ private void AddSharedHeaderActions() }); _restrictedHeaderActions.Add("Host", (r, v) => r.Host = v); #else - _restrictedHeaderActions.Add("Date", (r, v) => { /* Set by system */ }); - _restrictedHeaderActions.Add("Host", (r, v) => { /* Set by system */ }); + _restrictedHeaderActions.Add("Date", (r, v) => { /* Set by system */ }); + _restrictedHeaderActions.Add("Host", (r, v) => { /* Set by system */ }); #endif #if FRAMEWORK _restrictedHeaderActions.Add("Range", (r, v) => { AddRange(r, v); }); #endif - } + } - private const string FormBoundary = "-----------------------------28947758029299"; - private static string GetMultipartFormContentType() - { - return string.Format("multipart/form-data; boundary={0}", FormBoundary); - } - - private static string GetMultipartFileHeader (HttpFile file) - { - return string.Format ("--{0}{4}Content-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"{4}Content-Type: {3}{4}{4}", - FormBoundary, file.Name, file.FileName, file.ContentType ?? "application/octet-stream", _lineBreak); - } - - private static string GetMultipartFormData (HttpParameter param) - { - return string.Format ("--{0}{3}Content-Disposition: form-data; name=\"{1}\"{3}{3}{2}{3}", - FormBoundary, param.Name, param.Value, _lineBreak); - } - - private static string GetMultipartFooter () - { - return string.Format ("--{0}--{1}", FormBoundary, _lineBreak); - } - - private readonly IDictionary> _restrictedHeaderActions; + private const string FormBoundary = "-----------------------------28947758029299"; + private static string GetMultipartFormContentType() + { + return string.Format("multipart/form-data; boundary={0}", FormBoundary); + } - // handle restricted headers the .NET way - thanks @dimebrain! - // http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.headers.aspx - private void AppendHeaders(HttpWebRequest webRequest) - { - foreach (var header in Headers) - { - if (_restrictedHeaderActions.ContainsKey(header.Name)) - { - _restrictedHeaderActions[header.Name].Invoke(webRequest, header.Value); - } - else - { + private static string GetMultipartFileHeader(HttpFile file) + { + return string.Format("--{0}{4}Content-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"{4}Content-Type: {3}{4}{4}", + FormBoundary, file.Name, file.FileName, file.ContentType ?? "application/octet-stream", _lineBreak); + } + + private static string GetMultipartFormData(HttpParameter param) + { + return string.Format("--{0}{3}Content-Disposition: form-data; name=\"{1}\"{3}{3}{2}{3}", + FormBoundary, param.Name, param.Value, _lineBreak); + } + + private static string GetMultipartFooter() + { + return string.Format("--{0}--{1}", FormBoundary, _lineBreak); + } + + private readonly IDictionary> _restrictedHeaderActions; + + // handle restricted headers the .NET way - thanks @dimebrain! + // http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.headers.aspx + private void AppendHeaders(HttpWebRequest webRequest) + { + foreach (var header in Headers) + { + if (_restrictedHeaderActions.ContainsKey(header.Name)) + { + _restrictedHeaderActions[header.Name].Invoke(webRequest, header.Value); + } + else + { #if FRAMEWORK webRequest.Headers.Add(header.Name, header.Value); #else - webRequest.Headers[header.Name] = header.Value; + webRequest.Headers[header.Name] = header.Value; #endif - } - } - } + } + } + } - private void AppendCookies(HttpWebRequest webRequest) - { - webRequest.CookieContainer = this.CookieContainer ?? new CookieContainer(); - foreach (var httpCookie in Cookies) - { + private void AppendCookies(HttpWebRequest webRequest) + { + webRequest.CookieContainer = this.CookieContainer ?? new CookieContainer(); + foreach (var httpCookie in Cookies) + { #if FRAMEWORK var cookie = new Cookie { @@ -272,146 +273,148 @@ private void AppendCookies(HttpWebRequest webRequest) }; webRequest.CookieContainer.Add(cookie); #else - var cookie = new Cookie - { - Name = httpCookie.Name, - Value = httpCookie.Value - }; - var uri = webRequest.RequestUri; - webRequest.CookieContainer.Add(new Uri(string.Format("{0}://{1}", uri.Scheme, uri.Host)), cookie); + var cookie = new Cookie + { + Name = httpCookie.Name, + Value = httpCookie.Value + }; + var uri = webRequest.RequestUri; + webRequest.CookieContainer.Add(new Uri(string.Format("{0}://{1}", uri.Scheme, uri.Host)), cookie); #endif - } - } + } + } - private string EncodeParameters() - { - var querystring = new StringBuilder(); - foreach (var p in Parameters) - { - if (querystring.Length > 1) - querystring.Append("&"); - querystring.AppendFormat("{0}={1}", p.Name.UrlEncode(), p.Value.UrlEncode()); - } + private string EncodeParameters() + { + var querystring = new StringBuilder(); + foreach (var p in Parameters) + { + if (querystring.Length > 1) + querystring.Append("&"); + querystring.AppendFormat("{0}={1}", p.Name.UrlEncode(), p.Value.UrlEncode()); + } - return querystring.ToString(); - } + return querystring.ToString(); + } - private void PreparePostBody(HttpWebRequest webRequest) - { - if (HasFiles || AlwaysMultipartFormData) - { - webRequest.ContentType = GetMultipartFormContentType(); - } - else if(HasParameters) - { - webRequest.ContentType = "application/x-www-form-urlencoded"; - RequestBody = EncodeParameters(); - } - else if(HasBody) - { - webRequest.ContentType = RequestContentType; - } - } - - private static void WriteStringTo(Stream stream, string toWrite) - { - var bytes = _defaultEncoding.GetBytes(toWrite); - stream.Write(bytes, 0, bytes.Length); - } - - private void WriteMultipartFormData(Stream requestStream) - { - foreach (var param in Parameters) - { - WriteStringTo(requestStream, GetMultipartFormData(param)); - } + private void PreparePostBody(HttpWebRequest webRequest) + { + if (HasFiles || AlwaysMultipartFormData) + { + webRequest.ContentType = GetMultipartFormContentType(); + } + else if (HasParameters) + { + webRequest.ContentType = "application/x-www-form-urlencoded"; + RequestBody = EncodeParameters(); + } + else if (HasBody) + { + webRequest.ContentType = RequestContentType; + } + } - foreach (var file in Files) - { - // Add just the first part of this param, since we will write the file data directly to the Stream - WriteStringTo(requestStream, GetMultipartFileHeader(file)); + private static void WriteStringTo(Stream stream, string toWrite) + { + var bytes = _defaultEncoding.GetBytes(toWrite); + stream.Write(bytes, 0, bytes.Length); + } - // Write the file data directly to the Stream, rather than serializing it to a string. - file.Writer(requestStream); - WriteStringTo(requestStream, _lineBreak); - } + private void WriteMultipartFormData(Stream requestStream) + { + foreach (var param in Parameters) + { + WriteStringTo(requestStream, GetMultipartFormData(param)); + } - WriteStringTo(requestStream, GetMultipartFooter()); - } + foreach (var file in Files) + { + // Add just the first part of this param, since we will write the file data directly to the Stream + WriteStringTo(requestStream, GetMultipartFileHeader(file)); - private void ExtractResponseData(HttpResponse response, HttpWebResponse webResponse) - { - using (webResponse) - { + // Write the file data directly to the Stream, rather than serializing it to a string. + file.Writer(requestStream); + WriteStringTo(requestStream, _lineBreak); + } + + WriteStringTo(requestStream, GetMultipartFooter()); + } + + private HttpResponse ExtractResponseData(HttpWebResponse webResponse) + { + using (webResponse) + { + var response = new HttpResponse(); #if FRAMEWORK response.ContentEncoding = webResponse.ContentEncoding; response.Server = webResponse.Server; #endif - response.ContentType = webResponse.ContentType; - response.ContentLength = webResponse.ContentLength; - Stream webResponseStream = webResponse.GetResponseStream(); + response.ContentType = webResponse.ContentType; + response.ContentLength = webResponse.ContentLength; + Stream webResponseStream = webResponse.GetResponseStream(); #if WINDOWS_PHONE - if (String.Equals(webResponse.Headers[HttpRequestHeader.ContentEncoding], "gzip", StringComparison.OrdinalIgnoreCase)) - { - var gzStream = new GZipStream(webResponseStream); - ProcessResponseStream(gzStream, response); - } - else - { - ProcessResponseStream(webResponseStream, response); - } + if (String.Equals(webResponse.Headers[HttpRequestHeader.ContentEncoding], "gzip", StringComparison.OrdinalIgnoreCase)) + { + var gzStream = new GZipStream(webResponseStream); + ProcessResponseStream(gzStream, response); + } + else + { + ProcessResponseStream(webResponseStream, response); + } #else ProcessResponseStream(webResponseStream, response); #endif - response.StatusCode = webResponse.StatusCode; - response.StatusDescription = webResponse.StatusDescription; - response.ResponseUri = webResponse.ResponseUri; - response.ResponseStatus = ResponseStatus.Completed; + response.StatusCode = webResponse.StatusCode; + response.StatusDescription = webResponse.StatusDescription; + response.ResponseUri = webResponse.ResponseUri; + response.ResponseStatus = ResponseStatus.Completed; - if (webResponse.Cookies != null) - { - foreach (Cookie cookie in webResponse.Cookies) - { - response.Cookies.Add(new HttpCookie { - Comment = cookie.Comment, - CommentUri = cookie.CommentUri, - Discard = cookie.Discard, - Domain = cookie.Domain, - Expired = cookie.Expired, - Expires = cookie.Expires, - HttpOnly = cookie.HttpOnly, - Name = cookie.Name, - Path = cookie.Path, - Port = cookie.Port, - Secure = cookie.Secure, - TimeStamp = cookie.TimeStamp, - Value = cookie.Value, - Version = cookie.Version - }); - } - } + if (webResponse.Cookies != null) + { + foreach (Cookie cookie in webResponse.Cookies) + { + response.Cookies.Add(new HttpCookie + { + Comment = cookie.Comment, + CommentUri = cookie.CommentUri, + Discard = cookie.Discard, + Domain = cookie.Domain, + Expired = cookie.Expired, + Expires = cookie.Expires, + HttpOnly = cookie.HttpOnly, + Name = cookie.Name, + Path = cookie.Path, + Port = cookie.Port, + Secure = cookie.Secure, + TimeStamp = cookie.TimeStamp, + Value = cookie.Value, + Version = cookie.Version + }); + } + } - foreach (var headerName in webResponse.Headers.AllKeys) - { - var headerValue = webResponse.Headers[headerName]; - response.Headers.Add(new HttpHeader { Name = headerName, Value = headerValue }); - } + foreach (var headerName in webResponse.Headers.AllKeys) + { + var headerValue = webResponse.Headers[headerName]; + response.Headers.Add(new HttpHeader { Name = headerName, Value = headerValue }); + } - webResponse.Close(); - } - } + return response; + } + } - private void ProcessResponseStream(Stream webResponseStream, HttpResponse response) - { - if (ResponseWriter == null) - { - response.RawBytes = webResponseStream.ReadAsBytes(); - } - else - { - ResponseWriter(webResponseStream); - } - } + private void ProcessResponseStream(Stream webResponseStream, HttpResponse response) + { + if (ResponseWriter == null) + { + response.RawBytes = webResponseStream.ReadAsBytes(); + } + else + { + ResponseWriter(webResponseStream); + } + } #if FRAMEWORK private void AddRange(HttpWebRequest r, string range) @@ -427,5 +430,5 @@ private void AddRange(HttpWebRequest r, string range) r.AddRange(from, to); } #endif - } + } } \ No newline at end of file diff --git a/RestSharp/IHttp.cs b/RestSharp/IHttp.cs index c12e9f55e..6affc14d0 100644 --- a/RestSharp/IHttp.cs +++ b/RestSharp/IHttp.cs @@ -19,53 +19,54 @@ using System.IO; using System.Net; using System.Security.Cryptography.X509Certificates; +using System.Threading.Tasks; namespace RestSharp { - public interface IHttp - { - Action ResponseWriter { get; set; } - CookieContainer CookieContainer { get; set; } - ICredentials Credentials { get; set; } + public interface IHttp + { + Action ResponseWriter { get; set; } + CookieContainer CookieContainer { get; set; } + ICredentials Credentials { get; set; } - /// - /// Always send a multipart/form-data request - even when no Files are present. - /// - bool AlwaysMultipartFormData { get; set; } + /// + /// Always send a multipart/form-data request - even when no Files are present. + /// + bool AlwaysMultipartFormData { get; set; } - string UserAgent { get; set; } - int Timeout { get; set; } + string UserAgent { get; set; } + int Timeout { get; set; } #if !SILVERLIGHT - bool FollowRedirects { get; set; } + bool FollowRedirects { get; set; } #endif #if FRAMEWORK X509CertificateCollection ClientCertificates { get; set; } int? MaxRedirects { get; set; } #endif - IList Headers { get; } - IList Parameters { get; } - IList Files { get; } - IList Cookies { get; } - string RequestBody { get; set; } - string RequestContentType { get; set; } + IList Headers { get; } + IList Parameters { get; } + IList Files { get; } + IList Cookies { get; } + string RequestBody { get; set; } + string RequestContentType { get; set; } - /// - /// An alternative to RequestBody, for when the caller already has the byte array. - /// - byte[] RequestBodyBytes { get; set; } + /// + /// An alternative to RequestBody, for when the caller already has the byte array. + /// + byte[] RequestBodyBytes { get; set; } - Uri Url { get; set; } + Uri Url { get; set; } - HttpWebRequest DeleteAsync(Action action); - HttpWebRequest GetAsync(Action action); - HttpWebRequest HeadAsync(Action action); - HttpWebRequest OptionsAsync(Action action); - HttpWebRequest PostAsync(Action action); - HttpWebRequest PutAsync(Action action); - HttpWebRequest PatchAsync(Action action); - HttpWebRequest AsPostAsync(Action action, string httpMethod); - HttpWebRequest AsGetAsync(Action action, string httpMethod); + Task DeleteAsync(); + Task GetAsync(); + Task HeadAsync(); + Task OptionsAsync(); + Task PostAsync(); + Task PutAsync(); + Task PatchAsync(); + Task AsPostAsync(string httpMethod); + Task AsGetAsync(string httpMethod); #if FRAMEWORK HttpResponse Delete(); @@ -80,5 +81,5 @@ public interface IHttp IWebProxy Proxy { get; set; } #endif - } + } } \ No newline at end of file diff --git a/RestSharp/IRestClient.cs b/RestSharp/IRestClient.cs index 8dcc0e2c5..caaed230c 100644 --- a/RestSharp/IRestClient.cs +++ b/RestSharp/IRestClient.cs @@ -18,56 +18,56 @@ using System.Net; using System.Collections.Generic; using System.Security.Cryptography.X509Certificates; -#if NET4 || MONODROID || MONOTOUCH +#if NET4 || WP8 || MONODROID || MONOTOUCH using System.Threading; using System.Threading.Tasks; #endif namespace RestSharp { - /// - /// - /// - public interface IRestClient - { - /// - /// - /// - CookieContainer CookieContainer { get; set; } - /// - /// - /// - string UserAgent { get; set; } - /// - /// - /// - int Timeout { get; set; } - /// - /// - /// - bool UseSynchronizationContext { get; set; } - /// - /// - /// - IAuthenticator Authenticator { get; set; } - /// - /// - /// - string BaseUrl { get; set; } - /// - /// - /// - IList DefaultParameters { get; } - /// - /// - /// - /// - RestRequestAsyncHandle ExecuteAsync(IRestRequest request, Action callback); - /// - /// - /// - /// - RestRequestAsyncHandle ExecuteAsync(IRestRequest request, Action, RestRequestAsyncHandle> callback); + /// + /// + /// + public interface IRestClient + { + /// + /// + /// + CookieContainer CookieContainer { get; set; } + /// + /// + /// + string UserAgent { get; set; } + /// + /// + /// + int Timeout { get; set; } + /// + /// + /// + bool UseSynchronizationContext { get; set; } + /// + /// + /// + IAuthenticator Authenticator { get; set; } + /// + /// + /// + string BaseUrl { get; set; } + /// + /// + /// + IList DefaultParameters { get; } + /// + /// + /// + /// + Task ExecuteAsync(IRestRequest request); + /// + /// + /// + /// + Task> ExecuteAsync(IRestRequest request); #if FRAMEWORK /// @@ -80,41 +80,41 @@ public interface IRestClient IWebProxy Proxy { get; set; } #endif - Uri BuildUri(IRestRequest request); - - /// - /// Executes a GET-style request and callback asynchronously, authenticating if needed - /// - /// Request to be executed - /// Callback function to be executed upon completion providing access to the async handle. - /// The HTTP method to execute - RestRequestAsyncHandle ExecuteAsyncGet(IRestRequest request, Action callback, string httpMethod); - - /// - /// Executes a POST-style request and callback asynchronously, authenticating if needed - /// - /// Request to be executed - /// Callback function to be executed upon completion providing access to the async handle. - /// The HTTP method to execute - RestRequestAsyncHandle ExecuteAsyncPost(IRestRequest request, Action callback, string httpMethod); - - /// - /// Executes a GET-style request and callback asynchronously, authenticating if needed - /// - /// Target deserialization type - /// Request to be executed - /// Callback function to be executed upon completion - /// The HTTP method to execute - RestRequestAsyncHandle ExecuteAsyncGet(IRestRequest request, Action, RestRequestAsyncHandle> callback, string httpMethod); - - /// - /// Executes a GET-style request and callback asynchronously, authenticating if needed - /// - /// Target deserialization type - /// Request to be executed - /// Callback function to be executed upon completion - /// The HTTP method to execute - RestRequestAsyncHandle ExecuteAsyncPost(IRestRequest request, Action, RestRequestAsyncHandle> callback, string httpMethod); + Uri BuildUri(IRestRequest request); + + /// + /// Executes a GET-style request and callback asynchronously, authenticating if needed + /// + /// Request to be executed + /// Callback function to be executed upon completion providing access to the async handle. + /// The HTTP method to execute + Task ExecuteAsyncGet(IRestRequest request, string httpMethod); + + /// + /// Executes a POST-style request and callback asynchronously, authenticating if needed + /// + /// Request to be executed + /// Callback function to be executed upon completion providing access to the async handle. + /// The HTTP method to execute + Task ExecuteAsyncPost(IRestRequest request, string httpMethod); + + /// + /// Executes a GET-style request and callback asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + /// Callback function to be executed upon completion + /// The HTTP method to execute + Task> ExecuteAsyncGet(IRestRequest request, string httpMethod); + + /// + /// Executes a GET-style request and callback asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + /// Callback function to be executed upon completion + /// The HTTP method to execute + Task> ExecuteAsyncPost(IRestRequest request, string httpMethod); #if FRAMEWORK IRestResponse ExecuteAsGet(IRestRequest request, string httpMethod); @@ -123,90 +123,90 @@ public interface IRestClient IRestResponse ExecuteAsPost(IRestRequest request, string httpMethod) where T : new(); #endif -#if NET4 || MONODROID || MONOTOUCH - /// - /// Executes the request and callback asynchronously, authenticating if needed - /// - /// Target deserialization type - /// Request to be executed - /// The cancellation token - Task> ExecuteTaskAsync(IRestRequest request, CancellationToken token); - - /// - /// Executes the request asynchronously, authenticating if needed - /// - /// Target deserialization type - /// Request to be executed - Task> ExecuteTaskAsync(IRestRequest request); - - /// - /// Executes a GET-style request asynchronously, authenticating if needed - /// - /// Target deserialization type - /// Request to be executed - Task> ExecuteGetTaskAsync(IRestRequest request); - - /// - /// Executes a GET-style request asynchronously, authenticating if needed - /// - /// Target deserialization type - /// Request to be executed - /// The cancellation token - Task> ExecuteGetTaskAsync(IRestRequest request, CancellationToken token); - - /// - /// Executes a POST-style request asynchronously, authenticating if needed - /// - /// Target deserialization type - /// Request to be executed - Task> ExecutePostTaskAsync(IRestRequest request); - - /// - /// Executes a POST-style request asynchronously, authenticating if needed - /// - /// Target deserialization type - /// Request to be executed - /// The cancellation token - Task> ExecutePostTaskAsync(IRestRequest request, CancellationToken token); - - /// - /// Executes the request and callback asynchronously, authenticating if needed - /// - /// Request to be executed - /// The cancellation token - Task ExecuteTaskAsync(IRestRequest request, CancellationToken token); - - /// - /// Executes the request asynchronously, authenticating if needed - /// - /// Request to be executed - Task ExecuteTaskAsync(IRestRequest request); - - /// - /// Executes a GET-style asynchronously, authenticating if needed - /// - /// Request to be executed - Task ExecuteGetTaskAsync(IRestRequest request); - - /// - /// Executes a GET-style asynchronously, authenticating if needed - /// - /// Request to be executed - /// The cancellation token - Task ExecuteGetTaskAsync(IRestRequest request, CancellationToken token); - - /// - /// Executes a POST-style asynchronously, authenticating if needed - /// - /// Request to be executed - Task ExecutePostTaskAsync(IRestRequest request); - - /// - /// Executes a POST-style asynchronously, authenticating if needed - /// - /// Request to be executed - /// The cancellation token - Task ExecutePostTaskAsync(IRestRequest request, CancellationToken token); +#if NET4 || WP8 || MONODROID || MONOTOUCH + /// + /// Executes the request and callback asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + /// The cancellation token + Task> ExecuteTaskAsync(IRestRequest request, CancellationToken token); + + /// + /// Executes the request asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + Task> ExecuteTaskAsync(IRestRequest request); + + /// + /// Executes a GET-style request asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + Task> ExecuteGetTaskAsync(IRestRequest request); + + /// + /// Executes a GET-style request asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + /// The cancellation token + Task> ExecuteGetTaskAsync(IRestRequest request, CancellationToken token); + + /// + /// Executes a POST-style request asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + Task> ExecutePostTaskAsync(IRestRequest request); + + /// + /// Executes a POST-style request asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + /// The cancellation token + Task> ExecutePostTaskAsync(IRestRequest request, CancellationToken token); + + /// + /// Executes the request and callback asynchronously, authenticating if needed + /// + /// Request to be executed + /// The cancellation token + Task ExecuteTaskAsync(IRestRequest request, CancellationToken token); + + /// + /// Executes the request asynchronously, authenticating if needed + /// + /// Request to be executed + Task ExecuteTaskAsync(IRestRequest request); + + /// + /// Executes a GET-style asynchronously, authenticating if needed + /// + /// Request to be executed + Task ExecuteGetTaskAsync(IRestRequest request); + + /// + /// Executes a GET-style asynchronously, authenticating if needed + /// + /// Request to be executed + /// The cancellation token + Task ExecuteGetTaskAsync(IRestRequest request, CancellationToken token); + + /// + /// Executes a POST-style asynchronously, authenticating if needed + /// + /// Request to be executed + Task ExecutePostTaskAsync(IRestRequest request); + + /// + /// Executes a POST-style asynchronously, authenticating if needed + /// + /// Request to be executed + /// The cancellation token + Task ExecutePostTaskAsync(IRestRequest request, CancellationToken token); #endif - } + } } diff --git a/RestSharp/RestClient.Async.cs b/RestSharp/RestClient.Async.cs index ce19f7054..1bfe97068 100644 --- a/RestSharp/RestClient.Async.cs +++ b/RestSharp/RestClient.Async.cs @@ -15,373 +15,278 @@ #endregion using System; -using System.Collections.Generic; -using System.Linq; using System.Threading; -#if NET4 || MONODROID || MONOTOUCH +#if NET4 || WP8 || MONODROID || MONOTOUCH using System.Threading.Tasks; #endif -using System.Text; -using System.Net; - -using RestSharp.Extensions; namespace RestSharp { - 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) - { - - string method = Enum.GetName(typeof (Method), request.Method); - 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); - } - } - - /// - /// Executes a GET-style request and callback asynchronously, authenticating if needed - /// - /// Request to be executed - /// Callback function to be executed upon completion providing access to the async handle. - /// The HTTP method to execute - public virtual RestRequestAsyncHandle ExecuteAsyncGet(IRestRequest request, Action callback, string httpMethod) - { - return ExecuteAsync(request, callback, httpMethod, DoAsGetAsync); - } - - /// - /// Executes a POST-style request and callback asynchronously, authenticating if needed - /// - /// Request to be executed - /// Callback function to be executed upon completion providing access to the async handle. - /// The HTTP method to execute - public virtual RestRequestAsyncHandle ExecuteAsyncPost(IRestRequest request, Action callback, string httpMethod) - { - request.Method = Method.POST; // Required by RestClient.BuildUri... - return ExecuteAsync(request, callback, httpMethod, DoAsPostAsync); - } - - private RestRequestAsyncHandle ExecuteAsync(IRestRequest request, Action callback, string httpMethod, Func, string, HttpWebRequest> getWebRequest) - { - var http = HttpFactory.Create(); - AuthenticateIfNeeded(this, request); - - ConfigureHttp(request, http); - - var asyncHandle = new RestRequestAsyncHandle(); - - Action response_cb = r => ProcessResponse(request, r, asyncHandle, callback); - - if (UseSynchronizationContext && SynchronizationContext.Current != null) - { - var ctx = SynchronizationContext.Current; - var cb = response_cb; - - response_cb = resp => ctx.Post(s => cb(resp), null); - } - - asyncHandle.WebRequest = getWebRequest(http, response_cb, httpMethod); - return asyncHandle; - } - - private static HttpWebRequest DoAsGetAsync(IHttp http, Action response_cb, string method) - { - return http.AsGetAsync(response_cb, method); - } - - private static HttpWebRequest DoAsPostAsync(IHttp http, Action response_cb, string method) - { - return http.AsPostAsync(response_cb, method); - } - - private void ProcessResponse(IRestRequest request, HttpResponse httpResponse, RestRequestAsyncHandle asyncHandle, Action callback) - { - var restResponse = ConvertToRestResponse(request, httpResponse); - callback(restResponse, asyncHandle); - } - - /// - /// Executes the request and callback asynchronously, authenticating if needed - /// - /// Target deserialization type - /// Request to be executed - /// Callback function to be executed upon completion - public virtual RestRequestAsyncHandle ExecuteAsync(IRestRequest request, Action, RestRequestAsyncHandle> callback) - { - return ExecuteAsync(request, (response, asyncHandle) => DeserializeResponse(request, callback, response, asyncHandle)); - } - - /// - /// Executes a GET-style request and callback asynchronously, authenticating if needed - /// - /// Target deserialization type - /// Request to be executed - /// Callback function to be executed upon completion - /// The HTTP method to execute - public virtual RestRequestAsyncHandle ExecuteAsyncGet(IRestRequest request, Action, RestRequestAsyncHandle> callback, string httpMethod) - { - return ExecuteAsyncGet(request, (response, asyncHandle) => DeserializeResponse(request, callback, response, asyncHandle), httpMethod); - } - - /// - /// Executes a POST-style request and callback asynchronously, authenticating if needed - /// - /// Target deserialization type - /// Request to be executed - /// Callback function to be executed upon completion - /// The HTTP method to execute - public virtual RestRequestAsyncHandle ExecuteAsyncPost(IRestRequest request, Action, RestRequestAsyncHandle> callback, string httpMethod) - { - return ExecuteAsyncPost(request, (response, asyncHandle) => DeserializeResponse(request, callback, response, asyncHandle), httpMethod); - } - - private void DeserializeResponse(IRestRequest request, Action, RestRequestAsyncHandle> callback, IRestResponse response, RestRequestAsyncHandle asyncHandle) - { - IRestResponse restResponse = response as RestResponse; - if (response.ResponseStatus == ResponseStatus.Completed) - { - restResponse = Deserialize(request, response); - } - - callback(restResponse, asyncHandle); - } - -#if NET4 || MONODROID || MONOTOUCH - /// - /// Executes a GET-style request asynchronously, authenticating if needed - /// - /// Target deserialization type - /// Request to be executed - public virtual Task> ExecuteGetTaskAsync(IRestRequest request) - { - return ExecuteGetTaskAsync(request, CancellationToken.None); - } - - /// - /// Executes a GET-style request asynchronously, authenticating if needed - /// - /// Target deserialization type - /// Request to be executed - /// The cancellation token - public virtual Task> ExecuteGetTaskAsync(IRestRequest request, CancellationToken token) - { - if (request == null) - { - throw new ArgumentNullException("request"); - } - - request.Method = Method.GET; - return ExecuteTaskAsync(request, token); - } - - /// - /// Executes a POST-style request asynchronously, authenticating if needed - /// - /// Target deserialization type - /// Request to be executed - public virtual Task> ExecutePostTaskAsync(IRestRequest request) - { - return ExecutePostTaskAsync(request, CancellationToken.None); - } - - /// - /// Executes a POST-style request asynchronously, authenticating if needed - /// - /// Target deserialization type - /// Request to be executed - /// The cancellation token - public virtual Task> ExecutePostTaskAsync(IRestRequest request, CancellationToken token) - { - if (request == null) - { - throw new ArgumentNullException("request"); - } - - request.Method = Method.POST; - return ExecuteTaskAsync(request, token); - } - - /// - /// Executes the request asynchronously, authenticating if needed - /// - /// Target deserialization type - /// Request to be executed - public virtual Task> ExecuteTaskAsync(IRestRequest request) - { - return ExecuteTaskAsync(request, CancellationToken.None); - } - - /// - /// Executes the request asynchronously, authenticating if needed - /// - /// Target deserialization type - /// Request to be executed - /// The cancellation token - public virtual Task> ExecuteTaskAsync(IRestRequest request, CancellationToken token) - { - if (request == null) - { - throw new ArgumentNullException("request"); - } - - var taskCompletionSource = new TaskCompletionSource>(); - - try - { - var async = ExecuteAsync(request, (response, _) => - { - if (token.IsCancellationRequested) - { - taskCompletionSource.TrySetCanceled(); - } - else if (response.ErrorException != null) - { - taskCompletionSource.TrySetException(response.ErrorException); - } - else if (response.ResponseStatus != ResponseStatus.Completed) - { - taskCompletionSource.TrySetException(response.ResponseStatus.ToWebException()); - } - else - { - taskCompletionSource.TrySetResult(response); - } - }); - - token.Register(() => - { - async.Abort(); - taskCompletionSource.TrySetCanceled(); - }); - } - catch (Exception ex) - { - taskCompletionSource.TrySetException(ex); - } - - return taskCompletionSource.Task; - } - - /// - /// Executes the request asynchronously, authenticating if needed - /// - /// Request to be executed - public virtual Task ExecuteTaskAsync(IRestRequest request) - { - return ExecuteTaskAsync(request, CancellationToken.None); - } - - /// - /// Executes a GET-style asynchronously, authenticating if needed - /// - /// Request to be executed - public virtual Task ExecuteGetTaskAsync(IRestRequest request) - { - return this.ExecuteGetTaskAsync(request, CancellationToken.None); - } - - /// - /// Executes a GET-style asynchronously, authenticating if needed - /// - /// Request to be executed - /// The cancellation token - public virtual Task ExecuteGetTaskAsync(IRestRequest request, CancellationToken token) - { - if (request == null) - { - throw new ArgumentNullException("request"); - } - - request.Method = Method.GET; - return ExecuteTaskAsync(request, token); - } - - /// - /// Executes a POST-style asynchronously, authenticating if needed - /// - /// Request to be executed - public virtual Task ExecutePostTaskAsync(IRestRequest request) - { - return this.ExecutePostTaskAsync(request, CancellationToken.None); - } - - /// - /// Executes a POST-style asynchronously, authenticating if needed - /// - /// Request to be executed - /// The cancellation token - public virtual Task ExecutePostTaskAsync(IRestRequest request, CancellationToken token) - { - if (request == null) - { - throw new ArgumentNullException("request"); - } - - request.Method = Method.POST; - return ExecuteTaskAsync(request, token); - } - - /// - /// Executes the request asynchronously, authenticating if needed - /// - /// Request to be executed - /// The cancellation token - public virtual Task ExecuteTaskAsync(IRestRequest request, CancellationToken token) - { - if (request == null) - { - throw new ArgumentNullException("request"); - } - - var taskCompletionSource = new TaskCompletionSource(); - - try - { - var async = this.ExecuteAsync(request, (response, _) => - { - if (token.IsCancellationRequested) - { - taskCompletionSource.TrySetCanceled(); - } - else if (response.ErrorException != null) - { - taskCompletionSource.TrySetException(response.ErrorException); - } - else if (response.ResponseStatus != ResponseStatus.Completed) - { - taskCompletionSource.TrySetException(response.ResponseStatus.ToWebException()); - } - else - { - taskCompletionSource.TrySetResult(response); - } - }); - - token.Register(() => - { - async.Abort(); - taskCompletionSource.TrySetCanceled(); - }); - } - catch (Exception ex) - { - taskCompletionSource.TrySetException(ex); - } - - return taskCompletionSource.Task; - } + public partial class RestClient + { + /// + /// Executes the request and callback asynchronously, authenticating if needed + /// + /// Request to be executed + public virtual async Task ExecuteAsync(IRestRequest request) + { + + string method = Enum.GetName(typeof(Method), request.Method); + switch (request.Method) + { + case Method.PATCH: + case Method.POST: + case Method.PUT: + return await ExecuteAsync(request, method, DoAsPostAsync).ConfigureAwait(false); + default: + return await ExecuteAsync(request, method, DoAsGetAsync).ConfigureAwait(false); + } + } + + /// + /// Executes a GET-style request and callback asynchronously, authenticating if needed + /// + /// Request to be executed + /// The HTTP method to execute + public virtual async Task ExecuteAsyncGet(IRestRequest request, string httpMethod) + { + return await ExecuteAsync(request, httpMethod, DoAsGetAsync).ConfigureAwait(false); + } + + /// + /// Executes a POST-style request and callback asynchronously, authenticating if needed + /// + /// Request to be executed + /// The HTTP method to execute + public virtual async Task ExecuteAsyncPost(IRestRequest request, string httpMethod) + { + request.Method = Method.POST; // Required by RestClient.BuildUri... + return await ExecuteAsync(request, httpMethod, DoAsPostAsync).ConfigureAwait(false); + } + + private async Task ExecuteAsync(IRestRequest request, string httpMethod, Func> getWebRequest) + { + var http = HttpFactory.Create(); + AuthenticateIfNeeded(this, request); + + ConfigureHttp(request, http); + var response = await getWebRequest(http, httpMethod).ConfigureAwait(false); + return ProcessResponse(request, response); + } + + private async static Task DoAsGetAsync(IHttp http, string method) + { + return await http.AsGetAsync(method).ConfigureAwait(false); + } + + private async static Task DoAsPostAsync(IHttp http, string method) + { + return await http.AsPostAsync(method).ConfigureAwait(false); + } + + private IRestResponse ProcessResponse(IRestRequest request, HttpResponse httpResponse) + { + return ConvertToRestResponse(request, httpResponse); + } + + /// + /// Executes the request and callback asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + public virtual async Task> ExecuteAsync(IRestRequest request) + { + var response = await ExecuteAsync(request).ConfigureAwait(false); + return DeserializeResponse(request, response); + } + + /// + /// Executes a GET-style request and callback asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + /// The HTTP method to execute + public virtual async Task> ExecuteAsyncGet(IRestRequest request, string httpMethod) + { + var response = await ExecuteAsyncGet(request, httpMethod).ConfigureAwait(false); + return DeserializeResponse(request, response); + } + + /// + /// Executes a POST-style request and callback asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + /// The HTTP method to execute + public virtual async Task> ExecuteAsyncPost(IRestRequest request, string httpMethod) + { + var response = await ExecuteAsyncPost(request, httpMethod).ConfigureAwait(false); + return DeserializeResponse(request, response); + } + + private IRestResponse DeserializeResponse(IRestRequest request, IRestResponse response) + { + IRestResponse restResponse = response as RestResponse; + if (response.ResponseStatus == ResponseStatus.Completed) + { + restResponse = Deserialize(request, response); + } + return restResponse; + } + +#if NET4 || WP8 || MONODROID || MONOTOUCH + /// + /// Executes a GET-style request asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + public virtual async Task> ExecuteGetTaskAsync(IRestRequest request) + { + return await ExecuteGetTaskAsync(request, CancellationToken.None).ConfigureAwait(false); + } + + /// + /// Executes a GET-style request asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + /// The cancellation token + public virtual async Task> ExecuteGetTaskAsync(IRestRequest request, CancellationToken token) + { + if (request == null) + { + throw new ArgumentNullException("request"); + } + + request.Method = Method.GET; + return await ExecuteTaskAsync(request, token).ConfigureAwait(false); + } + + /// + /// Executes a POST-style request asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + public virtual async Task> ExecutePostTaskAsync(IRestRequest request) + { + return await ExecutePostTaskAsync(request, CancellationToken.None).ConfigureAwait(false); + } + + /// + /// Executes a POST-style request asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + /// The cancellation token + public virtual async Task> ExecutePostTaskAsync(IRestRequest request, CancellationToken token) + { + if (request == null) + { + throw new ArgumentNullException("request"); + } + + request.Method = Method.POST; + return await ExecuteTaskAsync(request, token).ConfigureAwait(false); + } + + /// + /// Executes the request asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + public virtual async Task> ExecuteTaskAsync(IRestRequest request) + { + return await ExecuteTaskAsync(request, CancellationToken.None).ConfigureAwait(false); + } + + /// + /// Executes the request asynchronously, authenticating if needed + /// + /// Target deserialization type + /// Request to be executed + /// The cancellation token + public virtual async Task> ExecuteTaskAsync(IRestRequest request, CancellationToken token) + { + if (request == null) + { + throw new ArgumentNullException("request"); + } + return await ExecuteAsync(request).ConfigureAwait(false); + } + + /// + /// Executes the request asynchronously, authenticating if needed + /// + /// Request to be executed + public virtual async Task ExecuteTaskAsync(IRestRequest request) + { + return await ExecuteTaskAsync(request, CancellationToken.None).ConfigureAwait(false); + } + + /// + /// Executes a GET-style asynchronously, authenticating if needed + /// + /// Request to be executed + public virtual async Task ExecuteGetTaskAsync(IRestRequest request) + { + return await ExecuteGetTaskAsync(request, CancellationToken.None).ConfigureAwait(false); + } + + /// + /// Executes a GET-style asynchronously, authenticating if needed + /// + /// Request to be executed + /// The cancellation token + public virtual async Task ExecuteGetTaskAsync(IRestRequest request, CancellationToken token) + { + if (request == null) + { + throw new ArgumentNullException("request"); + } + + request.Method = Method.GET; + return await ExecuteTaskAsync(request, token).ConfigureAwait(false); + } + + /// + /// Executes a POST-style asynchronously, authenticating if needed + /// + /// Request to be executed + public virtual async Task ExecutePostTaskAsync(IRestRequest request) + { + return await ExecutePostTaskAsync(request, CancellationToken.None).ConfigureAwait(false); + } + + /// + /// Executes a POST-style asynchronously, authenticating if needed + /// + /// Request to be executed + /// The cancellation token + public virtual async Task ExecutePostTaskAsync(IRestRequest request, CancellationToken token) + { + if (request == null) + { + throw new ArgumentNullException("request"); + } + + request.Method = Method.POST; + return await ExecuteTaskAsync(request, token).ConfigureAwait(false); + } + + /// + /// Executes the request asynchronously, authenticating if needed + /// + /// Request to be executed + /// The cancellation token + public virtual async Task ExecuteTaskAsync(IRestRequest request, CancellationToken token) + { + if (request == null) + { + throw new ArgumentNullException("request"); + } + + return await ExecuteAsync(request).ConfigureAwait(false); + } #endif - } + } } \ No newline at end of file diff --git a/RestSharp/RestClient.cs b/RestSharp/RestClient.cs index 5e00ebb10..746ca394a 100644 --- a/RestSharp/RestClient.cs +++ b/RestSharp/RestClient.cs @@ -26,129 +26,129 @@ namespace RestSharp { - /// - /// Client to translate RestRequests into Http requests and process response result - /// - public partial class RestClient : IRestClient - { - // silverlight friendly way to get current version - static readonly Version version = new AssemblyName(Assembly.GetExecutingAssembly().FullName).Version; - - public IHttpFactory HttpFactory = new SimpleFactory(); - - /// - /// Default constructor that registers default content handlers - /// - public RestClient() - { -#if WINDOWS_PHONE + /// + /// Client to translate RestRequests into Http requests and process response result + /// + public partial class RestClient : IRestClient + { + // silverlight friendly way to get current version + static readonly Version version = new AssemblyName(Assembly.GetExecutingAssembly().FullName).Version; + + public IHttpFactory HttpFactory = new SimpleFactory(); + + /// + /// Default constructor that registers default content handlers + /// + public RestClient() + { +#if WINDOWS_PHONE && !WP8 UseSynchronizationContext = true; #endif - ContentHandlers = new Dictionary(); - AcceptTypes = new List(); - DefaultParameters = new List(); - - // register default handlers - AddHandler("application/json", new JsonDeserializer()); - AddHandler("application/xml", new XmlDeserializer()); - AddHandler("text/json", new JsonDeserializer()); - AddHandler("text/x-json", new JsonDeserializer()); - AddHandler("text/javascript", new JsonDeserializer()); - AddHandler("text/xml", new XmlDeserializer()); - AddHandler("*", new XmlDeserializer()); - - FollowRedirects = true; - } - - /// - /// Sets the BaseUrl property for requests made by this client instance - /// - /// - public RestClient(string baseUrl) - : this() - { - BaseUrl = baseUrl; - } - - private IDictionary ContentHandlers { get; set; } - private IList AcceptTypes { get; set; } - - /// - /// Parameters included with every request made with this instance of RestClient - /// If specified in both client and request, the request wins - /// - public IList DefaultParameters { get; private set; } - - /// - /// Registers a content handler to process response content - /// - /// MIME content type of the response content - /// Deserializer to use to process content - public void AddHandler(string contentType, IDeserializer deserializer) - { - ContentHandlers[contentType] = deserializer; - if (contentType != "*") - { - AcceptTypes.Add(contentType); - // add Accept header based on registered deserializers - var accepts = string.Join(", ", AcceptTypes.ToArray()); - this.RemoveDefaultParameter("Accept"); - this.AddDefaultParameter("Accept", accepts, ParameterType.HttpHeader); - } - } - - /// - /// Remove a content handler for the specified MIME content type - /// - /// MIME content type to remove - public void RemoveHandler(string contentType) - { - ContentHandlers.Remove(contentType); - AcceptTypes.Remove(contentType); - this.RemoveDefaultParameter("Accept"); - } - - /// - /// Remove all content handlers - /// - public void ClearHandlers() - { - ContentHandlers.Clear(); - AcceptTypes.Clear(); - this.RemoveDefaultParameter("Accept"); - } - - /// - /// Retrieve the handler for the specified MIME content type - /// - /// MIME content type to retrieve - /// IDeserializer instance - IDeserializer GetHandler(string contentType) - { - if (string.IsNullOrEmpty(contentType) && ContentHandlers.ContainsKey("*")) - { - return ContentHandlers["*"]; - } + ContentHandlers = new Dictionary(); + AcceptTypes = new List(); + DefaultParameters = new List(); + + // register default handlers + AddHandler("application/json", new JsonDeserializer()); + AddHandler("application/xml", new XmlDeserializer()); + AddHandler("text/json", new JsonDeserializer()); + AddHandler("text/x-json", new JsonDeserializer()); + AddHandler("text/javascript", new JsonDeserializer()); + AddHandler("text/xml", new XmlDeserializer()); + AddHandler("*", new XmlDeserializer()); + + FollowRedirects = true; + } + + /// + /// Sets the BaseUrl property for requests made by this client instance + /// + /// + public RestClient(string baseUrl) + : this() + { + BaseUrl = baseUrl; + } + + private IDictionary ContentHandlers { get; set; } + private IList AcceptTypes { get; set; } + + /// + /// Parameters included with every request made with this instance of RestClient + /// If specified in both client and request, the request wins + /// + public IList DefaultParameters { get; private set; } + + /// + /// Registers a content handler to process response content + /// + /// MIME content type of the response content + /// Deserializer to use to process content + public void AddHandler(string contentType, IDeserializer deserializer) + { + ContentHandlers[contentType] = deserializer; + if (contentType != "*") + { + AcceptTypes.Add(contentType); + // add Accept header based on registered deserializers + var accepts = string.Join(", ", AcceptTypes.ToArray()); + this.RemoveDefaultParameter("Accept"); + this.AddDefaultParameter("Accept", accepts, ParameterType.HttpHeader); + } + } + + /// + /// Remove a content handler for the specified MIME content type + /// + /// MIME content type to remove + public void RemoveHandler(string contentType) + { + ContentHandlers.Remove(contentType); + AcceptTypes.Remove(contentType); + this.RemoveDefaultParameter("Accept"); + } + + /// + /// Remove all content handlers + /// + public void ClearHandlers() + { + ContentHandlers.Clear(); + AcceptTypes.Clear(); + this.RemoveDefaultParameter("Accept"); + } + + /// + /// Retrieve the handler for the specified MIME content type + /// + /// MIME content type to retrieve + /// IDeserializer instance + IDeserializer GetHandler(string contentType) + { + if (string.IsNullOrEmpty(contentType) && ContentHandlers.ContainsKey("*")) + { + return ContentHandlers["*"]; + } - var semicolonIndex = contentType.IndexOf(';'); - if (semicolonIndex > -1) contentType = contentType.Substring(0, semicolonIndex); - IDeserializer handler = null; - if (ContentHandlers.ContainsKey(contentType)) - { - handler = ContentHandlers[contentType]; - } - else if (ContentHandlers.ContainsKey("*")) - { - handler = ContentHandlers["*"]; - } + var semicolonIndex = contentType.IndexOf(';'); + if (semicolonIndex > -1) contentType = contentType.Substring(0, semicolonIndex); + IDeserializer handler = null; + if (ContentHandlers.ContainsKey(contentType)) + { + handler = ContentHandlers[contentType]; + } + else if (ContentHandlers.ContainsKey("*")) + { + handler = ContentHandlers["*"]; + } - return handler; - } + return handler; + } - /// - /// Maximum number of redirects to follow if FollowRedirects is true - /// - public int? MaxRedirects { get; set; } + /// + /// Maximum number of redirects to follow if FollowRedirects is true + /// + public int? MaxRedirects { get; set; } #if FRAMEWORK /// @@ -163,174 +163,174 @@ IDeserializer GetHandler(string contentType) public IWebProxy Proxy { get; set; } #endif - /// - /// Default is true. Determine whether or not requests that result in - /// HTTP status codes of 3xx should follow returned redirect - /// - public bool FollowRedirects { get; set; } - - /// - /// The CookieContainer used for requests made by this client instance - /// - public CookieContainer CookieContainer { get; set; } - - /// - /// UserAgent to use for requests made by this client instance - /// - public string UserAgent { get; set; } - - /// - /// Timeout in milliseconds to use for requests made by this client instance - /// - public int Timeout { get; set; } - - /// - /// Whether to invoke async callbacks using the SynchronizationContext.Current captured when invoked - /// - public bool UseSynchronizationContext { get; set; } - - /// - /// Authenticator to use for requests made by this client instance - /// - public IAuthenticator Authenticator { get; set; } - - private string _baseUrl; - /// - /// Combined with Request.Resource to construct URL for request - /// Should include scheme and domain without trailing slash. - /// - /// - /// client.BaseUrl = "http://example.com"; - /// - public virtual string BaseUrl - { - get - { - return _baseUrl; - } - set - { - _baseUrl = value; - if (_baseUrl != null && _baseUrl.EndsWith("/")) - { - _baseUrl = _baseUrl.Substring(0, _baseUrl.Length - 1); - } - } - } - - private void AuthenticateIfNeeded(RestClient client, IRestRequest request) - { - if (Authenticator != null) - { - Authenticator.Authenticate(client, request); - } - } + /// + /// Default is true. Determine whether or not requests that result in + /// HTTP status codes of 3xx should follow returned redirect + /// + public bool FollowRedirects { get; set; } + + /// + /// The CookieContainer used for requests made by this client instance + /// + public CookieContainer CookieContainer { get; set; } + + /// + /// UserAgent to use for requests made by this client instance + /// + public string UserAgent { get; set; } + + /// + /// Timeout in milliseconds to use for requests made by this client instance + /// + public int Timeout { get; set; } + + /// + /// Whether to invoke async callbacks using the SynchronizationContext.Current captured when invoked + /// + public bool UseSynchronizationContext { get; set; } + + /// + /// Authenticator to use for requests made by this client instance + /// + public IAuthenticator Authenticator { get; set; } + + private string _baseUrl; + /// + /// Combined with Request.Resource to construct URL for request + /// Should include scheme and domain without trailing slash. + /// + /// + /// client.BaseUrl = "http://example.com"; + /// + public virtual string BaseUrl + { + get + { + return _baseUrl; + } + set + { + _baseUrl = value; + if (_baseUrl != null && _baseUrl.EndsWith("/")) + { + _baseUrl = _baseUrl.Substring(0, _baseUrl.Length - 1); + } + } + } - /// - /// Assembles URL to call based on parameters, method and resource - /// - /// RestRequest to execute - /// Assembled System.Uri - public Uri BuildUri(IRestRequest request) - { - var assembled = request.Resource; - var urlParms = request.Parameters.Where(p => p.Type == ParameterType.UrlSegment); - foreach (var p in urlParms) - { - assembled = assembled.Replace("{" + p.Name + "}", p.Value.ToString().UrlEncode()); - } + private void AuthenticateIfNeeded(RestClient client, IRestRequest request) + { + if (Authenticator != null) + { + Authenticator.Authenticate(client, request); + } + } + + /// + /// Assembles URL to call based on parameters, method and resource + /// + /// RestRequest to execute + /// Assembled System.Uri + public Uri BuildUri(IRestRequest request) + { + var assembled = request.Resource; + var urlParms = request.Parameters.Where(p => p.Type == ParameterType.UrlSegment); + foreach (var p in urlParms) + { + assembled = assembled.Replace("{" + p.Name + "}", p.Value.ToString().UrlEncode()); + } - if (!string.IsNullOrEmpty(assembled) && assembled.StartsWith("/")) - { - assembled = assembled.Substring(1); - } + if (!string.IsNullOrEmpty(assembled) && assembled.StartsWith("/")) + { + assembled = assembled.Substring(1); + } - if (!string.IsNullOrEmpty(BaseUrl)) - { - if (string.IsNullOrEmpty(assembled)) - { - assembled = BaseUrl; - } - else - { - assembled = string.Format("{0}/{1}", BaseUrl, assembled); - } - } + if (!string.IsNullOrEmpty(BaseUrl)) + { + if (string.IsNullOrEmpty(assembled)) + { + assembled = BaseUrl; + } + else + { + assembled = string.Format("{0}/{1}", BaseUrl, assembled); + } + } - IEnumerable parameters = null; + IEnumerable parameters = null; - if (request.Method != Method.POST && request.Method != Method.PUT && request.Method != Method.PATCH) - { - // build and attach querystring if this is a get-style request - parameters = request.Parameters.Where(p => p.Type == ParameterType.GetOrPost || p.Type == ParameterType.QueryString); - } - else - { - parameters = request.Parameters.Where(p => p.Type == ParameterType.QueryString); - } + if (request.Method != Method.POST && request.Method != Method.PUT && request.Method != Method.PATCH) + { + // build and attach querystring if this is a get-style request + parameters = request.Parameters.Where(p => p.Type == ParameterType.GetOrPost || p.Type == ParameterType.QueryString); + } + else + { + parameters = request.Parameters.Where(p => p.Type == ParameterType.QueryString); + } - // build and attach querystring - if (parameters != null && parameters.Any()) - { - var data = EncodeParameters(request, parameters); - assembled = string.Format("{0}?{1}", assembled, data); - } + // build and attach querystring + if (parameters != null && parameters.Any()) + { + var data = EncodeParameters(request, parameters); + assembled = string.Format("{0}?{1}", assembled, data); + } - return new Uri(assembled); - } + return new Uri(assembled); + } - private string EncodeParameters(IRestRequest request, IEnumerable parameters) - { - var querystring = new StringBuilder(); - foreach (var p in parameters) - { - if (querystring.Length > 1) - querystring.Append("&"); - querystring.AppendFormat("{0}={1}", p.Name.UrlEncode(), (p.Value.ToString()).UrlEncode()); - } + private string EncodeParameters(IRestRequest request, IEnumerable parameters) + { + var querystring = new StringBuilder(); + foreach (var p in parameters) + { + if (querystring.Length > 1) + querystring.Append("&"); + querystring.AppendFormat("{0}={1}", p.Name.UrlEncode(), (p.Value.ToString()).UrlEncode()); + } - return querystring.ToString(); - } + return querystring.ToString(); + } - private void ConfigureHttp(IRestRequest request, IHttp http) - { - http.AlwaysMultipartFormData = request.AlwaysMultipartFormData; + private void ConfigureHttp(IRestRequest request, IHttp http) + { + http.AlwaysMultipartFormData = request.AlwaysMultipartFormData; - http.CookieContainer = CookieContainer; + http.CookieContainer = CookieContainer; - http.ResponseWriter = request.ResponseWriter; + http.ResponseWriter = request.ResponseWriter; - // move RestClient.DefaultParameters into Request.Parameters - foreach (var p in DefaultParameters) - { - if (request.Parameters.Any(p2 => p2.Name == p.Name && p2.Type == p.Type)) - { - continue; - } + // move RestClient.DefaultParameters into Request.Parameters + foreach (var p in DefaultParameters) + { + if (request.Parameters.Any(p2 => p2.Name == p.Name && p2.Type == p.Type)) + { + continue; + } - request.AddParameter(p); - } + request.AddParameter(p); + } - // Add Accept header based on registered deserializers if none has been set by the caller. - if (!request.Parameters.Any(p2 => p2.Name.ToLowerInvariant() == "accept")) - { - var accepts = string.Join(", ", AcceptTypes.ToArray()); - request.AddParameter("Accept", accepts, ParameterType.HttpHeader); - } + // Add Accept header based on registered deserializers if none has been set by the caller. + if (!request.Parameters.Any(p2 => p2.Name.ToLowerInvariant() == "accept")) + { + var accepts = string.Join(", ", AcceptTypes.ToArray()); + request.AddParameter("Accept", accepts, ParameterType.HttpHeader); + } - http.Url = BuildUri(request); + http.Url = BuildUri(request); - var userAgent = UserAgent ?? http.UserAgent; - http.UserAgent = userAgent.HasValue() ? userAgent : "RestSharp " + version.ToString(); + var userAgent = UserAgent ?? http.UserAgent; + http.UserAgent = userAgent.HasValue() ? userAgent : "RestSharp " + version.ToString(); - var timeout = request.Timeout > 0 ? request.Timeout : Timeout; - if (timeout > 0) - { - http.Timeout = timeout; - } + var timeout = request.Timeout > 0 ? request.Timeout : Timeout; + if (timeout > 0) + { + http.Timeout = timeout; + } #if !SILVERLIGHT - http.FollowRedirects = FollowRedirects; + http.FollowRedirects = FollowRedirects; #endif #if FRAMEWORK if (ClientCertificates != null) @@ -341,73 +341,73 @@ private void ConfigureHttp(IRestRequest request, IHttp http) http.MaxRedirects = MaxRedirects; #endif - if (request.Credentials != null) - { - http.Credentials = request.Credentials; - } + if (request.Credentials != null) + { + http.Credentials = request.Credentials; + } - var headers = from p in request.Parameters - where p.Type == ParameterType.HttpHeader - select new HttpHeader - { - Name = p.Name, - Value = p.Value.ToString() - }; + var headers = from p in request.Parameters + where p.Type == ParameterType.HttpHeader + select new HttpHeader + { + Name = p.Name, + Value = p.Value.ToString() + }; - foreach (var header in headers) - { - http.Headers.Add(header); - } + foreach (var header in headers) + { + http.Headers.Add(header); + } - var cookies = from p in request.Parameters - where p.Type == ParameterType.Cookie - select new HttpCookie - { - Name = p.Name, - Value = p.Value.ToString() - }; + var cookies = from p in request.Parameters + where p.Type == ParameterType.Cookie + select new HttpCookie + { + Name = p.Name, + Value = p.Value.ToString() + }; - foreach (var cookie in cookies) - { - http.Cookies.Add(cookie); - } + foreach (var cookie in cookies) + { + http.Cookies.Add(cookie); + } - var @params = from p in request.Parameters - where p.Type == ParameterType.GetOrPost - && p.Value != null - select new HttpParameter - { - Name = p.Name, - Value = p.Value.ToString() - }; + var @params = from p in request.Parameters + where p.Type == ParameterType.GetOrPost + && p.Value != null + select new HttpParameter + { + Name = p.Name, + Value = p.Value.ToString() + }; - foreach (var parameter in @params) - { - http.Parameters.Add(parameter); - } + foreach (var parameter in @params) + { + http.Parameters.Add(parameter); + } - foreach (var file in request.Files) - { - http.Files.Add(new HttpFile { Name = file.Name, ContentType = file.ContentType, Writer = file.Writer, FileName = file.FileName, ContentLength = file.ContentLength }); - } + foreach (var file in request.Files) + { + http.Files.Add(new HttpFile { Name = file.Name, ContentType = file.ContentType, Writer = file.Writer, FileName = file.FileName, ContentLength = file.ContentLength }); + } - var body = (from p in request.Parameters - where p.Type == ParameterType.RequestBody - select p).FirstOrDefault(); + var body = (from p in request.Parameters + where p.Type == ParameterType.RequestBody + select p).FirstOrDefault(); - if (body != null) - { - object val = body.Value; - if (val is byte[]) - http.RequestBodyBytes = (byte[])val; - else - http.RequestBody = body.Value.ToString(); - http.RequestContentType = body.Name; - } + if (body != null) + { + object val = body.Value; + if (val is byte[]) + http.RequestBodyBytes = (byte[])val; + else + http.RequestBody = body.Value.ToString(); + http.RequestContentType = body.Name; + } #if FRAMEWORK ConfigureProxy(http); #endif - } + } #if FRAMEWORK private void ConfigureProxy(IHttp http) @@ -419,55 +419,55 @@ private void ConfigureProxy(IHttp http) } #endif - private RestResponse ConvertToRestResponse(IRestRequest request, HttpResponse httpResponse) - { - var restResponse = new RestResponse(); - restResponse.Content = httpResponse.Content; - restResponse.ContentEncoding = httpResponse.ContentEncoding; - restResponse.ContentLength = httpResponse.ContentLength; - restResponse.ContentType = httpResponse.ContentType; - restResponse.ErrorException = httpResponse.ErrorException; - restResponse.ErrorMessage = httpResponse.ErrorMessage; - restResponse.RawBytes = httpResponse.RawBytes; - restResponse.ResponseStatus = httpResponse.ResponseStatus; - restResponse.ResponseUri = httpResponse.ResponseUri; - restResponse.Server = httpResponse.Server; - restResponse.StatusCode = httpResponse.StatusCode; - restResponse.StatusDescription = httpResponse.StatusDescription; - restResponse.Request = request; - - foreach (var header in httpResponse.Headers) - { - restResponse.Headers.Add(new Parameter { Name = header.Name, Value = header.Value, Type = ParameterType.HttpHeader }); - } + private RestResponse ConvertToRestResponse(IRestRequest request, HttpResponse httpResponse) + { + var restResponse = new RestResponse(); + restResponse.Content = httpResponse.Content; + restResponse.ContentEncoding = httpResponse.ContentEncoding; + restResponse.ContentLength = httpResponse.ContentLength; + restResponse.ContentType = httpResponse.ContentType; + restResponse.ErrorException = httpResponse.ErrorException; + restResponse.ErrorMessage = httpResponse.ErrorMessage; + restResponse.RawBytes = httpResponse.RawBytes; + restResponse.ResponseStatus = httpResponse.ResponseStatus; + restResponse.ResponseUri = httpResponse.ResponseUri; + restResponse.Server = httpResponse.Server; + restResponse.StatusCode = httpResponse.StatusCode; + restResponse.StatusDescription = httpResponse.StatusDescription; + restResponse.Request = request; + + foreach (var header in httpResponse.Headers) + { + restResponse.Headers.Add(new Parameter { Name = header.Name, Value = header.Value, Type = ParameterType.HttpHeader }); + } - foreach (var cookie in httpResponse.Cookies) - { - restResponse.Cookies.Add(new RestResponseCookie - { - Comment = cookie.Comment, - CommentUri = cookie.CommentUri, - Discard = cookie.Discard, - Domain = cookie.Domain, - Expired = cookie.Expired, - Expires = cookie.Expires, - HttpOnly = cookie.HttpOnly, - Name = cookie.Name, - Path = cookie.Path, - Port = cookie.Port, - Secure = cookie.Secure, - TimeStamp = cookie.TimeStamp, - Value = cookie.Value, - Version = cookie.Version - }); - } + foreach (var cookie in httpResponse.Cookies) + { + restResponse.Cookies.Add(new RestResponseCookie + { + Comment = cookie.Comment, + CommentUri = cookie.CommentUri, + Discard = cookie.Discard, + Domain = cookie.Domain, + Expired = cookie.Expired, + Expires = cookie.Expires, + HttpOnly = cookie.HttpOnly, + Name = cookie.Name, + Path = cookie.Path, + Port = cookie.Port, + Secure = cookie.Secure, + TimeStamp = cookie.TimeStamp, + Value = cookie.Value, + Version = cookie.Version + }); + } - return restResponse; - } + return restResponse; + } - private IRestResponse Deserialize(IRestRequest request, IRestResponse raw) - { - request.OnBeforeDeserialization(raw); + private IRestResponse Deserialize(IRestRequest request, IRestResponse raw) + { + request.OnBeforeDeserialization(raw); IRestResponse response = new RestResponse(); try @@ -479,7 +479,7 @@ private IRestResponse Deserialize(IRestRequest request, IRestResponse raw) // to a transport or framework exception. HTTP errors should attempt to // be deserialized - if (response.ErrorException==null) + if (response.ErrorException == null) { IDeserializer handler = GetHandler(raw.ContentType); handler.RootElement = request.RootElement; @@ -496,7 +496,7 @@ private IRestResponse Deserialize(IRestRequest request, IRestResponse raw) response.ErrorException = ex; } - return response; - } - } + return response; + } + } } diff --git a/RestSharp/RestClientExtensions.cs b/RestSharp/RestClientExtensions.cs index c0c29efde..b3f17cc71 100644 --- a/RestSharp/RestClientExtensions.cs +++ b/RestSharp/RestClientExtensions.cs @@ -8,113 +8,6 @@ namespace RestSharp { public static partial class RestClientExtensions { - /// - /// Executes the request and callback asynchronously, authenticating if needed - /// - /// The IRestClient this method extends - /// Request to be executed - /// Callback function to be executed upon completion - public static RestRequestAsyncHandle ExecuteAsync(this IRestClient client, IRestRequest request, Action callback) - { - return client.ExecuteAsync(request, (response, handle) => callback(response)); - } - - /// - /// Executes the request and callback asynchronously, authenticating if needed - /// - /// The IRestClient this method extends - /// Target deserialization type - /// Request to be executed - /// Callback function to be executed upon completion providing access to the async handle - public static RestRequestAsyncHandle ExecuteAsync(this IRestClient client, IRestRequest request, Action> callback) where T : new() - { - return client.ExecuteAsync(request, (response, asyncHandle) => callback(response)); - } - - public static RestRequestAsyncHandle GetAsync(this IRestClient client, IRestRequest request, Action, RestRequestAsyncHandle> callback) where T : new() - { - request.Method = Method.GET; - return client.ExecuteAsync(request, callback); - } - - public static RestRequestAsyncHandle PostAsync(this IRestClient client, IRestRequest request, Action, RestRequestAsyncHandle> callback) where T : new() - { - request.Method = Method.POST; - return client.ExecuteAsync(request, callback); - } - - public static RestRequestAsyncHandle PutAsync(this IRestClient client, IRestRequest request, Action, RestRequestAsyncHandle> callback) where T : new() - { - request.Method = Method.PUT; - return client.ExecuteAsync(request, callback); - } - - public static RestRequestAsyncHandle HeadAsync(this IRestClient client, IRestRequest request, Action, RestRequestAsyncHandle> callback) where T : new() - { - request.Method = Method.HEAD; - return client.ExecuteAsync(request, callback); - } - - public static RestRequestAsyncHandle OptionsAsync(this IRestClient client, IRestRequest request, Action, RestRequestAsyncHandle> callback) where T : new() - { - request.Method = Method.OPTIONS; - return client.ExecuteAsync(request, callback); - } - - public static RestRequestAsyncHandle PatchAsync(this IRestClient client, IRestRequest request, Action, RestRequestAsyncHandle> callback) where T : new() - { - request.Method = Method.PATCH; - return client.ExecuteAsync(request, callback); - } - - public static RestRequestAsyncHandle DeleteAsync(this IRestClient client, IRestRequest request, Action, RestRequestAsyncHandle> callback) where T : new() - { - request.Method = Method.DELETE; - return client.ExecuteAsync(request, callback); - } - - public static RestRequestAsyncHandle GetAsync(this IRestClient client, IRestRequest request, Action callback) - { - request.Method = Method.GET; - return client.ExecuteAsync(request, callback); - } - - public static RestRequestAsyncHandle PostAsync(this IRestClient client, IRestRequest request, Action callback) - { - request.Method = Method.POST; - return client.ExecuteAsync(request, callback); - } - - public static RestRequestAsyncHandle PutAsync(this IRestClient client, IRestRequest request, Action callback) - { - request.Method = Method.PUT; - return client.ExecuteAsync(request, callback); - } - - public static RestRequestAsyncHandle HeadAsync(this IRestClient client, IRestRequest request, Action callback) - { - request.Method = Method.HEAD; - return client.ExecuteAsync(request, callback); - } - - public static RestRequestAsyncHandle OptionsAsync(this IRestClient client, IRestRequest request, Action callback) - { - request.Method = Method.OPTIONS; - return client.ExecuteAsync(request, callback); - } - - public static RestRequestAsyncHandle PatchAsync(this IRestClient client, IRestRequest request, Action callback) - { - request.Method = Method.PATCH; - return client.ExecuteAsync(request, callback); - } - - public static RestRequestAsyncHandle DeleteAsync(this IRestClient client, IRestRequest request, Action callback) - { - request.Method = Method.DELETE; - return client.ExecuteAsync(request, callback); - } - #if NET4 public static Task GetTaskAsync(this IRestClient client, IRestRequest request) where T : new() { diff --git a/RestSharp/SharedAssemblyInfo.cs b/RestSharp/SharedAssemblyInfo.cs index 9afbe11c7..4667029c8 100644 --- a/RestSharp/SharedAssemblyInfo.cs +++ b/RestSharp/SharedAssemblyInfo.cs @@ -30,5 +30,5 @@ class SharedAssembylInfo { - public const string Version = "104.3.3"; + public const string Version = "104.3.4"; } diff --git a/package.cmd b/package.cmd index 41e87ed16..33b544013 100644 --- a/package.cmd +++ b/package.cmd @@ -3,12 +3,14 @@ if not exist Download\Net4 mkdir Download\Net4\ if not exist Download\Silverlight mkdir Download\Silverlight\ if not exist Download\WindowsPhone mkdir Download\WindowsPhone\ +if not exist Download\WindowsPhone8 mkdir Download\WindowsPhone8\ if not exist Download\package\lib\net35 mkdir Download\package\lib\net35\ if not exist Download\package\lib\net35-client mkdir Download\package\lib\net35-client\ if not exist Download\package\lib\net4 mkdir Download\package\lib\net4\ if not exist Download\package\lib\net4-client mkdir Download\package\lib\net4-client\ if not exist Download\package\lib\sl4-wp71 mkdir Download\package\lib\sl4-wp71\ if not exist Download\package\lib\sl4 mkdir Download\package\lib\sl4\ +if not exist Download\package\lib\wp8 mkdir Download\package\lib\wp8\ copy RestSharp\bin\Release\RestSharp.dll Download\ copy RestSharp\bin\Release\RestSharp.xml Download\ @@ -22,6 +24,9 @@ copy RestSharp.Silverlight\bin\Release\RestSharp.Silverlight.xml Download\Silver copy RestSharp.WindowsPhone\bin\Release\RestSharp.WindowsPhone.dll Download\WindowsPhone\ copy RestSharp.WindowsPhone\bin\Release\RestSharp.WindowsPhone.xml Download\WindowsPhone\ +copy RestSharp.WindowsPhone8\bin\Release\RestSharp.WindowsPhone8.dll Download\WindowsPhone8\ +copy RestSharp.WindowsPhone8\bin\Release\RestSharp.WindowsPhone8.xml Download\WindowsPhone8\ + copy LICENSE.txt Download\ copy readme.txt Download\ copy readme.txt Download\package\ @@ -34,6 +39,7 @@ copy RestSharp.Net4\bin\Release\RestSharp.dll Download\Package\lib\net4-client\ copy RestSharp.Silverlight\bin\Release\RestSharp.Silverlight.dll Download\Package\lib\sl4\ copy RestSharp.WindowsPhone\bin\Release\RestSharp.WindowsPhone.dll Download\Package\lib\sl4-wp71\ +copy RestSharp.WindowsPhone8\bin\Release\RestSharp.WindowsPhone8.dll Download\Package\lib\wp8\ copy RestSharp\bin\Release\RestSharp.xml Download\Package\lib\net35\ copy RestSharp\bin\Release\RestSharp.xml Download\Package\lib\net35-client\ @@ -44,6 +50,8 @@ copy RestSharp.Net4\bin\Release\RestSharp.xml Download\Package\lib\net4-client\ copy RestSharp.Silverlight\bin\Release\RestSharp.Silverlight.xml Download\Package\lib\sl4\ copy RestSharp.WindowsPhone\bin\Release\RestSharp.WindowsPhone.xml Download\Package\lib\sl4-wp71\ +copy RestSharp.WindowsPhone8\bin\Release\RestSharp.WindowsPhone8.xml Download\Package\lib\wp8\ + tools\nuget.exe update -self tools\nuget.exe pack restsharp-computed.nuspec -BasePath Download\Package -Output Download -rm restsharp-computed.nuspec \ No newline at end of file +del restsharp-computed.nuspec \ No newline at end of file