Пример #1
0
        private void SendRequest(string requestUri, object request, Action <WebRequest> callback)
        {
            var isHttpGet = HttpMethod != null && HttpMethod.ToUpper() == "GET";

            if (isHttpGet)
            {
                var queryString = QueryStringSerializer.SerializeToString(request);
                if (!string.IsNullOrEmpty(queryString))
                {
                    requestUri += "?" + queryString;
                }
            }

            SendRequest(HttpMethod ?? DefaultHttpMethod, requestUri, request, callback);
        }
Пример #2
0
        private void SendWebRequest <TResponse>(string httpMethod, string absoluteUrl, object request, CancellationToken token,
                                                Action <TResponse> onSuccess, Action <object, Exception> onError, Action <WebResponse> onResponseInit = null)
        {
            if (httpMethod == null)
            {
                throw new ArgumentNullException(nameof(httpMethod));
            }

            this.PopulateRequestMetadata(request);

            var requestUri     = absoluteUrl;
            var hasQueryString = request != null && !httpMethod.HasRequestBody();

            if (hasQueryString)
            {
                var queryString = QueryStringSerializer.SerializeToString(request);
                if (!string.IsNullOrEmpty(queryString))
                {
                    requestUri += "?" + queryString;
                }
            }

            var webRequest = this.CreateHttpWebRequest(requestUri);

            var requestState = new AsyncState <TResponse>(BufferSize)
            {
                HttpMethod                = httpMethod,
                Url                       = requestUri,
                WebRequest                = webRequest,
                Request                   = request,
                Token                     = token,
                OnResponseInit            = onResponseInit,
                OnSuccess                 = onSuccess,
                OnError                   = onError,
                UseSynchronizationContext = CaptureSynchronizationContext ? SynchronizationContext.Current : null,
                HandleCallbackOnUIThread  = HandleCallbackOnUiThread,
            };

            if (!DisableTimer)
            {
                requestState.StartTimer(this.Timeout.GetValueOrDefault(DefaultTimeout));
            }

            SendWebRequestAsync(httpMethod, request, requestState, webRequest);
        }
Пример #3
0
        public virtual Task <TResponse> PostFilesWithRequestAsync <TResponse>(string requestUri, object request, UploadFile[] files)
        {
            var queryString         = QueryStringSerializer.SerializeToString(request);
            var nameValueCollection = PclExportClient.Instance.ParseQueryString(queryString);

            var content = new MultipartFormDataContent();

            foreach (string key in nameValueCollection)
            {
                var value = nameValueCollection[key];
                content.Add(new StringContent(value), $"\"{key}\"");
            }

            var disposables = new List <IDisposable> {
                content
            };

            for (int i = 0; i < files.Length; i++)
            {
                var file        = files[i];
                var fileBytes   = file.Stream.ReadFully();
                var fileContent = new ByteArrayContent(fileBytes, 0, fileBytes.Length);
                disposables.Add(fileContent);
                var fieldName = file.FieldName ?? $"upload{i}";
                var fileName  = file.FileName ?? $"upload{i}";
                fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
                {
                    Name     = fieldName,
                    FileName = fileName,
                };
                fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse(MimeTypes.GetMimeType(fileName));

                content.Add(fileContent, fileName, fileName);
            }

            return(SendAsync <TResponse>(HttpMethods.Post, requestUri, content)
                   .ContinueWith(t => { foreach (var d in disposables)
                                        {
                                            d.Dispose();
                                        }
                                        return t.Result; },
                                 TaskContinuationOptions.ExecuteSynchronously));
        }
        private void SendWebRequest <TResponse>(string httpMethod, string absoluteUrl, object request,
                                                Action <TResponse> onSuccess, Action <TResponse, Exception> onError)
        {
            if (httpMethod == null)
            {
                throw new ArgumentNullException("httpMethod");
            }

            var requestUri            = absoluteUrl;
            var httpGetOrDeleteOrHead = (httpMethod == "GET" || httpMethod == "DELETE" || httpMethod == "HEAD");
            var hasQueryString        = request != null && httpGetOrDeleteOrHead;

            if (hasQueryString)
            {
                var queryString = QueryStringSerializer.SerializeToString(request);
                if (!string.IsNullOrEmpty(queryString))
                {
                    requestUri += "?" + queryString;
                }
            }

            var webRequest = this.CreateHttpWebRequest(requestUri);

            var requestState = new AsyncState <TResponse>(BufferSize)
            {
                HttpMethod = httpMethod,
                Url        = requestUri,
                WebRequest = webRequest,
                Request    = request,
                OnSuccess  = onSuccess,
                OnError    = onError,
                UseSynchronizationContext = CaptureSynchronizationContext ? SynchronizationContext.Current : null,
                HandleCallbackOnUIThread  = HandleCallbackOnUiThread,
            };

            requestState.StartTimer(this.Timeout.GetValueOrDefault(DefaultTimeout));

            SendWebRequestAsync(httpMethod, request, requestState, webRequest);
        }
