public AdkHttpRequestContext( AdkHttpConnection connection,
                               AdkHttpRequest request,
                               AdkHttpResponse response,
                               AdkHttpServer server )
 {
     fConnection = connection;
     fRequest = request;
     fResponse = response;
     fServer = server;
 }
예제 #2
0
 public AdkHttpRequestContext(AdkHttpConnection connection,
                              AdkHttpRequest request,
                              AdkHttpResponse response,
                              AdkHttpServer server)
 {
     fConnection = connection;
     fRequest    = request;
     fResponse   = response;
     fServer     = server;
 }
 public IAdkHttpHandler CreateHandler( AdkHttpRequest request )
 {
     if ( request.Method != "GET" ) {
         // TODO: We should be adding an "Allow" header as per RFC 2616
         throw new AdkHttpException
             ( AdkHttpStatusCode.ClientError_405_Method_Not_Allowed,
               request.Method + " Method Not Allowed" );
     }
     return new AdkHttpFileRequestHandler( this );
 }
 public IAdkHttpHandler CreateHandler(AdkHttpRequest request)
 {
     if (request.Method != "GET")
     {
         // TODO: We should be adding an "Allow" header as per RFC 2616
         throw new AdkHttpException
                   (AdkHttpStatusCode.ClientError_405_Method_Not_Allowed,
                   request.Method + " Method Not Allowed");
     }
     return(new AdkHttpFileRequestHandler(this));
 }
예제 #5
0
        internal IAdkHttpHandler GetHandlerForContext(AdkHttpRequest request)
        {
            IAdkHttpHandlerFactory factory = this.SearchForContextHandler(request.Url);

            if (factory != null)
            {
                return(factory.CreateHandler(request));
            }
            else
            {
                return(this.AnonymousHandler);
            }
        }
예제 #6
0
        public static void ProcessRequest( AdkSocketConnection socket,
                                           AdkHttpListener listener )
        {
            AdkHttpRequestContext context = socket.UserData as AdkHttpRequestContext;
            if ( context == null ) {
                AdkHttpConnection conn = new AdkHttpConnection( socket, listener );
                AdkHttpResponse response = new AdkHttpResponse( conn );
                AdkHttpRequest request = new AdkHttpRequest( conn );
                context = listener.Server.CreateContext( conn, request, response );
            }

            context.Connection.ProcessRequest( context, socket );
        }
예제 #7
0
        public static void ProcessRequest(AdkSocketConnection socket,
                                          AdkHttpListener listener)
        {
            AdkHttpRequestContext context = socket.UserData as AdkHttpRequestContext;

            if (context == null)
            {
                AdkHttpConnection conn     = new AdkHttpConnection(socket, listener);
                AdkHttpResponse   response = new AdkHttpResponse(conn);
                AdkHttpRequest    request  = new AdkHttpRequest(conn);
                context = listener.Server.CreateContext(conn, request, response);
            }

            context.Connection.ProcessRequest(context, socket);
        }
예제 #8
0
        private bool ShouldKeepAlive(AdkHttpRequest request)
        {
            if (!fListener.KeepAlivesEnabled)
            {
                return(false);
            }
            string connection = request.ConnectionHeader;

            if (request.Protocol == "HTTP/1.1")
            {
                // Keep Alive unless the Connection header is set to "close"
                return
                    (string.Compare(connection, "close", true, CultureInfo.InvariantCulture) != 0);
            }
            else
            {
                // Only keep alive if the Connection header is set to Keep-Alive
                return
                    (string.Compare(connection, "keep-alive", true, CultureInfo.InvariantCulture) ==
                     0);
            }
        }
