Skip to content

Commit

Permalink
First CORS release
Browse files Browse the repository at this point in the history
  • Loading branch information
geoperez committed May 18, 2015
1 parent 1ade6d6 commit 97d9004
Show file tree
Hide file tree
Showing 9 changed files with 198 additions and 34 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

![EmbedIO](http://unosquare.github.io/embedio/images/embedio.png)

A tiny, cross-platform, module based, MIT-licensed web server
A tiny, cross-platform, module based, MIT-licensed web server.

* New Version: Network operations make heavy use of the relatively recent async/await pattern
* Cross-platform (tested in Mono 3.10.x on Windows and on a custom Yocto image for the Raspberry Pi)
Expand All @@ -14,6 +14,7 @@ A tiny, cross-platform, module based, MIT-licensed web server
* Serve static files with 1 line of code (built-in module)
* Handle sessions with the built-in LocalSessionWebModule
* Web Sockets support (Not available on Mono though)
* CORS support. Origin, Headers and Methods validation with OPTIONS preflight

*For detailed usage and REST API implementation, download the code and take a look at the Samples project*

Expand Down Expand Up @@ -115,9 +116,10 @@ namespace Company.Project
url = args[0];

// Create Webserver with console logger and attach LocalSession and Static
// files module
// files module and CORS enabled
var server = WebServer
.CreateWithConsole(url)
.EnableCors()
.WithLocalSession()
.WithStaticFolderAt("c:/web");

Expand Down
2 changes: 1 addition & 1 deletion Unosquare.Labs.EmbedIO.Command/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ private static void Main(string[] args)
if (Properties.Settings.Default.UseLocalSessionModule)
server.WithLocalSession();

server.WithStaticFolderAt(options.RootPath,
server.EnableCors().WithStaticFolderAt(options.RootPath,
defaultDocument: Properties.Settings.Default.HtmlDefaultDocument);

server.Module<StaticFilesModule>().DefaultExtension = Properties.Settings.Default.HtmlDefaultExtension;
Expand Down
12 changes: 9 additions & 3 deletions Unosquare.Labs.EmbedIO.Samples/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ private static void Main(string[] args)

// Our web server is disposable. Note that if you don't want to use logging,
// there are alternate constructors that allow you to skip specifying an ILog object.
using (var server = new WebServer(url, new SimpleConsoleLog()))
using (var server = new WebServer(url, Log))
{
// First, we will configure our web server by adding Modules.
// Please note that order DOES matter.
Expand All @@ -30,8 +30,14 @@ private static void Main(string[] args)
// You can use the server.GetSession() method to get the SessionInfo object and manupulate it.
server.RegisterModule(new Modules.LocalSessionModule());

// Set the CORS Rules, Origins separated by comma without last slash
server.RegisterModule(new Modules.CorsModule("http://client.cors-api.appspot.com,http://unosquare.github.io,http://run.plnkr.co"));
// Set the CORS Rules
server.RegisterModule(new Modules.CorsModule(
// Origins, separated by comma without last slash
"http://client.cors-api.appspot.com,http://unosquare.github.io,http://run.plnkr.co",
// Allowed headers
"content-type, accept",
// Allowed methods
"post"));

// Register the static files server. See the html folder of this project. Also notice that
// the files under the html folder have Copy To Output Folder = Copy if Newer
Expand Down
52 changes: 52 additions & 0 deletions Unosquare.Labs.EmbedIO.Tests/CorsModuleTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
namespace Unosquare.Labs.EmbedIO.Tests
{
using NUnit.Framework;
using System;
using System.Net;
using System.Threading;
using Unosquare.Labs.EmbedIO.Modules;
using Unosquare.Labs.EmbedIO.Tests.Properties;

[TestFixture]
public class CorsModuleTest
{
protected WebServer WebServer;
protected TestConsoleLog Logger = new TestConsoleLog();

[SetUp]
public void Init()
{
WebServer = new WebServer(Resources.ServerAddress, Logger)
.EnableCors(
"http://client.cors-api.appspot.com,http://unosquare.github.io,http://run.plnkr.co",
"content-type",
"post,get");

WebServer.RegisterModule(new WebApiModule());
WebServer.Module<WebApiModule>().RegisterController<TestController>();
WebServer.RunAsync();
}

[Test]
public void PreFlight()
{
var request = (HttpWebRequest) WebRequest.Create(Resources.ServerAddress + TestController.GetPath);
request.Headers.Add(Constants.HeaderOrigin, "http://unosquare.github.io");
request.Headers.Add(Constants.HeaderAccessControlRequestMethod, "post");
request.Headers.Add(Constants.HeaderAccessControlRequestHeaders, "content-type");
request.Method = "OPTIONS";

using (var response = (HttpWebResponse) request.GetResponse())
{
Assert.AreEqual(response.StatusCode, HttpStatusCode.OK, "Status Code OK");
}
}

[TearDown]
public void Kill()
{
Thread.Sleep(TimeSpan.FromSeconds(1));
WebServer.Dispose();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CorsModuleTest.cs" />
<Compile Include="FluentTest.cs" />
<Compile Include="LocalSessionModuleTest.cs" />
<Compile Include="Properties\Resources.Designer.cs">
Expand Down
9 changes: 9 additions & 0 deletions Unosquare.Labs.EmbedIO.Tests/WebApiModuleTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
{
using Newtonsoft.Json;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
using Unosquare.Labs.EmbedIO.Modules;
using Unosquare.Labs.EmbedIO.Tests.Properties;

Expand Down Expand Up @@ -64,5 +66,12 @@ public void GetJsonData()
}

// TODO: Test POST

[TearDown]
public void Kill()
{
Thread.Sleep(TimeSpan.FromSeconds(1));
WebServer.Dispose();
}
}
}
59 changes: 51 additions & 8 deletions Unosquare.Labs.EmbedIO/Constants.cs
Original file line number Diff line number Diff line change
@@ -1,64 +1,73 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Unosquare.Labs.EmbedIO
namespace Unosquare.Labs.EmbedIO
{
using System;
using System.Collections.Generic;

/// <summary>
/// Defines assembly-wide constants
/// </summary>
static public class Constants
public static class Constants
{
/// <summary>
/// Accept-Encoding HTTP Header
/// </summary>
public const string HeaderAcceptEncoding = "Accept-Encoding";

/// <summary>
/// Content-Encoding HTTP Header
/// </summary>
public const string HeaderContentEncoding = "Content-Encoding";

/// <summary>
/// If-Modified-Since HTTP Header
/// </summary>
public const string HeaderIfModifiedSince = "If-Modified-Since";

/// <summary>
/// Cache-Control HTTP Header
/// </summary>
public const string HeaderCacheControl = "Cache-Control";

/// <summary>
/// Pragma HTTP Header
/// </summary>
public const string HeaderPragma = "Pragma";

/// <summary>
/// Expires HTTP Header
/// </summary>
public const string HeaderExpires = "Expires";

/// <summary>
/// Last-Modified HTTP Header
/// </summary>
public const string HeaderLastModified = "Last-Modified";

/// <summary>
/// If-None-Match HTTP Header
/// </summary>
public const string HeaderIfNotMatch = "If-None-Match";

/// <summary>
/// ETag HTTP Header
/// </summary>
public const string HeaderETag = "ETag";

/// <summary>
/// Accept-Ranges HTTP Header
/// </summary>
public const string HeaderAcceptRanges = "Accept-Ranges";

/// <summary>
/// Range HTTP Header
/// </summary>
public const string HeaderRange = "Range";

/// <summary>
/// Content-Range HTTP Header
/// </summary>
public const string HeaderContentRanges = "Content-Range";

/// <summary>
/// Default Browser time format
/// </summary>
Expand All @@ -69,6 +78,40 @@ static public class Constants
/// </summary>
public const string Response404Html = "<html><head></head><body><h1>404 - Not Found</h1></body></html>";

/// <summary>
/// Default CORS rule
/// </summary>
public const string CorsWildcard = "*";

/// <summary>
/// Access-Control-Allow-Origin HTTP Header
/// </summary>
public const string HeaderAccessControlAllowOrigin = "Access-Control-Allow-Origin: *";

/// <summary>
/// Access-Control-Allow-Headers HTTP Header
/// </summary>
public const string HeaderAccessControlAllowHeaders = "Access-Control-Allow-Headers: ";

/// <summary>
/// Access-Control-Allow-Methods HTTP Header
/// </summary>
public const string HeaderAccessControlAllowMethods = "Access-Control-Allow-Methods: ";

/// <summary>
/// Origin HTTP Header
/// </summary>
public const string HeaderOrigin = "Origin";

/// <summary>
/// Access-Control-Request-Headers HTTP Header
/// </summary>
public const string HeaderAccessControlRequestHeaders = "Access-Control-Request-Headers";
/// <summary>
/// Access-Control-Request-Headers HTTP Method
/// </summary>
public const string HeaderAccessControlRequestMethod = "Access-Control-Request-Method";

/// <summary>
/// Default Http Status 500 response output
/// The first format argument takes the error message.
Expand Down
20 changes: 19 additions & 1 deletion Unosquare.Labs.EmbedIO/FluentExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ public static WebServer LoadApiControllers(this WebServer webserver, Assembly as
/// </summary>
/// <param name="webserver">The webserver instance.</param>
/// <param name="assembly">The assembly to load WebSocketsServer types from. Leave null to load from the currently executing assembly.</param>
/// <param name="verbose">Set verbose</param>
/// <returns>The webserver instance.</returns>
public static WebServer LoadWebSockets(this WebServer webserver, Assembly assembly = null)
{
Expand All @@ -123,5 +122,24 @@ public static WebServer LoadWebSockets(this WebServer webserver, Assembly assemb

return webserver;
}

/// <summary>
/// Enables CORS in the WebServer
/// </summary>
/// <param name="webserver">The webserver instance.</param>
/// <param name="origins">The valid origins, default all</param>
/// <param name="headers">The valid headers, default all</param>
/// <param name="methods">The valid method, default all</param>
/// <returns></returns>
public static WebServer EnableCors(this WebServer webserver, string origins = Constants.CorsWildcard,
string headers = Constants.CorsWildcard,
string methods = Constants.CorsWildcard)
{
if (webserver == null) throw new ArgumentException("Argument cannot be null.", "webserver");

webserver.RegisterModule(new CorsModule(origins, headers, methods));

return webserver;
}
}
}
Loading

0 comments on commit 97d9004

Please sign in to comment.