Пример #5
0
        public Task <TResponse> SendAsync <TResponse>(string httpMethod, string absoluteUrl, object request)
        {
            if (!httpMethod.HasRequestBody() && request != null)
            {
                var queryString = QueryStringSerializer.SerializeToString(request);
                if (!string.IsNullOrEmpty(queryString))
                {
                    absoluteUrl += "?" + queryString;
                }
            }

            if (ResultsFilter != null)
            {
                var response = ResultsFilter(typeof(TResponse), httpMethod, absoluteUrl, request);
                if (response is TResponse)
                {
                    var tcs = new TaskCompletionSource <TResponse>();
                    tcs.SetResult((TResponse)response);
                    return(tcs.Task);
                }
            }

            var client = GetHttpClient();

            if (AlwaysSendBasicAuthHeader)
            {
                AddBasicAuth(client);
            }

            this.PopulateRequestMetadata(request);

            var httpReq = new HttpRequestMessage(new HttpMethod(httpMethod), absoluteUrl);

            foreach (var name in Headers.AllKeys)
            {
                httpReq.Headers.Add(name, Headers[name]);
            }
            httpReq.Headers.Add(HttpHeaders.Accept, ContentType);

            if (httpMethod.HasRequestBody() && request != null)
            {
                var httpContent = request as HttpContent;
                if (httpContent != null)
                {
                    httpReq.Content = httpContent;
                }
                else
                {
                    var str    = request as string;
                    var bytes  = request as byte[];
                    var stream = request as Stream;
                    if (str != null)
                    {
                        httpReq.Content = new StringContent(str);
                    }
                    else if (bytes != null)
                    {
                        httpReq.Content = new ByteArrayContent(bytes);
                    }
                    else if (stream != null)
                    {
                        httpReq.Content = new StreamContent(stream);
                    }
                    else
                    {
                        using (__requestAccess())
                        {
                            httpReq.Content = new StringContent(request.ToJson(), Encoding.UTF8, ContentType);
                        }
                    }
                }
            }

            ApplyWebRequestFilters(httpReq);

            Interlocked.Increment(ref activeAsyncRequests);

            if (CancelTokenSource == null)
            {
                CancelTokenSource = new CancellationTokenSource();
            }

            var sendAsyncTask = client.SendAsync(httpReq, CancelTokenSource.Token);

            if (typeof(TResponse) == typeof(HttpResponseMessage))
            {
                return((Task <TResponse>)(object) sendAsyncTask);
            }

            return(sendAsyncTask
                   .ContinueWith(responseTask =>
            {
                var httpRes = responseTask.Result;
                ApplyWebResponseFilters(httpRes);

                if (typeof(TResponse) == typeof(byte[]))
                {
                    return httpRes.Content.ReadAsByteArrayAsync().ContinueWith(task =>
                    {
                        ThrowIfError <TResponse>(task, httpRes, request, absoluteUrl, task.Result);

                        var response = (TResponse)(object)task.Result;

                        if (ResultsFilterResponse != null)
                        {
                            ResultsFilterResponse(httpRes, response, httpMethod, absoluteUrl, request);
                        }

                        return response;
                    });
                }
                if (typeof(TResponse) == typeof(Stream))
                {
                    return httpRes.Content.ReadAsStreamAsync().ContinueWith(task =>
                    {
                        ThrowIfError <TResponse>(task, httpRes, request, absoluteUrl, task.Result);

                        var response = (TResponse)(object)task.Result;

                        if (ResultsFilterResponse != null)
                        {
                            ResultsFilterResponse(httpRes, response, httpMethod, absoluteUrl, request);
                        }

                        return response;
                    });
                }

                return httpRes.Content.ReadAsStringAsync().ContinueWith(task =>
                {
                    ThrowIfError <TResponse>(task, httpRes, request, absoluteUrl, task.Result);

                    var body = task.Result;
                    using (__requestAccess())
                    {
                        var response = body.FromJson <TResponse>();

                        if (ResultsFilterResponse != null)
                        {
                            ResultsFilterResponse(httpRes, response, httpMethod, absoluteUrl, request);
                        }

                        return response;
                    }
                });
            }).Unwrap());
        }