예제 #9
0
        /// <summary>
        /// Copies the response buffer to the outgoing socket using an efficient asynchronous pattern.
        /// </summary>
        /// <param name="socket">The socket to write the result to</param>
        /// <param name="request">The source request</param>
        /// <param name="finishHandler">The delegate to call when the asynchronous operation is complete</param>
        /// <param name="asyncState">The state that should be returned to the async delegate</param>
        internal void AsyncFinishRequest(AdkSocketConnection socket,
                                         AdkHttpRequest request,
                                         bool keepAlive)
        {
            string statusDescription = ParseDescription(fStatus);

            if (this.Status != AdkHttpStatusCode.Success_200_OK)
            {
                this.Clear();
                if (ShouldReturnBody(this.Status))
                {
                    this.Write("<html><head><title>");
                    this.Write(statusDescription);
                    this.Write("</title></head><body><h1>HTTP ");
                    this.Write(((int)fStatus).ToString());
                    this.Write(" ");
                    this.Write(statusDescription);
                    this.Write("</h1><br>");
                    this.Write(this.AdditionalInfo);
                    this.Write("</body></html>");
                }
            }

            // Flush our underlying stream. We are done writing to the response and we need the correct length
            this.Flush();
            Stream       outputStream = socket.GetOutputDataStream();
            StreamWriter aWriter      = new StreamWriter(outputStream);

            {
                aWriter.Write(request.Protocol);
                aWriter.Write(" ");
                aWriter.Write((int)fStatus);
                aWriter.Write(" ");
                aWriter.Write(statusDescription);
                aWriter.Write("\r\n");
                aWriter.Write("Content-Length: " + fResponseStream.Length.ToString() + "\r\n");

                if (keepAlive)
                {
                    aWriter.Write("Connection: Keep-Alive\r\n");
                }
                else
                {
                    aWriter.Write("Connection: Close\r\n");
                }

                foreach (string aKey in fHeaders.Keys)
                {
                    aWriter.WriteLine("{0}: {1}", aKey, fHeaders[aKey]);
                }

                aWriter.Write(string.Empty + "\r\n");
                aWriter.Flush();
                GC.SuppressFinalize(aWriter);
            }
            if (socket.Connected && fResponseStream.Length > 0)
            {
                fWriter.Flush();
                GC.SuppressFinalize(fWriter);
                fResponseStream.Seek(0, SeekOrigin.Begin);
                Streams.CopyStream(fResponseStream, outputStream, 4096);
            }
        }
예제 #10
0
 public virtual AdkHttpRequestContext CreateContext(AdkHttpConnection connection,
                                                    AdkHttpRequest request,
                                                    AdkHttpResponse response)
 {
     return(new AdkHttpRequestContext(connection, request, response, this));
 }
예제 #11
0
        /// <summary>
        /// Copies the response buffer to the outgoing socket using an efficient asynchronous pattern.
        /// </summary>
        /// <param name="socket">The socket to write the result to</param>
        /// <param name="request">The source request</param>
        /// <param name="finishHandler">The delegate to call when the asynchronous operation is complete</param>
        /// <param name="asyncState">The state that should be returned to the async delegate</param>
        internal void AsyncFinishRequest( AdkSocketConnection socket,
                                          AdkHttpRequest request,
                                          bool keepAlive )
        {
            string statusDescription = ParseDescription( fStatus );

            if ( this.Status != AdkHttpStatusCode.Success_200_OK ) {
                this.Clear();
                if ( ShouldReturnBody( this.Status ) ) {
                    this.Write( "<html><head><title>" );
                    this.Write( statusDescription );
                    this.Write( "</title></head><body><h1>HTTP " );
                    this.Write( ((int) fStatus).ToString() );
                    this.Write( " " );
                    this.Write( statusDescription );
                    this.Write( "</h1><br>" );
                    this.Write( this.AdditionalInfo );
                    this.Write( "</body></html>" );
                }
            }

            // Flush our underlying stream. We are done writing to the response and we need the correct length
            this.Flush();
            Stream outputStream = socket.GetOutputDataStream();
            StreamWriter aWriter = new StreamWriter( outputStream );
            {
                aWriter.Write( request.Protocol );
                aWriter.Write( " " );
                aWriter.Write( (int) fStatus );
                aWriter.Write( " " );
                aWriter.Write( statusDescription );
                aWriter.Write( "\r\n" );
                aWriter.Write( "Content-Length: " + fResponseStream.Length.ToString() + "\r\n" );

                if ( keepAlive ) {
                    aWriter.Write( "Connection: Keep-Alive\r\n" );
                }
                else {
                    aWriter.Write( "Connection: Close\r\n" );
                }

                foreach ( string aKey in fHeaders.Keys ) {
                    aWriter.WriteLine( "{0}: {1}", aKey, fHeaders[aKey] );
                }

                aWriter.Write( string.Empty + "\r\n" );
                aWriter.Flush();
                GC.SuppressFinalize( aWriter );
            }
            if ( socket.Connected && fResponseStream.Length > 0 ) {
                fWriter.Flush();
                GC.SuppressFinalize( fWriter );
                fResponseStream.Seek( 0, SeekOrigin.Begin );
                Streams.CopyStream( fResponseStream, outputStream, 4096 );
            }
        }
