예제 #1
0
        private bool LoadFromCache(Uri uri)
        {
            int length;

            using (Stream stream = HTTPCacheService.GetBody(uri, out length))
            {
                if (stream == null)
                {
                    return(false);
                }
                if (!base.CurrentRequest.Response.HasHeader("content-length"))
                {
                    base.CurrentRequest.Response.Headers.Add("content-length", new List <string>(1)
                    {
                        length.ToString()
                    });
                }
                base.CurrentRequest.Response.IsFromCache = true;
                base.CurrentRequest.Response.ReadRaw(stream, length);
            }
            return(true);
        }
예제 #2
0
        public static void OnQuit()
        {
            HTTPManager.Logger.Information("HTTPManager", "OnQuit called!");

            IsQuitting = true;

            AbortAll();

#if !BESTHTTP_DISABLE_CACHING
            HTTPCacheService.SaveLibrary();
#endif

#if !BESTHTTP_DISABLE_COOKIES
            CookieJar.Persist();
#endif

            OnUpdate();

            HostManager.Clear();

            Heartbeats.Clear();
        }
 private bool TryLoadAllFromCache()
 {
     if (CurrentRequest.DisableCache)
     {
         return(false);
     }
     try
     {
         if (HTTPCacheService.IsCachedEntityExpiresInTheFuture(CurrentRequest))
         {
             CurrentRequest.Response = HTTPCacheService.GetFullResponse(CurrentRequest);
             if (CurrentRequest.Response != null)
             {
                 return(true);
             }
         }
     }
     catch
     {
         HTTPCacheService.DeleteEntity(CurrentRequest.CurrentUri);
     }
     return(false);
 }
예제 #4
0
        public static void Setup()
        {
            if (IsSetupCalled)
            {
                return;
            }
            IsSetupCalled = true;
            IsQuitting    = false;

            HTTPManager.Logger.Information("HTTPManager", "Setup called! UserAgent: " + UserAgent);

            HTTPUpdateDelegator.CheckInstance();

#if !BESTHTTP_DISABLE_CACHING
            HTTPCacheService.CheckSetup();
#endif

#if !BESTHTTP_DISABLE_COOKIES
            Cookies.CookieJar.SetupFolder();
            Cookies.CookieJar.Load();
#endif

            HostManager.Load();
        }
예제 #5
0
        private bool Receive()
        {
            SupportedProtocols protocol = CurrentRequest.ProtocolHandler == SupportedProtocols.Unknown ? HTTPProtocolFactory.GetProtocolFromUri(CurrentRequest.CurrentUri) : CurrentRequest.ProtocolHandler;

            CurrentRequest.Response = HTTPProtocolFactory.Get(protocol, CurrentRequest, Stream, CurrentRequest.UseStreaming, false);

            if (!CurrentRequest.Response.Receive())
            {
                CurrentRequest.Response = null;
                return(false);
            }

            // We didn't check HTTPManager.IsCachingDisabled's value on purpose. (sending out a request with conditional get then change IsCachingDisabled to true may produce undefined behavior)
            if (CurrentRequest.Response.StatusCode == 304)
            {
#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR)
                int bodyLength;
                using (var cacheStream = HTTPCacheService.GetBody(CurrentRequest.CurrentUri, out bodyLength))
                {
                    if (!CurrentRequest.Response.HasHeader("content-length"))
                    {
                        CurrentRequest.Response.Headers.Add("content-length", new List <string>(1)
                        {
                            bodyLength.ToString()
                        });
                    }
                    CurrentRequest.Response.IsFromCache = true;
                    CurrentRequest.Response.ReadRaw(cacheStream, bodyLength);
                }
#else
                return(false);
#endif
            }

            return(true);
        }
예제 #6
0
        private bool LoadFromCache(Uri uri)
        {
            if (HTTPManager.Logger.Level == Loglevels.All)
            {
                HTTPManager.Logger.Verbose("HTTPConnection", $"{base.CurrentRequest.CurrentUri.ToString()} - LoadFromCache for Uri: {uri.ToString()}");
            }
            HTTPCacheFileInfo entity = HTTPCacheService.GetEntity(uri);

            if (entity == null)
            {
                HTTPManager.Logger.Warning("HTTPConnection", $"{base.CurrentRequest.CurrentUri.ToString()} - LoadFromCache for Uri: {uri.ToString()} - Cached entity not found!");
                return(false);
            }
            base.CurrentRequest.Response.CacheFileInfo = entity;
            using (System.IO.Stream stream = entity.GetBodyStream(out int num))
            {
                if (stream == null)
                {
                    return(false);
                }
                if (!base.CurrentRequest.Response.HasHeader("content-length"))
                {
                    List <string> list = new List <string>(1)
                    {
                        num.ToString()
                    };
                    base.CurrentRequest.Response.Headers.Add("content-length", list);
                }
                base.CurrentRequest.Response.IsFromCache = true;
                if (!base.CurrentRequest.CacheOnly)
                {
                    base.CurrentRequest.Response.ReadRaw(stream, (long)num);
                }
            }
            return(true);
        }
예제 #7
0
        protected override void ThreadFunc(object param)
        {
            bool        flag        = false;
            bool        flag2       = false;
            RetryCauses retryCauses = RetryCauses.None;

            try
            {
                if (!base.HasProxy && base.CurrentRequest.HasProxy)
                {
                    base.Proxy = base.CurrentRequest.Proxy;
                }
                if (!TryLoadAllFromCache())
                {
                    if (Client != null && !Client.IsConnected())
                    {
                        Close();
                    }
                    while (true)
                    {
                        if (retryCauses == RetryCauses.Reconnect)
                        {
                            Close();
                            Thread.Sleep(100);
                        }
                        base.LastProcessedUri = base.CurrentRequest.CurrentUri;
                        retryCauses           = RetryCauses.None;
                        Connect();
                        if (base.State == HTTPConnectionStates.AbortRequested)
                        {
                            throw new Exception("AbortRequested");
                        }
                        if (!base.CurrentRequest.DisableCache)
                        {
                            HTTPCacheService.SetHeaders(base.CurrentRequest);
                        }
                        bool flag3 = false;
                        try
                        {
                            base.CurrentRequest.SendOutTo(Stream);
                            flag3 = true;
                        }
                        catch (Exception ex)
                        {
                            Close();
                            if (base.State == HTTPConnectionStates.TimedOut)
                            {
                                throw new Exception("AbortRequested");
                            }
                            if (flag || base.CurrentRequest.DisableRetry)
                            {
                                throw ex;
                            }
                            flag        = true;
                            retryCauses = RetryCauses.Reconnect;
                        }
                        if (flag3)
                        {
                            bool flag4 = Receive();
                            if (base.State == HTTPConnectionStates.TimedOut)
                            {
                                break;
                            }
                            if (!flag4 && !flag && !base.CurrentRequest.DisableRetry)
                            {
                                flag        = true;
                                retryCauses = RetryCauses.Reconnect;
                            }
                            if (base.CurrentRequest.Response != null)
                            {
                                if (base.CurrentRequest.IsCookiesEnabled)
                                {
                                    CookieJar.Set(base.CurrentRequest.Response);
                                }
                                switch (base.CurrentRequest.Response.StatusCode)
                                {
                                case 401:
                                {
                                    string text2 = DigestStore.FindBest(base.CurrentRequest.Response.GetHeaderValues("www-authenticate"));
                                    if (!string.IsNullOrEmpty(text2))
                                    {
                                        Digest orCreate2 = DigestStore.GetOrCreate(base.CurrentRequest.CurrentUri);
                                        orCreate2.ParseChallange(text2);
                                        if (base.CurrentRequest.Credentials != null && orCreate2.IsUriProtected(base.CurrentRequest.CurrentUri) && (!base.CurrentRequest.HasHeader("Authorization") || orCreate2.Stale))
                                        {
                                            retryCauses = RetryCauses.Authenticate;
                                        }
                                    }
                                    break;
                                }

                                case 407:
                                    if (base.CurrentRequest.HasProxy)
                                    {
                                        string text = DigestStore.FindBest(base.CurrentRequest.Response.GetHeaderValues("proxy-authenticate"));
                                        if (!string.IsNullOrEmpty(text))
                                        {
                                            Digest orCreate = DigestStore.GetOrCreate(base.CurrentRequest.Proxy.Address);
                                            orCreate.ParseChallange(text);
                                            if (base.CurrentRequest.Proxy.Credentials != null && orCreate.IsUriProtected(base.CurrentRequest.Proxy.Address) && (!base.CurrentRequest.HasHeader("Proxy-Authorization") || orCreate.Stale))
                                            {
                                                retryCauses = RetryCauses.ProxyAuthenticate;
                                            }
                                        }
                                    }
                                    break;

                                case 301:
                                case 302:
                                case 307:
                                case 308:
                                    if (base.CurrentRequest.RedirectCount < base.CurrentRequest.MaxRedirects)
                                    {
                                        base.CurrentRequest.RedirectCount++;
                                        string firstHeaderValue = base.CurrentRequest.Response.GetFirstHeaderValue("location");
                                        if (string.IsNullOrEmpty(firstHeaderValue))
                                        {
                                            throw new MissingFieldException($"Got redirect status({base.CurrentRequest.Response.StatusCode.ToString()}) without 'location' header!");
                                        }
                                        Uri redirectUri = GetRedirectUri(firstHeaderValue);
                                        if (!base.CurrentRequest.CallOnBeforeRedirection(redirectUri))
                                        {
                                            HTTPManager.Logger.Information("HTTPConnection", "OnBeforeRedirection returned False");
                                        }
                                        else
                                        {
                                            base.CurrentRequest.RemoveHeader("Host");
                                            base.CurrentRequest.SetHeader("Referer", base.CurrentRequest.CurrentUri.ToString());
                                            base.CurrentRequest.RedirectUri = redirectUri;
                                            base.CurrentRequest.Response    = null;
                                            bool flag5 = true;
                                            base.CurrentRequest.IsRedirected = flag5;
                                            flag2 = flag5;
                                        }
                                    }
                                    break;
                                }
                                TryStoreInCache();
                                if (base.CurrentRequest.Response == null || (!base.CurrentRequest.Response.IsClosedManually && base.CurrentRequest.Response.HasHeaderWithValue("connection", "close")))
                                {
                                    Close();
                                }
                            }
                        }
                        if (retryCauses == RetryCauses.None)
                        {
                            return;
                        }
                    }
                    throw new Exception("AbortRequested");
                }
            }
            catch (TimeoutException exception)
            {
                base.CurrentRequest.Response  = null;
                base.CurrentRequest.Exception = exception;
                base.CurrentRequest.State     = HTTPRequestStates.ConnectionTimedOut;
                Close();
            }
            catch (Exception exception2)
            {
                if (base.CurrentRequest != null)
                {
                    if (base.CurrentRequest.UseStreaming)
                    {
                        HTTPCacheService.DeleteEntity(base.CurrentRequest.CurrentUri);
                    }
                    base.CurrentRequest.Response = null;
                    switch (base.State)
                    {
                    case HTTPConnectionStates.AbortRequested:
                    case HTTPConnectionStates.Closed:
                        base.CurrentRequest.State = HTTPRequestStates.Aborted;
                        break;

                    case HTTPConnectionStates.TimedOut:
                        base.CurrentRequest.State = HTTPRequestStates.TimedOut;
                        break;

                    default:
                        base.CurrentRequest.Exception = exception2;
                        base.CurrentRequest.State     = HTTPRequestStates.Error;
                        break;
                    }
                }
                Close();
            }
            finally
            {
                if (base.CurrentRequest != null)
                {
                    lock (HTTPManager.Locker)
                    {
                        if (base.CurrentRequest != null && base.CurrentRequest.Response != null && base.CurrentRequest.Response.IsUpgraded)
                        {
                            base.State = HTTPConnectionStates.Upgraded;
                        }
                        else
                        {
                            base.State = (flag2 ? HTTPConnectionStates.Redirected : ((Client != null) ? HTTPConnectionStates.WaitForRecycle : HTTPConnectionStates.Closed));
                        }
                        if (base.CurrentRequest.State == HTTPRequestStates.Processing && (base.State == HTTPConnectionStates.Closed || base.State == HTTPConnectionStates.WaitForRecycle))
                        {
                            if (base.CurrentRequest.Response != null)
                            {
                                base.CurrentRequest.State = HTTPRequestStates.Finished;
                            }
                            else
                            {
                                base.CurrentRequest.State = HTTPRequestStates.Error;
                            }
                        }
                        if (base.CurrentRequest.State == HTTPRequestStates.ConnectionTimedOut)
                        {
                            base.State = HTTPConnectionStates.Closed;
                        }
                        LastProcessTime = DateTime.UtcNow;
                        if (OnConnectionRecycled != null)
                        {
                            RecycleNow();
                        }
                    }
                    HTTPCacheService.SaveLibrary();
                    CookieJar.Persist();
                }
            }
        }
