Skip to content

Commit

Permalink
Fixed #80
Browse files Browse the repository at this point in the history
  • Loading branch information
Scott Offen committed Jul 22, 2016
1 parent 7e33180 commit 9a99098
Show file tree
Hide file tree
Showing 11 changed files with 189 additions and 164 deletions.
16 changes: 8 additions & 8 deletions src/Grapevine.Local/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ public static void Main(string[] args)
{
using (var server = new RestServer())
{
server.PublicFolder = @"C:\source\gv-gh-pages";
server.PublicFolderPrefix = "/Grapevine";
server.PublicFolder.FolderPath = @"C:\source\gv-gh-pages";
server.PublicFolder.Prefix = "/Grapevine";

server.Router.Register(context =>
{
Expand All @@ -41,7 +41,7 @@ public static void UnitOfWork()

server.Router.Register(Route.For(HttpMethod.GET).To("/special/api").Use(context =>
{
context.Response.ContentType = ContentType.TEXT.ToValue();
context.Response.ContentType = ContentType.TEXT;
context.Response.SendResponse(context.Properties.UserName);
return context;
}));
Expand All @@ -50,7 +50,7 @@ public static void UnitOfWork()
{
var response = new StringBuilder();
context.Response.ContentType = ContentType.TEXT.ToValue();
context.Response.ContentType = ContentType.TEXT;
response.Append($"Method : {context.Request.HttpMethod}\n");
response.Append($"PathInfo : {context.Request.PathInfo}\n");
Expand Down Expand Up @@ -121,13 +121,13 @@ public static void RunRestCluster()
r.Register(Route.For(HttpMethod.GET).Use(context =>
{
context.Response.StatusCode = (int)Util.HttpStatusCode.ImATeapot;
context.Response.StatusCode = Util.HttpStatusCode.ImATeapot;
return context;
}));
r.Register(Route.For(HttpMethod.POST).Use(context =>
{
context.Response.StatusCode = (int)Util.HttpStatusCode.EnhanceYourCalm;
context.Response.StatusCode = Util.HttpStatusCode.EnhanceYourCalm;
return context;
}));
Expand Down Expand Up @@ -187,13 +187,13 @@ public static void RunRestCluster()
r.Register(Route.For(HttpMethod.GET).Use(context =>
{
context.Response.StatusCode = (int)Util.HttpStatusCode.ImATeapot;
context.Response.StatusCode = Util.HttpStatusCode.ImATeapot;
return context;
}));
r.Register(Route.For(HttpMethod.POST).Use(context =>
{
context.Response.StatusCode = (int)Util.HttpStatusCode.EnhanceYourCalm;
context.Response.StatusCode = Util.HttpStatusCode.EnhanceYourCalm;
return context;
}));
Expand Down
2 changes: 1 addition & 1 deletion src/Grapevine.Test/Server/PublicFolderTester.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public void default_index_can_be_changed()
public void default_folder_is_webroot()
{
var root = new PublicFolder();
root.FolderPath.EndsWith("webroot").ShouldBe(true);
root.FolderPath.EndsWith("public").ShouldBe(true);
}

[Fact]
Expand Down
13 changes: 10 additions & 3 deletions src/Grapevine.Test/Server/ServerOptionsTester.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using Grapevine.Server;
using Grapevine.Util;
using Shouldly;
using Xunit;

Expand All @@ -12,14 +13,20 @@ public void generic_configuration()
{
var options = new ServerOptions();

options.Logger.ShouldNotBeNull();
options.Logger.ShouldBeOfType<NullLogger>();

options.Router.ShouldNotBeNull();
options.Router.ShouldBeOfType<Router>();

options.PublicFolder.ShouldNotBeNull();
options.PublicFolder.ShouldBeOfType<PublicFolder>();

options.Protocol.ShouldBe("http");
options.Host.ShouldBe("localhost");
options.Port.ShouldBe("1234");

options.PublicFolder.EndsWith("public").ShouldBe(true);
options.DefaultPage.ShouldBe("index.html");
options.Connections.ShouldBe(50);
options.EnableThrowingExceptions.ShouldBeFalse();

options.OnAfterStart.ShouldBeNull();
options.OnBeforeStart.ShouldBeNull();
Expand Down
22 changes: 18 additions & 4 deletions src/Grapevine/Server/HttpRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Text;
using Grapevine.Util;
using System.IO;
using System.Linq;

namespace Grapevine.Server
{
Expand Down Expand Up @@ -36,7 +37,7 @@ public interface IHttpRequest
/// <summary>
/// Gets the MIME type of the body data included in the request
/// </summary>
string ContentType { get; }
ContentType ContentType { get; }

/// <summary>
/// Gets the cookies sent with the request
Expand Down Expand Up @@ -200,7 +201,7 @@ public class HttpRequest : IHttpRequest
private string _payload;

/// <summary>
/// The underlying HttpListenerResponse for this instance
/// The underlying HttpListenerRequest for this instance
/// </summary>
protected internal readonly HttpListenerRequest Request;

Expand All @@ -227,7 +228,10 @@ protected internal HttpRequest(HttpListenerRequest request)

public long ContentLength64 => Request.ContentLength64;

public string ContentType => Request.ContentType;
public ContentType ContentType
{
get { return Enum.GetValues(typeof(ContentType)).Cast<ContentType>().First(t => t.ToValue().Equals(Request.ContentType)); }
}

public CookieCollection Cookies => Request.Cookies;

Expand Down Expand Up @@ -323,8 +327,18 @@ internal AdvancedHttpRequest(HttpListenerRequest request)
}

/// <summary>
/// Gets a stream that contains the body data sent by the client; use Payload instead
/// Gets a stream that contains the body data sent by the client; recommended to use Payload property instead
/// </summary>
public Stream InputStream => _request.InputStream;

/// <summary>
/// Get the original ContentType string from the request
/// </summary>
public string ContentType => _request.ContentType;

/// <summary>
/// Gets the original HttpMethod string from the request
/// </summary>
public string HttpMethod => _request.HttpMethod;
}
}
50 changes: 30 additions & 20 deletions src/Grapevine/Server/HttpResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public interface IHttpResponse
/// <summary>
/// Gets or sets the MIME type of the content returned
/// </summary>
string ContentType { get; set; }
ContentType ContentType { get; set; }

/// <summary>
/// Gets or sets the collection of cookies returned with the response
Expand Down Expand Up @@ -68,7 +68,7 @@ public interface IHttpResponse
/// <summary>
/// Gets or sets the HTTP status code to be returned to the client
/// </summary>
int StatusCode { get; set; }
HttpStatusCode StatusCode { get; set; }

/// <summary>
/// Gets or sets a text description of the HTTP status code returned to the client
Expand Down Expand Up @@ -133,7 +133,7 @@ public interface IHttpResponse
/// <param name="type"></param>
/// <param name="filename"></param>
/// <param name="asAttachment"></param>
void SendResponse(FileStream stream, ContentType type, string filename, bool asAttachment);
void SendResponse(FileStream stream, ContentType type, string filename, bool asAttachment = false);

/// <summary>
/// Sends the specified status code and exception as a response to the client and closes the response
Expand Down Expand Up @@ -182,6 +182,7 @@ internal HttpResponse(HttpListenerResponse response, NameValueCollection request
{
Response = response;
RequestHeaders = requestHeaders;

ResponseSent = false;
Advanced = new AdvancedHttpResponse(this);
}
Expand All @@ -198,10 +199,10 @@ public long ContentLength64
set { Response.ContentLength64 = value; }
}

public string ContentType
public ContentType ContentType
{
get { return Response.ContentType; }
set { Response.ContentType = value; }
get { return Enum.GetValues(typeof (ContentType)).Cast<ContentType>().First(t => t.ToValue().Equals(Response.ContentType)); }
set { Response.ContentType = value.ToValue(); }
}

public CookieCollection Cookies
Expand Down Expand Up @@ -242,10 +243,14 @@ public bool SendChunked
set { Response.SendChunked = value; }
}

public int StatusCode
public HttpStatusCode StatusCode
{
get { return Response.StatusCode; }
set { Response.StatusCode = value; }
get { return (HttpStatusCode)Response.StatusCode; }
set
{
Response.StatusCode = (int)value;
StatusDescription = value.ConvertToString();
}
}

public string StatusDescription
Expand Down Expand Up @@ -294,22 +299,21 @@ public void SendResponse(string response, bool isFilePath = false)
}
else
{
SendResponse(response, Encoding.UTF8);
SendResponse(response, Response.ContentEncoding);
}
}

public void SendResponse(string response, Encoding encoding)
{
Response.ContentEncoding = encoding;
if (string.IsNullOrWhiteSpace(ContentType)) Response.ContentType = Util.ContentType.TEXT.ToValue();
FlushResponse(encoding.GetBytes(response));
}

public void SendResponse(FileStream stream, ContentType type, string filename, bool asAttachment = false)
{
ContentType = type;
if (!Response.Headers.AllKeys.Contains("Expires")) Response.AddHeader("Expires", DateTime.Now.AddHours(HoursToExpire).ToString("R"));
if (asAttachment) Response.AddHeader("Content-Disposition", $"attachment; filename=\"{filename}\"");
Response.ContentType = type.ToValue();

var buffer = GetFileBytes(stream, type.IsText());
FlushResponse(buffer);
Expand All @@ -322,13 +326,19 @@ public void SendResponse(HttpStatusCode statusCode, Exception exception)

public void SendResponse(HttpStatusCode statusCode, string response = null)
{
var description = statusCode.ToString().ConvertCamelCase();
var body = !string.IsNullOrWhiteSpace(response) ? response : $"<h1>{description}</h1>";
var buffer = Encoding.UTF8.GetBytes(body);
StatusDescription = statusCode.ToString().ConvertCamelCase();
StatusCode = statusCode;
byte[] buffer;

StatusDescription = description;
StatusCode = (int)statusCode;
ContentType = Util.ContentType.HTML.ToValue();
if (!string.IsNullOrWhiteSpace(response))
{
ContentType = ContentType.HTML;
buffer = Encoding.ASCII.GetBytes($"<h1>{StatusDescription}</h1>");
}
else
{
buffer = ContentEncoding.GetBytes(response);
}

FlushResponse(buffer);
}
Expand All @@ -355,7 +365,7 @@ protected ContentType GetFileType(string filepath)
var ext = Path.GetExtension(filepath)?.ToUpper().TrimStart('.');
return !string.IsNullOrWhiteSpace(ext) && Enum.IsDefined(typeof(ContentType), ext)
? (ContentType)Enum.Parse(typeof(ContentType), ext)
: Util.ContentType.DEFAULT;
: ContentType.DEFAULT;
}

/// <summary>
Expand Down Expand Up @@ -397,7 +407,7 @@ protected byte[] GetFileBytes(FileStream stream, bool istext)
{
using (var reader = new StreamReader(stream))
{
buffer = Encoding.UTF8.GetBytes(reader.ReadToEnd());
buffer = ContentEncoding.GetBytes(reader.ReadToEnd());
}
}
else
Expand Down
14 changes: 10 additions & 4 deletions src/Grapevine/Server/PublicFolder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ namespace Grapevine.Server
/// </summary>
public class PublicFolder
{
private const bool IsFilePath = true;
protected const string DefaultFolder = "public";
protected const bool IsFilePath = true;
private string _folderPath;

public PublicFolder()
{
var path = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location);
if (path != null) _folderPath = Path.Combine(path, "webroot");
if (path != null) _folderPath = Path.Combine(path, DefaultFolder);
if (!FolderExists(_folderPath)) CreateFolder(_folderPath);
}

Expand All @@ -24,6 +25,11 @@ public PublicFolder()
/// </summary>
public string DefaultFileName { get; set; } = "index.html";

/// <summary>
/// Gets or sets the optional prefix for specifying when static content should be returned
/// </summary>
public string Prefix { get; set; }

/// <summary>
/// Gets or sets the folder to be scanned for static content requests
/// </summary>
Expand All @@ -36,11 +42,11 @@ public string FolderPath
/// <summary>
/// If it exists, responds to the request with the requested file
/// </summary>
public IHttpContext ReturnFile(IHttpContext context, string prefix = null)
public IHttpContext SendPublicFile(IHttpContext context)
{
if ((context.Request.HttpMethod != HttpMethod.GET && context.Request.HttpMethod != HttpMethod.HEAD) || string.IsNullOrWhiteSpace(_folderPath)) return context;

var path = string.IsNullOrWhiteSpace(prefix) ? context.Request.PathInfo : context.Request.PathInfo.Replace(prefix, "");
var path = string.IsNullOrWhiteSpace(Prefix) ? context.Request.PathInfo : context.Request.PathInfo.Replace(Prefix, "");
path = path.TrimStart('/', '\\');

var filepath = GetFilePath(path);
Expand Down
Loading

0 comments on commit 9a99098

Please sign in to comment.