[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/eaba/NetCoreServer/master/source/NetCoreServer/HttpSession.cs [Back]  [Original]

namespace NetCoreServer
{
    /// 
    /// HTTP session is used to receive/send HTTP requests/responses from the connected HTTP client.
    /// 
    /// Thread-safe.
    public class HttpSession : TcpSession
    {
        public HttpSession(HttpServer server) : base(server)
        {
            Cache = server.Cache;
            Request = new HttpRequest();
            Response = new HttpResponse();
        }

        /// 
        /// Get the static content cache
        /// 
        public FileCache Cache { get; }

        /// 
        /// Get the HTTP request
        /// 
        protected HttpRequest Request { get; }

        /// 
        /// Get the HTTP response
        /// 
        public HttpResponse Response { get; }

        #region Send response / Send response body

        /// 
        /// Send the current HTTP response (synchronous)
        /// 
        /// Size of sent data
        public long SendResponse() { return SendResponse(Response); }
        /// 
        /// Send the HTTP response (synchronous)
        /// 
        /// HTTP response
        /// Size of sent data
        public long SendResponse(HttpResponse response) { return Send(response.Cache.Data, response.Cache.Offset, response.Cache.Size); }

        /// 
        /// Send the HTTP response body (synchronous)
        /// 
        /// HTTP response body
        /// Size of sent data
        public long SendResponseBody(string body) { return Send(body); }
        /// 
        /// Send the HTTP response body (synchronous)
        /// 
        /// HTTP response body buffer
        /// Size of sent data
        public long SendResponseBody(byte[] buffer) { return Send(buffer); }
        /// 
        /// Send the HTTP response body (synchronous)
        /// 
        /// HTTP response body buffer
        /// HTTP response body buffer offset
        /// HTTP response body size
        /// Size of sent data
        public long SendResponseBody(byte[] buffer, long offset, long size) { return Send(buffer, offset, size); }

        /// 
        /// Send the current HTTP response (asynchronous)
        /// 
        /// 'true' if the current HTTP response was successfully sent, 'false' if the session is not connected
        public bool SendResponseAsync() { return SendResponseAsync(Response); }
        /// 
        /// Send the HTTP response (asynchronous)
        /// 
        /// HTTP response
        /// 'true' if the current HTTP response was successfully sent, 'false' if the session is not connected
        public bool SendResponseAsync(HttpResponse response) { return SendAsync(response.Cache.Data, response.Cache.Offset, response.Cache.Size); }

        /// 
        /// Send the HTTP response body (asynchronous)
        /// 
        /// HTTP response body
        /// 'true' if the HTTP response body was successfully sent, 'false' if the session is not connected
        public bool SendResponseBodyAsync(string body) { return SendAsync(body); }
        /// 
        /// Send the HTTP response body (asynchronous)
        /// 
        /// HTTP response body buffer
        /// 'true' if the HTTP response body was successfully sent, 'false' if the session is not connected
        public bool SendResponseBodyAsync(byte[] buffer) { return SendAsync(buffer); }
        /// 
        /// Send the HTTP response body (asynchronous)
        /// 
        /// HTTP response body buffer
        /// HTTP response body buffer offset
        /// HTTP response body size
        /// 'true' if the HTTP response body was successfully sent, 'false' if the session is not connected
        public bool SendResponseBodyAsync(byte[] buffer, long offset, long size) { return SendAsync(buffer, offset, size); }

        #endregion

        #region Session handlers

        protected override void OnReceived(byte[] buffer, long offset, long size)
        {
            // Receive HTTP request header
            if (Request.IsPendingHeader())
            {
                if (Request.ReceiveHeader(buffer, (int)offset, (int)size))
                    OnReceivedRequestHeader(Request);

                size = 0;
            }

            // Check for HTTP request error
            if (Request.IsErrorSet)
            {
                OnReceivedRequestError(Request, "Invalid HTTP request!");
                Request.Clear();
                Disconnect();
                return;
            }

            // Receive HTTP request body
            if (Request.ReceiveBody(buffer, (int)offset, (int)size))
            {
                OnReceivedRequestInternal(Request);
                Request.Clear();
                return;
            }

            // Check for HTTP request error
            if (Request.IsErrorSet)
            {
                OnReceivedRequestError(Request, "Invalid HTTP request!");
                Request.Clear();
                Disconnect();
                return;
            }
        }

        protected override void OnDisconnected()
        {
            // Receive HTTP request body
            if (Request.IsPendingBody())
            {
                OnReceivedRequestInternal(Request);
                Request.Clear();
                return;
            }
        }

        /// 
        /// Handle HTTP request header received notification
        /// 
        /// Notification is called when HTTP request header was received from the client.
        /// HTTP request
        protected virtual void OnReceivedRequestHeader(HttpRequest request) {}

        /// 
        /// Handle HTTP request received notification
        /// 
        /// Notification is called when HTTP request was received from the client.
        /// HTTP request
        protected virtual void OnReceivedRequest(HttpRequest request) {}

        /// 
        /// Handle HTTP cached request received notification
        /// 
        /// 
        /// Notification is called when HTTP request was received
        /// from the client and the corresponding cached content
        /// was found.
        ///
        /// Default behavior is just send cached response content
        /// to the client.
        /// 
        /// HTTP request
        /// Cached response content
        protected virtual void OnReceivedCachedRequest(HttpRequest request, byte[] content) { SendAsync(content); }

        /// 
        /// Handle HTTP request error notification
        /// 
        /// Notification is called when HTTP request error was received from the client.
        /// HTTP request
        /// HTTP request error
        protected virtual void OnReceivedRequestError(HttpRequest request, string error) {}

        #endregion

        private void OnReceivedRequestInternal(HttpRequest request)
        {
            // Try to get the cached response
            if (request.Method == "GET")
            {
                var index = request.Url.IndexOf('?');
                var response = Cache.Find((index < 0) ? request.Url : request.Url.Substring(0, index));
                if (response.Item1)
                {
                    // Process the request with the cached response
                    OnReceivedCachedRequest(request, response.Item2);
                    return;
                }
            }

            // Process the request
            OnReceivedRequest(request);
        }
    }
}

Web Proxy Viewer  |  New URL  |  Original Page