private bool TryLoadAllFromCache()
 {
     if (!base.CurrentRequest.DisableCache && HTTPCacheService.IsSupported)
     {
         try
         {
             if (HTTPCacheService.IsCachedEntityExpiresInTheFuture(base.CurrentRequest))
             {
                 if (HTTPManager.Logger.Level == Loglevels.All)
                 {
                     HTTPManager.Logger.Verbose("HTTPConnection", $"{base.CurrentRequest.CurrentUri.ToString()} - TryLoadAllFromCache - whole response loading from cache");
                 }
                 base.CurrentRequest.Response = HTTPCacheService.GetFullResponse(base.CurrentRequest);
                 if (base.CurrentRequest.Response != null)
                 {
                     return(true);
                 }
             }
         }
         catch
         {
             HTTPCacheService.DeleteEntity(base.CurrentRequest.CurrentUri, true);
         }
     }
     return(false);
 }
        private bool TryLoadAllFromCache()
        {
            if (CurrentRequest.DisableCache || !HTTPCacheService.IsSupported)
            {
                return(false);
            }

            // We will try read the response from the cache, but if something happens we will fallback to the normal way.
            try
            {
                //Unless specifically constrained by a cache-control (section 14.9) directive, a caching system MAY always store a successful response (see section 13.8) as a cache entity,
                //  MAY return it without validation if it is fresh, and MAY    return it after successful validation.
                // MAY return it without validation if it is fresh!
                if (HTTPCacheService.IsCachedEntityExpiresInTheFuture(CurrentRequest))
                {
                    CurrentRequest.Response = HTTPCacheService.GetFullResponse(CurrentRequest);

                    if (CurrentRequest.Response != null)
                    {
                        return(true);
                    }
                }
            }
            catch
            {
                HTTPCacheService.DeleteEntity(CurrentRequest.CurrentUri);
            }

            return(false);
        }
        public static bool TryLoadAllFromCache(string context, HTTPRequest request)
        {
            if (!HTTPCacheService.IsCachedEntityExpiresInTheFuture(request))
            {
                return(false);
            }

            // We will try read the response from the cache, but if something happens we will fallback to the normal way.
            try
            {
                //Unless specifically constrained by a cache-control (section 14.9) directive, a caching system MAY always store a successful response (see section 13.8) as a cache entity,
                //  MAY return it without validation if it is fresh, and MAY    return it after successful validation.
                // MAY return it without validation if it is fresh!
                if (HTTPManager.Logger.Level == Logger.Loglevels.All)
                {
                    HTTPManager.Logger.Verbose("ConnectionHelper", string.Format("[{0}] - TryLoadAllFromCache - whole response loading from cache", context));
                }

                request.Response = HTTPCacheService.GetFullResponse(request);

                if (request.Response != null)
                {
                    return(true);
                }
            }
            catch
            {
                HTTPCacheService.DeleteEntity(request.CurrentUri);
            }

            return(false);
        }
 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);
 }
Exemple #5
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));
                }
            }
        }