예제 #8
0
        void ThreadFunc(object param)
        {
            bool alreadyReconnected = false;
            bool redirected         = false;

            RetryCauses cause = RetryCauses.None;

            try
            {
#if !BESTHTTP_DISABLE_PROXY
                if (!HasProxy && CurrentRequest.HasProxy)
                {
                    Proxy = CurrentRequest.Proxy;
                }
#endif

#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR)
                // Try load the full response from an already saved cache entity. If the response
                if (TryLoadAllFromCache())
                {
                    return;
                }
#endif

                if (Client != null && !Client.IsConnected())
                {
                    Close();
                }

                do // of while (reconnect)
                {
                    if (cause == RetryCauses.Reconnect)
                    {
                        Close();
#if NETFX_CORE
                        await Task.Delay(100);
#else
                        Thread.Sleep(100);
#endif
                    }

                    LastProcessedUri = CurrentRequest.CurrentUri;

                    cause = RetryCauses.None;

                    // Connect to the server
                    Connect();

                    if (State == HTTPConnectionStates.AbortRequested)
                    {
                        throw new Exception("AbortRequested");
                    }

                    #if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR)
                    // Setup cache control headers before we send out the request
                    if (!CurrentRequest.DisableCache)
                    {
                        HTTPCacheService.SetHeaders(CurrentRequest);
                    }
                    #endif

                    // Write the request to the stream
                    // sentRequest will be true if the request sent out successfully(no SocketException), so we can try read the response
                    bool sentRequest = false;
                    try
                    {
#if !NETFX_CORE
                        Client.NoDelay = CurrentRequest.TryToMinimizeTCPLatency;
#endif
                        CurrentRequest.SendOutTo(Stream);

                        sentRequest = true;
                    }
                    catch (Exception ex)
                    {
                        Close();

                        if (State == HTTPConnectionStates.TimedOut ||
                            State == HTTPConnectionStates.AbortRequested)
                        {
                            throw new Exception("AbortRequested");
                        }

                        // We will try again only once
                        if (!alreadyReconnected && !CurrentRequest.DisableRetry)
                        {
                            alreadyReconnected = true;
                            cause = RetryCauses.Reconnect;
                        }
                        else // rethrow exception
                        {
                            throw ex;
                        }
                    }

                    // If sending out the request succeeded, we will try read the response.
                    if (sentRequest)
                    {
                        bool received = Receive();

                        if (State == HTTPConnectionStates.TimedOut ||
                            State == HTTPConnectionStates.AbortRequested)
                        {
                            throw new Exception("AbortRequested");
                        }

                        if (!received && !alreadyReconnected && !CurrentRequest.DisableRetry)
                        {
                            alreadyReconnected = true;
                            cause = RetryCauses.Reconnect;
                        }

                        if (CurrentRequest.Response != null)
                        {
#if !BESTHTTP_DISABLE_COOKIES && (!UNITY_WEBGL || UNITY_EDITOR)
                            // Try to store cookies before we do anything else, as we may remove the response deleting the cookies as well.
                            if (CurrentRequest.IsCookiesEnabled)
                            {
                                CookieJar.Set(CurrentRequest.Response);
                            }
#endif

                            switch (CurrentRequest.Response.StatusCode)
                            {
                            // Not authorized
                            // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2
                            case 401:
                            {
                                string authHeader = DigestStore.FindBest(CurrentRequest.Response.GetHeaderValues("www-authenticate"));
                                if (!string.IsNullOrEmpty(authHeader))
                                {
                                    var digest = DigestStore.GetOrCreate(CurrentRequest.CurrentUri);
                                    digest.ParseChallange(authHeader);

                                    if (CurrentRequest.Credentials != null && digest.IsUriProtected(CurrentRequest.CurrentUri) && (!CurrentRequest.HasHeader("Authorization") || digest.Stale))
                                    {
                                        cause = RetryCauses.Authenticate;
                                    }
                                }

                                goto default;
                            }

#if !BESTHTTP_DISABLE_PROXY
                            // Proxy authentication required
                            // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.8
                            case 407:
                            {
                                if (CurrentRequest.HasProxy)
                                {
                                    string authHeader = DigestStore.FindBest(CurrentRequest.Response.GetHeaderValues("proxy-authenticate"));
                                    if (!string.IsNullOrEmpty(authHeader))
                                    {
                                        var digest = DigestStore.GetOrCreate(CurrentRequest.Proxy.Address);
                                        digest.ParseChallange(authHeader);

                                        if (CurrentRequest.Proxy.Credentials != null && digest.IsUriProtected(CurrentRequest.Proxy.Address) && (!CurrentRequest.HasHeader("Proxy-Authorization") || digest.Stale))
                                        {
                                            cause = RetryCauses.ProxyAuthenticate;
                                        }
                                    }
                                }

                                goto default;
                            }
#endif

                            // Redirected
                            case 301:     // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.2
                            case 302:     // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.3
                            case 307:     // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.8
                            case 308:     // http://tools.ietf.org/html/rfc7238
                            {
                                if (CurrentRequest.RedirectCount >= CurrentRequest.MaxRedirects)
                                {
                                    goto default;
                                }
                                CurrentRequest.RedirectCount++;

                                string location = CurrentRequest.Response.GetFirstHeaderValue("location");
                                if (!string.IsNullOrEmpty(location))
                                {
                                    Uri redirectUri = GetRedirectUri(location);

                                    if (HTTPManager.Logger.Level == Logger.Loglevels.All)
                                    {
                                        HTTPManager.Logger.Verbose("HTTPConnection", string.Format("{0} - Redirected to Location: '{1}' redirectUri: '{1}'", this.CurrentRequest.CurrentUri.ToString(), location, redirectUri));
                                    }

                                    // Let the user to take some control over the redirection
                                    if (!CurrentRequest.CallOnBeforeRedirection(redirectUri))
                                    {
                                        HTTPManager.Logger.Information("HTTPConnection", "OnBeforeRedirection returned False");
                                        goto default;
                                    }

                                    // Remove the previously set Host header.
                                    CurrentRequest.RemoveHeader("Host");

                                    // Set the Referer header to the last Uri.
                                    CurrentRequest.SetHeader("Referer", CurrentRequest.CurrentUri.ToString());

                                    // Set the new Uri, the CurrentUri will return this while the IsRedirected property is true
                                    CurrentRequest.RedirectUri = redirectUri;

                                    // Discard the redirect response, we don't need it any more
                                    CurrentRequest.Response = null;

                                    redirected = CurrentRequest.IsRedirected = true;
                                }
                                else
#if !NETFX_CORE
                                { throw new MissingFieldException(string.Format("Got redirect status({0}) without 'location' header!", CurrentRequest.Response.StatusCode.ToString())); }
#else
                                { throw new Exception(string.Format("Got redirect status({0}) without 'location' header!", CurrentRequest.Response.StatusCode.ToString())); }
#endif

                                goto default;
                            }


                            default:
#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR)
                                TryStoreInCache();
#endif
                                break;
                            }

                            // If we have a response and the server telling us that it closed the connection after the message sent to us, then
                            //  we will close the connection too.
                            bool closeByServer = CurrentRequest.Response == null || CurrentRequest.Response.HasHeaderWithValue("connection", "close");
                            bool closeByClient = !CurrentRequest.Response.IsClosedManually && !CurrentRequest.IsKeepAlive;
                            if (closeByServer || closeByClient)
                            {
                                Close();
                            }
                            else if (CurrentRequest.Response != null)
                            {
                                var keepAliveheaderValues = CurrentRequest.Response.GetHeaderValues("keep-alive");
                                if (keepAliveheaderValues != null && keepAliveheaderValues.Count > 0)
                                {
                                    if (KeepAlive == null)
                                    {
                                        KeepAlive = new KeepAliveHeader();
                                    }
                                    KeepAlive.Parse(keepAliveheaderValues);
                                }
                            }
                        }
                    }
                } while (cause != RetryCauses.None);
            }
            catch (TimeoutException e)
            {
                CurrentRequest.Response  = null;
                CurrentRequest.Exception = e;
                CurrentRequest.State     = HTTPRequestStates.ConnectionTimedOut;

                Close();
            }
            catch (Exception e)
            {
                if (CurrentRequest != null)
                {
#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR)
                    if (CurrentRequest.UseStreaming)
                    {
                        HTTPCacheService.DeleteEntity(CurrentRequest.CurrentUri);
                    }
#endif

                    // Something gone bad, Response must be null!
                    CurrentRequest.Response = null;

                    switch (State)
                    {
                    case HTTPConnectionStates.Closed:
                    case HTTPConnectionStates.AbortRequested:
                        CurrentRequest.State = HTTPRequestStates.Aborted;
                        break;

                    case HTTPConnectionStates.TimedOut:
                        CurrentRequest.State = HTTPRequestStates.TimedOut;
                        break;

                    default:
                        CurrentRequest.Exception = e;
                        CurrentRequest.State     = HTTPRequestStates.Error;
                        break;
                    }
                }

                Close();
            }
            finally
            {
                if (CurrentRequest != null)
                {
                    // Avoid state changes. While we are in this block changing the connection's State, on Unity's main thread
                    //  the HTTPManager's OnUpdate will check the connections's State and call functions that can change the inner state of
                    //  the object. (Like setting the CurrentRequest to null in function Recycle() causing a NullRef exception)
                    lock (HTTPManager.Locker)
                    {
                        if (CurrentRequest != null && CurrentRequest.Response != null && CurrentRequest.Response.IsUpgraded)
                        {
                            State = HTTPConnectionStates.Upgraded;
                        }
                        else
                        {
                            State = redirected ? HTTPConnectionStates.Redirected : (Client == null ? HTTPConnectionStates.Closed : HTTPConnectionStates.WaitForRecycle);
                        }

                        // Change the request's state only when the whole processing finished
                        if (CurrentRequest.State == HTTPRequestStates.Processing && (State == HTTPConnectionStates.Closed || State == HTTPConnectionStates.WaitForRecycle))
                        {
                            if (CurrentRequest.Response != null)
                            {
                                CurrentRequest.State = HTTPRequestStates.Finished;
                            }
                            else
                            {
                                CurrentRequest.Exception = new Exception(string.Format("Remote server closed the connection before sending response header! Previous request state: {0}. Connection state: {1}",
                                                                                       CurrentRequest.State.ToString(),
                                                                                       State.ToString()));
                                CurrentRequest.State = HTTPRequestStates.Error;
                            }
                        }

                        if (CurrentRequest.State == HTTPRequestStates.ConnectionTimedOut)
                        {
                            State = HTTPConnectionStates.Closed;
                        }

                        LastProcessTime = DateTime.UtcNow;

                        if (OnConnectionRecycled != null)
                        {
                            RecycleNow();
                        }
                    }

#if !BESTHTTP_DISABLE_CACHING && (!UNITY_WEBGL || UNITY_EDITOR)
                    HTTPCacheService.SaveLibrary();
#endif

#if !BESTHTTP_DISABLE_COOKIES && (!UNITY_WEBGL || UNITY_EDITOR)
                    CookieJar.Persist();
#endif
                }
            }
        }
예제 #9
0
    public static void DownloadImage(string imageUrl, int imageSize, OnImageDownloaded onImageDownload, string fallbackImageUrl = "", bool isRetry = false)
    {
        ImageDownloader imageDownloaderQueue = CreateInstanceIfNeeded();

        if (!string.IsNullOrEmpty(imageUrl))
        {
            if (downloadingImages == null)
            {
                downloadingImages = new Dictionary <string, List <OnImageDownloaded> >();
            }
            if (downloadedImages == null)
            {
                downloadedImages = new Dictionary <string, Texture2D>();
            }
            if (cachedImageQueue == null)
            {
                cachedImageQueue = new List <string>();
            }
            string cacheRef = imageUrl + ":" + imageSize;
            if (downloadedImages.ContainsKey(cacheRef))
            {
                onImageDownload(downloadedImages[cacheRef]);
            }
            else if (downloadingImages.ContainsKey(cacheRef))
            {
                downloadingImages[cacheRef].Add(onImageDownload);
            }
            else
            {
                try
                {
                    string url  = imageUrl;
                    bool   flag = false;
                    if (imageSize != 0 && imageUrl.StartsWith("https://api.vrchat.cloud/api/1/file/"))
                    {
                        string[] array = imageUrl.Remove(0, "https://api.vrchat.cloud/api/1/file/".Length).Split('/');
                        if (array.Length == 2 || (array.Length == 3 && array[2] == "file"))
                        {
                            string text  = array[0];
                            string text2 = array[1];
                            url  = "https://api.vrchat.cloud/api/1/image/" + text + "/" + text2 + "/" + imageSize.ToString();
                            flag = true;
                        }
                    }
                    downloadingImages[cacheRef] = new List <OnImageDownloaded>();
                    HTTPManager.SendRequest(url, HTTPMethods.Get, HTTPManager.KeepAliveDefaultValue, disableCache : false, delegate(HTTPRequest request, HTTPResponse response)
                    {
                        Action loadImage2 = delegate
                        {
                            if (response != null)
                            {
                                Texture2D dataAsTexture2D = response.DataAsTexture2D;
                                EncacheTexture(cacheRef, dataAsTexture2D);
                                onImageDownload(dataAsTexture2D);
                                foreach (OnImageDownloaded item in downloadingImages[cacheRef])
                                {
                                    item(response.DataAsTexture2D);
                                }
                                downloadingImages.Remove(cacheRef);
                            }
                            else
                            {
                                Debug.LogError((object)("No response received: " + ((request.Exception == null) ? "No Exception" : (request.Exception.Message + "\n" + request.Exception.StackTrace))));
                                DownloadFallbackOrUseErrorImage(fallbackImageUrl, onImageDownload);
                            }
                        };
                        if (response != null && response.Data == null)
                        {
                            downloadingImages.Remove(cacheRef);
                            HTTPCacheService.DeleteEntity(request.CurrentUri);
                            if (!isRetry)
                            {
                                DownloadImage(imageUrl, imageSize, onImageDownload, fallbackImageUrl, isRetry: true);
                            }
                        }
                        else if (imageDownloaderQueue != null)
                        {
                            imageDownloaderQueue.QueueImageLoad(loadImage2);
                        }
                    });
                }
                catch (Exception ex)
                {
                    Exception e;
                    Exception ex2       = e = ex;
                    Action    loadImage = delegate
                    {
                        Debug.Log((object)("Could not download image " + imageUrl + " - " + e.Message));
                        DownloadFallbackOrUseErrorImage(fallbackImageUrl, onImageDownload);
                    };
                    imageDownloaderQueue.QueueImageLoad(loadImage);
                }
            }
        }
    }
