New: CORS support on the API (for developing against the API)

pull/6/head
Mark McDowall 10 years ago
parent 4665682ea6
commit 3ee58979ec

@ -0,0 +1,12 @@
namespace NzbDrone.Api.Extensions
{
public static class AccessControlHeaders
{
public const string RequestMethod = "Access-Control-Request-Method";
public const string RequestHeaders = "Access-Control-Request-Headers";
public const string AllowOrigin = "Access-Control-Allow-Origin";
public const string AllowMethods = "Access-Control-Allow-Methods";
public const string AllowHeaders = "Access-Control-Allow-Headers";
}
}

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Nancy;
using Nancy.Bootstrapper;
namespace NzbDrone.Api.Extensions.Pipelines
{
public class CorsPipeline : IRegisterNancyPipeline
{
public void Register(IPipelines pipelines)
{
pipelines.AfterRequest.AddItemToEndOfPipeline(Handle);
}
private void Handle(NancyContext context)
{
if (context == null || context.Response.Headers.ContainsKey(AccessControlHeaders.AllowOrigin))
{
return;
}
ApplyResponseHeaders(context.Response, context.Request);
}
private static void ApplyResponseHeaders(Response response, Request request)
{
var allowedMethods = "GET, OPTIONS, PATCH, POST, PUT, DELETE";
if (response.Headers.ContainsKey("Allow"))
{
allowedMethods = response.Headers["Allow"];
}
var requestedHeaders = String.Join(", ", request.Headers[AccessControlHeaders.RequestHeaders]);
response.Headers.Add(AccessControlHeaders.AllowOrigin, "*");
response.Headers.Add(AccessControlHeaders.AllowMethods, allowedMethods);
if (request.Headers[AccessControlHeaders.RequestHeaders].Any())
{
response.Headers.Add(AccessControlHeaders.AllowHeaders, requestedHeaders);
}
}
}
}

@ -96,6 +96,8 @@
<Compile Include="ClientSchema\SelectOption.cs" /> <Compile Include="ClientSchema\SelectOption.cs" />
<Compile Include="Commands\CommandModule.cs" /> <Compile Include="Commands\CommandModule.cs" />
<Compile Include="Commands\CommandResource.cs" /> <Compile Include="Commands\CommandResource.cs" />
<Compile Include="Extensions\AccessControlHeaders.cs" />
<Compile Include="Extensions\Pipelines\CorsPipeline.cs" />
<Compile Include="RemotePathMappings\RemotePathMappingModule.cs" /> <Compile Include="RemotePathMappings\RemotePathMappingModule.cs" />
<Compile Include="RemotePathMappings\RemotePathMappingResource.cs" /> <Compile Include="RemotePathMappings\RemotePathMappingResource.cs" />
<Compile Include="Config\UiConfigModule.cs" /> <Compile Include="Config\UiConfigModule.cs" />

@ -45,7 +45,6 @@ namespace NzbDrone.Integration.Test.Client
request.AddParameter("sortKey", sortKey); request.AddParameter("sortKey", sortKey);
request.AddParameter("sortDir", sortDir); request.AddParameter("sortDir", sortDir);
return Get<PagingResource<TResource>>(request); return Get<PagingResource<TResource>>(request);
} }
public TResource Post(TResource body, HttpStatusCode statusCode = HttpStatusCode.Created) public TResource Post(TResource body, HttpStatusCode statusCode = HttpStatusCode.Created)

@ -0,0 +1,57 @@
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Api.Extensions;
using RestSharp;
namespace NzbDrone.Integration.Test
{
[TestFixture]
public class CorsFixture : IntegrationTest
{
private RestRequest BuildRequest()
{
var request = new RestRequest("series");
request.AddHeader(AccessControlHeaders.RequestMethod, "POST");
return request;
}
[Test]
public void should_not_have_allow_headers_in_response_when_not_included_in_the_request()
{
var request = BuildRequest();
var response = RestClient.Get(request);
response.Headers.Should().NotContain(h => h.Name == AccessControlHeaders.AllowHeaders);
}
[Test]
public void should_have_allow_headers_in_response_when_included_in_the_request()
{
var request = BuildRequest();
request.AddHeader(AccessControlHeaders.RequestHeaders, "X-Test");
var response = RestClient.Get(request);
response.Headers.Should().Contain(h => h.Name == AccessControlHeaders.AllowHeaders);
}
[Test]
public void should_have_allow_origin_in_response()
{
var request = BuildRequest();
var response = RestClient.Get(request);
response.Headers.Should().Contain(h => h.Name == AccessControlHeaders.AllowOrigin);
}
[Test]
public void should_have_allow_methods_in_response()
{
var request = BuildRequest();
var response = RestClient.Get(request);
response.Headers.Should().Contain(h => h.Name == AccessControlHeaders.AllowMethods);
}
}
}

@ -63,7 +63,6 @@ namespace NzbDrone.Integration.Test
} }
[TestFixtureSetUp] [TestFixtureSetUp]
//[SetUp]
public void SmokeTestSetup() public void SmokeTestSetup()
{ {
_runner = new NzbDroneRunner(); _runner = new NzbDroneRunner();
@ -87,6 +86,8 @@ namespace NzbDrone.Integration.Test
private void InitRestClients() private void InitRestClients()
{ {
RestClient = new RestClient(RootUrl + "api/"); RestClient = new RestClient(RootUrl + "api/");
RestClient.AddDefaultHeader("Authentication", _runner.ApiKey);
Series = new SeriesClient(RestClient, _runner.ApiKey); Series = new SeriesClient(RestClient, _runner.ApiKey);
Releases = new ReleaseClient(RestClient, _runner.ApiKey); Releases = new ReleaseClient(RestClient, _runner.ApiKey);
RootFolders = new ClientBase<RootFolderResource>(RestClient, _runner.ApiKey); RootFolders = new ClientBase<RootFolderResource>(RestClient, _runner.ApiKey);
@ -99,7 +100,6 @@ namespace NzbDrone.Integration.Test
} }
[TestFixtureTearDown] [TestFixtureTearDown]
//[TearDown]
public void SmokeTestTearDown() public void SmokeTestTearDown()
{ {
_runner.KillAll(); _runner.KillAll();
@ -153,6 +153,5 @@ namespace NzbDrone.Integration.Test
_signalrConnection.Received += json => _signalRReceived.Add(Json.Deserialize<SignalRMessage>(json)); ; _signalrConnection.Received += json => _signalRReceived.Add(Json.Deserialize<SignalRMessage>(json)); ;
} }
} }
} }

@ -109,6 +109,7 @@
<Compile Include="Client\ReleaseClient.cs" /> <Compile Include="Client\ReleaseClient.cs" />
<Compile Include="Client\SeriesClient.cs" /> <Compile Include="Client\SeriesClient.cs" />
<Compile Include="CommandIntegerationTests.cs" /> <Compile Include="CommandIntegerationTests.cs" />
<Compile Include="CorsFixture.cs" />
<Compile Include="EpisodeIntegrationTests.cs" /> <Compile Include="EpisodeIntegrationTests.cs" />
<Compile Include="HistoryIntegrationTest.cs" /> <Compile Include="HistoryIntegrationTest.cs" />
<Compile Include="IndexerIntegrationFixture.cs" /> <Compile Include="IndexerIntegrationFixture.cs" />

Loading…
Cancel
Save