diff --git a/README.md b/README.md index d213a60..1ce9b49 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,18 @@ A very lightweight & simple embedded http server for c# +## In this branch + +A few changes I'm making for [another project](https://github.com/sandrock/MarkDownBrowser/): + +* Allow multiple instances (on multiple TCP/IP ports) + * Bye bye static stuff +* Allow bit of IoC +* Convert the HttpHandler class to a IHttpHandler interface +* Create a HttpContext class to simplify IHttpHandler + +## License + Copyright (C) 2011 uhttpsharp project This library is free software; you can redistribute it and/or diff --git a/uhttpsharp-demo/AboutHandler.cs b/uhttpsharp-demo/AboutHandler.cs index 5bbc501..b7fb880 100644 --- a/uhttpsharp-demo/AboutHandler.cs +++ b/uhttpsharp-demo/AboutHandler.cs @@ -23,9 +23,9 @@ namespace uhttpsharpdemo [HttpRequestHandlerAttributes("about")] public class AboutHandler : HttpRequestHandler { - public override HttpResponse Handle(HttpRequest httpRequest) + public override HttpResponse Handle(HttpContext context) { - return HttpResponse.CreateWithMessage(HttpResponseCode.Ok, "Sample http-request-handler"); + return HttpResponse.CreateWithMessage(context, HttpResponseCode.Ok, "Sample http-request-handler"); } } } \ No newline at end of file diff --git a/uhttpsharp-demo/ConsoleTraceListener.cs b/uhttpsharp-demo/ConsoleTraceListener.cs new file mode 100644 index 0000000..a176edd --- /dev/null +++ b/uhttpsharp-demo/ConsoleTraceListener.cs @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2011 uhttpsharp project - http://github.com/raistlinthewiz/uhttpsharp + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +namespace uhttpsharpdemo +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Linq; + using System.Text; + + /// + /// Logs tracing event to the with coloration. + /// + public class ConsoleTraceListener : TraceListener + { + private readonly object syncRoot = new object(); + + public static ConsoleTraceListener Bind() + { + var listener = Trace.Listeners.OfType().FirstOrDefault(); + + if (listener == null) + { + Trace.Listeners.Add(listener = new ConsoleTraceListener()); + } + + return listener; + } + + public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message) + { + base.TraceEvent(eventCache, source, eventType, id, message); + + lock (this.syncRoot) + { + var foreg = Console.ForegroundColor; + var backg = Console.BackgroundColor; + + switch (eventType) + { + case TraceEventType.Critical: + Console.ForegroundColor = ConsoleColor.White; + Console.BackgroundColor = ConsoleColor.Red; + break; + + case TraceEventType.Error: + Console.ForegroundColor = ConsoleColor.Red; + Console.BackgroundColor = ConsoleColor.White; + break; + + case TraceEventType.Verbose: + Console.ForegroundColor = ConsoleColor.Gray; + Console.BackgroundColor = ConsoleColor.White; + break; + + case TraceEventType.Warning: + Console.ForegroundColor = ConsoleColor.Yellow; + Console.BackgroundColor = ConsoleColor.Black; + break; + + case TraceEventType.Information: + case TraceEventType.Resume: + case TraceEventType.Start: + case TraceEventType.Stop: + case TraceEventType.Suspend: + case TraceEventType.Transfer: + default: + Console.ForegroundColor = ConsoleColor.White; + Console.BackgroundColor = ConsoleColor.Black; + break; + } + + Console.Write(eventType.ToString().Substring(0, 4).ToUpperInvariant() + " "); + + Console.ForegroundColor = ConsoleColor.White; + Console.BackgroundColor = ConsoleColor.Black; + + Console.WriteLine(message); + + Console.ForegroundColor = foreg; + Console.BackgroundColor = backg; + } + } + + public override void Write(string message) + { + } + + public override void WriteLine(string message) + { + } + } +} diff --git a/uhttpsharp-demo/ErrorHandler.cs b/uhttpsharp-demo/ErrorHandler.cs index 92d38ea..5f83264 100644 --- a/uhttpsharp-demo/ErrorHandler.cs +++ b/uhttpsharp-demo/ErrorHandler.cs @@ -16,16 +16,16 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -using uhttpsharp; - namespace uhttpsharpdemo { + using uhttpsharp; + [HttpRequestHandlerAttributes("404")] public class ErrorHandler : HttpRequestHandler { - public override HttpResponse Handle(HttpRequest httpRequest) + public override HttpResponse Handle(HttpContext context) { - return new HttpResponse(HttpResponseCode.NotFound, "These are not the droids you are looking for."); + return new HttpResponse(context, HttpResponseCode.NotFound, "These are not the droids you are looking for."); } } } \ No newline at end of file diff --git a/uhttpsharp-demo/FileHandler.cs b/uhttpsharp-demo/FileHandler.cs index 3450fb8..cf2cf12 100644 --- a/uhttpsharp-demo/FileHandler.cs +++ b/uhttpsharp-demo/FileHandler.cs @@ -33,16 +33,26 @@ static FileHandler() { DefaultMimeType = "text/plain"; MimeTypes = new Dictionary - { - {".css", "text/css"}, - {".gif", "image/gif"}, - {".htm", "text/html"}, - {".html", "text/html"}, - {".jpg", "image/jpeg"}, - {".js", "application/javascript"}, - {".png", "image/png"}, - {".xml", "application/xml"}, - }; + { + {".css", "text/css"}, + {".gif", "image/gif"}, + {".htm", "text/html"}, + {".html", "text/html"}, + {".jpg", "image/jpeg"}, + {".js", "application/javascript"}, + {".png", "image/png"}, + {".xml", "application/xml"}, + }; + } + + public override HttpResponse Handle(HttpContext context) + { + var httpRoot = Path.GetFullPath(HttpRootDirectory ?? "."); + var requestPath = context.Request.Uri.AbsolutePath.TrimStart('/'); + var path = Path.GetFullPath(Path.Combine(httpRoot, requestPath)); + if (!File.Exists(path)) + return null; + return new HttpResponse(context, GetContentType(path), File.OpenRead(path)); } private string GetContentType(string path) @@ -52,14 +62,5 @@ private string GetContentType(string path) return MimeTypes[extension]; return DefaultMimeType; } - public override HttpResponse Handle(HttpRequest httpRequest) - { - var httpRoot = Path.GetFullPath(HttpRootDirectory ?? "."); - var requestPath = httpRequest.Uri.AbsolutePath.TrimStart('/'); - var path = Path.GetFullPath(Path.Combine(httpRoot, requestPath)); - if (!File.Exists(path)) - return null; - return new HttpResponse(GetContentType(path), File.OpenRead(path)); - } } } \ No newline at end of file diff --git a/uhttpsharp-demo/IndexHandler.cs b/uhttpsharp-demo/IndexHandler.cs index e6a31ed..e361758 100644 --- a/uhttpsharp-demo/IndexHandler.cs +++ b/uhttpsharp-demo/IndexHandler.cs @@ -23,9 +23,9 @@ namespace uhttpsharpdemo [HttpRequestHandlerAttributes("")] public class IndexHandler : HttpRequestHandler { - public override HttpResponse Handle(HttpRequest httpRequest) + public override HttpResponse Handle(HttpContext context) { - return new HttpResponse(HttpResponseCode.Ok, "Welcome to the Index. ☺"); + return new HttpResponse(context, HttpResponseCode.Ok, "Welcome to the Index. ☺"); } } } \ No newline at end of file diff --git a/uhttpsharp-demo/Program.cs b/uhttpsharp-demo/Program.cs index a70866d..051cd4f 100644 --- a/uhttpsharp-demo/Program.cs +++ b/uhttpsharp-demo/Program.cs @@ -19,6 +19,7 @@ using System; using System.Net.Sockets; using uhttpsharp; +using System.Net; namespace uhttpsharpdemo { @@ -26,12 +27,15 @@ internal static class Program { private static void Main() { + ConsoleTraceListener.Bind(); + + HttpServer server = null; for (var port = 8000; port <= 65535; ++port) { - HttpServer.Instance.Port = port; + server = new HttpServer(IPAddress.Loopback, port); try { - HttpServer.Instance.StartUp(); + server.Start(); } catch (SocketException) { @@ -39,7 +43,13 @@ private static void Main() } break; } + + Console.WriteLine("Hit return to exit"); Console.ReadLine(); + + Console.WriteLine("Stopping..."); + server.Dispose(); // TODO: this should be waiting for requests to end + Console.WriteLine("Stopped."); } } } \ No newline at end of file diff --git a/uhttpsharp-demo/uhttpsharp-demo.csproj b/uhttpsharp-demo/uhttpsharp-demo.csproj index 9c70de9..6cbdea9 100644 --- a/uhttpsharp-demo/uhttpsharp-demo.csproj +++ b/uhttpsharp-demo/uhttpsharp-demo.csproj @@ -47,6 +47,7 @@ Properties\AssemblyCommon.cs + diff --git a/uhttpsharp/HttpClient.cs b/uhttpsharp/HttpClient.cs index 37d59eb..049837e 100644 --- a/uhttpsharp/HttpClient.cs +++ b/uhttpsharp/HttpClient.cs @@ -16,27 +16,32 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -using System.IO; -using System.Net.Sockets; -using System.Threading; - namespace uhttpsharp { + using System.IO; + using System.Net.Sockets; + using System.Threading; + public sealed class HttpClient { private readonly TcpClient _client; private readonly Stream _inputStream; private readonly Stream _outputStream; private readonly HttpRouter _router; + private readonly HttpContext context; - public HttpClient(TcpClient client) + public HttpClient(HttpContext context, TcpClient client) { - _client = client; - _inputStream = new BufferedStream(_client.GetStream()); - _outputStream = _client.GetStream(); - _router = new HttpRouter(); + this._client = client; + this.context = context; + this._inputStream = new BufferedStream(this._client.GetStream()); + this._outputStream = this._client.GetStream(); + this._router = new HttpRouter(); // TODO: extract router instantiation - var clientThread = new Thread(Process) {IsBackground = true}; + var clientThread = new Thread(this.Process) + { + IsBackground = true, + }; clientThread.Start(); } @@ -54,22 +59,31 @@ private void Process() // Socket exceptions on read will be re-thrown as IOException by BufferedStream } } + private void ProcessInternal() { while (_client.Connected) { var request = new HttpRequest(_inputStream); - if (request.Valid) + request.Process(context); + this.context.Request = request; + if (request.IsValid) { - var response = _router.Route(request); + var response = _router.Route(context); + this.context.Response = response; if (response != null) { - response.WriteResponse(_outputStream); - if (response.CloseConnection) _client.Close(); + response.WriteResponse(context, _outputStream); + if (response.CloseConnection) + { + _client.Close(); + } } } else + { _client.Close(); + } } } } diff --git a/uhttpsharp/HttpContext.cs b/uhttpsharp/HttpContext.cs new file mode 100644 index 0000000..7444b55 --- /dev/null +++ b/uhttpsharp/HttpContext.cs @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2011 uhttpsharp project - http://github.com/raistlinthewiz/uhttpsharp + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +namespace uhttpsharp +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + + public class HttpContext + { + public HttpServer Server { get; set; } + + public HttpRequest Request { get; set; } + + public HttpResponse Response { get; set; } + } +} diff --git a/uhttpsharp/HttpRequest.cs b/uhttpsharp/HttpRequest.cs index a16c4e1..20491e2 100644 --- a/uhttpsharp/HttpRequest.cs +++ b/uhttpsharp/HttpRequest.cs @@ -19,12 +19,13 @@ using System; using System.Collections.Generic; using System.IO; +using System.Diagnostics; namespace uhttpsharp { public sealed class HttpRequest { - public bool Valid { get; private set; } + public bool IsValid { get; private set; } public Dictionary Headers { get; private set; } public HttpMethod HttpMethod { get; private set; } public string HttpProtocol { get; private set; } @@ -38,12 +39,12 @@ public HttpRequest(Stream stream) { Headers = new Dictionary(); _stream = stream; - Process(); + ////Process(); } - private void Process() + internal void Process(HttpContext context) { - Valid = false; + IsValid = false; // parse the http request var request = ReadLine(); @@ -53,7 +54,7 @@ private void Process() if (tokens.Length != 3) { - Console.WriteLine("httpserver: invalid http request."); + Trace.TraceError("httpserver: invalid http request."); return; } @@ -69,10 +70,10 @@ private void Process() HttpProtocol = tokens[2]; URL = tokens[1]; - Uri = new Uri("http://" + HttpServer.Instance.Address + "/" + URL.TrimStart('/')); + Uri = new Uri("http://" + context.Server.Address + "/" + URL.TrimStart('/')); Parameters = new HttpRequestParameters(URL); - Console.WriteLine(string.Format("[{0}:{1}] URL: {2}", HttpProtocol, HttpMethod, URL)); + Trace.TraceInformation(string.Format("[{0}:{1}] URL: {2}", HttpProtocol, HttpMethod, URL)); // get the headers string line; @@ -83,7 +84,7 @@ private void Process() Headers.Add(keys[0], keys[1]); } - Valid = true; + IsValid = true; } private string ReadLine() diff --git a/uhttpsharp/HttpRequestHandler.cs b/uhttpsharp/HttpRequestHandler.cs index f87c645..817f8c6 100644 --- a/uhttpsharp/HttpRequestHandler.cs +++ b/uhttpsharp/HttpRequestHandler.cs @@ -16,15 +16,15 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -using System; - namespace uhttpsharp { - public class HttpRequestHandler + using System; + + public class HttpRequestHandler : IHttpHandler { - public virtual HttpResponse Handle(HttpRequest httpRequest) + public virtual HttpResponse Handle(HttpContext context) { - throw new NotImplementedException(); + throw new NotSupportedException("This method must be overriden in a subclass."); } } @@ -35,7 +35,7 @@ public class HttpRequestHandlerAttributes : Attribute public HttpRequestHandlerAttributes(string functionName) { - Function = functionName; + this.Function = functionName; } } } \ No newline at end of file diff --git a/uhttpsharp/HttpResponse.cs b/uhttpsharp/HttpResponse.cs index 4317b1f..942ea68 100644 --- a/uhttpsharp/HttpResponse.cs +++ b/uhttpsharp/HttpResponse.cs @@ -42,15 +42,17 @@ public sealed class HttpResponse public HttpResponseCode Code { get; private set; } private Stream ContentStream { get; set; } - public HttpResponse(HttpResponseCode code, string content) - : this(code, "text/html; charset=utf-8", StringToStream(content)) + public HttpResponse(HttpContext context, HttpResponseCode code, string content, string contentType = "text/html; charset=utf-8") + : this(context, code, contentType, StringToStream(content)) { } - public HttpResponse(string contentType, Stream contentStream) - : this(HttpResponseCode.Ok, contentType, contentStream) + + public HttpResponse(HttpContext context, string contentType, Stream contentStream) + : this(context, HttpResponseCode.Ok, contentType, contentStream) { } - private HttpResponse(HttpResponseCode code, string contentType, Stream contentStream) + + private HttpResponse(HttpContext context, HttpResponseCode code, string contentType, Stream contentStream) { Protocol = "HTTP/1.1"; ContentType = contentType; @@ -60,14 +62,16 @@ private HttpResponse(HttpResponseCode code, string contentType, Stream contentSt ContentStream = contentStream; } - public static HttpResponse CreateWithMessage(HttpResponseCode code, string message, string body = "") + public static HttpResponse CreateWithMessage(HttpContext context, HttpResponseCode code, string message, string body = "") { return new HttpResponse( + context, code, string.Format( "{0}