예제 #10
0
        private void ProcessState(List <HTTP2FrameHeaderAndPayload> outgoingFrames)
        {
            switch (this.State)
            {
            case HTTP2StreamStates.Idle:

                UInt32 initiatedInitialWindowSize = this.settings.InitiatedMySettings[HTTP2Settings.INITIAL_WINDOW_SIZE];
                this.localWindow = initiatedInitialWindowSize;
                // window update with a zero increment would be an error (https://httpwg.org/specs/rfc7540.html#WINDOW_UPDATE)
                //if (HTTP2Connection.MaxValueFor31Bits > initiatedInitialWindowSize)
                //    this.outgoing.Enqueue(HTTP2FrameHelper.CreateWindowUpdateFrame(this.Id, HTTP2Connection.MaxValueFor31Bits - initiatedInitialWindowSize));
                //this.localWindow = HTTP2Connection.MaxValueFor31Bits;

#if !BESTHTTP_DISABLE_CACHING
                // Setup cache control headers before we send out the request
                if (!this.AssignedRequest.DisableCache)
                {
                    HTTPCacheService.SetHeaders(this.AssignedRequest);
                }
#endif

                // hpack encode the request's header
                this.encoder.Encode(this, this.AssignedRequest, this.outgoing, this.Id);

                // HTTP/2 uses DATA frames to carry message payloads.
                // The chunked transfer encoding defined in Section 4.1 of [RFC7230] MUST NOT be used in HTTP/2.
                this.bodyToSend = this.AssignedRequest.GetEntityBody();

                this.State = HTTP2StreamStates.Open;

                if (this.bodyToSend == null || this.bodyToSend.Length == 0)
                {
                    this.State = HTTP2StreamStates.HalfClosedLocal;
                }
                else
                {
                    this.State = HTTP2StreamStates.Open;
                }
                break;

            case HTTP2StreamStates.Open:
                // remote Window can be negative! See https://httpwg.org/specs/rfc7540.html#InitialWindowSize
                if (this.remoteWindow <= 0)
                {
                    HTTPManager.Logger.Warning("HTTP2Stream", string.Format("[{0}] Skipping data sending as remote Window is {1}!", this.Id, this.remoteWindow));
                    return;
                }

                // This step will send one frame per OpenState call.

                Int64 maxFrameSize = Math.Min(this.remoteWindow, this.settings.RemoteSettings[HTTP2Settings.MAX_FRAME_SIZE]);

                HTTP2FrameHeaderAndPayload frame = new HTTP2FrameHeaderAndPayload();
                frame.Type     = HTTP2FrameTypes.DATA;
                frame.StreamId = this.Id;

                frame.Payload        = this.bodyToSend;
                frame.PayloadLength  = (UInt32)Math.Min(maxFrameSize, this.bodyToSend.Length - this.bodyToSendOffset);
                frame.PayloadOffset  = this.bodyToSendOffset;
                frame.DontUseMemPool = true;

                this.bodyToSendOffset += frame.PayloadLength;

                if (this.bodyToSendOffset >= this.bodyToSend.Length)
                {
                    frame.Flags = (byte)(HTTP2DataFlags.END_STREAM);

                    this.State = HTTP2StreamStates.HalfClosedLocal;
                }

                this.outgoing.Enqueue(frame);

                this.remoteWindow -= frame.PayloadLength;

                this.sentData += frame.PayloadLength;

                //HTTPManager.Logger.Information("HTTP2Stream", string.Format("[{0}] New DATA frame created! remoteWindow: {1:N0}", this.Id, this.remoteWindow));
                break;

            case HTTP2StreamStates.HalfClosedLocal:
                break;

            case HTTP2StreamStates.HalfClosedRemote:
                break;

            case HTTP2StreamStates.Closed:
                break;
            }
        }
        private void ThreadFunc(object param)
        {
            bool        flag        = false;
            bool        flag2       = false;
            RetryCauses retryCauses = RetryCauses.None;
            object      obj         = null;

            try
            {
                if (!CurrentRequest.DisableCache)
                {
                    Monitor.Enter(obj = HTTPCacheFileLock.Acquire(CurrentRequest.CurrentUri));
                }
                CurrentRequest.Processing = true;
                if (!TryLoadAllFromCache())
                {
                    if (Client != null && !Client.IsConnected())
                    {
                        Close();
                    }
                    do
                    {
                        if (retryCauses == RetryCauses.Reconnect)
                        {
                            Close();
                            Thread.Sleep(100);
                        }
                        retryCauses = RetryCauses.None;
                        Connect();
                        if (!CurrentRequest.DisableCache)
                        {
                            HTTPCacheService.SetHeaders(CurrentRequest);
                        }
                        bool flag3 = CurrentRequest.SendOutTo(Stream);
                        if (!flag3)
                        {
                            Close();
                            if (!flag)
                            {
                                flag        = true;
                                retryCauses = RetryCauses.Reconnect;
                            }
                        }
                        if (flag3)
                        {
                            if (!Receive() && !flag)
                            {
                                flag        = true;
                                retryCauses = RetryCauses.Reconnect;
                            }
                            if (CurrentRequest.Response != null)
                            {
                                switch (CurrentRequest.Response.StatusCode)
                                {
                                case 401:
                                {
                                    string firstHeaderValue2 = CurrentRequest.Response.GetFirstHeaderValue("www-authenticate");
                                    if (!string.IsNullOrEmpty(firstHeaderValue2))
                                    {
                                        Digest orCreate = DigestStore.GetOrCreate(CurrentRequest.CurrentUri);
                                        orCreate.ParseChallange(firstHeaderValue2);
                                        if (CurrentRequest.Credentials != null && orCreate.IsUriProtected(CurrentRequest.CurrentUri) && (!CurrentRequest.HasHeader("Authorization") || orCreate.Stale))
                                        {
                                            retryCauses = RetryCauses.Authenticate;
                                        }
                                    }
                                    break;
                                }

                                case 301:
                                case 302:
                                case 307:
                                    if (CurrentRequest.RedirectCount < CurrentRequest.MaxRedirects)
                                    {
                                        CurrentRequest.RedirectCount++;
                                        string firstHeaderValue = CurrentRequest.Response.GetFirstHeaderValue("location");
                                        if (string.IsNullOrEmpty(firstHeaderValue))
                                        {
                                            throw new MissingFieldException($"Got redirect status({CurrentRequest.Response.StatusCode.ToString()}) without 'location' header!");
                                        }
                                        CurrentRequest.RedirectUri = GetRedirectUri(firstHeaderValue);
                                        CurrentRequest.Response    = null;
                                        bool flag4 = true;
                                        CurrentRequest.IsRedirected = flag4;
                                        flag2 = flag4;
                                    }
                                    break;
                                }
                                TryStoreInCache();
                                if (CurrentRequest.Response.HasHeaderWithValue("connection", "close") || CurrentRequest.UseAlternateSSL)
                                {
                                    Close();
                                }
                            }
                        }
                    }while (retryCauses != 0);
                }
            }
            catch (Exception exception)
            {
                if (CurrentRequest.UseStreaming)
                {
                    HTTPCacheService.DeleteEntity(CurrentRequest.CurrentUri);
                }
                CurrentRequest.Response  = null;
                CurrentRequest.Exception = exception;
                Close();
            }
            finally
            {
                if (!CurrentRequest.DisableCache && obj != null)
                {
                    Monitor.Exit(obj);
                }
                HTTPCacheService.SaveLibrary();
                CurrentRequest.Processing = false;
                if (CurrentRequest != null && CurrentRequest.Response != null && CurrentRequest.Response.IsUpgraded)
                {
                    State = HTTPConnectionStates.Upgraded;
                }
                else
                {
                    State = (flag2 ? HTTPConnectionStates.Redirected : ((Client != null) ? HTTPConnectionStates.WaitForRecycle : HTTPConnectionStates.Closed));
                }
                LastProcessTime = DateTime.UtcNow;
            }
        }
        private void ProcessState(List <HTTP2FrameHeaderAndPayload> outgoingFrames)
        {
            switch (this.State)
            {
            case HTTP2StreamStates.Idle:

                UInt32 initiatedInitialWindowSize = this.settings.InitiatedMySettings[HTTP2Settings.INITIAL_WINDOW_SIZE];
                this.localWindow = initiatedInitialWindowSize;
                // window update with a zero increment would be an error (https://httpwg.org/specs/rfc7540.html#WINDOW_UPDATE)
                //if (HTTP2Connection.MaxValueFor31Bits > initiatedInitialWindowSize)
                //    this.outgoing.Enqueue(HTTP2FrameHelper.CreateWindowUpdateFrame(this.Id, HTTP2Connection.MaxValueFor31Bits - initiatedInitialWindowSize));
                //this.localWindow = HTTP2Connection.MaxValueFor31Bits;

#if !BESTHTTP_DISABLE_CACHING
                // Setup cache control headers before we send out the request
                if (!this.AssignedRequest.DisableCache)
                {
                    HTTPCacheService.SetHeaders(this.AssignedRequest);
                }
#endif

                // hpack encode the request's headers
                this.encoder.Encode(this, this.AssignedRequest, this.outgoing, this.Id);

                // HTTP/2 uses DATA frames to carry message payloads.
                // The chunked transfer encoding defined in Section 4.1 of [RFC7230] MUST NOT be used in HTTP/2.
                this.uploadStreamInfo = this.AssignedRequest.GetUpStream();

                //this.State = HTTP2StreamStates.Open;

                if (this.uploadStreamInfo.Stream == null)
                {
                    this.State = HTTP2StreamStates.HalfClosedLocal;
                    this.AssignedRequest.Timing.Add(TimingEventNames.Request_Sent);
                }
                else
                {
                    this.State         = HTTP2StreamStates.Open;
                    this.lastReadCount = 1;
                }
                break;

            case HTTP2StreamStates.Open:
                // remote Window can be negative! See https://httpwg.org/specs/rfc7540.html#InitialWindowSize
                if (this.remoteWindow <= 0)
                {
                    HTTPManager.Logger.Warning("HTTP2Stream", string.Format("[{0}] Skipping data sending as remote Window is {1}!", this.Id, this.remoteWindow), this.Context, this.AssignedRequest.Context, this.parent.Context);
                    return;
                }

                // This step will send one frame per OpenState call.

                Int64 maxFrameSize = Math.Min(this.remoteWindow, this.settings.RemoteSettings[HTTP2Settings.MAX_FRAME_SIZE]);

                HTTP2FrameHeaderAndPayload frame = new HTTP2FrameHeaderAndPayload();
                frame.Type     = HTTP2FrameTypes.DATA;
                frame.StreamId = this.Id;

                frame.Payload = BufferPool.Get(maxFrameSize, true);

                // Expect a readCount of zero if it's end of the stream. But, to enable non-blocking scenario to wait for data, going to treat a negative value as no data.
                this.lastReadCount = this.uploadStreamInfo.Stream.Read(frame.Payload, 0, (int)Math.Min(maxFrameSize, int.MaxValue));
                if (this.lastReadCount <= 0)
                {
                    BufferPool.Release(frame.Payload);
                    frame.Payload       = null;
                    frame.PayloadLength = 0;

                    if (this.lastReadCount < 0)
                    {
                        break;
                    }
                }
                else
                {
                    frame.PayloadLength = (UInt32)this.lastReadCount;
                }

                frame.PayloadOffset  = 0;
                frame.DontUseMemPool = false;

                if (this.lastReadCount <= 0)
                {
                    this.uploadStreamInfo.Stream.Dispose();
                    this.uploadStreamInfo = new HTTPRequest.UploadStreamInfo();

                    frame.Flags = (byte)(HTTP2DataFlags.END_STREAM);

                    this.State = HTTP2StreamStates.HalfClosedLocal;

                    this.AssignedRequest.Timing.Add(TimingEventNames.Request_Sent);
                }

                this.outgoing.Enqueue(frame);

                this.remoteWindow -= frame.PayloadLength;

                this.sentData += frame.PayloadLength;

                if (this.AssignedRequest.OnUploadProgress != null)
                {
                    RequestEventHelper.EnqueueRequestEvent(new RequestEventInfo(this.AssignedRequest, RequestEvents.UploadProgress, this.sentData, this.uploadStreamInfo.Length));
                }

                //HTTPManager.Logger.Information("HTTP2Stream", string.Format("[{0}] New DATA frame created! remoteWindow: {1:N0}", this.Id, this.remoteWindow), this.Context, this.AssignedRequest.Context, this.parent.Context);
                break;

            case HTTP2StreamStates.HalfClosedLocal:
                break;

            case HTTP2StreamStates.HalfClosedRemote:
                break;

            case HTTP2StreamStates.Closed:
                break;
            }
        }
