/// <summary> /// <para>Generates the authorize URI as an asynchronous operation.</para> /// <para>Then call <see cref="CoreTweet.OAuth.GetTokensAsync"/> after get the pin code.</para> /// </summary> /// <param name="consumerKey">The consumer key.</param> /// <param name="consumerSecret">The consumer secret.</param> /// <param name="oauthCallback"> /// <para>For OAuth 1.0a compliance this parameter is required.</para> /// <para>The value you specify here will be used as the URL a user is redirected to should they approve your application's access to their account.</para> /// <para>Set this to oob for out-of-band pin mode.</para> /// <para>This is also how you specify custom callbacks for use in desktop/mobile applications.</para> /// <para>Always send an oauth_callback on this step, regardless of a pre-registered callback.</para> /// </param> /// <param name="options">The connection options for the request.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns> /// <para>The task object representing the asynchronous operation.</para> /// <para>The Result property on the task object returns the authorize URI.</para> /// </returns> public static Task<OAuthSession> AuthorizeAsync(string consumerKey, string consumerSecret, string oauthCallback = "oob", ConnectionOptions options = null, CancellationToken cancellationToken = default(CancellationToken)) { var reqUrl = GetRequestTokenUrl(options); var prm = new Dictionary<string, object>(); if(!string.IsNullOrEmpty(oauthCallback)) prm.Add("oauth_callback", oauthCallback); var header = Tokens.Create(consumerKey, consumerSecret, null, null) .CreateAuthorizationHeader(MethodType.Get, reqUrl, prm); return Request.HttpGetAsync(reqUrl, prm, header, options, cancellationToken) .ResponseCallback(cancellationToken) .ContinueWith( t => InternalUtils.ReadResponse(t, s => { var dic = s.Split('&') .Where(z => z.Contains("=")) .Select(z => z.Split('=')) .ToDictionary(z => z[0], z => z[1]); return new OAuthSession() { RequestToken = dic["oauth_token"], RequestTokenSecret = dic["oauth_token_secret"], ConsumerKey = consumerKey, ConsumerSecret = consumerSecret, ConnectionOptions = options }; }, cancellationToken), cancellationToken ).Unwrap(); }
internal static HttpWebResponse HttpPost(string url, IEnumerable<KeyValuePair<string, object>> prm, string authorizationHeader, ConnectionOptions options) { if(prm == null) prm = new Dictionary<string,object>(); if(options == null) options = new ConnectionOptions(); var data = Encoding.UTF8.GetBytes(CreateQueryString(prm)); var req = (HttpWebRequest)WebRequest.Create(url); req.ServicePoint.Expect100Continue = false; req.Method = "POST"; req.Timeout = options.Timeout; req.ReadWriteTimeout = options.ReadWriteTimeout; req.UserAgent = options.UserAgent; req.Proxy = options.Proxy; req.ContentType = "application/x-www-form-urlencoded"; req.ContentLength = data.Length; req.Headers.Add(HttpRequestHeader.Authorization, authorizationHeader); if(options.UseCompression) req.AutomaticDecompression = CompressionType; if (options.DisableKeepAlive) req.KeepAlive = false; options.BeforeRequestAction?.Invoke(req); using(var reqstr = req.GetRequestStream()) reqstr.Write(data, 0, data.Length); return (HttpWebResponse)req.GetResponse(); }
/// <summary> /// Sends a POST request with multipart/form-data as an asynchronous operation. /// </summary> /// <param name="url">The URL.</param> /// <param name="prm">The parameters.</param> /// <param name="authorizationHeader">The OAuth header.</param> /// <param name="options">The connection options for the request.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns> /// <para>The task object representing the asynchronous operation.</para> /// <para>The Result property on the task object returns the response.</para> /// </returns> internal static async Task<AsyncResponse> HttpPostWithMultipartFormDataAsync(Uri url, KeyValuePair<string, object>[] prm, string authorizationHeader, ConnectionOptions options, CancellationToken cancellationToken, IProgress<UploadProgressInfo> progress) { if(options == null) options = ConnectionOptions.Default; var req = new HttpRequestMessage(HttpMethod.Post, url); var toDispose = new List<IDisposable>(); #if WIN_RT var content = new HttpMultipartFormDataContent(); foreach(var x in prm) { cancellationToken.ThrowIfCancellationRequested(); var valueStream = x.Value as Stream; var valueInputStream = x.Value as IInputStream; var valueArraySegment = x.Value as ArraySegment<byte>?; var valueBytes = x.Value as IEnumerable<byte>; var valueBuffer = x.Value as IBuffer; var valueInputStreamReference = x.Value as IInputStreamReference; var valueStorageItem = x.Value as IStorageItem; var fileName = "file"; if (valueStorageItem != null) { fileName = valueStorageItem.Name; } else if (x.Value.GetType().FullName == "System.IO.FileInfo") { var ti = x.Value.GetType().GetTypeInfo(); valueStream = (Stream)ti.GetDeclaredMethod("OpenRead").Invoke(x.Value, null); fileName = (string)ti.GetDeclaredProperty("Name").GetValue(x.Value); toDispose.Add(valueStream); } if (valueInputStreamReference != null) { valueInputStream = await valueInputStreamReference.OpenSequentialReadAsync().AsTask().ConfigureAwait(false); toDispose.Add(valueInputStream); } else if (valueStream != null) { valueInputStream = valueStream.AsInputStream(); } else if (valueArraySegment != null) { valueBuffer = valueArraySegment.Value.Array.AsBuffer(valueArraySegment.Value.Offset, valueArraySegment.Value.Count); } else if (valueBytes != null) { var valueByteArray = valueBytes as byte[] ?? valueBytes.ToArray(); valueBuffer = valueByteArray.AsBuffer(); } if(valueInputStream != null) content.Add(new HttpStreamContent(valueInputStream), x.Key, fileName); else if(valueBuffer != null) content.Add(new HttpBufferContent(valueBuffer), x.Key, fileName); else content.Add(new HttpStringContent(x.Value.ToString()), x.Key); } #else var content = new MultipartFormDataContent(); foreach (var x in prm) { cancellationToken.ThrowIfCancellationRequested(); var valueStream = x.Value as Stream; if (valueStream != null) { content.Add(new StreamContent(valueStream), x.Key, "file"); continue; } var valueArraySegment = x.Value as ArraySegment<byte>?; if (valueArraySegment != null) { content.Add( new ByteArrayContent(valueArraySegment.Value.Array, valueArraySegment.Value.Offset, valueArraySegment.Value.Count), x.Key, "file"); continue; } var valueBytes = x.Value as IEnumerable<byte>; if (valueBytes != null) { content.Add(new ByteArrayContent(valueBytes as byte[] ?? valueBytes.ToArray()), x.Key, "file"); continue; } #if FILEINFO var valueFileInfo = x.Value as FileInfo; if (valueFileInfo != null) { valueStream = valueFileInfo.OpenRead(); content.Add(new StreamContent(valueStream), x.Key, valueFileInfo.Name); toDispose.Add(valueStream); continue; } #else var fileInfoType = x.Value.GetType(); if (fileInfoType.FullName == "System.IO.FileInfo") { var ti = fileInfoType.GetTypeInfo(); valueStream = (Stream)ti.GetDeclaredMethod("OpenRead").Invoke(x.Value, null); content.Add(new StreamContent(valueStream), x.Key, (string)ti.GetDeclaredProperty("Name").GetValue(x.Value)); toDispose.Add(valueStream); continue; } #endif content.Add(new StringContent(x.Value.ToString()), x.Key); } #endif cancellationToken.ThrowIfCancellationRequested(); req.Content = content; var res = await ExecuteRequest(req, authorizationHeader, options, cancellationToken, progress).ConfigureAwait(false); foreach (var x in toDispose) x.Dispose(); return res; }
internal static Task<AsyncResponse> HttpPostAsync(Uri url, string contentType, byte[] content, string authorizationHeader, ConnectionOptions options, CancellationToken cancellationToken, IProgress<UploadProgressInfo> progress = null) { if(options == null) options = ConnectionOptions.Default; var req = new HttpRequestMessage(HttpMethod.Post, url); #if WIN_RT var httpContent = new HttpBufferContent(content.AsBuffer()); httpContent.Headers.ContentType = HttpMediaTypeHeaderValue.Parse(contentType); #else var httpContent = new ByteArrayContent(content); httpContent.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType); #endif req.Content = httpContent; return ExecuteRequest(req, authorizationHeader, options, cancellationToken, progress); }
private static async Task<AsyncResponse> ExecuteRequest(HttpRequestMessage req, string authorizationHeader, ConnectionOptions options, CancellationToken cancellationToken, IProgress<UploadProgressInfo> progress) { req.Headers.TryAddWithoutValidation("User-Agent", options.UserAgent); req.Headers.ExpectContinue = false; req.Headers.Authorization = AuthenticationHeaderValue.Parse(authorizationHeader); req.Headers.ConnectionClose = options.DisableKeepAlive; if (req.Content != null) { var contentLength = req.Content.Headers.ContentLength; if (!contentLength.HasValue) req.Headers.TransferEncodingChunked = true; // Do not buffer the content if (progress != null) req.Content = new ProgressHttpContent(req.Content, contentLength, progress); } return new AsyncResponse(await options.GetHttpClient() .SendAsync(req, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false)); }
/// <summary> /// Gets the OAuth 2 Bearer Token. /// </summary> /// <param name="consumerKey">The consumer key.</param> /// <param name="consumerSecret">The consumer secret.</param> /// <param name="options">The connection options for the request.</param> /// <returns>The tokens.</returns> public static OAuth2Token GetToken(string consumerKey, string consumerSecret, ConnectionOptions options = null) { var token = from x in Request.HttpPost( AccessTokenUrl, new Dictionary<string,object>() { { "grant_type", "client_credentials" } }, // At this time, only client_credentials is allowed. CreateCredentials(consumerKey, consumerSecret), options).Use() from y in new StreamReader(x.GetResponseStream()).Use() select (string)JObject.Parse(y.ReadToEnd())["access_token"]; var t = OAuth2Token.Create(consumerKey, consumerSecret, token); t.ConnectionOptions = options; return t; }
internal static HttpWebResponse HttpPost(Uri url, IEnumerable<KeyValuePair<string, object>> prm, string authorizationHeader, ConnectionOptions options) { return HttpPost(url, "application/x-www-form-urlencoded", Encoding.UTF8.GetBytes(CreateQueryString(prm)), authorizationHeader, options); }
internal static HttpWebResponse HttpGet(Uri url, string authorizationHeader, ConnectionOptions options) { if(options == null) options = ConnectionOptions.Default; var req = (HttpWebRequest)WebRequest.Create(url); req.Timeout = options.Timeout; req.ReadWriteTimeout = options.ReadWriteTimeout; req.UserAgent = options.UserAgent; req.Headers.Add(HttpRequestHeader.Authorization, authorizationHeader); if(options.UseCompression) req.AutomaticDecompression = CompressionType; if (options.UseProxy) { if (options.Proxy != null) req.Proxy = options.Proxy; } else { req.Proxy = null; } if (options.DisableKeepAlive) req.KeepAlive = false; return (HttpWebResponse)req.GetResponse(); }
private static async Task<AsyncResponse> ExecuteRequest(HttpRequestMessage req, string authorizationHeader, ConnectionOptions options, CancellationToken cancellationToken) { var splitAuth = authorizationHeader.Split(new[] { ' ' }, 2); req.Headers.Add("User-Agent", options.UserAgent); req.Headers.Expect.Clear(); req.Headers.Authorization = new HttpCredentialsHeaderValue(splitAuth[0], splitAuth[1]); if(options.DisableKeepAlive) { req.Headers.Connection.Clear(); req.Headers.Connection.Add(new HttpConnectionOptionHeaderValue("close")); } if(options.BeforeRequestAction != null) options.BeforeRequestAction(req); var cancellation = new CancellationTokenSource(); var handler = new HttpBaseProtocolFilter(); handler.AutomaticDecompression = options.UseCompression; using(var reg = cancellationToken.Register(cancellation.Cancel)) using(var client = new HttpClient(handler)) { var task = client.SendRequestAsync(req, HttpCompletionOption.ResponseHeadersRead).AsTask(cancellation.Token); var timeoutCancellation = new CancellationTokenSource(); DelayAction(options.Timeout, timeoutCancellation.Token, cancellation.Cancel); return await task.ContinueWith(t => { timeoutCancellation.Cancel(); if (t.IsFaulted) t.Exception.InnerException.Rethrow(); if (!cancellationToken.IsCancellationRequested && cancellation.IsCancellationRequested) throw new TimeoutException(); return new AsyncResponse(t.Result); }, cancellationToken).ConfigureAwait(false); } }
internal static HttpWebResponse HttpPostWithMultipartFormData(string url, IEnumerable<KeyValuePair<string, object>> prm, string authorizationHeader, ConnectionOptions options) { if(options == null) options = new ConnectionOptions(); var boundary = Guid.NewGuid().ToString(); var req = (HttpWebRequest)WebRequest.Create(url); req.ServicePoint.Expect100Continue = false; req.Method = "POST"; req.Timeout = options.Timeout; req.ReadWriteTimeout = options.ReadWriteTimeout; req.UserAgent = options.UserAgent; req.Proxy = options.Proxy; req.ContentType = "multipart/form-data;boundary=" + boundary; req.Headers.Add(HttpRequestHeader.Authorization, authorizationHeader); using(var memstr = new MemoryStream()) { WriteMultipartFormData(memstr, boundary, prm); req.ContentLength = memstr.Length; if(options.BeforeRequestAction != null) options.BeforeRequestAction(req); using(var reqstr = req.GetRequestStream()) memstr.WriteTo(reqstr); } return (HttpWebResponse)req.GetResponse(); }
private static Uri GetAccessTokenUrl(ConnectionOptions options) { if (options == null) options = new ConnectionOptions(); return new Uri(InternalUtils.GetUrl(options, options.ApiUrl, false, "oauth/access_token")); }
private static Uri GetRequestTokenUrl(ConnectionOptions options) { if (options == null) options = ConnectionOptions.Default; return new Uri(InternalUtils.GetUrl(options, options.ApiUrl, false, "oauth/request_token")); }
/// <summary> /// Gets the OAuth 2 Bearer Token. /// </summary> /// <param name="consumerKey">The consumer key.</param> /// <param name="consumerSecret">The consumer secret.</param> /// <param name="options">The connection options for the request.</param> /// <returns>The tokens.</returns> public static OAuth2Token GetToken(string consumerKey, string consumerSecret, ConnectionOptions options = null) { if (options == null) options = new ConnectionOptions(); try { var token = from x in Request.HttpPost( GetAccessTokenUrl(options), new Dictionary<string, object>() { { "grant_type", "client_credentials" } }, // At this time, only client_credentials is allowed. CreateCredentials(consumerKey, consumerSecret), options).Use() from y in new StreamReader(x.GetResponseStream()).Use() select (string)JObject.Parse(y.ReadToEnd())["access_token"]; var t = OAuth2Token.Create(consumerKey, consumerSecret, token); t.ConnectionOptions = options; return t; } catch(WebException ex) { var tex = TwitterException.Create(ex); if(tex != null) throw tex; throw; } }
Task <AsyncResponse> HttpPostWithMultipartFormDataAsync(string url, IEnumerable <KeyValuePair <string, object> > prm, string authorizationHeader, ConnectionOptions options, CancellationToken cancellationToken) { if (options == null) { options = new ConnectionOptions(); } #if WIN_RT var req = new HttpRequestMessage(HttpMethod.Post, new Uri(url)); var content = new MultipartFormDataContent(); foreach (var x in prm) { cancellationToken.ThrowIfCancellationRequested(); var valueStream = x.Value as Stream; var valueInputStream = x.Value as IInputStream; var valueBytes = x.Value as IEnumerable <byte>; var valueBuffer = x.Value as IBuffer; var valueInputStreamReference = x.Value as IInputStreamReference; var valueStorageItem = x.Value as IStorageItem; if (valueInputStreamReference != null) { valueInputStream = await valueInputStreamReference.OpenSequentialReadAsync(); } if (valueInputStream != null) { valueStream = valueInputStream.AsStreamForRead(); } if (valueBuffer != null) { valueStream = valueBuffer.AsStream(); } if (valueStream != null) { content.Add(new StreamContent(valueStream), x.Key, valueStorageItem != null ? valueStorageItem.Name : "file"); } else if (valueBytes != null) { var valueByteArray = valueBytes as byte[]; if (valueByteArray == null) { valueByteArray = valueBytes.ToArray(); } content.Add(new ByteArrayContent(valueByteArray), x.Key, valueStorageItem != null ? valueStorageItem.Name : "file"); } else { content.Add(new StringContent(x.Value.ToString()), x.Key); } } cancellationToken.ThrowIfCancellationRequested(); req.Content = content; return(await ExecuteRequest(req, authorizationHeader, options, cancellationToken).ConfigureAwait(false)); #else var task = new TaskCompletionSource <AsyncResponse>(); if (cancellationToken.IsCancellationRequested) { task.TrySetCanceled(); return(task.Task); } try { var boundary = Guid.NewGuid().ToString(); var req = (HttpWebRequest)WebRequest.Create(url); var reg = cancellationToken.Register(() => { task.TrySetCanceled(); req.Abort(); }); req.Method = "POST"; #if !(PCL || WP) req.ServicePoint.Expect100Continue = false; req.ReadWriteTimeout = options.ReadWriteTimeout; req.Proxy = options.Proxy; req.SendChunked = true; if (options.UseCompression) { req.AutomaticDecompression = CompressionType; } if (options.DisableKeepAlive) { req.KeepAlive = false; } #endif #if !PCL req.UserAgent = options.UserAgent; #endif req.ContentType = "multipart/form-data;boundary=" + boundary; req.Headers[HttpRequestHeader.Authorization] = authorizationHeader; #if !PCL if (options.BeforeRequestAction != null) { options.BeforeRequestAction(req); } #endif var timeoutCancellation = new CancellationTokenSource(); DelayAction(options.Timeout, timeoutCancellation.Token, () => { #if PCL task.TrySetException(new TimeoutException()); #else task.TrySetException(new WebException("Timeout", WebExceptionStatus.Timeout)); #endif req.Abort(); }); req.BeginGetRequestStream(reqStrAr => { try { using (var stream = req.EndGetRequestStream(reqStrAr)) WriteMultipartFormData(stream, boundary, prm); req.BeginGetResponse(resAr => { timeoutCancellation.Cancel(); reg.Dispose(); try { task.TrySetResult(new AsyncResponse((HttpWebResponse)req.EndGetResponse(resAr))); } catch (Exception ex) { task.TrySetException(ex); } }, null); } catch (Exception ex) { task.TrySetException(ex); } }, null); } catch (Exception ex) { task.TrySetException(ex); } return(task.Task); #endif }
/// <summary> /// Sends a POST request as an asynchronous operation. /// </summary> /// <param name="url">The URL.</param> /// <param name="prm">The parameters.</param> /// <param name="authorizationHeader">The OAuth header.</param> /// <param name="options">The connection options for the request.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns> /// <para>The task object representing the asynchronous operation.</para> /// <para>The Result property on the task object returns the response.</para> /// </returns> internal static Task <AsyncResponse> HttpPostAsync(string url, IEnumerable <KeyValuePair <string, object> > prm, string authorizationHeader, ConnectionOptions options, CancellationToken cancellationToken) { if (options == null) { options = new ConnectionOptions(); } if (prm == null) { prm = new Dictionary <string, object>(); } #if WIN_RT var req = new HttpRequestMessage(HttpMethod.Post, new Uri(url)); req.Content = new FormUrlEncodedContent( prm.Select(kvp => new KeyValuePair <string, string>(kvp.Key, kvp.Value.ToString())) ); return(ExecuteRequest(req, authorizationHeader, options, cancellationToken)); #else var task = new TaskCompletionSource <AsyncResponse>(); if (cancellationToken.IsCancellationRequested) { task.TrySetCanceled(); return(task.Task); } try { var req = (HttpWebRequest)WebRequest.Create(url); var reg = cancellationToken.Register(() => { task.TrySetCanceled(); req.Abort(); }); req.Method = "POST"; req.ContentType = "application/x-www-form-urlencoded"; req.Headers[HttpRequestHeader.Authorization] = authorizationHeader; #if !(PCL || WP) req.ServicePoint.Expect100Continue = false; req.ReadWriteTimeout = options.ReadWriteTimeout; req.Proxy = options.Proxy; if (options.UseCompression) { req.AutomaticDecompression = CompressionType; } if (options.DisableKeepAlive) { req.KeepAlive = false; } #endif #if !PCL req.UserAgent = options.UserAgent; if (options.BeforeRequestAction != null) { options.BeforeRequestAction(req); } #endif var timeoutCancellation = new CancellationTokenSource(); DelayAction(options.Timeout, timeoutCancellation.Token, () => { #if PCL task.TrySetException(new TimeoutException()); #else task.TrySetException(new WebException("Timeout", WebExceptionStatus.Timeout)); #endif req.Abort(); }); req.BeginGetRequestStream(reqStrAr => { try { var data = Encoding.UTF8.GetBytes(CreateQueryString(prm)); using (var stream = req.EndGetRequestStream(reqStrAr)) stream.Write(data, 0, data.Length); req.BeginGetResponse(resAr => { timeoutCancellation.Cancel(); reg.Dispose(); try { task.TrySetResult(new AsyncResponse((HttpWebResponse)req.EndGetResponse(resAr))); } catch (Exception ex) { task.TrySetException(ex); } }, null); } catch (Exception ex) { task.TrySetException(ex); } }, null); } catch (Exception ex) { task.TrySetException(ex); } return(task.Task); #endif }
/// <summary> /// Gets the OAuth 2 Bearer Token as an asynchronous operation. /// </summary> /// <param name="consumerKey">The consumer key.</param> /// <param name="consumerSecret">The consumer secret.</param> /// <param name="options">The connection options for the request.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns> /// <para>The task object representing the asynchronous operation.</para> /// <para>The Result property on the task object returns the tokens.</para> /// </returns> public static Task<OAuth2Token> GetTokenAsync(string consumerKey, string consumerSecret, ConnectionOptions options = null, CancellationToken cancellationToken = default(CancellationToken)) { return Request.HttpPostAsync( GetAccessTokenUrl(options), new Dictionary<string, object>() { { "grant_type", "client_credentials" } }, CreateCredentials(consumerKey, consumerSecret), options, cancellationToken ) .ResponseCallback(cancellationToken) .ContinueWith( t => InternalUtils.ReadResponse(t, s => { var token = OAuth2Token.Create( consumerKey, consumerSecret, (string)JObject.Parse(s)["access_token"] ); token.ConnectionOptions = options; return token; }, cancellationToken), cancellationToken ).Unwrap(); }
/// <summary> /// Sends a GET request as an asynchronous operation. /// </summary> /// <param name="url">The URL.</param> /// <param name="prm">The parameters.</param> /// <param name="authorizationHeader">The OAuth header.</param> /// <param name="options">The connection options for the request.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns> /// <para>The task object representing the asynchronous operation.</para> /// <para>The Result property on the task object returns the response.</para> /// </returns> internal static Task <AsyncResponse> HttpGetAsync(string url, IEnumerable <KeyValuePair <string, object> > prm, string authorizationHeader, ConnectionOptions options, CancellationToken cancellationToken) { if (options == null) { options = new ConnectionOptions(); } if (prm == null) { prm = new Dictionary <string, object>(); } var reqUrl = url + '?' + CreateQueryString(prm); #if WIN_RT var req = new HttpRequestMessage(HttpMethod.Get, new Uri(reqUrl)); return(ExecuteRequest(req, authorizationHeader, options, cancellationToken)); #else var task = new TaskCompletionSource <AsyncResponse>(); if (cancellationToken.IsCancellationRequested) { task.TrySetCanceled(); return(task.Task); } try { if (prm == null) { prm = new Dictionary <string, object>(); } var req = (HttpWebRequest)WebRequest.Create(reqUrl); var reg = cancellationToken.Register(() => { task.TrySetCanceled(); req.Abort(); }); #if !(PCL || WP) req.ReadWriteTimeout = options.ReadWriteTimeout; req.Proxy = options.Proxy; if (options.UseCompression) { req.AutomaticDecompression = CompressionType; } if (options.DisableKeepAlive) { req.KeepAlive = false; } #endif req.Headers[HttpRequestHeader.Authorization] = authorizationHeader; #if !PCL req.UserAgent = options.UserAgent; if (options.BeforeRequestAction != null) { options.BeforeRequestAction(req); } #endif var timeoutCancellation = new CancellationTokenSource(); DelayAction(options.Timeout, timeoutCancellation.Token, () => { #if PCL task.TrySetException(new TimeoutException()); #else task.TrySetException(new WebException("Timeout", WebExceptionStatus.Timeout)); #endif req.Abort(); }); req.BeginGetResponse(ar => { timeoutCancellation.Cancel(); reg.Dispose(); try { task.TrySetResult(new AsyncResponse((HttpWebResponse)req.EndGetResponse(ar))); } catch (Exception ex) { task.TrySetException(ex); } }, null); } catch (Exception ex) { task.TrySetException(ex); } return(task.Task); #endif }
private static string GetInvalidateTokenUrl(ConnectionOptions options) { if (options == null) options = new ConnectionOptions(); return InternalUtils.GetUrl(options, options.ApiUrl, false, "oauth2/invalidate_token"); }
internal static HttpWebResponse HttpPost(Uri url, string contentType, byte[] content, string authorizationHeader, ConnectionOptions options) { if (options == null) options = ConnectionOptions.Default; var req = (HttpWebRequest)WebRequest.Create(url); req.ServicePoint.Expect100Continue = false; req.Method = "POST"; req.Timeout = options.Timeout; req.ReadWriteTimeout = options.ReadWriteTimeout; req.UserAgent = options.UserAgent; req.ContentType = contentType; if (content != null) req.ContentLength = content.Length; req.Headers.Add(HttpRequestHeader.Authorization, authorizationHeader); if (options.UseCompression) req.AutomaticDecompression = CompressionType; if (options.UseProxy) { if (options.Proxy != null) req.Proxy = options.Proxy; } else { req.Proxy = null; } if (options.DisableKeepAlive) req.KeepAlive = false; if (content != null) { using (var reqstr = req.GetRequestStream()) reqstr.Write(content, 0, content.Length); } return (HttpWebResponse)req.GetResponse(); }
private static string GetRequestTokenUrl(ConnectionOptions options) { if (options == null) options = new ConnectionOptions(); return InternalUtils.GetUrl(options, options.ApiUrl, false, "oauth/request_token"); }
/// <summary> /// <para>Generates the authorize URI.</para> /// <para>Then call <see cref="CoreTweet.OAuth.GetTokens"/> after get the pin code.</para> /// </summary> /// <param name="consumerKey">The Consumer key.</param> /// <param name="consumerSecret">The Consumer secret.</param> /// <param name="oauthCallback"> /// <para>For OAuth 1.0a compliance this parameter is required.</para> /// <para>The value you specify here will be used as the URL a user is redirected to should they approve your application's access to their account.</para> /// <para>Set this to oob for out-of-band pin mode.</para> /// <para>This is also how you specify custom callbacks for use in desktop/mobile applications.</para> /// <para>Always send an oauth_callback on this step, regardless of a pre-registered callback.</para> /// </param> /// <param name="options">The connection options for the request.</param> /// <returns>The authorize URI.</returns> public static OAuthSession Authorize(string consumerKey, string consumerSecret, string oauthCallback = "oob", ConnectionOptions options = null) { // Note: Twitter says, // "If you're using HTTP-header based OAuth, you shouldn't include oauth_* parameters in the POST body or querystring." var prm = new Dictionary<string,object>(); if(!string.IsNullOrEmpty(oauthCallback)) prm.Add("oauth_callback", oauthCallback); var header = Tokens.Create(consumerKey, consumerSecret, null, null) .CreateAuthorizationHeader(MethodType.Get, RequestTokenUrl, prm); var dic = from x in Request.HttpGet(RequestTokenUrl, prm, header, options).Use() from y in new StreamReader(x.GetResponseStream()).Use() select y.ReadToEnd() .Split('&') .Where(z => z.Contains('=')) .Select(z => z.Split('=')) .ToDictionary(z => z[0], z => z[1]); return new OAuthSession() { RequestToken = dic["oauth_token"], RequestTokenSecret = dic["oauth_token_secret"], ConsumerKey = consumerKey, ConsumerSecret = consumerSecret, ConnectionOptions = options }; }
private static async Task<AsyncResponse> ExecuteRequest(HttpRequestMessage req, string authorizationHeader, ConnectionOptions options, CancellationToken cancellationToken) { var splitAuth = authorizationHeader.Split(new[] { ' ' }, 2); #if WIN_RT req.Headers.Add("User-Agent", options.UserAgent); req.Headers.Expect.Clear(); req.Headers.Authorization = new HttpCredentialsHeaderValue(splitAuth[0], splitAuth[1]); if(options.DisableKeepAlive) { req.Headers.Connection.Clear(); req.Headers.Connection.Add(new HttpConnectionOptionHeaderValue("close")); } options.BeforeRequestAction?.Invoke(req); var handler = new HttpBaseProtocolFilter(); handler.AutomaticDecompression = options.UseCompression; var cancellation = new CancellationTokenSource(); cancellationToken.Register(cancellation.Cancel); cancellation.CancelAfter(options.Timeout); var client = new HttpClient(handler); var task = client.SendRequestAsync(req, HttpCompletionOption.ResponseHeadersRead).AsTask(cancellation.Token); return new AsyncResponse(await task.ConfigureAwait(false)); #else req.Headers.TryAddWithoutValidation("User-Agent", options.UserAgent); req.Headers.ExpectContinue = false; req.Headers.Authorization = new AuthenticationHeaderValue(splitAuth[0], splitAuth[1]); req.Headers.ConnectionClose = options.DisableKeepAlive; var handler = new HttpClientHandler(); if(options.UseCompression) handler.AutomaticDecompression = CompressionType; var client = new HttpClient(handler) { Timeout = new TimeSpan(TimeSpan.TicksPerMillisecond * options.Timeout) }; return new AsyncResponse(await client.SendAsync(req, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false)); #endif }
private static async Task<AsyncResponse> ExecuteRequest(HttpRequestMessage req, string authorizationHeader, ConnectionOptions options, CancellationToken cancellationToken, IProgress<UploadProgressInfo> progress) { req.Headers.Add("User-Agent", options.UserAgent); req.Headers.Expect.Clear(); req.Headers.TryAppendWithoutValidation("Authorization", authorizationHeader); // Bearer token violates token68 if(options.DisableKeepAlive) { req.Headers.Connection.Clear(); req.Headers.Connection.Add(new HttpConnectionOptionHeaderValue("close")); } using (var cancellation = new CancellationTokenSource()) { cancellationToken.Register(cancellation.Cancel); if (options.Timeout != Timeout.Infinite) cancellation.CancelAfter(options.Timeout); var task = options.GetHttpClient().SendRequestAsync(req, HttpCompletionOption.ResponseHeadersRead).AsTask( cancellation.Token, progress == null ? null : new SimpleProgress<HttpProgress>(x => { if (x.Stage == HttpProgressStage.SendingContent) progress.Report(new UploadProgressInfo((long)x.BytesSent, (long?)x.TotalBytesToSend)); })); return new AsyncResponse(await task.ConfigureAwait(false)); } }
/// <summary> /// Sends a GET request as an asynchronous operation. /// </summary> /// <param name="url">The URL.</param> /// <param name="authorizationHeader">The OAuth header.</param> /// <param name="options">The connection options for the request.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns> /// <para>The task object representing the asynchronous operation.</para> /// <para>The Result property on the task object returns the response.</para> /// </returns> internal static Task<AsyncResponse> HttpGetAsync(Uri url, string authorizationHeader, ConnectionOptions options, CancellationToken cancellationToken) { if(options == null) options = new ConnectionOptions(); #if WIN_RT || PCL var req = new HttpRequestMessage(HttpMethod.Get, url); return ExecuteRequest(req, authorizationHeader, options, cancellationToken); #else var task = new TaskCompletionSource<AsyncResponse>(); if(cancellationToken.IsCancellationRequested) { task.TrySetCanceled(); return task.Task; } try { var req = (HttpWebRequest)WebRequest.Create(url); var reg = cancellationToken.Register(() => { task.TrySetCanceled(); req.Abort(); }); #if !WP req.ReadWriteTimeout = options.ReadWriteTimeout; req.Proxy = options.Proxy; if(options.UseCompression) req.AutomaticDecompression = CompressionType; if (options.DisableKeepAlive) req.KeepAlive = false; #endif req.Headers[HttpRequestHeader.Authorization] = authorizationHeader; req.UserAgent = options.UserAgent; options.BeforeRequestAction?.Invoke(req); var result = req.BeginGetResponse(ar => { reg.Dispose(); try { task.TrySetResult(new AsyncResponse((HttpWebResponse)req.EndGetResponse(ar))); } catch(Exception ex) { task.TrySetException(ex); } }, null); ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle, (_, timeout) => { if (!timeout) return; task.TrySetCanceled(); req.Abort(); }, null, options.Timeout, true); } catch(Exception ex) { task.TrySetException(ex); } return task.Task; #endif }
/// <summary> /// Sends a GET request as an asynchronous operation. /// </summary> /// <param name="url">The URL.</param> /// <param name="authorizationHeader">The OAuth header.</param> /// <param name="options">The connection options for the request.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns> /// <para>The task object representing the asynchronous operation.</para> /// <para>The Result property on the task object returns the response.</para> /// </returns> internal static Task<AsyncResponse> HttpGetAsync(Uri url, string authorizationHeader, ConnectionOptions options, CancellationToken cancellationToken) { if(options == null) options = ConnectionOptions.Default; var req = new HttpRequestMessage(HttpMethod.Get, url); return ExecuteRequest(req, authorizationHeader, options, cancellationToken, null); }
Task<AsyncResponse> HttpPostWithMultipartFormDataAsync(Uri url, IEnumerable<KeyValuePair<string, object>> prm, string authorizationHeader, ConnectionOptions options, CancellationToken cancellationToken) { if(options == null) options = new ConnectionOptions(); #if WIN_RT || PCL var req = new HttpRequestMessage(HttpMethod.Post, url); #endif #if WIN_RT var content = new HttpMultipartFormDataContent(); foreach(var x in prm) { cancellationToken.ThrowIfCancellationRequested(); var valueStream = x.Value as Stream; var valueInputStream = x.Value as IInputStream; var valueBytes = x.Value as IEnumerable<byte>; var valueBuffer = x.Value as IBuffer; var valueInputStreamReference = x.Value as IInputStreamReference; var valueStorageItem = x.Value as IStorageItem; if(valueInputStreamReference != null) valueInputStream = await valueInputStreamReference.OpenSequentialReadAsync(); if(valueStream != null) valueInputStream = valueStream.AsInputStream(); if(valueBytes != null) { var valueByteArray = valueBytes as byte[] ?? valueBytes.ToArray(); valueBuffer = valueByteArray.AsBuffer(); } if(valueInputStream != null) content.Add(new HttpStreamContent(valueInputStream), x.Key, valueStorageItem?.Name ?? "file"); else if(valueBuffer != null) content.Add(new HttpBufferContent(valueBuffer), x.Key, valueStorageItem?.Name ?? "file"); else content.Add(new HttpStringContent(x.Value.ToString()), x.Key); } cancellationToken.ThrowIfCancellationRequested(); req.Content = content; return await ExecuteRequest(req, authorizationHeader, options, cancellationToken).ConfigureAwait(false); #elif PCL var content = new MultipartFormDataContent(); foreach (var x in prm) { var valueStream = x.Value as Stream; var valueBytes = x.Value as IEnumerable<byte>; if(valueStream != null) content.Add(new StreamContent(valueStream), x.Key, "file"); else if(valueBytes != null) content.Add(new ByteArrayContent(valueBytes as byte[] ?? valueBytes.ToArray()), x.Key, "file"); else content.Add(new StringContent(x.Value.ToString()), x.Key); } req.Content = content; return ExecuteRequest(req, authorizationHeader, options, cancellationToken); #else var task = new TaskCompletionSource<AsyncResponse>(); if(cancellationToken.IsCancellationRequested) { task.TrySetCanceled(); return task.Task; } try { var boundary = Guid.NewGuid().ToString(); var req = (HttpWebRequest)WebRequest.Create(url); var reg = cancellationToken.Register(() => { task.TrySetCanceled(); req.Abort(); }); req.Method = "POST"; #if !WP req.ServicePoint.Expect100Continue = false; req.ReadWriteTimeout = options.ReadWriteTimeout; req.Proxy = options.Proxy; req.SendChunked = true; if(options.UseCompression) req.AutomaticDecompression = CompressionType; if (options.DisableKeepAlive) req.KeepAlive = false; #endif req.UserAgent = options.UserAgent; req.ContentType = "multipart/form-data;boundary=" + boundary; req.Headers[HttpRequestHeader.Authorization] = authorizationHeader; options.BeforeRequestAction?.Invoke(req); var timeoutCancellation = new CancellationTokenSource(); DelayAction(options.Timeout, timeoutCancellation.Token, () => { task.TrySetCanceled(); req.Abort(); }); req.BeginGetRequestStream(reqStrAr => { try { using(var stream = req.EndGetRequestStream(reqStrAr)) WriteMultipartFormData(stream, boundary, prm); req.BeginGetResponse(resAr => { timeoutCancellation.Cancel(); reg.Dispose(); try { task.TrySetResult(new AsyncResponse((HttpWebResponse)req.EndGetResponse(resAr))); } catch(Exception ex) { task.TrySetException(ex); } }, null); } catch(Exception ex) { task.TrySetException(ex); } }, null); } catch(Exception ex) { task.TrySetException(ex); } return task.Task; #endif }
/// <summary> /// Sends a POST request as an asynchronous operation. /// </summary> /// <param name="url">The URL.</param> /// <param name="prm">The parameters.</param> /// <param name="authorizationHeader">The OAuth header.</param> /// <param name="options">The connection options for the request.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns> /// <para>The task object representing the asynchronous operation.</para> /// <para>The Result property on the task object returns the response.</para> /// </returns> internal static Task<AsyncResponse> HttpPostAsync(Uri url, IEnumerable<KeyValuePair<string, object>> prm, string authorizationHeader, ConnectionOptions options, CancellationToken cancellationToken, IProgress<UploadProgressInfo> progress = null) { if(prm == null) prm = new Dictionary<string, object>(); if(options == null) options = ConnectionOptions.Default; var req = new HttpRequestMessage(HttpMethod.Post, url); #if WIN_RT req.Content = new HttpFormUrlEncodedContent( prm.Select(kvp => new KeyValuePair<string, string>(kvp.Key, kvp.Value.ToString()))); #else req.Content = new FormUrlEncodedContent( prm.Select(kvp => new KeyValuePair<string, string>(kvp.Key, kvp.Value.ToString()))); #endif return ExecuteRequest(req, authorizationHeader, options, cancellationToken, progress); }
private static Task<AsyncResponse> ExecuteRequest(HttpClient client, HttpRequestMessage req, string authorizationHeader, ConnectionOptions options, CancellationToken cancellationToken) { var splitAuth = authorizationHeader.Split(new[] { ' ' }, 2); req.Headers.Add("User-Agent", options.UserAgent); #if WIN8 req.Headers.ExpectContinue = false; req.Headers.Authorization = new AuthenticationHeaderValue(splitAuth[0], splitAuth[1]); #else req.Headers.Expect.Clear(); req.Headers.Authorization = new HttpCredentialsHeaderValue(splitAuth[0], splitAuth[1]); #endif if(options.BeforeRequestAction != null) options.BeforeRequestAction(req); var cancellation = new CancellationTokenSource(); var reg = cancellationToken.Register(cancellation.Cancel); #if WIN8 var task = client.SendAsync(req, HttpCompletionOption.ResponseHeadersRead, cancellation.Token); #else var task = client.SendRequestAsync(req, HttpCompletionOption.ResponseHeadersRead).AsTask(cancellation.Token); #endif var timeoutCancellation = new CancellationTokenSource(); DelayAction(options.Timeout, timeoutCancellation.Token, cancellation.Cancel); return task.ContinueWith(t => { timeoutCancellation.Cancel(); reg.Dispose(); if(t.IsFaulted) throw t.Exception.InnerException; if(!cancellationToken.IsCancellationRequested && cancellation.IsCancellationRequested) throw new TimeoutException(); return new AsyncResponse(t.Result); }, cancellationToken); }
internal static HttpWebResponse HttpGet(string url, IEnumerable<KeyValuePair<string, object>> prm, string authorizationHeader, ConnectionOptions options) { if(prm == null) prm = new Dictionary<string,object>(); if(options == null) options = new ConnectionOptions(); var req = (HttpWebRequest)WebRequest.Create(url + '?' + CreateQueryString(prm)); req.Timeout = options.Timeout; req.ReadWriteTimeout = options.ReadWriteTimeout; req.UserAgent = options.UserAgent; req.Proxy = options.Proxy; req.Headers.Add(HttpRequestHeader.Authorization, authorizationHeader); if(options.UseCompression) req.AutomaticDecompression = CompressionType; if (options.DisableKeepAlive) req.KeepAlive = false; options.BeforeRequestAction?.Invoke(req); return (HttpWebResponse)req.GetResponse(); }
/// <summary> /// Sends a GET request as an asynchronous operation. /// </summary> /// <param name="url">The URL.</param> /// <param name="prm">The parameters.</param> /// <param name="authorizationHeader">The OAuth header.</param> /// <param name="options">The connection options for the request.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns> /// <para>The task object representing the asynchronous operation.</para> /// <para>The Result property on the task object returns the response.</para> /// </returns> internal static Task<AsyncResponse> HttpGetAsync(string url, IEnumerable<KeyValuePair<string, object>> prm, string authorizationHeader, ConnectionOptions options, CancellationToken cancellationToken) { if(options == null) options = new ConnectionOptions(); if(prm == null) prm = new Dictionary<string, object>(); var reqUrl = url + '?' + CreateQueryString(prm); #if WIN_RT var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Get, new Uri(reqUrl)); req.Headers.Add("Authorization", authorizationHeader); return ExecuteRequest(client, req, authorizationHeader, options, cancellationToken); #else var task = new TaskCompletionSource<AsyncResponse>(); if(cancellationToken.IsCancellationRequested) { task.TrySetCanceled(); return task.Task; } try { if(prm == null) prm = new Dictionary<string, object>(); var req = (HttpWebRequest)WebRequest.Create(reqUrl); var reg = cancellationToken.Register(() => { task.TrySetCanceled(); req.Abort(); }); #if NET45 || WP req.AllowReadStreamBuffering = false; #endif #if !(PCL || WP) req.ReadWriteTimeout = options.ReadWriteTimeout; #endif #if !PCL req.UserAgent = options.UserAgent; #endif #if !(PCL || WP) req.Proxy = options.Proxy; #endif req.Headers[HttpRequestHeader.Authorization] = authorizationHeader; #if !PCL if(options.BeforeRequestAction != null) options.BeforeRequestAction(req); #endif var timeoutCancellation = new CancellationTokenSource(); DelayAction(options.Timeout, timeoutCancellation.Token, () => { #if PCL task.TrySetException(new TimeoutException()); #else task.TrySetException(new WebException("Timeout", WebExceptionStatus.Timeout)); #endif req.Abort(); }); req.BeginGetResponse(ar => { timeoutCancellation.Cancel(); reg.Dispose(); try { task.TrySetResult(new AsyncResponse((HttpWebResponse)req.EndGetResponse(ar))); } catch(Exception ex) { task.TrySetException(ex); } }, null); } catch(Exception ex) { task.TrySetException(ex); } return task.Task; #endif }
internal static HttpWebResponse HttpPostWithMultipartFormData(string url, IEnumerable<KeyValuePair<string, object>> prm, string authorizationHeader, ConnectionOptions options) { if(options == null) options = new ConnectionOptions(); var boundary = Guid.NewGuid().ToString(); var req = (HttpWebRequest)WebRequest.Create(url); req.ServicePoint.Expect100Continue = false; req.Method = "POST"; req.Timeout = options.Timeout; req.ReadWriteTimeout = options.ReadWriteTimeout; req.UserAgent = options.UserAgent; req.Proxy = options.Proxy; req.ContentType = "multipart/form-data;boundary=" + boundary; req.Headers.Add(HttpRequestHeader.Authorization, authorizationHeader); req.SendChunked = true; if(options.UseCompression) req.AutomaticDecompression = CompressionType; if (options.DisableKeepAlive) req.KeepAlive = false; options.BeforeRequestAction?.Invoke(req); using(var reqstr = req.GetRequestStream()) WriteMultipartFormData(reqstr, boundary, prm); return (HttpWebResponse)req.GetResponse(); }
/// <summary> /// Sends a POST request as an asynchronous operation. /// </summary> /// <param name="url">The URL.</param> /// <param name="prm">The parameters.</param> /// <param name="authorizationHeader">The OAuth header.</param> /// <param name="options">The connection options for the request.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns> /// <para>The task object representing the asynchronous operation.</para> /// <para>The Result property on the task object returns the response.</para> /// </returns> internal static Task<AsyncResponse> HttpPostAsync(string url, IEnumerable<KeyValuePair<string, object>> prm, string authorizationHeader, ConnectionOptions options, CancellationToken cancellationToken) { if(options == null) options = new ConnectionOptions(); if(prm == null) prm = new Dictionary<string, object>(); #if WIN_RT var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, new Uri(url)); req.Content = #if WIN8 new FormUrlEncodedContent( #else new HttpFormUrlEncodedContent( #endif prm.Select(kvp =>new KeyValuePair<string, string>(kvp.Key, kvp.Value.ToString())) ); return ExecuteRequest(client, req, authorizationHeader, options, cancellationToken); #else var task = new TaskCompletionSource<AsyncResponse>(); if(cancellationToken.IsCancellationRequested) { task.TrySetCanceled(); return task.Task; } try { var data = Encoding.UTF8.GetBytes(CreateQueryString(prm)); var req = (HttpWebRequest)WebRequest.Create(url); var reg = cancellationToken.Register(() => { task.TrySetCanceled(); req.Abort(); }); #if NET45 || WP req.AllowReadStreamBuffering = false; #endif req.Method = "POST"; req.ContentType = "application/x-www-form-urlencoded"; req.Headers[HttpRequestHeader.Authorization] = authorizationHeader; #if !(PCL || WP) req.ServicePoint.Expect100Continue = false; req.ReadWriteTimeout = options.ReadWriteTimeout; #endif #if !PCL req.UserAgent = options.UserAgent; req.ContentLength = data.Length; #endif #if !(PCL || WP) req.Proxy = options.Proxy; #endif #if !PCL if(options.BeforeRequestAction != null) options.BeforeRequestAction(req); #endif var timeoutCancellation = new CancellationTokenSource(); DelayAction(options.Timeout, timeoutCancellation.Token, () => { #if PCL task.TrySetException(new TimeoutException()); #else task.TrySetException(new WebException("Timeout", WebExceptionStatus.Timeout)); #endif req.Abort(); }); req.BeginGetRequestStream(reqStrAr => { try { using(var stream = req.EndGetRequestStream(reqStrAr)) stream.Write(data, 0, data.Length); req.BeginGetResponse(resAr => { timeoutCancellation.Cancel(); reg.Dispose(); try { task.TrySetResult(new AsyncResponse((HttpWebResponse)req.EndGetResponse(resAr))); } catch(Exception ex) { task.TrySetException(ex); } }, null); } catch(Exception ex) { task.TrySetException(ex); } }, null); } catch(Exception ex) { task.TrySetException(ex); } return task.Task; #endif }
Task<AsyncResponse> HttpPostWithMultipartFormDataAsync(string url, IEnumerable<KeyValuePair<string, object>> prm, string authorizationHeader, ConnectionOptions options, CancellationToken cancellationToken) { if(options == null) options = new ConnectionOptions(); #if WIN_RT var client = new HttpClient(); var req = new HttpRequestMessage(HttpMethod.Post, new Uri(url)); #if WIN8 var content = new MultipartFormDataContent(); #else var content = new HttpMultipartFormDataContent(); #endif foreach(var x in prm) { cancellationToken.ThrowIfCancellationRequested(); var valueStream = x.Value as Stream; var valueInputStream = x.Value as IInputStream; var valueBytes = x.Value as IEnumerable<byte>; var valueBuffer = x.Value as IBuffer; var valueInputStreamReference = x.Value as IInputStreamReference; var valueStorageItem = x.Value as IStorageItem; if(valueInputStreamReference != null) valueInputStream = await valueInputStreamReference.OpenSequentialReadAsync(); #if WIN8 if(valueInputStream != null) valueStream = valueInputStream.AsStreamForRead(); if(valueBuffer != null) valueStream = valueBuffer.AsStream(); if(valueStream != null) content.Add(new StreamContent(valueStream), x.Key, valueStorageItem != null ? valueStorageItem.Name : "file"); else if(valueBytes != null) { var valueByteArray = valueBytes as byte[]; if(valueByteArray == null) valueByteArray = valueBytes.ToArray(); content.Add(new ByteArrayContent(valueByteArray), x.Key, valueStorageItem != null ? valueStorageItem.Name : "file"); } else content.Add(new StringContent(x.Value.ToString()), x.Key); #else if (valueStream != null) valueInputStream = valueStream.AsInputStream(); if (valueBytes != null) { var valueByteArray = valueBytes as byte[]; if (valueByteArray == null) valueByteArray = valueBytes.ToArray(); valueBuffer = valueByteArray.AsBuffer(); } if (valueInputStream != null) content.Add(new HttpStreamContent(valueInputStream), x.Key, valueStorageItem != null ? valueStorageItem.Name : "file"); else if (valueBuffer != null) content.Add(new HttpBufferContent(valueBuffer), x.Key, valueStorageItem != null ? valueStorageItem.Name : "file"); else content.Add(new HttpStringContent(x.Value.ToString()), x.Key); #endif } cancellationToken.ThrowIfCancellationRequested(); req.Content = content; return await ExecuteRequest(client, req, authorizationHeader, options, cancellationToken).ConfigureAwait(false); #else return Task.Factory.StartNew(() => { cancellationToken.ThrowIfCancellationRequested(); var task = new TaskCompletionSource<AsyncResponse>(); var boundary = Guid.NewGuid().ToString(); var req = (HttpWebRequest)WebRequest.Create(url); var reg = cancellationToken.Register(() => { task.TrySetCanceled(); req.Abort(); }); #if NET45 || WP req.AllowReadStreamBuffering = false; #endif req.Method = "POST"; #if !(PCL || WP) req.ServicePoint.Expect100Continue = false; req.ReadWriteTimeout = options.ReadWriteTimeout; #endif #if !PCL req.UserAgent = options.UserAgent; #endif #if !(PCL || WP) req.Proxy = options.Proxy; #endif req.ContentType = "multipart/form-data;boundary=" + boundary; req.Headers[HttpRequestHeader.Authorization] = authorizationHeader; cancellationToken.ThrowIfCancellationRequested(); var memstr = new MemoryStream(); try { WriteMultipartFormData(memstr, boundary, prm); cancellationToken.ThrowIfCancellationRequested(); #if !PCL req.ContentLength = memstr.Length; if(options.BeforeRequestAction != null) options.BeforeRequestAction(req); #endif var timeoutCancellation = new CancellationTokenSource(); DelayAction(options.Timeout, timeoutCancellation.Token, () => { #if PCL task.TrySetException(new TimeoutException()); #else task.TrySetException(new WebException("Timeout", WebExceptionStatus.Timeout)); #endif req.Abort(); }); req.BeginGetRequestStream(reqStrAr => { try { using(var stream = req.EndGetRequestStream(reqStrAr)) memstr.WriteTo(stream); req.BeginGetResponse(resAr => { timeoutCancellation.Cancel(); reg.Dispose(); try { task.TrySetResult(new AsyncResponse((HttpWebResponse)req.EndGetResponse(resAr))); } catch(Exception ex) { task.TrySetException(ex); } }, null); } catch(Exception ex) { task.TrySetException(ex); } finally { memstr.Dispose(); } }, null); return task.Task; } catch { memstr.Dispose(); throw; } }, cancellationToken).CheckCanceled(cancellationToken).Unwrap(); #endif }
private static async Task <AsyncResponse> ExecuteRequest(HttpRequestMessage req, string authorizationHeader, ConnectionOptions options, CancellationToken cancellationToken) { var splitAuth = authorizationHeader.Split(new[] { ' ' }, 2); req.Headers.Add("User-Agent", options.UserAgent); req.Headers.ExpectContinue = false; req.Headers.Authorization = new AuthenticationHeaderValue(splitAuth[0], splitAuth[1]); if (options.DisableKeepAlive) { req.Headers.ConnectionClose = true; } if (options.BeforeRequestAction != null) { options.BeforeRequestAction(req); } var cancellation = new CancellationTokenSource(); var handler = new HttpClientHandler(); if (options.UseCompression) { handler.AutomaticDecompression = CompressionType; } using (var reg = cancellationToken.Register(cancellation.Cancel)) using (var client = new HttpClient(handler)) { var task = client.SendAsync(req, HttpCompletionOption.ResponseHeadersRead, cancellation.Token); var timeoutCancellation = new CancellationTokenSource(); DelayAction(options.Timeout, timeoutCancellation.Token, cancellation.Cancel); return(await task.ContinueWith(t => { timeoutCancellation.Cancel(); if (t.IsFaulted) { throw t.Exception.InnerException; } if (!cancellationToken.IsCancellationRequested && cancellation.IsCancellationRequested) { throw new TimeoutException(); } return new AsyncResponse(t.Result); }, cancellationToken).ConfigureAwait(false)); } }