void WriteOutput(StreamWriter writer, string response, bool persistentConnection, HttpContext context,
			 Action<StreamWriter> action)
        {
            bool binaryOutput = ms != null && ms.Length > 0;
            writer.WriteLine("HTTP/1.1 " + statusCode + " " + statusDescription);
            writer.WriteLine("Date: " + DateFormatter.FormatDateTimeGmt(DateTime.UtcNow));
            writer.WriteLine("Expires: Thu, 01 Jan 1970 00:00:01 GMT");
            writer.WriteLine("Server: " + Server.WebServerSoftwareName);
            writer.WriteLine("Cache-Control: no-cache, no-store, must-revalidate");
            writer.WriteLine("Pragma: no-cache");
            if (binaryOutput)
                writer.WriteLine("Content-Length: " + ms.Length);
            else
                writer.WriteLine("Content-Length: " + Encoding.UTF8.GetByteCount(response));
            writer.WriteLine("Connection: " + (persistentConnection ? "keep-alive" : "close"));
            writer.WriteLine("Content-Type: " + contentType + (contentType.Contains("text/") ? "; charset=" + encodingString : string.Empty));
            if (context != null)
            {
                if (context.Cookie.Count > 0)
                    foreach (HttpCookieEntry cookie in context.Cookie)
                        writer.WriteLine(string.Format("Set-Cookie: {0}", cookie));
                if (context.Session.Entries != null)
                    writer.WriteLine("Set-Cookie: " + SessionCookieKey + "=" + context.Session.Sid);
            }
            if (extraHeaders != null && extraHeaders.Count > 0)
                foreach (string extraHeader in extraHeaders)
                    writer.WriteLine(extraHeader);
            if (action != null) action(writer);
            writer.WriteLine();
            if (binaryOutput)
            {
                writer.Flush();
                ms.Position = 0;
                ms.WriteTo(writer.BaseStream);
            }
            else
            {
                writer.WriteLine(response);
                writer.WriteLine();
            }
            writer.Flush();
        }
 void Write500Error(StreamWriter writer, HttpContext context)
 {
     WriteError(writer, 500, "Internal Server Error", "<h1>Sorry, server is unavailable now, try later...</h1>", context, null);
 }
 void WriteError(StreamWriter writer, int code, string status, string html, HttpContext context, Action<StreamWriter> action)
 {
     try
     {
         ms.Close();
         ms = null;
         if (extraHeaders != null)
             extraHeaders.Clear();
         ContentType = "text/html";
         EncodingString = "UTF-8";
         StatusCode = code;
         StatusDescription = status;
         string content = string.Format("<html><head><title>{0} - {1}</title></head><body>{2}</body></html>",
             code, status, html);
         WriteOutput(writer, content, false, context, action);
     }
     catch (IOException) { }
     writer.Dispose();
 }
 void Write404Error(StreamWriter writer, HttpContext context)
 {
     WriteError(writer, 404, "Not found", "<h1>Resource not found</h1>", context, null);
 }
 void Write405Error(StreamWriter writer, HttpContext context)
 {
     WriteError(writer, 405, "Method Not Allowed", "<h1>Method not allowed</h1>", context, null);
 }
 void Write401Error(StreamWriter writer, HttpContext context)
 {
     WriteError(writer, 401, "Unauthorised", "<h1>Unauthorised</h1>", context,
         delegate
         {
             switch (ci.AuthenticationMethod)
             {
                 case AuthenticationMethod.Basic:
                     writer.WriteLine("WWW-Authenticate: Basic realm=\"" + GetHeaderValue("Host") + "\"");
                     break;
                 case AuthenticationMethod.Digest:
                     writer.WriteLine("WWW-Authenticate: " + ComposeDigestAuthenticationRequest());
                     break;
             }
         });
 }
 void Write400Error(StreamWriter writer, HttpContext context)
 {
     WriteError(writer, 400, "Bad Request", "<h1>Bad request</h1>", context, null);
 }
 void InitializeSession(HttpContext context, string id)
 {
     if (!SessionStore.ContainsKey(id))
         return;
     context.Session.Entries = SessionStore[id];
     context.Session.Sid = id;
     context.Session.Entries.UpdateLastAccess();
 }
 void GetCookies(HttpContext context)
 {
     HttpCookie cookies = context.Cookie;
     foreach (string headerLine in requestHeaders)
     {
         if (headerLine.StartsWith("Cookie: "))
         {
             string[] scookies = headerLine.Substring(8).Split(';');
             foreach (string scookie in scookies)
             {
                 string[] keyvaluepair = scookie.Split('=');
                 if (keyvaluepair[0].Trim() == SessionCookieKey)
                     InitializeSession(context, keyvaluepair[1]);
                 else
                     cookies[keyvaluepair[0].Trim()] = new HttpCookieEntry(
                         keyvaluepair.Length > 0 ? keyvaluepair[1].Trim() : string.Empty, string.Empty);
             }
         }
     }
 }
        public void Run()
        {
            bool persistentConnection;
            var reader = new StreamReader(stream);
            var writer = new StreamWriter(stream);
            do
            {
                var inbox = new StringBuilder();
                outputStream = new StringBuilder();
                ms = new MemoryStream();
                bool firstLine = true;
                try
                {
                    string line;
                    while (!string.IsNullOrEmpty((line = reader.ReadLine())))
                    {
                        if (firstLine)
                        {
                            ParseUrl(line);
                            firstLine = false;
                        }
                        inbox.AppendLine(line);
                    }
                }
                catch (IOException)
                {
                    writer.Dispose();
                    return;
                }
                catch (IndexOutOfRangeException)
                {
                    Write400Error(writer, null);
                    return;
                }

                requestHeaders = ParseHeaders(inbox.ToString());
                persistentConnection = IsPersistent();

                if (httpMethod != "GET" && httpMethod != "POST")
                {
                    Write405Error(writer, null);
                    return;
                }

                if (httpMethod == "POST")
                {
                    try
                    {
                        int inboxContentLength;
                        int.TryParse(GetHeaderValue("Content-Length"), out inboxContentLength);
                        if (inboxContentLength > 0)
                        {
                            if (GetHeaderValue("Content-Type").StartsWith("multipart/form-data"))
                            {
                                binaryRequest = new byte[inboxContentLength];
                                reader.BaseStream.Read(binaryRequest, 0, inboxContentLength);
                            }
                            else
                            {
                                var buffer = new char[inboxContentLength];
                                reader.Read(buffer, 0, inboxContentLength);
                                requestBody = new string(buffer);
                            }
                        }
                    }
                    catch (IOException)
                    {
                        writer.Dispose();
                        return;
                    }
                }

                if (string.IsNullOrEmpty(inbox.ToString()))
                {
                    Write400Error(writer, null);
                    return;
                }

                GetAuthorization();
                if (ci.AuthenticationMethod != AuthenticationMethod.None && string.IsNullOrEmpty(ci.LogonUser))
                {
                    Write401Error(writer, null);
                    return;
                }

                var context = new HttpContext(this);
                GetCookies(context);

                Type handlerType = Router.GetHandler(path);
                if (handlerType == null)
                {
                    Write404Error(writer, null);
                    return;
                }
                var page = HandlerActivator.Instance.GetHandler(handlerType);
                try
                {
                    contentType = "text/html";
                    encodingString = "utf-8";
                    page.ProcessRequest(new HttpApplicationRuntime(context));
                }
                catch (Exception)
                {
                    Write500Error(writer, null);
                    return;
                }

                string response = outputStream.ToString();

                WriteOutput(writer, response, persistentConnection, context, null);

            } while (persistentConnection);
            writer.Dispose();
        }