예제 #13
0
 private void Awake()
 {
     HTTPCacheService.SetupCacheFolder();
     CookieJar.SetupFolder();
     CookieJar.Load();
 }
        public static void HandleResponse(string context, HTTPRequest request, out bool resendRequest, out HTTPConnectionStates proposedConnectionState, ref KeepAliveHeader keepAlive, LoggingContext loggingContext1 = null, LoggingContext loggingContext2 = null, LoggingContext loggingContext3 = null)
        {
            resendRequest           = false;
            proposedConnectionState = HTTPConnectionStates.Processing;

            if (request.Response != null)
            {
#if !BESTHTTP_DISABLE_COOKIES
                // Try to store cookies before we do anything else, as we may remove the response deleting the cookies as well.
                if (request.IsCookiesEnabled)
                {
                    CookieJar.Set(request.Response);
                }
#endif

                switch (request.Response.StatusCode)
                {
                // Not authorized
                // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2
                case 401:
                {
                    string authHeader = DigestStore.FindBest(request.Response.GetHeaderValues("www-authenticate"));
                    if (!string.IsNullOrEmpty(authHeader))
                    {
                        var digest = DigestStore.GetOrCreate(request.CurrentUri);
                        digest.ParseChallange(authHeader);

                        if (request.Credentials != null && digest.IsUriProtected(request.CurrentUri) && (!request.HasHeader("Authorization") || digest.Stale))
                        {
                            resendRequest = true;
                        }
                    }

                    goto default;
                }

                // Redirected
                case 301:     // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.2
                case 302:     // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.3
                case 307:     // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.8
                case 308:     // http://tools.ietf.org/html/rfc7238
                {
                    if (request.RedirectCount >= request.MaxRedirects)
                    {
                        goto default;
                    }
                    request.RedirectCount++;

                    string location = request.Response.GetFirstHeaderValue("location");
                    if (!string.IsNullOrEmpty(location))
                    {
                        Uri redirectUri = ConnectionHelper.GetRedirectUri(request, location);

                        if (HTTPManager.Logger.Level == Logger.Loglevels.All)
                        {
                            HTTPManager.Logger.Verbose("HTTPConnection", string.Format("[{0}] - Redirected to Location: '{1}' redirectUri: '{1}'", context, location, redirectUri), loggingContext1, loggingContext2, loggingContext3);
                        }

                        // Let the user to take some control over the redirection
                        if (!request.CallOnBeforeRedirection(redirectUri))
                        {
                            HTTPManager.Logger.Information("HTTPConnection", string.Format("[{0}] OnBeforeRedirection returned False", context), loggingContext1, loggingContext2, loggingContext3);
                            goto default;
                        }

                        // Remove the previously set Host header.
                        request.RemoveHeader("Host");

                        // Set the Referer header to the last Uri.
                        request.SetHeader("Referer", request.CurrentUri.ToString());

                        // Set the new Uri, the CurrentUri will return this while the IsRedirected property is true
                        request.RedirectUri = redirectUri;

                        request.IsRedirected = true;

                        resendRequest = true;
                    }
                    else
                    {
                        throw new Exception(string.Format("[{0}] Got redirect status({1}) without 'location' header!", context, request.Response.StatusCode.ToString()));
                    }

                    goto default;
                }

#if !BESTHTTP_DISABLE_CACHING
                case 304:
                    if (request.DisableCache)
                    {
                        break;
                    }

                    if (ConnectionHelper.LoadFromCache(context, request, loggingContext1, loggingContext2, loggingContext3))
                    {
                        request.Timing.Add(TimingEventNames.Loading_From_Cache);
                        HTTPManager.Logger.Verbose("HTTPConnection", string.Format("[{0}] - HandleResponse - Loaded from cache successfully!", context), loggingContext1, loggingContext2, loggingContext3);

                        // Update any caching value
                        HTTPCacheService.SetUpCachingValues(request.CurrentUri, request.Response);
                    }
                    else
                    {
                        HTTPManager.Logger.Verbose("HTTPConnection", string.Format("[{0}] - HandleResponse - Loaded from cache failed!", context), loggingContext1, loggingContext2, loggingContext3);
                        resendRequest = true;
                    }

                    break;
#endif

                default:
#if !BESTHTTP_DISABLE_CACHING
                    ConnectionHelper.TryStoreInCache(request);
#endif
                    break;
                }

                // Closing the stream is done manually?
                if (request.Response != null && !request.Response.IsClosedManually)
                {
                    // If we have a response and the server telling us that it closed the connection after the message sent to us, then
                    //  we will close the connection too.
                    bool closeByServer = request.Response.HasHeaderWithValue("connection", "close");
                    bool closeByClient = !request.IsKeepAlive;

                    if (closeByServer || closeByClient)
                    {
                        proposedConnectionState = HTTPConnectionStates.Closed;
                    }
                    else if (request.Response != null)
                    {
                        var keepAliveheaderValues = request.Response.GetHeaderValues("keep-alive");
                        if (keepAliveheaderValues != null && keepAliveheaderValues.Count > 0)
                        {
                            if (keepAlive == null)
                            {
                                keepAlive = new KeepAliveHeader();
                            }
                            keepAlive.Parse(keepAliveheaderValues);
                        }
                    }
                }

                // Null out the response here instead of the redirected cases (301, 302, 307, 308)
                //  because response might have a Connection: Close header that we would miss to process.
                // If Connection: Close is present, the server is closing the connection and we would
                // reuse that closed connection.
                if (resendRequest)
                {
                    // Discard the redirect response, we don't need it any more
                    request.Response = null;

                    if (proposedConnectionState == HTTPConnectionStates.Closed)
                    {
                        proposedConnectionState = HTTPConnectionStates.ClosedResendRequest;
                    }
                }
            }
        }
예제 #15
0
 private void TryStoreInCache()
 {
     if (((!base.CurrentRequest.UseStreaming && !base.CurrentRequest.DisableCache) && ((base.CurrentRequest.Response != null) && HTTPCacheService.IsSupported)) && HTTPCacheService.IsCacheble(base.CurrentRequest.CurrentUri, base.CurrentRequest.MethodType, base.CurrentRequest.Response))
     {
         if (base.CurrentRequest.IsRedirected)
         {
             HTTPCacheService.Store(base.CurrentRequest.Uri, base.CurrentRequest.MethodType, base.CurrentRequest.Response);
         }
         else
         {
             HTTPCacheService.Store(base.CurrentRequest.CurrentUri, base.CurrentRequest.MethodType, base.CurrentRequest.Response);
         }
     }
 }
예제 #16
0
        protected override void ThreadFunc(object param)
        {
            bool        flag  = false;
            bool        flag2 = false;
            RetryCauses none  = RetryCauses.None;

            try
            {
                if (!base.HasProxy && base.CurrentRequest.HasProxy)
                {
                    base.Proxy = base.CurrentRequest.Proxy;
                }
                if (!this.TryLoadAllFromCache())
                {
                    if ((this.Client != null) && !this.Client.IsConnected())
                    {
                        this.Close();
                    }
                    do
                    {
                        if (none == RetryCauses.Reconnect)
                        {
                            this.Close();
                            Thread.Sleep(100);
                        }
                        base.LastProcessedUri = base.CurrentRequest.CurrentUri;
                        none = RetryCauses.None;
                        this.Connect();
                        if (base.State == HTTPConnectionStates.AbortRequested)
                        {
                            throw new Exception("AbortRequested");
                        }
                        if (!base.CurrentRequest.DisableCache)
                        {
                            HTTPCacheService.SetHeaders(base.CurrentRequest);
                        }
                        bool flag3 = false;
                        try
                        {
                            this.Client.NoDelay = base.CurrentRequest.TryToMinimizeTCPLatency;
                            base.CurrentRequest.SendOutTo(this.Stream);
                            flag3 = true;
                        }
                        catch (Exception exception)
                        {
                            this.Close();
                            if ((base.State == HTTPConnectionStates.TimedOut) || (base.State == HTTPConnectionStates.AbortRequested))
                            {
                                throw new Exception("AbortRequested");
                            }
                            if (flag || base.CurrentRequest.DisableRetry)
                            {
                                throw exception;
                            }
                            flag = true;
                            none = RetryCauses.Reconnect;
                        }
                        if (flag3)
                        {
                            bool flag4 = this.Receive();
                            if ((base.State == HTTPConnectionStates.TimedOut) || (base.State == HTTPConnectionStates.AbortRequested))
                            {
                                throw new Exception("AbortRequested");
                            }
                            if ((!flag4 && !flag) && !base.CurrentRequest.DisableRetry)
                            {
                                flag = true;
                                none = RetryCauses.Reconnect;
                            }
                            if (base.CurrentRequest.Response != null)
                            {
                                if (base.CurrentRequest.IsCookiesEnabled)
                                {
                                    CookieJar.Set(base.CurrentRequest.Response);
                                }
                                switch (base.CurrentRequest.Response.StatusCode)
                                {
                                case 0x12d:
                                case 0x12e:
                                case 0x133:
                                case 0x134:
                                    if (base.CurrentRequest.RedirectCount < base.CurrentRequest.MaxRedirects)
                                    {
                                        HTTPRequest currentRequest = base.CurrentRequest;
                                        currentRequest.RedirectCount++;
                                        string firstHeaderValue = base.CurrentRequest.Response.GetFirstHeaderValue("location");
                                        if (string.IsNullOrEmpty(firstHeaderValue))
                                        {
                                            throw new MissingFieldException($"Got redirect status({base.CurrentRequest.Response.StatusCode.ToString()}) without 'location' header!");
                                        }
                                        Uri redirectUri = this.GetRedirectUri(firstHeaderValue);
                                        if (HTTPManager.Logger.Level == Loglevels.All)
                                        {
                                            HTTPManager.Logger.Verbose("HTTPConnection", string.Format("{0} - Redirected to Location: '{1}' redirectUri: '{1}'", base.CurrentRequest.CurrentUri.ToString(), firstHeaderValue, redirectUri));
                                        }
                                        if (!base.CurrentRequest.CallOnBeforeRedirection(redirectUri))
                                        {
                                            HTTPManager.Logger.Information("HTTPConnection", "OnBeforeRedirection returned False");
                                        }
                                        else
                                        {
                                            base.CurrentRequest.RemoveHeader("Host");
                                            base.CurrentRequest.SetHeader("Referer", base.CurrentRequest.CurrentUri.ToString());
                                            base.CurrentRequest.RedirectUri = redirectUri;
                                            base.CurrentRequest.Response    = null;
                                            bool flag5 = true;
                                            base.CurrentRequest.IsRedirected = flag5;
                                            flag2 = flag5;
                                        }
                                    }
                                    break;

                                case 0x191:
                                {
                                    string str = DigestStore.FindBest(base.CurrentRequest.Response.GetHeaderValues("www-authenticate"));
                                    if (!string.IsNullOrEmpty(str))
                                    {
                                        Digest orCreate = DigestStore.GetOrCreate(base.CurrentRequest.CurrentUri);
                                        orCreate.ParseChallange(str);
                                        if (((base.CurrentRequest.Credentials != null) && orCreate.IsUriProtected(base.CurrentRequest.CurrentUri)) && (!base.CurrentRequest.HasHeader("Authorization") || orCreate.Stale))
                                        {
                                            none = RetryCauses.Authenticate;
                                        }
                                    }
                                    break;
                                }

                                case 0x197:
                                    if (base.CurrentRequest.HasProxy)
                                    {
                                        string str2 = DigestStore.FindBest(base.CurrentRequest.Response.GetHeaderValues("proxy-authenticate"));
                                        if (!string.IsNullOrEmpty(str2))
                                        {
                                            Digest orCreate = DigestStore.GetOrCreate(base.CurrentRequest.Proxy.Address);
                                            orCreate.ParseChallange(str2);
                                            if (((base.CurrentRequest.Proxy.Credentials != null) && orCreate.IsUriProtected(base.CurrentRequest.Proxy.Address)) && (!base.CurrentRequest.HasHeader("Proxy-Authorization") || orCreate.Stale))
                                            {
                                                none = RetryCauses.ProxyAuthenticate;
                                            }
                                        }
                                    }
                                    break;
                                }
                                this.TryStoreInCache();
                                if ((base.CurrentRequest.Response == null) || !base.CurrentRequest.Response.IsClosedManually)
                                {
                                    bool flag6 = (base.CurrentRequest.Response == null) || base.CurrentRequest.Response.HasHeaderWithValue("connection", "close");
                                    bool flag7 = !base.CurrentRequest.IsKeepAlive;
                                    if (flag6 || flag7)
                                    {
                                        this.Close();
                                    }
                                    else if (base.CurrentRequest.Response != null)
                                    {
                                        List <string> headerValues = base.CurrentRequest.Response.GetHeaderValues("keep-alive");
                                        if ((headerValues != null) && (headerValues.Count > 0))
                                        {
                                            if (this.KeepAlive == null)
                                            {
                                                this.KeepAlive = new KeepAliveHeader();
                                            }
                                            this.KeepAlive.Parse(headerValues);
                                        }
                                    }
                                }
                            }
                        }
                    }while (none != RetryCauses.None);
                }
            }
            catch (TimeoutException exception2)
            {
                base.CurrentRequest.Response  = null;
                base.CurrentRequest.Exception = exception2;
                base.CurrentRequest.State     = HTTPRequestStates.ConnectionTimedOut;
                this.Close();
            }
            catch (Exception exception3)
            {
                if (base.CurrentRequest != null)
                {
                    if (base.CurrentRequest.UseStreaming)
                    {
                        HTTPCacheService.DeleteEntity(base.CurrentRequest.CurrentUri, true);
                    }
                    base.CurrentRequest.Response = null;
                    switch (base.State)
                    {
                    case HTTPConnectionStates.AbortRequested:
                    case HTTPConnectionStates.Closed:
                        base.CurrentRequest.State = HTTPRequestStates.Aborted;
                        goto Label_0685;

                    case HTTPConnectionStates.TimedOut:
                        base.CurrentRequest.State = HTTPRequestStates.TimedOut;
                        goto Label_0685;
                    }
                    base.CurrentRequest.Exception = exception3;
                    base.CurrentRequest.State     = HTTPRequestStates.Error;
                }
Label_0685:
                this.Close();
            }
            finally
            {
                if (base.CurrentRequest != null)
                {
                    object locker = HTTPManager.Locker;
                    lock (locker)
                    {
                        if (((base.CurrentRequest != null) && (base.CurrentRequest.Response != null)) && base.CurrentRequest.Response.IsUpgraded)
                        {
                            base.State = HTTPConnectionStates.Upgraded;
                        }
                        else
                        {
                            base.State = !flag2 ? ((this.Client != null) ? HTTPConnectionStates.WaitForRecycle : HTTPConnectionStates.Closed) : HTTPConnectionStates.Redirected;
                        }
                        if ((base.CurrentRequest.State == HTTPRequestStates.Processing) && ((base.State == HTTPConnectionStates.Closed) || (base.State == HTTPConnectionStates.WaitForRecycle)))
                        {
                            if (base.CurrentRequest.Response != null)
                            {
                                base.CurrentRequest.State = HTTPRequestStates.Finished;
                            }
                            else
                            {
                                base.CurrentRequest.Exception = new Exception($"Remote server closed the connection before sending response header! Previous request state: {base.CurrentRequest.State.ToString()}. Connection state: {base.State.ToString()}");
                                base.CurrentRequest.State     = HTTPRequestStates.Error;
                            }
                        }
                        if (base.CurrentRequest.State == HTTPRequestStates.ConnectionTimedOut)
                        {
                            base.State = HTTPConnectionStates.Closed;
                        }
                        base.LastProcessTime = DateTime.UtcNow;
                        if (base.OnConnectionRecycled != null)
                        {
                            base.RecycleNow();
                        }
                    }
                    HTTPCacheService.SaveLibrary();
                    CookieJar.Persist();
                }
            }
        }
 private void TryStoreInCache()
 {
     if (!CurrentRequest.UseStreaming && !CurrentRequest.DisableCache && CurrentRequest.Response != null && HTTPCacheService.IsCacheble(CurrentRequest.CurrentUri, CurrentRequest.MethodType, CurrentRequest.Response))
     {
         HTTPCacheService.Store(CurrentRequest.CurrentUri, CurrentRequest.MethodType, CurrentRequest.Response);
     }
 }
