Esempio n. 1
0
        private static LazyUri MaybeAddAdditionalQueryParameters(LazyUri url, WebRequestOptions options)
        {
            bool cloned = false;

            if (options != null && options.AdditionalQueryParameters != null)
            {
                foreach (var item in Flatten(options.AdditionalQueryParameters))
                {
                    if (!cloned)
                    {
                        cloned = true;
                        url    = url.Clone();
                    }
                    url.AppendQueryParameter(item.Key, ToString(item.Value));
                }
            }
            return(url);
        }
Esempio n. 2
0
        internal static async Task <HttpResponseInfo> SendAsync(this LazyUri url, WebRequestOptions options, HttpRequestMessageBox messageBox, bool alwaysCatchAndForbidRedirects = false, bool keepResponseAliveOnError = false, bool synchronous = false)
        {
            HttpUtils.EnsureInitialized();
            if (!synchronous)
            {
                await Utils.CheckLocalFileAccessAsync(url);
            }
            Utils.RaiseWebRequestEvent(url, false);
            HttpResponseMessage result            = null;
            LazyUri             previousResponse2 = null;

            try
            {
                if (options == WebRequestOptions.DefaultOptions)
                {
                    throw new ArgumentException();
                }
                if (options.WaitBefore.Ticks != 0 && !synchronous)
                {
                    await TaskEx.Delay(options.WaitBefore);
                }
                LazyUri previousResponse1 = null;
                previousResponse2 = url.Clone();
                previousResponse2 = MaybeAddAdditionalQueryParameters(previousResponse2, options);
                var redirectIndex = 0;
                while (true)
                {
#if WEBCLIENT
                    HttpContent requestContent = null;
#endif
                    var message = messageBox?.PrebuiltRequest ?? CreateRequestInternal(previousResponse2, options, true, redirectIndex
#if WEBCLIENT
                                                                                       , out requestContent
#endif
                                                                                       );
                    if (messageBox != null)
                    {
                        messageBox.Dispose();
                        messageBox.Message = message;
                    }

#if WEBCLIENT
                    if (requestContent != null)
                    {
                        if (requestContent.ContentType != null)
                        {
                            message.ContentType = requestContent.ContentType;
                        }
                        if (requestContent.ContentDisposition != null)
                        {
                            message.Headers["Content-Disposition"] = requestContent.ContentDisposition;
                        }
                        using (var req = await message.GetRequestStreamAsync())
                        {
                            await requestContent.CopyToAsync(req);
                        }
                    }
                    result = (HttpWebResponse)await message.GetResponseAsync();
#else
                    message.Properties["ShamanURL"] = url;
                    if (options.CustomHttpClient != null)
                    {
                        result = await options.CustomHttpClient.SendAsync(message, HttpCompletionOption.ResponseHeadersRead);
                    }
                    else
                    {
                        if (defaultHttpClient == null)
                        {
                            defaultHttpClient = CreateHttpClient();
                        }

                        result = messageBox?.PrebuiltResponse ?? await defaultHttpClient.SendAsync(message, HttpCompletionOption.ResponseHeadersRead);
                    }
#endif



#if !WEBCLIENT
                    if (result.Content != null && result.Content.Headers.ContentType != null && result.Content.Headers.ContentType.CharSet == "utf8")
                    {
                        result.Content.Headers.ContentType.CharSet = "utf-8";
                    }
#endif

                    if ((int)result.StatusCode >= 400)
                    {
                        if (!keepResponseAliveOnError)
                        {
                            result.Dispose();
                        }
                        // Hackish, change purpose of enumeration type
                        throw new WebException("The web server returned: " + result.StatusCode.ToString(), (WebExceptionStatus)result.StatusCode);
                    }
#if WEBCLIENT
                    var zz = result.Headers["Location"];
                    var redirectUrlNative = zz != null?HttpUtils.GetAbsoluteUri(url.PathConsistentUrl, zz) : null;
#else
                    var redirectUrlNative = result.Headers.Location;
#endif

                    if (redirectUrlNative == null)
                    {
                        return(new HttpResponseInfo()
                        {
                            RespondingUrl = previousResponse2, Response = result
                        });
                    }
                    else
                    {
                        if (alwaysCatchAndForbidRedirects)
                        {
                            return new HttpResponseInfo()
                                   {
                                       Response = result, RespondingUrl = previousResponse2, Exception = new WebException("Unexpected redirect", HttpUtils.Error_UnexpectedRedirect)
                                   }
                        }
                        ;

                        result.Dispose();
                        var redirectUrl = new LazyUri(redirectUrlNative);
                        if (!redirectUrl.IsAbsoluteUri)
                        {
                            redirectUrl = new LazyUri(new Uri(previousResponse2.PathConsistentUrl, redirectUrlNative));
                        }
                        if (options != null && !options.AllowRedirects)
                        {
                            throw new WebException("Unexpected redirect was received.", HttpUtils.Error_UnexpectedRedirect);
                        }
                        if (redirectIndex == Configuration_MaximumNumberOfRedirects)
                        {
                            throw new WebException("The maximum number of redirects has been reached.", HttpUtils.Error_MaximumNumberOfRedirectsExceeded);
                        }

                        if (!(redirectIndex == 0 && options != null && (options.PostData != null || options.PostString != null)))
                        {
                            if ((
                                    (previousResponse1 != null && HttpUtils.UrisEqual(redirectUrl.PathAndQueryConsistentUrl, previousResponse1.PathAndQueryConsistentUrl)) ||
                                    HttpUtils.UrisEqual(redirectUrl, previousResponse2)))
                            {
                                if (url.GetFragmentParameter("$allow-same-redirect") == "1")
                                {
                                    if (!synchronous)
                                    {
#if NET35
                                        await TaskEx.Delay(Configuration_SameRedirectDelayTimeMs);
#else
                                        await Task.Delay(Configuration_SameRedirectDelayTimeMs);
#endif
                                    }
                                }
                                else
                                {
                                    throw new WebException("The server isn't redirecting the requested resource properly.", HttpUtils.Error_RedirectLoopDetected);
                                }
                            }
                        }
                        previousResponse1 = previousResponse2;
                        previousResponse2 = redirectUrl;

                        redirectIndex++;
                    }
                }
            }
            catch (Exception ex)
            {
                var orig = ex;
#if !WEBCLIENT
                var hre = ex as HttpRequestException;
                if (hre != null && hre.InnerException != null)
                {
                    ex = hre.InnerException;
                }
#endif
                if (alwaysCatchAndForbidRedirects)
                {
                    return new HttpResponseInfo()
                           {
                               Exception = ex, Response = result, RespondingUrl = previousResponse2
                           }
                }
                ;
                else if (ex == orig)
                {
                    throw;
                }
                else
                {
                    throw ex.Rethrow();
                }
            }
        }