public override Boolean ConnectionEstablished() { //NetworkStream dataStream = null; using (var _DataStream = GetStream(TcpClientConnection)) { try { #region Wait until new StreamData is available (returns true), timeout or server shutdown if (!WaitForStreamDataAvailable()) { return(false); } #endregion #region Get header & body HTTPHeader requestHeader = null; Byte[] requestBody = null; Byte[] responseBodyBytes = new byte[0]; Byte[] responseHeaderBytes = null; HTTPContext _HTTPWebContext = null; Exception _LastException = null; var _HeaderErrors = GetHeaderAndBody(_DataStream, out requestHeader, out requestBody); #if DEBUG if (requestHeader.Destination == null) { return(false); } if (requestHeader.Headers.AllKeys.Contains("SENDER")) { Debug.WriteLine(string.Format("{0} Retrieved a request to resource {1} from {2}", DateTime.Now.TimeOfDay, requestHeader.Destination, requestHeader.Headers["SENDER"]), "HttpHandler"); } else { Debug.WriteLine(string.Format("{0} Retrieved a request to resource {1}", DateTime.Now.TimeOfDay, requestHeader.Destination), "HttpHandler"); } #endif if (requestHeader == null || requestBody == null) { return(false); } #endregion #region Trace //System.Diagnostics.Trace.WriteLine("-------------------request started-------------------"); //System.Diagnostics.Trace.Indent(); //System.Diagnostics.Trace.WriteLine("requestHeader:"); //System.Diagnostics.Trace.Indent(); //System.Diagnostics.Trace.WriteLine(requestHeader.PlainHeader); //System.Diagnostics.Trace.Unindent(); //System.Diagnostics.Trace.WriteLine("requestBody:"); //System.Diagnostics.Trace.Indent(); //System.Diagnostics.Trace.WriteLine(Encoding.UTF8.GetString(requestBody)); //System.Diagnostics.Trace.Unindent(); //System.Diagnostics.Trace.Unindent(); //System.Diagnostics.Trace.WriteLine("-----------------------------------------------------"); #endregion #region Check if a error occurred during header processing... HTTPHeader responseHeader = null; if (requestHeader.HttpStatusCode != HTTPStatusCodes.OK) { responseHeader = new HTTPHeader() { HttpStatusCode = requestHeader.HttpStatusCode, }; _HTTPWebContext = new HTTPContext(requestHeader, requestBody, responseHeader, _DataStream); HTTPServer.HTTPContext = _HTTPWebContext; } #endregion #region ... or process request and create a response header else { responseHeader = new HTTPHeader() { HttpStatusCode = HTTPStatusCodes.OK, ContentType = new ContentType("text/html") }; #region Create and set HTTPContext _HTTPWebContext = new HTTPContext(requestHeader, requestBody, responseHeader, _DataStream); HTTPServer.HTTPContext = _HTTPWebContext; #endregion // Process request try { // Get Callback var parsedCallback = _Parser.GetCallback(_HTTPWebContext.RequestHeader.RawUrl, _HTTPWebContext.RequestHeader.HttpMethodString); #region Check callback... if (parsedCallback == null || parsedCallback.Item1 == null) { Debug.WriteLine("Could not find a valid handler for url: " + _HTTPWebContext.RequestHeader.RawUrl); responseBodyBytes = Encoding.UTF8.GetBytes("Could not find a valid handler for url: " + _HTTPWebContext.RequestHeader.RawUrl); _HTTPWebContext.ResponseHeader = new HTTPHeader() { HttpStatusCode = HTTPStatusCodes.NotFound, ContentType = new ContentType("text/plain"), ContentLength = responseBodyBytes.ULongLength() }; responseHeaderBytes = _HTTPWebContext.ResponseHeader.ToBytes(); } #endregion #region ...check authentication and invoke method callback else { var authenticated = false; #region Check HTTPSecurity // the server switched on authentication AND the method does not explicit allow not authentication if (HTTPSecurity != null && !(parsedCallback.Item1.NeedsExplicitAuthentication.HasValue && !parsedCallback.Item1.NeedsExplicitAuthentication.Value)) { #region Authentication //in this case the client is already been authenticated by his certificate if (HTTPSecurity.CredentialType == HttpClientCredentialType.Certificate) { authenticated = true; } if (HTTPSecurity.CredentialType == HttpClientCredentialType.Basic) { if (requestHeader.Authorization == null) { #region No authorisation info was sent responseHeader = GetAuthenticationRequiredHeader(); responseHeaderBytes = responseHeader.ToBytes(); #endregion } else if (!Authorize(_HTTPWebContext.RequestHeader.Authorization)) { #region Authorization failed responseHeader = GetAuthenticationRequiredHeader(); responseHeaderBytes = responseHeader.ToBytes(); #endregion } else { authenticated = true; } } else { if (HTTPSecurity.CredentialType != HttpClientCredentialType.Certificate) { responseBodyBytes = Encoding.UTF8.GetBytes("Authentication other than Basic or Certificate currently not provided"); responseHeader = new HTTPHeader() { HttpStatusCode = HTTPStatusCodes.InternalServerError, ContentLength = responseBodyBytes.ULongLength() }; responseHeaderBytes = responseHeader.ToBytes(); Debug.WriteLine("------------------------------------------------------------"); Debug.WriteLine("!!!Authentication other than Basic or Certificate currently not provided!!!"); } } #endregion } else if (parsedCallback.Item1.NeedsExplicitAuthentication.HasValue && parsedCallback.Item1.NeedsExplicitAuthentication.Value) { #region The server does not have authentication but the Interface explicitly needs authentication responseBodyBytes = Encoding.UTF8.GetBytes("Authentication not provided from server"); responseHeader = new HTTPHeader() { HttpStatusCode = HTTPStatusCodes.InternalServerError, ContentLength = responseBodyBytes.ULongLength() }; responseHeaderBytes = responseHeader.ToBytes(); #endregion Debug.WriteLine("---------------------------------------------"); Debug.WriteLine("!!!Authentication not provided from server!!!"); } else { authenticated = true; } #endregion if (authenticated) { InvokeURL(parsedCallback, _HTTPWebContext, ref responseHeaderBytes, ref responseBodyBytes); } } #endregion } #region Handle exceptions occurred during request processing catch (Exception ex) { Debug.WriteLine(ex.ToString()); responseBodyBytes = Encoding.UTF8.GetBytes(ex.ToString()); responseHeader = new HTTPHeader() { HttpStatusCode = HTTPStatusCodes.InternalServerError, ContentType = new ContentType("text/plain"), ContentLength = responseBodyBytes.ULongLength() }; responseHeaderBytes = responseHeader.ToBytes(); ExceptionThrowed(this, ex); _LastException = ex; } #endregion } #endregion #region Handle errors... if ((Int32)responseHeader.HttpStatusCode >= 400 && (Int32)responseHeader.HttpStatusCode <= 599) { #region Handle custom error pages... var _CustomErrorPage = _Instance as ICustomErrorPageHandler; if (_CustomErrorPage != null) { responseBodyBytes = _CustomErrorPage.GetCustomErrorPage(responseHeader.HttpStatusCode, _HTTPWebContext.RequestHeader, _HTTPWebContext.RequestBody, _LastException); responseHeader.ContentLength = responseBodyBytes.ULongLength(); responseHeaderBytes = responseHeader.ToBytes(); } #endregion #region ...or generate a generic errorpage! else { var _StringBuilder = new StringBuilder(); _StringBuilder.AppendLine("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">"); _StringBuilder.AppendLine("<html>"); _StringBuilder.AppendLine(" <head>"); _StringBuilder.Append(" <title>").Append((Int32)responseHeader.HttpStatusCode).Append(" ").Append(HTTPHeader.HttpStatusCodeToSimpleString(responseHeader.HttpStatusCode)).AppendLine("</title>"); _StringBuilder.AppendLine(" </head>"); _StringBuilder.AppendLine(" <body>"); _StringBuilder.Append(" <h1>Error ").Append((Int32)responseHeader.HttpStatusCode).Append(" - ").Append(HTTPHeader.HttpStatusCodeToSimpleString(responseHeader.HttpStatusCode)).AppendLine("</h1>"); _StringBuilder.AppendLine(" Your client sent a request which led to an error!<br />"); _StringBuilder.AppendLine(" </body>"); _StringBuilder.AppendLine("</html>"); _StringBuilder.AppendLine(); responseBodyBytes = Encoding.UTF8.GetBytes(_StringBuilder.ToString()); responseHeader.ContentLength = responseBodyBytes.ULongLength(); responseHeaderBytes = responseHeader.ToBytes(); } #endregion } #endregion #region Send Response // Remove HttpWebContext HTTPServer.HTTPContext = null; if (!_HTTPWebContext.StreamDataAvailable) { // The user did not write into the stream itself - we will add header and the invocation result var BytesToSend = new Byte[responseBodyBytes.Length + responseHeaderBytes.Length]; Array.Copy(responseHeaderBytes, BytesToSend, responseHeaderBytes.Length); Array.Copy(responseBodyBytes, 0, BytesToSend, responseHeaderBytes.Length, responseBodyBytes.Length); _DataStream.Write(BytesToSend, 0, BytesToSend.Length); } #endregion } finally { if (_DataStream != null) { _DataStream.Close(); } if (TcpClientConnection != null) { TcpClientConnection.Close(); } } } #region Trace //System.Diagnostics.Trace.WriteLine("-------------------response started-------------------"); //System.Diagnostics.Trace.Indent(); //System.Diagnostics.Trace.WriteLine("responseHeader:"); //System.Diagnostics.Trace.Indent(); //System.Diagnostics.Trace.WriteLine(responseHeader.ToString()); //System.Diagnostics.Trace.Unindent(); //System.Diagnostics.Trace.WriteLine("responseBody:"); //System.Diagnostics.Trace.Indent(); //System.Diagnostics.Trace.WriteLine(Encoding.UTF8.GetString(responseBodyBytes)); //System.Diagnostics.Trace.Unindent(); //System.Diagnostics.Trace.Unindent(); //System.Diagnostics.Trace.WriteLine("-----------------------------------------------------"); #endregion return(true); }