예제 #18
0
    // Token: 0x060025A8 RID: 9640 RVA: 0x000B99E4 File Offset: 0x000B7DE4
    private void OnGUI()
    {
        GeneralStatistics stats = HTTPManager.GetGeneralStatistics(StatisticsQueryFlags.All);

        GUIHelper.DrawArea(new Rect(0f, 0f, (float)(Screen.width / 3), 160f), false, delegate
        {
            GUIHelper.DrawCenteredText("Connections");
            GUILayout.Space(5f);
            GUIHelper.DrawRow("Sum:", stats.Connections.ToString());
            GUIHelper.DrawRow("Active:", stats.ActiveConnections.ToString());
            GUIHelper.DrawRow("Free:", stats.FreeConnections.ToString());
            GUIHelper.DrawRow("Recycled:", stats.RecycledConnections.ToString());
            GUIHelper.DrawRow("Requests in queue:", stats.RequestsInQueue.ToString());
        });
        GUIHelper.DrawArea(new Rect((float)(Screen.width / 3), 0f, (float)(Screen.width / 3), 160f), false, delegate
        {
            GUIHelper.DrawCenteredText("Cache");
            if (!HTTPCacheService.IsSupported)
            {
                GUI.color = Color.yellow;
                GUIHelper.DrawCenteredText("Disabled in WebPlayer, WebGL & Samsung Smart TV Builds!");
                GUI.color = Color.white;
            }
            else
            {
                GUILayout.Space(5f);
                GUIHelper.DrawRow("Cached entities:", stats.CacheEntityCount.ToString());
                GUIHelper.DrawRow("Sum Size (bytes): ", stats.CacheSize.ToString("N0"));
                GUILayout.BeginVertical(new GUILayoutOption[0]);
                GUILayout.FlexibleSpace();
                if (GUILayout.Button("Clear Cache", new GUILayoutOption[0]))
                {
                    HTTPCacheService.BeginClear();
                }
                GUILayout.EndVertical();
            }
        });
        GUIHelper.DrawArea(new Rect((float)(Screen.width / 3 * 2), 0f, (float)(Screen.width / 3), 160f), false, delegate
        {
            GUIHelper.DrawCenteredText("Cookies");
            if (!CookieJar.IsSavingSupported)
            {
                GUI.color = Color.yellow;
                GUIHelper.DrawCenteredText("Saving and loading from disk is disabled in WebPlayer, WebGL & Samsung Smart TV Builds!");
                GUI.color = Color.white;
            }
            else
            {
                GUILayout.Space(5f);
                GUIHelper.DrawRow("Cookies:", stats.CookieCount.ToString());
                GUIHelper.DrawRow("Estimated size (bytes):", stats.CookieJarSize.ToString("N0"));
                GUILayout.BeginVertical(new GUILayoutOption[0]);
                GUILayout.FlexibleSpace();
                if (GUILayout.Button("Clear Cookies", new GUILayoutOption[0]))
                {
                    HTTPManager.OnQuit();
                }
                GUILayout.EndVertical();
            }
        });
        if (SampleSelector.SelectedSample == null || (SampleSelector.SelectedSample != null && !SampleSelector.SelectedSample.IsRunning))
        {
            GUIHelper.DrawArea(new Rect(0f, 165f, (float)((SampleSelector.SelectedSample != null) ? (Screen.width / 3) : Screen.width), (float)(Screen.height - 160 - 5)), false, delegate
            {
                this.scrollPos = GUILayout.BeginScrollView(this.scrollPos, new GUILayoutOption[0]);
                for (int i = 0; i < this.Samples.Count; i++)
                {
                    this.DrawSample(this.Samples[i]);
                }
                GUILayout.EndScrollView();
            });
            if (SampleSelector.SelectedSample != null)
            {
                this.DrawSampleDetails(SampleSelector.SelectedSample);
            }
        }
        else if (SampleSelector.SelectedSample != null && SampleSelector.SelectedSample.IsRunning)
        {
            GUILayout.BeginArea(new Rect(0f, (float)(Screen.height - 50), (float)Screen.width, 50f), string.Empty);
            GUILayout.FlexibleSpace();
            GUILayout.BeginHorizontal(new GUILayoutOption[0]);
            GUILayout.FlexibleSpace();
            GUILayout.BeginVertical(new GUILayoutOption[0]);
            GUILayout.FlexibleSpace();
            if (GUILayout.Button("Back", new GUILayoutOption[]
            {
                GUILayout.MinWidth(100f)
            }))
            {
                SampleSelector.SelectedSample.DestroyUnityObject();
            }
            GUILayout.FlexibleSpace();
            GUILayout.EndVertical();
            GUILayout.EndHorizontal();
            GUILayout.EndArea();
        }
    }
예제 #19
0
 private void Awake()
 {
     HTTPCacheService.SetupCacheFolder();
 }
예제 #20
0
    private void OnGUI()
    {
        GUIHelper.DrawArea(GUIHelper.ClientArea, true, delegate
        {
            GUILayout.BeginHorizontal(new GUILayoutOption[0]);
            GUILayout.Label("Delete cached entities older then", new GUILayoutOption[0]);
            GUILayout.Label(this.value.ToString(), new GUILayoutOption[]
            {
                GUILayout.MinWidth(50f)
            });
            this.value = (int)GUILayout.HorizontalSlider((float)this.value, 1f, 60f, new GUILayoutOption[]
            {
                GUILayout.MinWidth(100f)
            });
            GUILayout.Space(10f);
            this.deleteOlderType = (CacheMaintenanceSample.DeleteOlderTypes)GUILayout.SelectionGrid((int)this.deleteOlderType, new string[]
            {
                "Days",
                "Hours",
                "Mins",
                "Secs"
            }, 4, new GUILayoutOption[0]);
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();
            GUILayout.Space(10f);
            GUILayout.BeginHorizontal(new GUILayoutOption[0]);
            GUILayout.Label("Max Cache Size (bytes): ", new GUILayoutOption[]
            {
                GUILayout.Width(150f)
            });
            GUILayout.Label(this.maxCacheSize.ToString("N0"), new GUILayoutOption[]
            {
                GUILayout.Width(70f)
            });
            this.maxCacheSize = (int)GUILayout.HorizontalSlider((float)this.maxCacheSize, 1024f, 1.048576E+07f, new GUILayoutOption[0]);
            GUILayout.EndHorizontal();
            GUILayout.Space(10f);
            if (GUILayout.Button("Maintenance", new GUILayoutOption[0]))
            {
                TimeSpan deleteOlder = TimeSpan.FromDays(14.0);
                switch (this.deleteOlderType)
                {
                case CacheMaintenanceSample.DeleteOlderTypes.Days:
                    deleteOlder = TimeSpan.FromDays((double)this.value);
                    break;

                case CacheMaintenanceSample.DeleteOlderTypes.Hours:
                    deleteOlder = TimeSpan.FromHours((double)this.value);
                    break;

                case CacheMaintenanceSample.DeleteOlderTypes.Mins:
                    deleteOlder = TimeSpan.FromMinutes((double)this.value);
                    break;

                case CacheMaintenanceSample.DeleteOlderTypes.Secs:
                    deleteOlder = TimeSpan.FromSeconds((double)this.value);
                    break;
                }
                HTTPCacheService.BeginMaintainence(new HTTPCacheMaintananceParams(deleteOlder, (ulong)((long)this.maxCacheSize)));
            }
        });
    }
        public void RunHandler()
        {
            HTTPManager.Logger.Information("HTTP1Handler", string.Format("[{0}] started processing request '{1}'", this, this.conn.CurrentRequest.CurrentUri.ToString()), this.Context, this.conn.CurrentRequest.Context);

            HTTPConnectionStates proposedConnectionState = HTTPConnectionStates.Processing;

            bool resendRequest = false;

            try
            {
                if (this.conn.CurrentRequest.IsCancellationRequested)
                {
                    return;
                }

#if !BESTHTTP_DISABLE_CACHING
                // Setup cache control headers before we send out the request
                if (!this.conn.CurrentRequest.DisableCache)
                {
                    HTTPCacheService.SetHeaders(this.conn.CurrentRequest);
                }
#endif

                // Write the request to the stream
                this.conn.CurrentRequest.SendOutTo(this.conn.connector.Stream);

                if (this.conn.CurrentRequest.IsCancellationRequested)
                {
                    return;
                }

                this.conn.CurrentRequest.OnCancellationRequested += OnCancellationRequested;

                // Receive response from the server
                bool received = Receive(this.conn.CurrentRequest);

                if (this.conn.CurrentRequest.IsCancellationRequested)
                {
                    return;
                }

                if (!received && this.conn.CurrentRequest.Retries < this.conn.CurrentRequest.MaxRetries)
                {
                    proposedConnectionState = HTTPConnectionStates.Closed;
                    this.conn.CurrentRequest.Retries++;
                    resendRequest = true;
                    return;
                }

                ConnectionHelper.HandleResponse(this.conn.ToString(), this.conn.CurrentRequest, out resendRequest, out proposedConnectionState, ref this._keepAlive, this.conn.Context, this.conn.CurrentRequest.Context);
            }
            catch (TimeoutException e)
            {
                this.conn.CurrentRequest.Response = null;

                // We will try again only once
                if (this.conn.CurrentRequest.Retries < this.conn.CurrentRequest.MaxRetries)
                {
                    this.conn.CurrentRequest.Retries++;
                    resendRequest = true;
                }
                else
                {
                    this.conn.CurrentRequest.Exception = e;
                    this.conn.CurrentRequest.State     = HTTPRequestStates.ConnectionTimedOut;
                }

                proposedConnectionState = HTTPConnectionStates.Closed;
            }
            catch (Exception e)
            {
                if (this.ShutdownType == ShutdownTypes.Immediate)
                {
                    return;
                }

                string exceptionMessage = string.Empty;
                if (e == null)
                {
                    exceptionMessage = "null";
                }
                else
                {
                    System.Text.StringBuilder sb = new System.Text.StringBuilder();

                    Exception exception = e;
                    int       counter   = 1;
                    while (exception != null)
                    {
                        sb.AppendFormat("{0}: {1} {2}", counter++.ToString(), exception.Message, exception.StackTrace);

                        exception = exception.InnerException;

                        if (exception != null)
                        {
                            sb.AppendLine();
                        }
                    }

                    exceptionMessage = sb.ToString();
                }
                HTTPManager.Logger.Verbose("HTTP1Handler", exceptionMessage, this.Context, this.conn.CurrentRequest.Context);

#if !BESTHTTP_DISABLE_CACHING
                if (this.conn.CurrentRequest.UseStreaming)
                {
                    HTTPCacheService.DeleteEntity(this.conn.CurrentRequest.CurrentUri);
                }
#endif

                // Something gone bad, Response must be null!
                this.conn.CurrentRequest.Response = null;

                if (!this.conn.CurrentRequest.IsCancellationRequested)
                {
                    this.conn.CurrentRequest.Exception = e;
                    this.conn.CurrentRequest.State     = HTTPRequestStates.Error;
                }

                proposedConnectionState = HTTPConnectionStates.Closed;
            }
            finally
            {
                this.conn.CurrentRequest.OnCancellationRequested -= OnCancellationRequested;

                // Exit ASAP
                if (this.ShutdownType != ShutdownTypes.Immediate)
                {
                    if (this.conn.CurrentRequest.IsCancellationRequested)
                    {
                        // we don't know what stage the request is canceled, we can't safely reuse the tcp channel.
                        proposedConnectionState = HTTPConnectionStates.Closed;

                        this.conn.CurrentRequest.Response = null;

                        this.conn.CurrentRequest.State = this.conn.CurrentRequest.IsTimedOut ? HTTPRequestStates.TimedOut : HTTPRequestStates.Aborted;
                    }
                    else if (resendRequest)
                    {
                        RequestEventHelper.EnqueueRequestEvent(new RequestEventInfo(this.conn.CurrentRequest, RequestEvents.Resend));
                    }
                    else if (this.conn.CurrentRequest.Response != null && this.conn.CurrentRequest.Response.IsUpgraded)
                    {
                        proposedConnectionState = HTTPConnectionStates.WaitForProtocolShutdown;
                    }
                    else if (this.conn.CurrentRequest.State == HTTPRequestStates.Processing)
                    {
                        if (this.conn.CurrentRequest.Response != null)
                        {
                            this.conn.CurrentRequest.State = HTTPRequestStates.Finished;
                        }
                        else
                        {
                            this.conn.CurrentRequest.Exception = new Exception(string.Format("[{0}] Remote server closed the connection before sending response header! Previous request state: {1}. Connection state: {2}",
                                                                                             this.ToString(),
                                                                                             this.conn.CurrentRequest.State.ToString(),
                                                                                             this.conn.State.ToString()));
                            this.conn.CurrentRequest.State = HTTPRequestStates.Error;

                            proposedConnectionState = HTTPConnectionStates.Closed;
                        }
                    }

                    this.conn.CurrentRequest = null;

                    if (proposedConnectionState == HTTPConnectionStates.Processing)
                    {
                        proposedConnectionState = HTTPConnectionStates.Recycle;
                    }

                    ConnectionEventHelper.EnqueueConnectionEvent(new ConnectionEventInfo(this.conn, proposedConnectionState));
                }
            }
        }