Пример #6
0
        private WebRequest PrepareWebRequest(string httpMethod, string requestUri, object request, Action <HttpWebRequest> sendRequestAction)
        {
            if (httpMethod == null)
            {
                throw new ArgumentNullException("httpMethod");
            }

            var httpMethodGetOrHead = httpMethod == HttpMethods.Get || httpMethod == HttpMethods.Head;

            if (httpMethodGetOrHead && request != null)
            {
                var queryString = QueryStringSerializer.SerializeToString(request);
                if (!string.IsNullOrEmpty(queryString))
                {
                    requestUri += "?" + queryString;
                }
            }

            var client = (HttpWebRequest)WebRequest.Create(requestUri);

            try
            {
                client.MaximumResponseHeadersLength = int.MaxValue; //throws "The message length limit was exceeded" exception
                client.Accept = Accept;
                client.Method = httpMethod;
                client.Headers.Add(Headers);

                if (Proxy != null)
                {
                    client.Proxy = Proxy;
                }
                if (this.Timeout.HasValue)
                {
                    client.Timeout = (int)this.Timeout.Value.TotalMilliseconds;
                }
                if (this.ReadWriteTimeout.HasValue)
                {
                    client.ReadWriteTimeout = (int)this.ReadWriteTimeout.Value.TotalMilliseconds;
                }
                if (this.credentials != null)
                {
                    client.Credentials = this.credentials;
                }

                if (null != this.authInfo)
                {
                    client.AddAuthInfo(this.UserName, this.Password, authInfo);
                }
                else
                {
                    if (this.AlwaysSendBasicAuthHeader)
                    {
                        client.AddBasicAuth(this.UserName, this.Password);
                    }
                }

                if (!DisableAutoCompression)
                {
                    client.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate");
                    client.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
                }

                if (StoreCookies)
                {
                    client.CookieContainer = CookieContainer;
                }

                client.AllowAutoRedirect = AllowAutoRedirect;

                ApplyWebRequestFilters(client);

                if (httpMethod != HttpMethods.Get &&
                    httpMethod != HttpMethods.Delete &&
                    httpMethod != HttpMethods.Head)
                {
                    client.ContentType = ContentType;

                    if (sendRequestAction != null)
                    {
                        sendRequestAction(client);
                    }
                }
            }
            catch (AuthenticationException ex)
            {
                throw WebRequestUtils.CreateCustomException(requestUri, ex) ?? ex;
            }
            return(client);
        }
