From b50f78e5da6f3fdfc59e577ca61b88771da7d211 Mon Sep 17 00:00:00 2001 From: LukePulverenti Luke Pulverenti luke pulverenti Date: Thu, 12 Jul 2012 02:55:27 -0400 Subject: Initial check-in --- .../Net/CollectionExtensions.cs | 14 +++++++ MediaBrowser.Controller/Net/HttpServer.cs | 47 +++++++++++++++++++++ MediaBrowser.Controller/Net/Request.cs | 18 ++++++++ MediaBrowser.Controller/Net/RequestContext.cs | 37 ++++++++++++++++ MediaBrowser.Controller/Net/Response.cs | 49 ++++++++++++++++++++++ MediaBrowser.Controller/Net/StreamExtensions.cs | 20 +++++++++ 6 files changed, 185 insertions(+) create mode 100644 MediaBrowser.Controller/Net/CollectionExtensions.cs create mode 100644 MediaBrowser.Controller/Net/HttpServer.cs create mode 100644 MediaBrowser.Controller/Net/Request.cs create mode 100644 MediaBrowser.Controller/Net/RequestContext.cs create mode 100644 MediaBrowser.Controller/Net/Response.cs create mode 100644 MediaBrowser.Controller/Net/StreamExtensions.cs (limited to 'MediaBrowser.Controller/Net') diff --git a/MediaBrowser.Controller/Net/CollectionExtensions.cs b/MediaBrowser.Controller/Net/CollectionExtensions.cs new file mode 100644 index 000000000..137fbe50b --- /dev/null +++ b/MediaBrowser.Controller/Net/CollectionExtensions.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Linq; + +namespace MediaBrowser.Controller.Net +{ + public static class CollectionExtensions + { + public static IDictionary> ToDictionary(this NameValueCollection source) + { + return source.AllKeys.ToDictionary>(key => key, source.GetValues); + } + } +} \ No newline at end of file diff --git a/MediaBrowser.Controller/Net/HttpServer.cs b/MediaBrowser.Controller/Net/HttpServer.cs new file mode 100644 index 000000000..bb014ca5a --- /dev/null +++ b/MediaBrowser.Controller/Net/HttpServer.cs @@ -0,0 +1,47 @@ +using System; +using System.Net; +using System.Reactive.Linq; + +namespace MediaBrowser.Controller.Net +{ + public class HttpServer : IObservable, IDisposable + { + private readonly HttpListener listener; + private readonly IObservable stream; + + public HttpServer(int port) + : this("http://+:" + port + "/") + { + } + + public HttpServer(string url) + { + listener = new HttpListener(); + listener.Prefixes.Add(url); + listener.Start(); + stream = ObservableHttpContext(); + } + + private IObservable ObservableHttpContext() + { + return Observable.Create(obs => + Observable.FromAsyncPattern(listener.BeginGetContext, + listener.EndGetContext)() + .Select(c => new RequestContext(c)) + .Subscribe(obs)) + .Repeat() + .Retry() + .Publish() + .RefCount(); + } + public void Dispose() + { + listener.Stop(); + } + + public IDisposable Subscribe(IObserver observer) + { + return stream.Subscribe(observer); + } + } +} \ No newline at end of file diff --git a/MediaBrowser.Controller/Net/Request.cs b/MediaBrowser.Controller/Net/Request.cs new file mode 100644 index 000000000..751c1e384 --- /dev/null +++ b/MediaBrowser.Controller/Net/Request.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace MediaBrowser.Controller.Net +{ + public class Request + { + public string HttpMethod { get; set; } + public IDictionary> Headers { get; set; } + public Stream InputStream { get; set; } + public string RawUrl { get; set; } + public int ContentLength + { + get { return int.Parse(Headers["Content-Length"].First()); } + } + } +} \ No newline at end of file diff --git a/MediaBrowser.Controller/Net/RequestContext.cs b/MediaBrowser.Controller/Net/RequestContext.cs new file mode 100644 index 000000000..531faab84 --- /dev/null +++ b/MediaBrowser.Controller/Net/RequestContext.cs @@ -0,0 +1,37 @@ +using System.Linq; +using System.Net; +using System.IO.Compression; + +namespace MediaBrowser.Controller.Net +{ + public class RequestContext + { + public HttpListenerRequest Request { get; private set; } + public HttpListenerResponse Response { get; private set; } + + public RequestContext(HttpListenerContext context) + { + Response = context.Response; + Request = context.Request; + } + + public void Respond(Response response) + { + Response.AddHeader("Access-Control-Allow-Origin", "*"); + + foreach (var header in response.Headers) + { + Response.AddHeader(header.Key, header.Value); + } + + Response.ContentType = response.ContentType; + Response.StatusCode = response.StatusCode; + + Response.SendChunked = true; + + GZipStream gzipStream = new GZipStream(Response.OutputStream, CompressionMode.Compress, false); + + response.WriteStream(Response.OutputStream); + } + } +} \ No newline at end of file diff --git a/MediaBrowser.Controller/Net/Response.cs b/MediaBrowser.Controller/Net/Response.cs new file mode 100644 index 000000000..a119198cb --- /dev/null +++ b/MediaBrowser.Controller/Net/Response.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace MediaBrowser.Controller.Net +{ + public class Response + { + protected RequestContext RequestContext { get; private set; } + + public Response(RequestContext ctx) + { + RequestContext = ctx; + + WriteStream = s => { }; + StatusCode = 200; + Headers = new Dictionary(); + CacheDuration = TimeSpan.FromTicks(0); + ContentType = "text/html"; + } + + public int StatusCode { get; set; } + public string ContentType { get; set; } + public IDictionary Headers { get; set; } + public TimeSpan CacheDuration { get; set; } + public Action WriteStream { get; set; } + } + + /*public class ByteResponse : Response + { + public ByteResponse(byte[] bytes) + { + WriteStream = async s => + { + await s.WriteAsync(bytes, 0, bytes.Length); + s.Close(); + }; + } + } + + public class StringResponse : ByteResponse + { + public StringResponse(string message) + : base(Encoding.UTF8.GetBytes(message)) + { + } + }*/ +} \ No newline at end of file diff --git a/MediaBrowser.Controller/Net/StreamExtensions.cs b/MediaBrowser.Controller/Net/StreamExtensions.cs new file mode 100644 index 000000000..451a43acb --- /dev/null +++ b/MediaBrowser.Controller/Net/StreamExtensions.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Reactive.Linq; + +namespace MediaBrowser.Controller.Net +{ + public static class StreamExtensions + { + public static IObservable ReadBytes(this Stream stream, int count) + { + var buffer = new byte[count]; + return Observable.FromAsyncPattern((cb, state) => stream.BeginRead(buffer, 0, count, cb, state), ar => + { + stream.EndRead(ar); + return buffer; + })(); + } + } +} \ No newline at end of file -- cgit v1.2.3