예제 #22
0
        private void ThreadFunc(object param)
        {
            bool flag  = false;
            bool flag2 = false;

            HTTPConnection.RetryCauses retryCauses = HTTPConnection.RetryCauses.None;
            try
            {
                if (!this.HasProxy && this.CurrentRequest.HasProxy)
                {
                    this.Proxy = this.CurrentRequest.Proxy;
                }
                if (!this.TryLoadAllFromCache())
                {
                    if (this.Client != null && !this.Client.IsConnected())
                    {
                        this.Close();
                    }
                    while (true)
                    {
                        if (retryCauses == HTTPConnection.RetryCauses.Reconnect)
                        {
                            this.Close();
                            Thread.Sleep(100);
                        }
                        this.LastProcessedUri = this.CurrentRequest.CurrentUri;
                        retryCauses           = HTTPConnection.RetryCauses.None;
                        this.Connect();
                        if (this.State == HTTPConnectionStates.AbortRequested)
                        {
                            break;
                        }
                        if (!this.CurrentRequest.DisableCache)
                        {
                            HTTPCacheService.SetHeaders(this.CurrentRequest);
                        }
                        bool flag3 = this.CurrentRequest.SendOutTo(this.Stream);
                        if (!flag3)
                        {
                            this.Close();
                            if (this.State == HTTPConnectionStates.TimedOut)
                            {
                                goto Block_13;
                            }
                            if (!flag)
                            {
                                flag        = true;
                                retryCauses = HTTPConnection.RetryCauses.Reconnect;
                            }
                        }
                        if (flag3)
                        {
                            bool flag4 = this.Receive();
                            if (this.State == HTTPConnectionStates.TimedOut)
                            {
                                goto Block_16;
                            }
                            if (!flag4 && !flag)
                            {
                                flag        = true;
                                retryCauses = HTTPConnection.RetryCauses.Reconnect;
                            }
                            if (this.CurrentRequest.Response != null)
                            {
                                int statusCode = this.CurrentRequest.Response.StatusCode;
                                switch (statusCode)
                                {
                                case 301:
                                case 302:
                                case 307:
                                case 308:
                                {
                                    if (this.CurrentRequest.RedirectCount >= this.CurrentRequest.MaxRedirects)
                                    {
                                        goto IL_3F7;
                                    }
                                    this.CurrentRequest.RedirectCount++;
                                    string firstHeaderValue = this.CurrentRequest.Response.GetFirstHeaderValue("location");
                                    if (string.IsNullOrEmpty(firstHeaderValue))
                                    {
                                        goto IL_3C9;
                                    }
                                    Uri redirectUri = this.GetRedirectUri(firstHeaderValue);
                                    if (!this.CurrentRequest.CallOnBeforeRedirection(redirectUri))
                                    {
                                        HTTPManager.Logger.Information("HTTPConnection", "OnBeforeRedirection returned False");
                                        goto IL_3F7;
                                    }
                                    this.CurrentRequest.RemoveHeader("Host");
                                    this.CurrentRequest.SetHeader("Referer", this.CurrentRequest.CurrentUri.ToString());
                                    this.CurrentRequest.RedirectUri = redirectUri;
                                    this.CurrentRequest.Response    = null;
                                    bool flag5 = true;
                                    this.CurrentRequest.IsRedirected = flag5;
                                    flag2 = flag5;
                                    goto IL_3F7;
                                }

                                case 303:
                                case 304:
                                case 305:
                                case 306:
IL_186:
                                    if (statusCode == 401)
                                    {
                                        string firstHeaderValue2 = this.CurrentRequest.Response.GetFirstHeaderValue("www-authenticate");
                                        if (!string.IsNullOrEmpty(firstHeaderValue2))
                                        {
                                            Digest orCreate = DigestStore.GetOrCreate(this.CurrentRequest.CurrentUri);
                                            orCreate.ParseChallange(firstHeaderValue2);
                                            if (this.CurrentRequest.Credentials != null && orCreate.IsUriProtected(this.CurrentRequest.CurrentUri) && (!this.CurrentRequest.HasHeader("Authorization") || orCreate.Stale))
                                            {
                                                retryCauses = HTTPConnection.RetryCauses.Authenticate;
                                            }
                                        }
                                        goto IL_3F7;
                                    }
                                    if (statusCode != 407)
                                    {
                                        goto IL_3F7;
                                    }
                                    if (this.CurrentRequest.HasProxy)
                                    {
                                        string firstHeaderValue3 = this.CurrentRequest.Response.GetFirstHeaderValue("proxy-authenticate");
                                        if (!string.IsNullOrEmpty(firstHeaderValue3))
                                        {
                                            Digest orCreate2 = DigestStore.GetOrCreate(this.CurrentRequest.Proxy.Address);
                                            orCreate2.ParseChallange(firstHeaderValue3);
                                            if (this.CurrentRequest.Proxy.Credentials != null && orCreate2.IsUriProtected(this.CurrentRequest.Proxy.Address) && (!this.CurrentRequest.HasHeader("Proxy-Authorization") || orCreate2.Stale))
                                            {
                                                retryCauses = HTTPConnection.RetryCauses.ProxyAuthenticate;
                                            }
                                        }
                                    }
                                    goto IL_3F7;
                                }
                                goto IL_186;
IL_3F7:
                                if (this.CurrentRequest.IsCookiesEnabled)
                                {
                                    CookieJar.Set(this.CurrentRequest.Response);
                                }
                                this.TryStoreInCache();
                                if (this.CurrentRequest.Response == null || this.CurrentRequest.Response.HasHeaderWithValue("connection", "close") || this.CurrentRequest.UseAlternateSSL)
                                {
                                    this.Close();
                                }
                            }
                        }
                        if (retryCauses == HTTPConnection.RetryCauses.None)
                        {
                            goto Block_37;
                        }
                    }
                    throw new Exception("AbortRequested");
Block_13:
                    throw new Exception("AbortRequested");
Block_16:
                    throw new Exception("AbortRequested");
IL_3C9:
                    throw new MissingFieldException(string.Format("Got redirect status({0}) without 'location' header!", this.CurrentRequest.Response.StatusCode.ToString()));
                    Block_37 :;
                }
            }
            catch (TimeoutException exception)
            {
                this.CurrentRequest.Response  = null;
                this.CurrentRequest.Exception = exception;
                this.CurrentRequest.State     = HTTPRequestStates.ConnectionTimedOut;
                this.Close();
            }
            catch (Exception exception2)
            {
                if (this.CurrentRequest != null)
                {
                    if (this.CurrentRequest.UseStreaming)
                    {
                        HTTPCacheService.DeleteEntity(this.CurrentRequest.CurrentUri, true);
                    }
                    this.CurrentRequest.Response = null;
                    HTTPConnectionStates state = this.State;
                    if (state != HTTPConnectionStates.AbortRequested)
                    {
                        if (state != HTTPConnectionStates.TimedOut)
                        {
                            this.CurrentRequest.Exception = exception2;
                            this.CurrentRequest.State     = HTTPRequestStates.Error;
                        }
                        else
                        {
                            this.CurrentRequest.State = HTTPRequestStates.TimedOut;
                        }
                    }
                    else
                    {
                        this.CurrentRequest.State = HTTPRequestStates.Aborted;
                    }
                }
                this.Close();
            }
            finally
            {
                if (this.CurrentRequest != null)
                {
                    object locker = HTTPManager.Locker;
                    lock (locker)
                    {
                        if (this.CurrentRequest != null && this.CurrentRequest.Response != null && this.CurrentRequest.Response.IsUpgraded)
                        {
                            this.State = HTTPConnectionStates.Upgraded;
                        }
                        else
                        {
                            this.State = ((!flag2) ? ((this.Client != null) ? HTTPConnectionStates.WaitForRecycle : HTTPConnectionStates.Closed) : HTTPConnectionStates.Redirected);
                        }
                        if (this.CurrentRequest.State == HTTPRequestStates.Processing && (this.State == HTTPConnectionStates.Closed || this.State == HTTPConnectionStates.WaitForRecycle))
                        {
                            this.CurrentRequest.State = HTTPRequestStates.Finished;
                        }
                        if (this.CurrentRequest.State == HTTPRequestStates.ConnectionTimedOut)
                        {
                            this.State = HTTPConnectionStates.Closed;
                        }
                        this.LastProcessTime = DateTime.UtcNow;
                    }
                    HTTPCacheService.SaveLibrary();
                    CookieJar.Persist();
                }
            }
        }
    // Token: 0x0600512E RID: 20782 RVA: 0x001BB51C File Offset: 0x001B991C
    private IEnumerator DownloadAndLoadRemotePluginCoroutine(AssetBundleDownload download)
    {
        if (Player.Instance != null && Player.Instance.isInternal)
        {
            Debug.Log(string.Concat(new object[]
            {
                "[",
                download.downloadId,
                "] Requires plugin. About to download ",
                download.pluginUrl
            }));
        }
        if (!PluginManager.IsAllowedUrl(download.pluginUrl))
        {
            yield break;
        }
        HTTPRequest pluginReq = null;

        try
        {
            pluginReq = new HTTPRequest(new Uri(download.pluginUrl), null);
        }
        catch (Exception ex)
        {
            download.OnDownloadError("Bad plugin url: " + ex.Message, LoadErrorReason.InvalidURL);
            yield break;
        }
        if (download.forceRefreshCache)
        {
            HTTPCacheService.DeleteEntity(pluginReq.CurrentUri, true);
        }
        pluginReq.OnProgress = new OnDownloadProgressDelegate(download.OnDownloadProgress);
        pluginReq.Send();
        yield return(base.StartCoroutine(pluginReq));

        VRC.Network.ValidateCompletedHTTPRequest(pluginReq, delegate(HTTPResponse response)
        {
            if (!this.CheckForCancellation(download))
            {
                VRC.Core.Logger.Log("[" + download.downloadId + "] Downloaded and loading plugin...", DebugLevel.AssetBundleDownloadManager);
                try
                {
                    PluginManager.Instance.Load(download.pluginUrl, pluginReq.Response.Data);
                }
                catch (Exception ex2)
                {
                    download.OnPluginLoadError(ex2.Message);
                }
            }
        }, delegate(string errorStr)
        {
            string text = "Failed to download plugin from " + download.pluginUrl + " - " + errorStr;
            VRC.Core.Logger.LogError(string.Concat(new object[]
            {
                "[",
                download.downloadId,
                "] ",
                text
            }), DebugLevel.AssetBundleDownloadManager);
            download.OnDownloadError(text, LoadErrorReason.ConnectionError);
        });
        yield break;
    }
        void OnResponse(int httpStatus, byte[] buffer, int bufferLength)
        {
            HTTPConnectionStates proposedConnectionState = HTTPConnectionStates.Processing;
            bool resendRequest = false;

            try
            {
                if (this.CurrentRequest.IsCancellationRequested)
                {
                    return;
                }

                using (var ms = new BufferPoolMemoryStream())
                {
                    Stream = ms;

                    XHR_GetStatusLine(NativeId, OnBufferCallback);
                    XHR_GetResponseHeaders(NativeId, OnBufferCallback);

                    if (buffer != null && bufferLength > 0)
                    {
                        ms.Write(buffer, 0, bufferLength);
                    }

                    ms.Seek(0L, SeekOrigin.Begin);

                    var    internalBuffer = ms.GetBuffer();
                    string tmp            = System.Text.Encoding.UTF8.GetString(internalBuffer);
                    HTTPManager.Logger.Information(this.NativeId + " OnResponse - full response ", tmp, this.Context);

                    SupportedProtocols protocol = CurrentRequest.ProtocolHandler == SupportedProtocols.Unknown ? HTTPProtocolFactory.GetProtocolFromUri(CurrentRequest.CurrentUri) : CurrentRequest.ProtocolHandler;
                    CurrentRequest.Response = HTTPProtocolFactory.Get(protocol, CurrentRequest, ms, CurrentRequest.UseStreaming, false);

                    CurrentRequest.Response.Receive(buffer != null && bufferLength > 0 ? (int)bufferLength : -1, true);

                    KeepAliveHeader keepAlive = null;
                    ConnectionHelper.HandleResponse(this.ToString(), this.CurrentRequest, out resendRequest, out proposedConnectionState, ref keepAlive);
                }
            }
            catch (Exception e)
            {
                HTTPManager.Logger.Exception(this.NativeId + " WebGLConnection", "OnResponse", e, this.Context);

                if (this.ShutdownType == ShutdownTypes.Immediate)
                {
                    return;
                }

#if !BESTHTTP_DISABLE_CACHING
                if (this.CurrentRequest.UseStreaming)
                {
                    HTTPCacheService.DeleteEntity(this.CurrentRequest.CurrentUri);
                }
#endif

                // Something gone bad, Response must be null!
                this.CurrentRequest.Response = null;

                if (!this.CurrentRequest.IsCancellationRequested)
                {
                    this.CurrentRequest.Exception = e;
                    this.CurrentRequest.State     = HTTPRequestStates.Error;
                }

                proposedConnectionState = HTTPConnectionStates.Closed;
            }
            finally
            {
                // Exit ASAP
                if (this.ShutdownType != ShutdownTypes.Immediate)
                {
                    if (this.CurrentRequest.IsCancellationRequested)
                    {
                        // we don't know what stage the request is cancelled, we can't safely reuse the tcp channel.
                        proposedConnectionState = HTTPConnectionStates.Closed;

                        this.CurrentRequest.Response = null;

                        this.CurrentRequest.State = this.CurrentRequest.IsTimedOut ? HTTPRequestStates.TimedOut : HTTPRequestStates.Aborted;
                    }
                    else if (resendRequest)
                    {
                        RequestEventHelper.EnqueueRequestEvent(new RequestEventInfo(this.CurrentRequest, RequestEvents.Resend));
                    }
                    else if (this.CurrentRequest.Response != null && this.CurrentRequest.Response.IsUpgraded)
                    {
                        proposedConnectionState = HTTPConnectionStates.WaitForProtocolShutdown;
                    }
                    else if (this.CurrentRequest.State == HTTPRequestStates.Processing)
                    {
                        if (this.CurrentRequest.Response != null)
                        {
                            this.CurrentRequest.State = HTTPRequestStates.Finished;
                        }
                        else
                        {
                            this.CurrentRequest.Exception = new Exception(string.Format("[{0}] Remote server closed the connection before sending response header! Previous request state: {1}. Connection state: {2}",
                                                                                        this.ToString(),
                                                                                        this.CurrentRequest.State.ToString(),
                                                                                        this.State.ToString()));
                            this.CurrentRequest.State = HTTPRequestStates.Error;

                            proposedConnectionState = HTTPConnectionStates.Closed;
                        }
                    }

                    this.CurrentRequest = null;

                    if (proposedConnectionState == HTTPConnectionStates.Processing)
                    {
                        proposedConnectionState = HTTPConnectionStates.Closed;
                    }

                    ConnectionEventHelper.EnqueueConnectionEvent(new ConnectionEventInfo(this, proposedConnectionState));
                }
            }
        }