{1}


{0}{2}", - HttpServer.Instance.Banner, message, body)); + context.Server.Banner, message, body)); } + private static Stream StringToStream(string content) { var stream = new MemoryStream(); @@ -76,12 +80,13 @@ private static Stream StringToStream(string content) writer.Flush(); return stream; } - public void WriteResponse(Stream stream) + + public void WriteResponse(HttpContext context, Stream stream) { - var writer = new StreamWriter(stream) {NewLine = "\r\n"}; - writer.WriteLine("{0} {1} {2}", Protocol, (int) Code, _responseTexts[(int) Code]); + var writer = new StreamWriter(stream) { NewLine = "\r\n" }; + writer.WriteLine("{0} {1} {2}", Protocol, (int)Code, _responseTexts[(int)Code]); writer.WriteLine("Date: {0}", DateTime.UtcNow.ToString("R")); - writer.WriteLine("Server: {0}", HttpServer.Instance.Banner); + writer.WriteLine("Server: {0}", context.Server.Banner); writer.WriteLine("Connection: {0}", CloseConnection ? "close" : "Keep-Alive"); writer.WriteLine("Content-Type: {0}", ContentType); writer.WriteLine("Content-Length: {0}", ContentStream.Length); diff --git a/uhttpsharp/HttpRouter.cs b/uhttpsharp/HttpRouter.cs index 27a5da0..a9710b7 100644 --- a/uhttpsharp/HttpRouter.cs +++ b/uhttpsharp/HttpRouter.cs @@ -19,61 +19,73 @@ using System; using System.Collections.Generic; using System.Reflection; +using System.Diagnostics; namespace uhttpsharp { - internal sealed class HttpRouter + public sealed class HttpRouter { - private readonly Dictionary _handlers = new Dictionary(); + private readonly Dictionary _handlers = new Dictionary(); - public HttpRouter() + internal HttpRouter() { RegisterHandlers(); } - private HttpResponse DefaultError() + private HttpResponse DefaultError(HttpContext context) { - return HttpResponse.CreateWithMessage(HttpResponseCode.NotFound, "Not Found"); + return HttpResponse.CreateWithMessage(context, HttpResponseCode.NotFound, "Not Found"); } - private HttpResponse DefaultIndex() + + private HttpResponse DefaultIndex(HttpContext context) { - return HttpResponse.CreateWithMessage(HttpResponseCode.Ok, "Welcome to uhttpsharp!"); + return HttpResponse.CreateWithMessage(context, HttpResponseCode.Ok, "Welcome to uhttpsharp!"); } - public HttpResponse Route(HttpRequest request) + + public HttpResponse Route(HttpContext context) { + var request = context.Request; var function = request.Parameters.Function; return - RouteToFunction(request, function) ?? - RouteToFunction(request, "*") ?? - (string.IsNullOrEmpty(function) ? (RouteToFunction(request, "") ?? DefaultIndex()) : null) ?? - RouteToFunction(request, "404") ?? - DefaultError(); + RouteToFunction(context, function) ?? + RouteToFunction(context, "*") ?? + (string.IsNullOrEmpty(function) ? (RouteToFunction(context, "") ?? DefaultIndex(context)) : null) ?? + RouteToFunction(context, "404") ?? + DefaultError(context); } - private HttpResponse RouteToFunction(HttpRequest request, string function) + + private HttpResponse RouteToFunction(HttpContext context, string function) { - HttpRequestHandler handler; + var request = context.Request; + IHttpHandler handler; + if (_handlers.TryGetValue(function, out handler)) - return handler.Handle(request); + { + context.Response = handler.Handle(context); + return context.Response; + } + return null; } + private void RegisterHandlers() { - foreach (var t in Assembly.GetEntryAssembly().GetTypes()) + foreach (var type in Assembly.GetEntryAssembly().GetTypes()) { - if (t.IsSubclassOf(typeof(HttpRequestHandler))) + if (type.IsSubclassOf(typeof(HttpRequestHandler))) { try { - var attributes = t.GetCustomAttributes(typeof(HttpRequestHandlerAttributes), true); + var attributes = type.GetCustomAttributes(typeof(HttpRequestHandlerAttributes), true); if (attributes.Length > 0) { - var handler = (HttpRequestHandler)Activator.CreateInstance(t); + var handler = (HttpRequestHandler)Activator.CreateInstance(type); _handlers.Add(((HttpRequestHandlerAttributes)attributes[0]).Function, handler); } } - catch (Exception e) + catch (Exception ex) { - Console.WriteLine(string.Format("Exception during activating the IHttpRequestHandler: {0} - {1}", t, e)); + Trace.TraceError(string.Format("Exception during activating the IHttpRequestHandler: {0} - {1}", type, ex)); } } } diff --git a/uhttpsharp/HttpServer.cs b/uhttpsharp/HttpServer.cs index ee3ae38..4d60b6e 100644 --- a/uhttpsharp/HttpServer.cs +++ b/uhttpsharp/HttpServer.cs @@ -16,54 +16,117 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -using System; -using System.Net; -using System.Net.Sockets; -using System.Reflection; -using System.Threading; - namespace uhttpsharp { - public sealed class HttpServer - { - public static readonly HttpServer Instance = new HttpServer(); + using System; + using System.Net; + using System.Net.Sockets; + using System.Reflection; + using System.Threading; + using System.Diagnostics; - public int Port = 80; + public class HttpServer : IDisposable + { public string Banner = string.Empty; + private bool isDisposed; + private TcpListener listener; + private bool isActive; + private Thread serverThread; + + public HttpServer(IPAddress address, int port) + { + this.Address = address; + this.Port = port; + this.Banner = string.Format("uhttpsharp {0}", Assembly.GetExecutingAssembly().GetName().Version); + this.Router = new HttpRouter(); + } - private TcpListener _listener; - private bool _isActive; + public IPAddress Address { get; set; } - public string Address + public int Port { get; set; } + + public HttpRouter Router { get; private set; } + + public void Start() { - get { return string.Format("{0}:{1}", IPAddress.Loopback, Port); } + if (this.isActive) + return; + this.listener = new TcpListener(IPAddress.Loopback, Port); + this.listener.Start(); + this.serverThread = new Thread(Listen) + { + IsBackground = true, + }; + this.serverThread.Start(); } - private HttpServer() + public void Dispose() { - Banner = string.Format("uhttpsharp {0}", Assembly.GetExecutingAssembly().GetName().Version); + this.Dispose(true, TimeSpan.FromSeconds(60D)); + GC.SuppressFinalize(this); } - public void StartUp() + public void Dispose(TimeSpan timeout) { - if (_isActive) - return; - _listener = new TcpListener(IPAddress.Loopback, Port); - _listener.Start(); - var serverThread = new Thread(Listen) {IsBackground = true}; - serverThread.Start(); + this.Dispose(true, timeout); + GC.SuppressFinalize(this); + } + + public override string ToString() + { + return this.GetType().Name + " " + this.Address.ToString() + ":" + this.Port.ToString(); + } + + protected virtual void Dispose(bool disposing, TimeSpan timeout) + { + if (!this.isDisposed) + { + if (disposing) + { + this.isActive = false; + + if (this.listener != null) + { + this.listener.Stop(); + this.listener = null; + } + + if (this.serverThread != null) + { + this.serverThread.Join(timeout); + this.serverThread = null; + } + } + + this.isDisposed = true; + } } private void Listen() { - _isActive = true; + this.isActive = true; - Console.WriteLine(string.Format("Embedded httpserver started.. [{0}:{1}]", IPAddress.Loopback, Port)); + Trace.TraceInformation(this.ToString() + " is now listenning."); - while (_isActive) + while (this.isActive) { - new HttpClient(_listener.AcceptTcpClient()); + var context = new HttpContext + { + Server = this, + }; + try + { + var client = listener.AcceptTcpClient(); + new HttpClient(context, client); + } + catch (SocketException ex) + { + // "A blocking operation was interrupted by a call to WSACancelBlockingCall" + // occurs during shutdown + } } + + Trace.TraceInformation(this.ToString() + " is not listenning anymore."); } } } \ No newline at end of file diff --git a/uhttpsharp/IHttpHandler.cs b/uhttpsharp/IHttpHandler.cs new file mode 100644 index 0000000..c7deb74 --- /dev/null +++ b/uhttpsharp/IHttpHandler.cs @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2011 uhttpsharp project - http://github.com/raistlinthewiz/uhttpsharp + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +namespace uhttpsharp +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + + public interface IHttpHandler + { + HttpResponse Handle(HttpContext context); + } +} diff --git a/uhttpsharp/uhttpsharp.csproj b/uhttpsharp/uhttpsharp.csproj index 0de8e1b..9aaba02 100644 --- a/uhttpsharp/uhttpsharp.csproj +++ b/uhttpsharp/uhttpsharp.csproj @@ -29,6 +29,7 @@ TRACE prompt 4 + bin\Release\uhttpsharp.xml @@ -44,11 +45,13 @@ Properties\AssemblyCommon.cs
+ +