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(); }
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(); }
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(); }