예제 #25
0
        public void RunHandler()
        {
            HTTPManager.Logger.Information("HTTP1Handler", string.Format("[{0}] started processing request '{1}'", this, this.conn.CurrentRequest.CurrentUri.ToString()), this.Context, this.conn.CurrentRequest.Context);

            System.Threading.Thread.CurrentThread.Name = "BestHTTP.HTTP1 R&W";

            HTTPConnectionStates proposedConnectionState = HTTPConnectionStates.Processing;

            bool resendRequest = false;

            try
            {
                if (this.conn.CurrentRequest.IsCancellationRequested)
                {
                    return;
                }

#if !BESTHTTP_DISABLE_CACHING
                // Setup cache control headers before we send out the request
                if (!this.conn.CurrentRequest.DisableCache)
                {
                    HTTPCacheService.SetHeaders(this.conn.CurrentRequest);
                }
#endif

                // Write the request to the stream
                this.conn.CurrentRequest.QueuedAt          = DateTime.MinValue;
                this.conn.CurrentRequest.ProcessingStarted = DateTime.UtcNow;
                this.conn.CurrentRequest.SendOutTo(this.conn.connector.Stream);
                this.conn.CurrentRequest.Timing.Add(TimingEventNames.Request_Sent);

                if (this.conn.CurrentRequest.IsCancellationRequested)
                {
                    return;
                }

                this.conn.CurrentRequest.OnCancellationRequested += OnCancellationRequested;

                // Receive response from the server
                bool received = Receive(this.conn.CurrentRequest);

                this.conn.CurrentRequest.Timing.Add(TimingEventNames.Response_Received);

                if (this.conn.CurrentRequest.IsCancellationRequested)
                {
                    return;
                }

                if (!received && this.conn.CurrentRequest.Retries < this.conn.CurrentRequest.MaxRetries)
                {
                    proposedConnectionState = HTTPConnectionStates.Closed;
                    this.conn.CurrentRequest.Retries++;
                    resendRequest = true;
                    return;
                }

                ConnectionHelper.HandleResponse(this.conn.ToString(), this.conn.CurrentRequest, out resendRequest, out proposedConnectionState, ref this._keepAlive, this.conn.Context, this.conn.CurrentRequest.Context);
            }
            catch (TimeoutException e)
            {
                this.conn.CurrentRequest.Response = null;

                // Do nothing here if Abort() got called on the request, its State is already set.
                if (!this.conn.CurrentRequest.IsTimedOut)
                {
                    // We will try again only once
                    if (this.conn.CurrentRequest.Retries < this.conn.CurrentRequest.MaxRetries)
                    {
                        this.conn.CurrentRequest.Retries++;
                        resendRequest = true;
                    }
                    else
                    {
                        this.conn.CurrentRequest.Exception = e;
                        this.conn.CurrentRequest.State     = HTTPRequestStates.ConnectionTimedOut;
                    }
                }

                proposedConnectionState = HTTPConnectionStates.Closed;
            }
            catch (Exception e)
            {
                if (this.ShutdownType == ShutdownTypes.Immediate)
                {
                    return;
                }

                string exceptionMessage = string.Empty;
                if (e == null)
                {
                    exceptionMessage = "null";
                }
                else
                {
                    System.Text.StringBuilder sb = new System.Text.StringBuilder();

                    Exception exception = e;
                    int       counter   = 1;
                    while (exception != null)
                    {
                        sb.AppendFormat("{0}: {1} {2}", counter++.ToString(), exception.Message, exception.StackTrace);

                        exception = exception.InnerException;

                        if (exception != null)
                        {
                            sb.AppendLine();
                        }
                    }

                    exceptionMessage = sb.ToString();
                }
                HTTPManager.Logger.Verbose("HTTP1Handler", exceptionMessage, this.Context, this.conn.CurrentRequest.Context);

#if !BESTHTTP_DISABLE_CACHING
                if (this.conn.CurrentRequest.UseStreaming)
                {
                    HTTPCacheService.DeleteEntity(this.conn.CurrentRequest.CurrentUri);
                }
#endif

                // Something gone bad, Response must be null!
                this.conn.CurrentRequest.Response = null;

                // Do nothing here if Abort() got called on the request, its State is already set.
                if (!this.conn.CurrentRequest.IsCancellationRequested)
                {
                    this.conn.CurrentRequest.Exception = e;
                    this.conn.CurrentRequest.State     = HTTPRequestStates.Error;
                }

                proposedConnectionState = HTTPConnectionStates.Closed;
            }
            finally
            {
                this.conn.CurrentRequest.OnCancellationRequested -= OnCancellationRequested;

                // Exit ASAP
                if (this.ShutdownType != ShutdownTypes.Immediate)
                {
                    if (this.conn.CurrentRequest.IsCancellationRequested)
                    {
                        // we don't know what stage the request is canceled, we can't safely reuse the tcp channel.
                        proposedConnectionState = HTTPConnectionStates.Closed;

                        this.conn.CurrentRequest.Response = null;

                        // The request's State already set, or going to be set soon in RequestEvents.cs.
                        //this.conn.CurrentRequest.State = this.conn.CurrentRequest.IsTimedOut ? HTTPRequestStates.TimedOut : HTTPRequestStates.Aborted;
                    }
                    else if (resendRequest)
                    {
                        // Here introducing a ClosedResendRequest connection state, where we have to process the connection's state change to Closed
                        // than we have to resend the request.
                        // If we would send the Resend request here, than a few lines below the Closed connection state change,
                        //  request events are processed before connection events (just switching the EnqueueRequestEvent and EnqueueConnectionEvent wouldn't work
                        //  see order of ProcessQueues in HTTPManager.OnUpdate!) and it would pick this very same closing/closed connection!

                        if (proposedConnectionState == HTTPConnectionStates.Closed)
                        {
                            ConnectionEventHelper.EnqueueConnectionEvent(new ConnectionEventInfo(this.conn, this.conn.CurrentRequest));
                        }
                        else
                        {
                            RequestEventHelper.EnqueueRequestEvent(new RequestEventInfo(this.conn.CurrentRequest, RequestEvents.Resend));
                        }
                    }
                    else if (this.conn.CurrentRequest.Response != null && this.conn.CurrentRequest.Response.IsUpgraded)
                    {
                        proposedConnectionState = HTTPConnectionStates.WaitForProtocolShutdown;
                    }
                    else if (this.conn.CurrentRequest.State == HTTPRequestStates.Processing)
                    {
                        if (this.conn.CurrentRequest.Response != null)
                        {
                            this.conn.CurrentRequest.State = HTTPRequestStates.Finished;
                        }
                        else
                        {
                            this.conn.CurrentRequest.Exception = new Exception(string.Format("[{0}] Remote server closed the connection before sending response header! Previous request state: {1}. Connection state: {2}",
                                                                                             this.ToString(),
                                                                                             this.conn.CurrentRequest.State.ToString(),
                                                                                             this.conn.State.ToString()));
                            this.conn.CurrentRequest.State = HTTPRequestStates.Error;

                            proposedConnectionState = HTTPConnectionStates.Closed;
                        }
                    }

                    this.conn.CurrentRequest = null;

                    if (proposedConnectionState == HTTPConnectionStates.Processing)
                    {
                        proposedConnectionState = HTTPConnectionStates.Recycle;
                    }

                    if (proposedConnectionState != HTTPConnectionStates.ClosedResendRequest)
                    {
                        ConnectionEventHelper.EnqueueConnectionEvent(new ConnectionEventInfo(this.conn, proposedConnectionState));
                    }
                }
            }
        }
