Example #1
0
        public void WriteToStream(Stream stream, HTTPHeaderData requestHeader, bool closingConnection = true)
        {
            Header.AddHeaderField("Connection", closingConnection ? "close" : "keep-alive")
            .AddHeaderField("Date", DateTime.Now.ToUniversalTime().ToString("r"))
            .AddHeaderField("Server", Program.GetVersionString())
            .AddHeaderField("ETag", ETag);

            if (!closingConnection)
            {
                Header.AddHeaderField("Keep-Alive", "timeout=" + (NetworkManager.ConnectionTTL / 1000) + ", max=100");
            }
            if (Body != null)
            {
                Header.AddHeaderField("Content-Length", Body.Length.ToString());
            }
            if (ContentType != null)
            {
                Header.AddHeaderField("Content-Type", ContentType);
            }
            if (lastModified != DateTime.MinValue)
            {
                Header.AddHeaderField("Last-Modified", lastModified.ToUniversalTime().ToString("r"));
            }

            byte[] finalBody = Body;

            if (requestHeader.HasHeaderField("Accept-Encoding"))
            {
                string[] encodings = requestHeader.GetHeaderField("Accept-Encoding").Split(',');

                for (int i = 0; i < encodings.Length; ++i)
                {
                    if (EncodingManager.CanEncode(encodings[i].Trim()) && EncodingManager.Encode(encodings[i].Trim(), finalBody, out finalBody))
                    {
                        Header.AddHeaderField("Content-Encoding", encodings[i]);
                        break;
                    }
                }
            }

            byte[] headerData = Encoding.ASCII.GetBytes(Header.ToString());
            stream.Write(headerData, 0, headerData.Length);
            stream.Write(finalBody, 0, finalBody.Length);
            stream.Flush();
        }
Example #2
0
        public void WriteToStream(Stream stream, HTTPHeaderData requestHeader, bool closingConnection = true)
        {
            Header.AddHeaderField("Connection", closingConnection ? "close" : "keep-alive")
                .AddHeaderField("Date", DateTime.Now.ToUniversalTime().ToString("r"))
                .AddHeaderField("Server", Program.GetVersionString())
                .AddHeaderField("ETag", ETag);

            if (!closingConnection) Header.AddHeaderField("Keep-Alive", "timeout=" + (NetworkManager.ConnectionTTL / 1000) + ", max=100");
            if (Body != null) Header.AddHeaderField("Content-Length", Body.Length.ToString());
            if (ContentType != null) Header.AddHeaderField("Content-Type", ContentType);
            if (lastModified != DateTime.MinValue) Header.AddHeaderField("Last-Modified", lastModified.ToUniversalTime().ToString("r"));

            byte[] finalBody = Body;

            if (requestHeader.HasHeaderField("Accept-Encoding"))
            {
                string[] encodings = requestHeader.GetHeaderField("Accept-Encoding").Split(',');

                for (int i = 0; i < encodings.Length; ++i)
                {
                    if (EncodingManager.CanEncode(encodings[i].Trim()) && EncodingManager.Encode(encodings[i].Trim(), finalBody, out finalBody))
                    {
                        Header.AddHeaderField("Content-Encoding", encodings[i]);
                        break;
                    }
                }
            }

            byte[] headerData = Encoding.ASCII.GetBytes(Header.ToString());
            stream.Write(headerData, 0, headerData.Length);
            stream.Write(finalBody, 0, finalBody.Length);
            stream.Flush();
        }
Example #3
0
        private static void HandleClient(TcpClient client)
        {
            NetworkStream stream = client.GetStream();

            bool         closingConnection = false;
            EHTTPVersion lastHTTPVersion   = EHTTPVersion.HTTP10;

            LogManager.Log(client, "Opening connection - Thread Started");

            Stopwatch timeSinceLastRequest = new Stopwatch();

            while (!closingConnection)
            {
                timeSinceLastRequest.Restart();

                while (client.Connected && client.Available == 0)
                {
                    if (timeSinceLastRequest.ElapsedMilliseconds > ConnectionTTL)
                    {
                        closingConnection = true;
                        break;
                    }
                }

                if (closingConnection || !client.Connected)
                {
                    break;
                }

                MemoryStream ms = new MemoryStream();
                while (client.Available > 0)
                {
                    byte[] pdata = new byte[client.Available];
                    stream.Read(pdata, 0, pdata.Length);
                    ms.Write(pdata, 0, pdata.Length);
                }

                byte[] requestData = ms.ToArray();

                //Hand data to plugins if necessary

                //HTTP parse
                string         request       = Encoding.ASCII.GetString(requestData, 0, requestData.Length);
                HTTPHeaderData requestHeader = new HTTPHeaderData(request);

                if (requestHeader.InvalidHeader)
                {
                    //Maybe it's SSL? Can't handle that
                    LogManager.Error(client, "Recieved SSL - Cannot Handle (Yet)");
                    HTTPResponse sslErrorResponse = SimpleResponseManager.PrepareSimpleResponse(EHTTPResponse.R501_NotImplemented, null);
                    sslErrorResponse.WriteToStream(stream, requestHeader, true);
                    break;
                }

                if (!requestHeader.HasHeaderField("Connection") || !requestHeader.GetHeaderField("Connection").Contains("keep-alive"))
                {
                    closingConnection = true;
                }

                lastHTTPVersion = requestHeader.HTTPVersion;

                //TODO: Plugin parse headers

                string requestLogStr = "Requested " + (requestHeader.HasHeaderField("Host") ? requestHeader.GetHeaderField("Host") : "") + requestHeader.GetRequestedResource();

                VirtualHost  vhost    = VirtualHostManager.GetVirtualHost(requestHeader.GetHeaderField("Host"));
                HTTPResponse response = null;
                if (vhost == null)
                {
                    response       = SimpleResponseManager.PrepareSimpleResponse(EHTTPResponse.R404_NotFound, requestHeader);
                    requestLogStr += " - 404";
                }
                else
                {
                    string resourceLoc = vhost.GetFinalResourceLocation(requestHeader);
                    string clientETag  = HTTPResponse.MakeETag(resourceLoc);
                    string IFNONEMATCH = requestHeader.GetHeaderField("If-None-Match");
                    bool   TEST        = clientETag == IFNONEMATCH;

                    if (clientETag != null && (
                            (requestHeader.HasHeaderField("If-Modified-Since") && vhost.HasBeenModifiedSince(resourceLoc, DateTime.Parse(requestHeader.GetHeaderField("If-Modified-Since")))) ||
                            (requestHeader.HasHeaderField("If-None-Match") && requestHeader.GetHeaderField("If-None-Match") == clientETag)
                            ))
                    {
                        response       = SimpleResponseManager.PrepareSimpleResponse(EHTTPResponse.R304_NotModified, requestHeader);
                        requestLogStr += " - 304";
                    }
                    else
                    {
                        response = vhost.GetResource(requestHeader);
                    }
                }

                if (response == null)
                {
                    response       = SimpleResponseManager.PrepareSimpleResponse(EHTTPResponse.R500_InternalServerError, requestHeader);
                    requestLogStr += " - 500";
                }

                LogManager.Log(client, requestLogStr);
                response.WriteToStream(stream, requestHeader, closingConnection);
            }

            LogManager.Log(client, "Closing connection");
            client.Close();
        }