예제 #12
0
        private void ProcessRequest(AdkHttpRequestContext context,
                                    AdkSocketConnection socket)
        {
            int aStart = Environment.TickCount;

            bool            keepAlive = true;
            AdkHttpRequest  request   = context.Request;
            AdkHttpResponse response  = context.Response;

            try {
                context.Request.Receive(socket);
                if (!context.Request.ReceiveComplete)
                {
                    socket.UserData = context;
                    return;
                }
                else
                {
                    IAdkHttpHandler handler = fListener.GetHandlerForContext(request);
                    handler.ProcessRequest(context);
                }
            }

            catch (AdkHttpException httpEx) {
                _logError(httpEx);
                response.Clear();
                response.Status = httpEx.HttpExceptionCode;
                if ((int)httpEx.HttpExceptionCode > 499)
                {
                    keepAlive = false;
                }
                response.AdditionalInfo = httpEx.GetType().FullName + " - " + httpEx.Message + " - " +
                                          httpEx.StackTrace;
            }
            catch (Exception ex) {
                keepAlive = false;
                _logError(ex);
                // TODO : Implement more verbose error output ( internalexceptions and such )
                response.Clear();
                response.Status         = AdkHttpStatusCode.ServerError_500_Internal_Server_Error;
                response.AdditionalInfo = ex.GetType().FullName + " - " + ex.Message + " - " +
                                          ex.StackTrace;
            }

            // Clear out the context state because we are done with this request and the socket
            // may remain open for the next request
            socket.UserData = null;

            if (socket.Connected)
            {
                if (keepAlive)
                {
                    keepAlive = ShouldKeepAlive(context.Request);
                }
                context.Response.Headers.Add("X-Powered-By", fListener.Server.Name);
                // Write the Response
                context.Response.AsyncFinishRequest(socket, context.Request, keepAlive);

                if ((Adk.Debug & AdkDebugFlags.Messaging_Detailed) != 0 &&
                    fListener.Server.Log.IsDebugEnabled)
                {
                    fListener.Server.Log.Info
                        (string.Format
                            ("Processed Request for {0}:{1} ( {2} ) in {3} milliseconds",
                            this.ClientEndPoint.Address, this.ClientEndPoint.Port,
                            context.Request.Path, (Environment.TickCount - aStart).ToString()));
                }
                if (!keepAlive)
                {
                    socket.Close();
                }
            }
        }
 IAdkHttpHandler IAdkHttpHandlerFactory.CreateHandler( AdkHttpRequest request )
 {
     return fHandler;
 }
예제 #14
0
 public virtual AdkHttpRequestContext CreateContext( AdkHttpConnection connection,
                                                     AdkHttpRequest request,
                                                     AdkHttpResponse response )
 {
     return new AdkHttpRequestContext( connection, request, response, this );
 }
예제 #15
0
 internal IAdkHttpHandler GetHandlerForContext( AdkHttpRequest request )
 {
     IAdkHttpHandlerFactory factory = this.SearchForContextHandler( request.Url );
     if ( factory != null ) {
         return factory.CreateHandler( request );
     }
     else {
         return this.AnonymousHandler;
     }
 }
예제 #16
0
 IAdkHttpHandler IAdkHttpHandlerFactory.CreateHandler(AdkHttpRequest request)
 {
     return(fHandler);
 }
예제 #17
0
 private bool ShouldKeepAlive( AdkHttpRequest request )
 {
     if ( !fListener.KeepAlivesEnabled ) {
         return false;
     }
     string connection = request.ConnectionHeader;
     if ( request.Protocol == "HTTP/1.1" ) {
         // Keep Alive unless the Connection header is set to "close"
         return
             string.Compare( connection, "close", true, CultureInfo.InvariantCulture ) != 0;
     }
     else {
         // Only keep alive if the Connection header is set to Keep-Alive
         return
             string.Compare( connection, "keep-alive", true, CultureInfo.InvariantCulture ) ==
             0;
     }
 }