Пример #7
0
        public virtual TResponse PostFileWithRequest <TResponse>(string relativeOrAbsoluteUrl, Stream fileToUpload, string fileName, object request)
        {
            var requestUri            = GetUrl(relativeOrAbsoluteUrl);
            var currentStreamPosition = fileToUpload.Position;

            Func <WebRequest> createWebRequest = () =>
            {
                var webRequest = PrepareWebRequest(HttpMethods.Post, requestUri, null, null);

                var queryString = QueryStringSerializer.SerializeToString(request);
#if !MONOTOUCH
                var nameValueCollection = System.Web.HttpUtility.ParseQueryString(queryString);
#endif
                var boundary = DateTime.UtcNow.Ticks.ToString(CultureInfo.InvariantCulture);
                webRequest.ContentType = "multipart/form-data; boundary=" + boundary;
                boundary = "--" + boundary;
                var newLine = "\r\n";
                using (var outputStream = webRequest.GetRequestStream())
                {
#if !MONOTOUCH
                    foreach (var key in nameValueCollection.AllKeys)
                    {
                        outputStream.Write(boundary + newLine);
                        outputStream.Write("Content-Disposition: form-data;name=\"{0}\"{1}".FormatWith(key, newLine));
                        outputStream.Write("Content-Type: text/plain;charset=utf-8{0}{1}".FormatWith(newLine, newLine));
                        outputStream.Write(nameValueCollection[key] + newLine);
                    }
#endif
                    outputStream.Write(boundary + newLine);
                    outputStream.Write("Content-Disposition: form-data;name=\"{0}\";filename=\"{1}\"{2}{3}".FormatWith("upload", fileName, newLine, newLine));
                    var buffer = new byte[4096];
                    int byteCount;
                    while ((byteCount = fileToUpload.Read(buffer, 0, 4096)) > 0)
                    {
                        outputStream.Write(buffer, 0, byteCount);
                    }
                    outputStream.Write(newLine);
                    outputStream.Write(boundary + "--");
                }

                return(webRequest);
            };

            try
            {
                var webRequest  = createWebRequest();
                var webResponse = webRequest.GetResponse();
                return(HandleResponse <TResponse>(webResponse));
            }
            catch (Exception ex)
            {
                TResponse response;

                // restore original position before retry
                fileToUpload.Seek(currentStreamPosition, SeekOrigin.Begin);

                if (!HandleResponseException(
                        ex, request, requestUri, createWebRequest, c => c.GetResponse(), out response))
                {
                    throw;
                }

                return(response);
            }
        }
Пример #8
0
        public Task <TResponse> SendAsync <TResponse>(string httpMethod, string absoluteUrl, object request, CancellationToken token = default(CancellationToken))
        {
            var client = GetHttpClient();

            if (!HttpUtils.HasRequestBody(httpMethod) && request != null)
            {
                var queryString = QueryStringSerializer.SerializeToString(request);
                if (!string.IsNullOrEmpty(queryString))
                {
                    absoluteUrl += "?" + queryString;
                }
            }

            try
            {
                absoluteUrl = new Uri(absoluteUrl).ToString();
            }
            catch (Exception ex)
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("Could not parse URL: " + absoluteUrl, ex);
                }
            }

            var response = ResultsFilter?.Invoke(typeof(TResponse), httpMethod, absoluteUrl, request);

            if (response is TResponse)
            {
                var tcs = new TaskCompletionSource <TResponse>();
                tcs.SetResult((TResponse)response);
                return(tcs.Task);
            }

            if (token == default(CancellationToken))
            {
                if (CancelTokenSource == null)
                {
                    CancelTokenSource = new CancellationTokenSource();
                }
                token = CancelTokenSource.Token;
            }

            var httpReq       = CreateRequest(httpMethod, absoluteUrl, request);
            var sendAsyncTask = client.SendAsync(httpReq, token);

            if (typeof(TResponse) == typeof(HttpResponseMessage))
            {
                return((Task <TResponse>)(object) sendAsyncTask);
            }

            return(sendAsyncTask
                   .ContinueWith(responseTask =>
            {
                var httpRes = responseTask.Result;

                if (httpRes.StatusCode == HttpStatusCode.Unauthorized)
                {
                    if (RefreshToken != null)
                    {
                        var refreshDto = new GetAccessToken {
                            RefreshToken = RefreshToken
                        };
                        var uri = this.RefreshTokenUri ?? this.BaseUri.CombineWith(refreshDto.ToPostUrl());
                        return this.PostAsync <GetAccessTokenResponse>(uri, refreshDto)
                        .ContinueWith(t =>
                        {
                            if (t.IsFaulted)
                            {
                                if (t.Exception.UnwrapIfSingleException() is WebServiceException refreshEx)
                                {
                                    throw new RefreshTokenException(refreshEx);
                                }
                                throw t.Exception;
                            }

                            var accessToken = t.Result?.AccessToken;
                            if (string.IsNullOrEmpty(accessToken))
                            {
                                throw new RefreshTokenException("Could not retrieve new AccessToken from: " + uri);
                            }

                            var refreshRequest = CreateRequest(httpMethod, absoluteUrl, request);
                            if (this.GetTokenCookie() != null)
                            {
                                this.SetTokenCookie(accessToken);
                            }
                            else
                            {
                                refreshRequest.AddBearerToken(this.BearerToken = accessToken);
                            }

                            return client.SendAsync(refreshRequest, token).ContinueWith(refreshTask =>
                                                                                        ConvertToResponse <TResponse>(refreshTask.Result,
                                                                                                                      httpMethod, absoluteUrl, refreshRequest, token),
                                                                                        token).Unwrap();
                        }, token).Unwrap();
                    }
                    if (UserName != null && Password != null && client.DefaultRequestHeaders.Authorization == null)
                    {
                        AddBasicAuth(client);
                        httpReq = CreateRequest(httpMethod, absoluteUrl, request);
                        sendAsyncTask = client.SendAsync(httpReq, token);
                        return sendAsyncTask.ContinueWith(t =>
                                                          ConvertToResponse <TResponse>(t.Result, httpMethod, absoluteUrl, request, token),
                                                          token).Unwrap();
                    }
                }

                return ConvertToResponse <TResponse>(httpRes, httpMethod, absoluteUrl, request, token);
            }, token).Unwrap());
        }
