From 5c593fa87c76c814d92cf85a2a33bd2b7a56e1e5 Mon Sep 17 00:00:00 2001 From: Scott Louvau Date: Mon, 29 Jan 2018 16:16:06 -0800 Subject: [PATCH] XForm: Refactor HttpService slightly to allow other hosts (sort of). --- .gitignore | 6 +++- XForm/XForm/BackgroundWebServer.cs | 44 +++++++++++++++++++++++++---- XForm/XForm/HttpService.cs | 20 ++++++------- XForm/XForm/IO/TabularFileWriter.cs | 2 +- XForm/XForm/XForm.csproj | 2 +- 5 files changed, 55 insertions(+), 19 deletions(-) diff --git a/.gitignore b/.gitignore index 29917215f..95fb87d0e 100644 --- a/.gitignore +++ b/.gitignore @@ -232,4 +232,8 @@ DiskCache/ # Exclude Arriba Database Configurations Arriba/Databases/* !Arriba/Databases/Louvau/ -!Arriba/Databases/Walkthrough/ \ No newline at end of file +!Arriba/Databases/Walkthrough/ + +# Exclude Arriba.HttpShim +Arriba.HttpShim/ +Arriba.HttpShim.sln \ No newline at end of file diff --git a/XForm/XForm/BackgroundWebServer.cs b/XForm/XForm/BackgroundWebServer.cs index 8bca686aa..daa452ca8 100644 --- a/XForm/XForm/BackgroundWebServer.cs +++ b/XForm/XForm/BackgroundWebServer.cs @@ -11,6 +11,40 @@ namespace XForm { + /// + /// IHttpResponse is a generic interface for interacting with System.Net.HttpListenerResponse and System.Net.Http.HttpResponseMessage uniformly. + /// + public interface IHttpResponse + { + HttpStatusCode StatusCode { get; set; } + string ContentType { get; set; } + Stream OutputStream { get; } + } + + public class HttpListenerResponseWrapper : IHttpResponse + { + private HttpListenerResponse Response; + + public HttpListenerResponseWrapper(HttpListenerResponse response) + { + this.Response = response; + } + + public HttpStatusCode StatusCode + { + get { return (HttpStatusCode)Response.StatusCode; } + set { Response.StatusCode = (int)value; } + } + + public string ContentType + { + get { return Response.ContentType; } + set { Response.ContentType = value; } + } + + public Stream OutputStream => Response.OutputStream; + } + /// /// BackgroundWebServer handles Http Requests for the XForm engine on a background thread. /// @@ -28,7 +62,7 @@ public class BackgroundWebServer : IDisposable private Thread ListenerThread { get; set; } private string DefaultDocument { get; set; } - private Dictionary> MethodsToServe { get; set; } + private Dictionary> MethodsToServe { get; set; } private Dictionary FilesToServe { get; set; } private string FolderToServe { get; set; } @@ -37,7 +71,7 @@ public BackgroundWebServer(string defaultDocument, string serveUnderRelativePath this.IsRunning = false; this.DefaultDocument = defaultDocument; - this.MethodsToServe = new Dictionary>(StringComparer.OrdinalIgnoreCase); + this.MethodsToServe = new Dictionary>(StringComparer.OrdinalIgnoreCase); this.FilesToServe = new Dictionary(StringComparer.OrdinalIgnoreCase); if (!String.IsNullOrEmpty(serveUnderRelativePath)) @@ -50,7 +84,7 @@ public BackgroundWebServer(string defaultDocument, string serveUnderRelativePath } } - public void AddResponder(string url, Action itemWrite) + public void AddResponder(string url, Action itemWrite) { this.MethodsToServe[url] = itemWrite; } @@ -212,14 +246,14 @@ private bool ReturnDefaultDocument(string requestUri, HttpListenerResponse respo private bool ReturnMethodItem(string requestUri, HttpListenerContext context, HttpListenerResponse response) { - Action writeMethod; + Action writeMethod; if (this.MethodsToServe.TryGetValue(requestUri, out writeMethod)) { response.AddHeader("Cache-Control", "no-cache, no-store"); response.ContentType = ContentType(requestUri); response.StatusCode = 200; - writeMethod(context, response); + writeMethod(context, new HttpListenerResponseWrapper(response)); response.Close(); return true; } diff --git a/XForm/XForm/HttpService.cs b/XForm/XForm/HttpService.cs index 1d7334c15..998619c0d 100644 --- a/XForm/XForm/HttpService.cs +++ b/XForm/XForm/HttpService.cs @@ -42,7 +42,7 @@ public void Run() } } - private void Suggest(HttpListenerContext context, HttpListenerResponse response) + private void Suggest(HttpListenerContext context, IHttpResponse response) { using (ITabularWriter writer = WriterForFormat("json", response)) { @@ -72,7 +72,7 @@ private void Suggest(HttpListenerContext context, HttpListenerResponse response) } } - private void Run(HttpListenerContext context, HttpListenerResponse response) + private void Run(HttpListenerContext context, IHttpResponse response) { try { @@ -93,7 +93,7 @@ private void Run(HttpListenerContext context, HttpListenerResponse response) } } - private void Download(HttpListenerContext context, HttpListenerResponse response) + private void Download(HttpListenerContext context, IHttpResponse response) { try { @@ -114,7 +114,7 @@ private void Download(HttpListenerContext context, HttpListenerResponse response } } - private void CountWithinTimeout(HttpListenerContext context, HttpListenerResponse response) + private void CountWithinTimeout(HttpListenerContext context, IHttpResponse response) { try { @@ -133,7 +133,7 @@ private void CountWithinTimeout(HttpListenerContext context, HttpListenerRespons } } - private void CountWithinTimeout(string query, TimeSpan timeout, DateTime asOfDate, HttpListenerResponse response) + private void CountWithinTimeout(string query, TimeSpan timeout, DateTime asOfDate, IHttpResponse response) { IXTable pipeline = null; @@ -173,7 +173,7 @@ private void CountWithinTimeout(string query, TimeSpan timeout, DateTime asOfDat } } - private void Run(string query, string format, int rowCountLimit, int colCountLimit, DateTime asOfDate, HttpListenerResponse response) + private void Run(string query, string format, int rowCountLimit, int colCountLimit, DateTime asOfDate, IHttpResponse response) { IXTable pipeline = null; @@ -214,7 +214,7 @@ private void Run(string query, string format, int rowCountLimit, int colCountLim } } - private void Save(HttpListenerContext context, HttpListenerResponse response) + private void Save(HttpListenerContext context, IHttpResponse response) { try { @@ -223,7 +223,7 @@ private void Save(HttpListenerContext context, HttpListenerResponse response) Require(context, "name")); // Success - response.StatusCode = 200; + response.StatusCode = HttpStatusCode.OK; } catch (Exception ex) { @@ -239,7 +239,7 @@ private void Save(string query, string tableName) _xDatabaseContext.Runner.Save(query, tableName); } - private ITabularWriter WriterForFormat(string format, HttpListenerResponse response) + private ITabularWriter WriterForFormat(string format, IHttpResponse response) { Stream toStream = response.OutputStream; toStream = new BufferedStream(toStream, 64 * 1024); @@ -249,10 +249,8 @@ private ITabularWriter WriterForFormat(string format, HttpListenerResponse respo case "json": return new JsonTabularWriter(toStream); case "csv": - response.AddHeader("Content-Disposition", "attachment; filename=\"Result.csv\""); return new CsvWriter(toStream); case "tsv": - response.AddHeader("Content-Disposition", "attachment; filename=\"Result.tsv\""); return new TsvWriter(toStream); default: throw new ArgumentException("fmt"); diff --git a/XForm/XForm/IO/TabularFileWriter.cs b/XForm/XForm/IO/TabularFileWriter.cs index 78504ee1a..d9846de2d 100644 --- a/XForm/XForm/IO/TabularFileWriter.cs +++ b/XForm/XForm/IO/TabularFileWriter.cs @@ -133,7 +133,7 @@ public void Dispose() _writer = null; // On Dispose, tell the StreamProvider to publish the table - _streamProvider.Publish(_outputFilePath); + if(_streamProvider != null) _streamProvider.Publish(_outputFilePath); } } } diff --git a/XForm/XForm/XForm.csproj b/XForm/XForm/XForm.csproj index e1bc5ccef..c924384e1 100644 --- a/XForm/XForm/XForm.csproj +++ b/XForm/XForm/XForm.csproj @@ -223,6 +223,6 @@ - $(SolutionDir)\Deploy.WebSite.cmd $(TargetDir) + $(ProjectDir)\..\Deploy.WebSite.cmd $(TargetDir) \ No newline at end of file