예제 #26
0
        public void RunHandler()
        {
            HTTPManager.Logger.Information("HTTP1Handler", string.Format("[{0}] started processing request '{1}'", this, this.conn.CurrentRequest.CurrentUri.ToString()));

            HTTPConnectionStates proposedConnectionState = HTTPConnectionStates.Processing;

            bool resendRequest = false;

            try
            {
                if (this.conn.CurrentRequest.IsCancellationRequested)
                {
                    return;
                }

#if !BESTHTTP_DISABLE_CACHING
                // Try load the full response from an already saved cache entity.
                // If the response could be loaded completely, we can skip connecting (if not already) and a full round-trip time to the server.
                if (HTTPCacheService.IsCachedEntityExpiresInTheFuture(this.conn.CurrentRequest) && ConnectionHelper.TryLoadAllFromCache(this.ToString(), this.conn.CurrentRequest))
                {
                    HTTPManager.Logger.Information("HTTP1Handler", string.Format("[{0}] Request could be fully loaded from cache! '{1}'", this, this.conn.CurrentRequest.CurrentUri.ToString()));
                    return;
                }
#endif

                if (this.conn.CurrentRequest.IsCancellationRequested)
                {
                    return;
                }

#if !BESTHTTP_DISABLE_CACHING
                // Setup cache control headers before we send out the request
                if (!this.conn.CurrentRequest.DisableCache)
                {
                    HTTPCacheService.SetHeaders(this.conn.CurrentRequest);
                }
#endif

                // Write the request to the stream
                this.conn.CurrentRequest.SendOutTo(this.conn.connector.Stream);

                if (this.conn.CurrentRequest.IsCancellationRequested)
                {
                    return;
                }

                // Receive response from the server
                bool received = Receive(this.conn.CurrentRequest);

                if (this.conn.CurrentRequest.IsCancellationRequested)
                {
                    return;
                }

                if (!received && this.conn.CurrentRequest.Retries < this.conn.CurrentRequest.MaxRetries)
                {
                    proposedConnectionState = HTTPConnectionStates.Closed;
                    this.conn.CurrentRequest.Retries++;
                    resendRequest = true;
                    return;
                }

                ConnectionHelper.HandleResponse(this.conn.ToString(), this.conn.CurrentRequest, out resendRequest, out proposedConnectionState, ref this._keepAlive);
            }
            catch (TimeoutException e)
            {
                this.conn.CurrentRequest.Response = null;

                // We will try again only once
                if (this.conn.CurrentRequest.Retries < this.conn.CurrentRequest.MaxRetries)
                {
                    this.conn.CurrentRequest.Retries++;
                    resendRequest = true;
                }
                else
                {
                    this.conn.CurrentRequest.Exception = e;
                    this.conn.CurrentRequest.State     = HTTPRequestStates.ConnectionTimedOut;
                }

                proposedConnectionState = HTTPConnectionStates.Closed;
            }
            catch (Exception e)
            {
                if (this.ShutdownType == ShutdownTypes.Immediate)
                {
                    return;
                }

#if !BESTHTTP_DISABLE_CACHING
                if (this.conn.CurrentRequest.UseStreaming)
                {
                    HTTPCacheService.DeleteEntity(this.conn.CurrentRequest.CurrentUri);
                }
#endif

                // Something gone bad, Response must be null!
                this.conn.CurrentRequest.Response = null;

                if (!this.conn.CurrentRequest.IsCancellationRequested)
                {
                    this.conn.CurrentRequest.Exception = e;
                    this.conn.CurrentRequest.State     = HTTPRequestStates.Error;
                }

                proposedConnectionState = HTTPConnectionStates.Closed;
            }
            finally
            {
                // Exit ASAP
                if (this.ShutdownType != ShutdownTypes.Immediate)
                {
                    if (this.conn.CurrentRequest.IsCancellationRequested)
                    {
                        // we don't know what stage the request is cancelled, we can't safely reuse the tcp channel.
                        proposedConnectionState = HTTPConnectionStates.Closed;

                        this.conn.CurrentRequest.Response = null;

                        this.conn.CurrentRequest.State = this.conn.CurrentRequest.IsTimedOut ? HTTPRequestStates.TimedOut : HTTPRequestStates.Aborted;
                    }
                    else if (resendRequest)
                    {
                        RequestEventHelper.EnqueueRequestEvent(new RequestEventInfo(this.conn.CurrentRequest, RequestEvents.Resend));
                    }
                    else if (this.conn.CurrentRequest.Response != null && this.conn.CurrentRequest.Response.IsUpgraded)
                    {
                        proposedConnectionState = HTTPConnectionStates.WaitForProtocolShutdown;
                    }
                    else if (this.conn.CurrentRequest.State == HTTPRequestStates.Processing)
                    {
                        if (this.conn.CurrentRequest.Response != null)
                        {
                            this.conn.CurrentRequest.State = HTTPRequestStates.Finished;
                        }
                        else
                        {
                            this.conn.CurrentRequest.Exception = new Exception(string.Format("[{0}] Remote server closed the connection before sending response header! Previous request state: {1}. Connection state: {2}",
                                                                                             this.ToString(),
                                                                                             this.conn.CurrentRequest.State.ToString(),
                                                                                             this.conn.State.ToString()));
                            this.conn.CurrentRequest.State = HTTPRequestStates.Error;

                            proposedConnectionState = HTTPConnectionStates.Closed;
                        }
                    }

                    this.conn.CurrentRequest = null;

                    if (proposedConnectionState == HTTPConnectionStates.Processing)
                    {
                        proposedConnectionState = HTTPConnectionStates.Recycle;
                    }

                    ConnectionEventHelper.EnqueueConnectionEvent(new ConnectionEventInfo(this.conn, proposedConnectionState));
                }
            }
        }
예제 #27
0
    void OnGUI()
    {
        GUI.Label(new Rect(5, 5, Screen.width - 10, 30), string.Format("Cache size: {0,10:N0} Entity Count: {1}", HTTPCacheService.GetCacheSize(), HTTPCacheService.GetCacheEntityCount()));

        float height = (Screen.height - 300) / TestScenes.Length;

        if (GUI.Button(new Rect(5, 40, Screen.width, height), "Clear Cache"))
        {
            BestHTTP.Caching.HTTPCacheService.BeginClear();
        }

        for (int i = 0; i < TestScenes.Length; ++i)
        {
            if (GUI.Button(new Rect(3, 300 + (i * height), Screen.width - 6, height), TestScenes[i]))
            {
                Application.LoadLevel(TestScenes[i]);
            }
        }
    }
예제 #28
0
 public static void Setup()
 {
     HTTPUpdateDelegator.CheckInstance();
     HTTPCacheService.CheckSetup();
     Cookies.CookieJar.SetupFolder();
 }
예제 #29
0
        void ThreadFunc(object param)
        {
            bool alreadyReconnected = false;
            bool redirected         = false;

            RetryCauses cause = RetryCauses.None;

#if LOCK_ON_FILE
            object uriLock = null;
#endif

#if UNITY_WEBPLAYER
            // Right now, no caching supported in the webplayer
            if (!CurrentRequest.DisableCache)
            {
                CurrentRequest.DisableCache = true;
            }
#endif

            try
            {
                if (!HasProxy && CurrentRequest.HasProxy)
                {
                    Proxy = CurrentRequest.Proxy;
                }

                // Lock only if we will use the cached entity.
#if LOCK_ON_FILE
                if (!CurrentRequest.DisableCache)
                {
                    Monitor.Enter(uriLock = HTTPCacheFileLock.Acquire(CurrentRequest.CurrentUri));
                }
#endif

                // Try load the full response from an already saved cache entity. If the response
                if (TryLoadAllFromCache())
                {
                    return;
                }

                if (Client != null && !Client.IsConnected())
                {
                    Close();
                }

                do // of while (reconnect)
                {
                    if (cause == RetryCauses.Reconnect)
                    {
                        Close();
#if NETFX_CORE
                        await Task.Delay(100);
#else
                        Thread.Sleep(100);
#endif
                    }

                    LastProcessedUri = CurrentRequest.CurrentUri;

                    cause = RetryCauses.None;

                    // Connect to the server
                    Connect();

                    if (State == HTTPConnectionStates.AbortRequested)
                    {
                        throw new Exception("AbortRequested");
                    }

                    // Setup cache control headers before we send out the request
                    if (!CurrentRequest.DisableCache)
                    {
                        HTTPCacheService.SetHeaders(CurrentRequest);
                    }

                    // Write the request to the stream
                    // sentRequest will be true if the request sent out successfully(no SocketException), so we can try read the response
                    bool sentRequest = CurrentRequest.SendOutTo(Stream);

                    // sentRequest only true if there are no exceptions during CurrentRequest.SendOutTo.
                    if (!sentRequest)
                    {
                        Close();

                        if (State == HTTPConnectionStates.TimedOut)
                        {
                            throw new Exception("AbortRequested");
                        }

                        // We will try again only once
                        if (!alreadyReconnected)
                        {
                            alreadyReconnected = true;
                            cause = RetryCauses.Reconnect;
                        }
                    }

                    // If sending out the request succeded, we will try read the response.
                    if (sentRequest)
                    {
                        bool received = Receive();

                        if (State == HTTPConnectionStates.TimedOut)
                        {
                            throw new Exception("AbortRequested");
                        }

                        if (!received && !alreadyReconnected)
                        {
                            alreadyReconnected = true;
                            cause = RetryCauses.Reconnect;
                        }

                        if (CurrentRequest.Response != null)
                        {
                            switch (CurrentRequest.Response.StatusCode)
                            {
                            // Not authorized
                            // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2
                            case 401:
                            {
                                string authHeader = CurrentRequest.Response.GetFirstHeaderValue("www-authenticate");
                                if (!string.IsNullOrEmpty(authHeader))
                                {
                                    var digest = DigestStore.GetOrCreate(CurrentRequest.CurrentUri);
                                    digest.ParseChallange(authHeader);

                                    if (CurrentRequest.Credentials != null && digest.IsUriProtected(CurrentRequest.CurrentUri) && (!CurrentRequest.HasHeader("Authorization") || digest.Stale))
                                    {
                                        cause = RetryCauses.Authenticate;
                                    }
                                }

                                goto default;
                            }

                            // Proxy authentication required
                            // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.8
                            case 407:
                            {
                                if (CurrentRequest.HasProxy)
                                {
                                    string authHeader = CurrentRequest.Response.GetFirstHeaderValue("proxy-authenticate");
                                    if (!string.IsNullOrEmpty(authHeader))
                                    {
                                        var digest = DigestStore.GetOrCreate(CurrentRequest.Proxy.Address);
                                        digest.ParseChallange(authHeader);

                                        if (CurrentRequest.Proxy.Credentials != null && digest.IsUriProtected(CurrentRequest.Proxy.Address) && (!CurrentRequest.HasHeader("Proxy-Authorization") || digest.Stale))
                                        {
                                            cause = RetryCauses.ProxyAuthenticate;
                                        }
                                    }
                                }

                                goto default;
                            }

                            // Redirected
                            case 301:     // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.2
                            case 302:     // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.3
                            case 307:     // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.8
                            case 308:     // http://tools.ietf.org/html/rfc7238
                            {
                                if (CurrentRequest.RedirectCount >= CurrentRequest.MaxRedirects)
                                {
                                    goto default;
                                }
                                CurrentRequest.RedirectCount++;

                                string location = CurrentRequest.Response.GetFirstHeaderValue("location");
                                if (!string.IsNullOrEmpty(location))
                                {
                                    Uri redirectUri = GetRedirectUri(location);

                                    // Let the user to take some control over the redirection
                                    if (!CurrentRequest.CallOnBeforeRedirection(redirectUri))
                                    {
                                        HTTPManager.Logger.Information("HTTPConnection", "OnBeforeRedirection returned False");
                                        goto default;
                                    }

                                    // Remove the previously set Host header.
                                    CurrentRequest.RemoveHeader("Host");

                                    // Set the Referer header to the last Uri.
                                    CurrentRequest.SetHeader("Referer", CurrentRequest.CurrentUri.ToString());

                                    // Set the new Uri, the CurrentUri will return this while the IsRedirected property is true
                                    CurrentRequest.RedirectUri = redirectUri;

                                    // Discard the redirect response, we don't need it any more
                                    CurrentRequest.Response = null;

                                    redirected = CurrentRequest.IsRedirected = true;
                                }
                                else
                                            #if !NETFX_CORE
                                { throw new MissingFieldException(string.Format("Got redirect status({0}) without 'location' header!", CurrentRequest.Response.StatusCode.ToString())); }
                                            #else
                                { throw new Exception(string.Format("Got redirect status({0}) without 'location' header!", CurrentRequest.Response.StatusCode.ToString())); }
                                            #endif

                                goto default;
                            }

                            default:
                                if (CurrentRequest.IsCookiesEnabled)
                                {
                                    CookieJar.Set(CurrentRequest.Response);
                                }

                                TryStoreInCache();
                                break;
                            }

                            // If we have a response and the server telling us that it closed the connection after the message sent to us, then
                            //  we will colse the connection too.
                            if (CurrentRequest.Response == null ||
                                CurrentRequest.Response.HasHeaderWithValue("connection", "close") ||
                                CurrentRequest.UseAlternateSSL)
                            {
                                Close();
                            }
                        }
                    }
                } while (cause != RetryCauses.None);
            }
            catch (TimeoutException e)
            {
                CurrentRequest.Response  = null;
                CurrentRequest.Exception = e;
                CurrentRequest.State     = HTTPRequestStates.ConnectionTimedOut;

                Close();
            }
            catch (Exception e)
            {
                if (CurrentRequest.UseStreaming)
                {
                    HTTPCacheService.DeleteEntity(CurrentRequest.CurrentUri);
                }

                // Something gone bad, Response must be null!
                CurrentRequest.Response = null;

                switch (State)
                {
                case HTTPConnectionStates.AbortRequested:
                    CurrentRequest.State = HTTPRequestStates.Aborted;
                    break;

                case HTTPConnectionStates.TimedOut:
                    CurrentRequest.State = HTTPRequestStates.TimedOut;
                    break;

                default:
                    CurrentRequest.Exception = e;
                    CurrentRequest.State     = HTTPRequestStates.Error;
                    break;
                }

                Close();
            }
            finally
            {
#if LOCK_ON_FILE
                if (!CurrentRequest.DisableCache && uriLock != null)
                {
                    Monitor.Exit(uriLock);
                }
#endif

                // Avoid state changes. While we are in this block changing the connection's State, on Unity's main thread
                //  the HTTPManager's OnUpdate will check the connections's State and call functions that can change the inner state of
                //  the object. (Like setting the CurrentRequest to null in function Recycle() causing a NullRef exception)
                lock (HTTPManager.Locker)
                {
                    if (CurrentRequest != null && CurrentRequest.Response != null && CurrentRequest.Response.IsUpgraded)
                    {
                        State = HTTPConnectionStates.Upgraded;
                    }
                    else
                    {
                        State = redirected ? HTTPConnectionStates.Redirected : (Client == null ? HTTPConnectionStates.Closed : HTTPConnectionStates.WaitForRecycle);
                    }

                    // Change the request's state only when the whole processing finished
                    if (CurrentRequest.State == HTTPRequestStates.Processing && (State == HTTPConnectionStates.Closed || State == HTTPConnectionStates.WaitForRecycle))
                    {
                        CurrentRequest.State = HTTPRequestStates.Finished;
                    }

                    if (CurrentRequest.State == HTTPRequestStates.ConnectionTimedOut)
                    {
                        State = HTTPConnectionStates.Closed;
                    }

                    LastProcessTime = DateTime.UtcNow;
                }

                HTTPCacheService.SaveLibrary();
                CookieJar.Persist();
            }
        }
예제 #30
0
 protected void BeginReceiveStreamFragments()
 {
     if (!baseRequest.DisableCache && baseRequest.UseStreaming && !IsFromCache && HTTPCacheService.IsCacheble(baseRequest.CurrentUri, baseRequest.MethodType, this))
     {
         cacheStream = HTTPCacheService.PrepareStreamed(baseRequest.CurrentUri, this);
     }
     allFragmentSize = 0;
 }