Пример #9
0
        private async Task <T> SendWebRequestAsync <T>(string httpMethod, string absoluteUrl, object request, CancellationToken token, bool recall = false)
        {
            if (httpMethod == null)
            {
                throw new ArgumentNullException(nameof(httpMethod));
            }

            this.PopulateRequestMetadata(request);

            var requestUri     = absoluteUrl;
            var hasQueryString = request != null && !HttpUtils.HasRequestBody(httpMethod);

            if (hasQueryString)
            {
                var queryString = QueryStringSerializer.SerializeToString(request);
                if (!string.IsNullOrEmpty(queryString))
                {
                    requestUri += "?" + queryString;
                }
            }

            var webReq = this.CreateHttpWebRequest(requestUri);

            if (webReq != null && Proxy != null)
            {
                webReq.Proxy = Proxy;
            }

            var    timedOut = false;
            ITimer timer    = null;

            timer = PclExportClient.Instance.CreateTimer(state =>
            {
                timedOut = true;
                webReq?.Abort();
                webReq = null;
                timer?.Cancel();
                timer = null;
            }, this.Timeout.GetValueOrDefault(DefaultTimeout), this);

            Exception ResolveException(Exception ex)
            {
                if (token.IsCancellationRequested)
                {
                    return(new OperationCanceledException(token));
                }
                if (timedOut)
                {
                    return(PclExportClient.Instance.CreateTimeoutException(ex, "The request timed out"));
                }
                return(ex);
            }

            bool            returningWebResponse = false;
            HttpWebResponse webRes = null;

            T Complete(T response)
            {
                timer.Cancel();
                PclExportClient.Instance.SynchronizeCookies(this);
                ResultsFilterResponse?.Invoke(webRes, response, httpMethod, absoluteUrl, request);
                return(response);
            }

            webReq.Accept = ContentType;

            if (this.EmulateHttpViaPost)
            {
                webReq.Method = "POST";
                webReq.Headers[HttpHeaders.XHttpMethodOverride] = httpMethod;
            }
            else
            {
                webReq.Method = httpMethod;
            }

            PclExportClient.Instance.AddHeader(webReq, Headers);
            PclExport.Instance.Config(webReq, userAgent: UserAgent);

            if (this.authInfo != null && !string.IsNullOrEmpty(this.UserName))
            {
                webReq.AddAuthInfo(this.UserName, this.Password, authInfo);
            }
            else if (this.BearerToken != null)
            {
                webReq.Headers[HttpHeaders.Authorization] = "Bearer " + this.BearerToken;
            }
            else if (this.Credentials != null)
            {
                webReq.Credentials = this.Credentials;
            }
            else if (this.AlwaysSendBasicAuthHeader)
            {
                webReq.AddBasicAuth(this.UserName, this.Password);
            }

            if (!DisableAutoCompression)
            {
                PclExport.Instance.AddCompression(webReq);
            }

            ApplyWebRequestFilters(webReq);

            try
            {
                if (HttpUtils.HasRequestBody(webReq.Method))
                {
                    webReq.ContentType = ContentType;

                    if (RequestCompressionType != null)
                    {
                        webReq.Headers[HttpHeaders.ContentEncoding] = RequestCompressionType;
                    }

                    using var requestStream = await webReq.GetRequestStreamAsync().ConfigAwait();

                    token.ThrowIfCancellationRequested();
                    if (request != null)
                    {
                        StreamSerializer(null, request, requestStream);
                    }
                }
            }
            catch (Exception ex)
            {
                if (Log.IsDebugEnabled)
                {
                    Log.Debug($"Error Sending Request: {ex.Message}", ex);
                }

                throw HandleResponseError <T>(ResolveException(ex), requestUri, request);
            }

            try
            {
                webRes = (HttpWebResponse)await webReq.GetResponseAsync().ConfigAwait();

                {
                    token.ThrowIfCancellationRequested();

                    ApplyWebResponseFilters(webRes);

                    returningWebResponse = typeof(T) == typeof(HttpWebResponse);
                    if (returningWebResponse)
                    {
                        return(Complete((T)(object)webRes));
                    }

                    var responseStream = webRes.ResponseStream();

                    var responseBodyLength = webRes.ContentLength;
                    var bufferRead         = new byte[BufferSize];

                    var totalRead = 0;
                    int read;
                    var ms = MemoryStreamFactory.GetStream();

                    while ((read = await responseStream.ReadAsync(bufferRead, 0, bufferRead.Length, token).ConfigAwait()) != 0)
                    {
                        await ms.WriteAsync(bufferRead, 0, read, token).ConfigAwait();

                        totalRead += read;
                        OnDownloadProgress?.Invoke(totalRead, responseBodyLength);
                    }

                    try
                    {
                        ms.Position = 0;
                        if (typeof(T) == typeof(Stream))
                        {
                            return(Complete((T)(object)ms));
                        }
                        else
                        {
                            var stream = ms;
                            try
                            {
                                if (typeof(T) == typeof(string))
                                {
                                    return(Complete((T)(object)await stream.ReadToEndAsync().ConfigAwait()));
                                }
                                else if (typeof(T) == typeof(byte[]))
                                {
                                    return(Complete((T)(object)stream.ToArray()));
                                }
                                else
                                {
                                    return(Complete((T)this.StreamDeserializer(typeof(T), stream)));
                                }
                            }
                            finally
                            {
                                if (stream.CanRead)
                                {
                                    stream.Dispose(); // Not yet disposed, but could've been.
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        if (Log.IsDebugEnabled)
                        {
                            Log.Debug($"Error Reading Response Error: {ex.Message}", ex);
                        }

                        throw;
                    }
                    finally
                    {
                        responseStream.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                var webEx                 = ex as WebException;
                var firstCall             = !recall;
                var hasRefreshTokenCookie = this.CookieContainer.GetRefreshTokenCookie(BaseUri) != null;
                var hasRefreshToken       = RefreshToken != null || hasRefreshTokenCookie;

                if (firstCall && WebRequestUtils.ShouldAuthenticate(webEx,
                                                                    (!string.IsNullOrEmpty(UserName) && !string.IsNullOrEmpty(Password)) ||
                                                                    Credentials != null ||
                                                                    BearerToken != null ||
                                                                    hasRefreshToken ||
                                                                    OnAuthenticationRequired != null))
                {
                    try
                    {
                        if (hasRefreshToken)
                        {
                            var refreshRequest = new GetAccessToken {
                                RefreshToken   = RefreshToken,
                                UseTokenCookie = UseTokenCookie,
                            };
                            var uri = this.RefreshTokenUri ?? this.BaseUri.CombineWith(refreshRequest.ToPostUrl());

                            GetAccessTokenResponse tokenResponse;
                            try
                            {
                                tokenResponse = (await uri.PostJsonToUrlAsync(refreshRequest, requestFilter: req => {
                                    if (UseTokenCookie || hasRefreshTokenCookie)
                                    {
                                        req.CookieContainer = CookieContainer;
                                    }
                                }, token: token).ConfigAwait()).FromJson <GetAccessTokenResponse>();
                            }
                            catch (WebException refreshEx)
                            {
                                var webServiceEx = ServiceClientBase.ToWebServiceException(refreshEx,
                                                                                           stream => StreamDeserializer(typeof(T), stream),
                                                                                           ContentType);

                                if (webServiceEx != null)
                                {
                                    throw new RefreshTokenException(webServiceEx);
                                }

                                throw new RefreshTokenException(refreshEx.Message, refreshEx);
                            }

                            var accessToken   = tokenResponse?.AccessToken;
                            var refreshClient = webReq = (HttpWebRequest)WebRequest.Create(requestUri);
                            var tokenCookie   = this.CookieContainer.GetTokenCookie(BaseUri);

                            if (UseTokenCookie)
                            {
                                if (tokenCookie == null)
                                {
                                    throw new RefreshTokenException("Could not retrieve new AccessToken Cooke from: " + uri);
                                }

                                refreshClient.CookieContainer.SetTokenCookie(BaseUri, tokenCookie);
                            }
                            else
                            {
                                if (string.IsNullOrEmpty(accessToken))
                                {
                                    throw new RefreshTokenException("Could not retrieve new AccessToken from: " + uri);
                                }

                                if (tokenCookie != null)
                                {
                                    this.CookieContainer.SetTokenCookie(accessToken, BaseUri);
                                    refreshClient.CookieContainer.SetTokenCookie(BaseUri, accessToken);
                                }
                                else
                                {
                                    refreshClient.AddBearerToken(this.BearerToken = accessToken);
                                }
                            }

                            return(await SendWebRequestAsync <T>(httpMethod, absoluteUrl, request, token, recall : true).ConfigAwait());
                        }

                        OnAuthenticationRequired?.Invoke();

                        var newReq = (HttpWebRequest)WebRequest.Create(requestUri);

                        if (StoreCookies)
                        {
                            newReq.CookieContainer = CookieContainer;
                        }

                        HandleAuthException(ex, webReq);

                        return(await SendWebRequestAsync <T>(httpMethod, absoluteUrl, request, token, recall : true).ConfigAwait());
                    }
                    catch (WebServiceException)
                    {
                        throw;
                    }
                    catch (Exception /*subEx*/)
                    {
                        throw HandleResponseError <T>(ResolveException(ex), requestUri, request);
                    }
                }

                if (ExceptionFilter != null && webEx?.Response != null)
                {
                    var cachedResponse = ExceptionFilter(webEx, webEx.Response, requestUri, typeof(T));
                    if (cachedResponse is T variable)
                    {
                        return(variable);
                    }
                }

                throw HandleResponseError <T>(ResolveException(ex), requestUri, request);
            }
            finally
            {
                if (!returningWebResponse)
                {
                    webRes?.Dispose();
                }
            }
        }
Пример #10
0
        private WebRequest PrepareWebRequest(string httpMethod, string requestUri, object request, Action <HttpWebRequest> sendRequestAction)
        {
            if (httpMethod == null)
            {
                throw new ArgumentNullException("httpMethod");
            }

            var httpMethodGetOrHead = httpMethod == HttpMethods.Get || httpMethod == HttpMethods.Head;

            if (httpMethodGetOrHead && request != null)
            {
                var queryString = QueryStringSerializer.SerializeToString(request);
                if (!string.IsNullOrEmpty(queryString))
                {
                    requestUri += "?" + queryString;
                }
            }

            var client = (HttpWebRequest)WebRequest.Create(requestUri);

            try
            {
                client.Accept = Accept;
                client.Method = httpMethod;
                PclExportClient.Instance.AddHeader(client, Headers);

#if !SL5
                if (Proxy != null)
                {
                    client.Proxy = Proxy;
                }
#endif
                PclExport.Instance.Config(client,
                                          allowAutoRedirect: AllowAutoRedirect,
                                          timeout: this.Timeout,
                                          readWriteTimeout: ReadWriteTimeout,
                                          userAgent: UserAgent);

                if (this.credentials != null)
                {
                    client.Credentials = this.credentials;
                }

                if (null != this.authInfo)
                {
                    client.AddAuthInfo(this.UserName, this.Password, authInfo);
                }
                else
                {
                    if (this.AlwaysSendBasicAuthHeader)
                    {
                        client.AddBasicAuth(this.UserName, this.Password);
                    }
                }

                if (!DisableAutoCompression)
                {
                    PclExport.Instance.AddCompression(client);
                }

                if (StoreCookies)
                {
                    PclExportClient.Instance.SetCookieContainer(client, this);
                }

                ApplyWebRequestFilters(client);

                if (httpMethod != HttpMethods.Get &&
                    httpMethod != HttpMethods.Delete &&
                    httpMethod != HttpMethods.Head)
                {
                    client.ContentType = ContentType;

                    if (sendRequestAction != null)
                    {
                        sendRequestAction(client);
                    }
                }
            }
            catch (AuthenticationException ex)
            {
                throw WebRequestUtils.CreateCustomException(requestUri, ex) ?? ex;
            }
            return(client);
        }
Пример #11
0
        public Task <TResponse> SendAsync <TResponse>(string httpMethod, string absoluteUrl, object request, CancellationToken token = default(CancellationToken))
        {
            var client = GetHttpClient();

            if (!httpMethod.HasRequestBody() && request != null)
            {
                var queryString = QueryStringSerializer.SerializeToString(request);
                if (!string.IsNullOrEmpty(queryString))
                {
                    absoluteUrl += "?" + queryString;
                }
            }

            if (ResultsFilter != null)
            {
                var response = ResultsFilter(typeof(TResponse), httpMethod, absoluteUrl, request);
                if (response is TResponse)
                {
                    var tcs = new TaskCompletionSource <TResponse>();
                    tcs.SetResult((TResponse)response);
                    return(tcs.Task);
                }
            }

            if (token == default(CancellationToken))
            {
                if (CancelTokenSource == null)
                {
                    CancelTokenSource = new CancellationTokenSource();
                }
                token = CancelTokenSource.Token;
            }

            var httpReq       = CreateRequest(httpMethod, absoluteUrl, request);
            var sendAsyncTask = client.SendAsync(httpReq, token);

            if (typeof(TResponse) == typeof(HttpResponseMessage))
            {
                return((Task <TResponse>)(object) sendAsyncTask);
            }

            return(sendAsyncTask
                   .ContinueWith(responseTask =>
            {
                var httpRes = responseTask.Result;

                if (httpRes.StatusCode == HttpStatusCode.Unauthorized)
                {
                    if (RefreshToken != null)
                    {
                        var refreshDto = new GetAccessToken {
                            RefreshToken = RefreshToken
                        };
                        var uri = this.RefreshTokenUri ?? this.BaseUri.CombineWith(refreshDto.ToPostUrl());
                        return this.PostAsync <GetAccessTokenResponse>(uri, refreshDto)
                        .ContinueWith(t =>
                        {
                            var accessToken = t.Result?.AccessToken;
                            if (string.IsNullOrEmpty(accessToken))
                            {
                                throw new Exception("Could not retrieve new AccessToken from: " + uri);
                            }

                            var refreshRequest = CreateRequest(httpMethod, absoluteUrl, request);
                            if (this.GetTokenCookie() != null)
                            {
                                this.SetTokenCookie(accessToken);
                            }
                            else
                            {
                                refreshRequest.AddBearerToken(this.BearerToken = accessToken);
                            }

                            return client.SendAsync(refreshRequest, token).ContinueWith(refreshTask =>
                                                                                        ConvertToResponse <TResponse>(refreshTask.Result,
                                                                                                                      httpMethod, absoluteUrl, refreshRequest, token),
                                                                                        token).Unwrap();
                        }, token).Unwrap();
                    }
                }

                return ConvertToResponse <TResponse>(httpRes, httpMethod, absoluteUrl, request, token);
            }, token).Unwrap());
        }