forked from Azure/azure-functions-host
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added global HTTP response headers configuration. Resolves Azure#3788.
- Loading branch information
Showing
15 changed files
with
389 additions
and
1 deletion.
There are no files selected for viewing
40 changes: 40 additions & 0 deletions
40
src/WebJobs.Script.WebHost/Middleware/CustomHeadersMiddleware.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the MIT License. See License.txt in the project root for license information. | ||
|
||
using System.Collections.Generic; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Http; | ||
using Microsoft.Azure.WebJobs.Script.Middleware; | ||
using Microsoft.Extensions.Options; | ||
|
||
namespace Microsoft.Azure.WebJobs.Script.WebHost.Middleware | ||
{ | ||
public class CustomHeadersMiddleware : IJobHostHttpMiddleware | ||
{ | ||
private RequestDelegate _invoke; | ||
|
||
public CustomHeadersMiddleware(IOptions<ScriptJobHostOptions> hostOptions) | ||
{ | ||
RequestDelegate contextNext = async context => | ||
{ | ||
if (context.Items.Remove(ScriptConstants.CustomHeadersMiddlewareRequestDelegate, out object requestDelegate) && requestDelegate is RequestDelegate next) | ||
{ | ||
await next(context); | ||
foreach (var header in hostOptions.Value.CustomHeaders) | ||
{ | ||
context.Response.Headers[header.Key] = header.Value; | ||
} | ||
} | ||
}; | ||
|
||
_invoke = contextNext; | ||
} | ||
|
||
public async Task Invoke(HttpContext context, RequestDelegate next) | ||
{ | ||
context.Items.Add(ScriptConstants.CustomHeadersMiddlewareRequestDelegate, next); | ||
await _invoke(context); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
50 changes: 50 additions & 0 deletions
50
...WebJobs.Script.Tests.Integration/Middleware/CustomHeadersMiddlewareCSharpEndToEndTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the MIT License. See License.txt in the project root for license information. | ||
|
||
using System.Threading.Tasks; | ||
using Microsoft.Azure.WebJobs.Script.Rpc; | ||
using Xunit; | ||
|
||
namespace Microsoft.Azure.WebJobs.Script.Tests.Middleware | ||
{ | ||
public class CustomHeadersMiddlewareCSharpEndToEndTests : | ||
CustomHeadersMiddlewareEndToEndTestsBase<CustomHeadersMiddlewareCSharpEndToEndTests.TestFixture> | ||
{ | ||
public CustomHeadersMiddlewareCSharpEndToEndTests(TestFixture fixture) : base(fixture) | ||
{ | ||
} | ||
|
||
[Fact] | ||
public Task CustomHeadersMiddlewareRootUrl() | ||
{ | ||
return CustomHeadersMiddlewareRootUrlTest(); | ||
} | ||
|
||
[Fact] | ||
public Task CustomHeadersMiddlewareAdminUrl() | ||
{ | ||
return CustomHeadersMiddlewareAdminUrlTest(); | ||
} | ||
|
||
[Fact] | ||
public Task CustomHeadersMiddlewareHttpTriggerUrl() | ||
{ | ||
return CustomHeadersMiddlewareHttpTriggerUrlTest(); | ||
} | ||
|
||
[Fact] | ||
public Task CustomHeadersMiddlewareExtensionWebhookUrl() | ||
{ | ||
return CustomHeadersMiddlewareExtensionWebhookUrlTest(); | ||
} | ||
|
||
public class TestFixture : CustomHeadersMiddlewareTestFixture | ||
{ | ||
private const string ScriptRoot = @"TestScripts\CustomHeadersMiddleware\CSharp"; | ||
|
||
public TestFixture() : base(ScriptRoot, "csharp", LanguageWorkerConstants.DotNetLanguageWorkerName) | ||
{ | ||
} | ||
} | ||
} | ||
} |
99 changes: 99 additions & 0 deletions
99
test/WebJobs.Script.Tests.Integration/Middleware/CustomHeadersMiddlewareEndToEndTestsBase.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the MIT License. See License.txt in the project root for license information. | ||
|
||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Net; | ||
using System.Net.Http; | ||
using System.Threading.Tasks; | ||
using Microsoft.Azure.WebJobs.Script.Models; | ||
using Xunit; | ||
|
||
namespace Microsoft.Azure.WebJobs.Script.Tests.Middleware | ||
{ | ||
public abstract class CustomHeadersMiddlewareEndToEndTestsBase<TTestFixture> : | ||
EndToEndTestsBase<TTestFixture> where TTestFixture : CustomHeadersMiddlewareTestFixture, new() | ||
{ | ||
public CustomHeadersMiddlewareEndToEndTestsBase(TTestFixture fixture) : base(fixture) | ||
{ | ||
} | ||
|
||
protected async Task CustomHeadersMiddlewareRootUrlTest() | ||
{ | ||
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, string.Empty); | ||
|
||
HttpResponseMessage response = await Fixture.Host.HttpClient.SendAsync(request); | ||
response.EnsureSuccessStatusCode(); | ||
|
||
Assert.Equal(HttpStatusCode.OK, response.StatusCode); | ||
|
||
IEnumerable<string> values; | ||
Assert.True(response.Headers.TryGetValues("X-Content-Type-Options", out values)); | ||
Assert.Equal("nosniff", values.FirstOrDefault()); | ||
} | ||
|
||
protected async Task CustomHeadersMiddlewareAdminUrlTest() | ||
{ | ||
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "admin/host/ping"); | ||
|
||
HttpResponseMessage response = await Fixture.Host.HttpClient.SendAsync(request); | ||
response.EnsureSuccessStatusCode(); | ||
|
||
Assert.Equal(HttpStatusCode.OK, response.StatusCode); | ||
|
||
IEnumerable<string> values; | ||
Assert.True(response.Headers.TryGetValues("X-Content-Type-Options", out values)); | ||
Assert.Equal("nosniff", values.FirstOrDefault()); | ||
} | ||
|
||
protected async Task CustomHeadersMiddlewareHttpTriggerUrlTest() | ||
{ | ||
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "api/HttpTrigger"); | ||
|
||
HttpResponseMessage response = await Fixture.Host.HttpClient.SendAsync(request); | ||
response.EnsureSuccessStatusCode(); | ||
|
||
Assert.Equal(HttpStatusCode.OK, response.StatusCode); | ||
|
||
IEnumerable<string> values; | ||
Assert.True(response.Headers.TryGetValues("X-Content-Type-Options", out values)); | ||
Assert.Equal("nosniff", values.FirstOrDefault()); | ||
} | ||
|
||
protected async Task CustomHeadersMiddlewareExtensionWebhookUrlTest() | ||
{ | ||
var secrets = await Fixture.Host.SecretManager.GetHostSecretsAsync(); | ||
var url = $"/runtime/webhooks/durableTask/instances?taskHub=MiddlewareTestHub&code={secrets.MasterKey}"; | ||
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url); | ||
|
||
HttpResponseMessage response = await Fixture.Host.HttpClient.SendAsync(request); | ||
response.EnsureSuccessStatusCode(); | ||
|
||
Assert.Equal(HttpStatusCode.OK, response.StatusCode); | ||
|
||
IEnumerable<string> values; | ||
Assert.True(response.Headers.TryGetValues("X-Content-Type-Options", out values)); | ||
Assert.Equal("nosniff", values.FirstOrDefault()); | ||
} | ||
} | ||
|
||
public abstract class CustomHeadersMiddlewareTestFixture: EndToEndTestFixture | ||
{ | ||
protected override ExtensionPackageReference[] GetExtensionsToInstall() | ||
{ | ||
return new ExtensionPackageReference[] | ||
{ | ||
new ExtensionPackageReference | ||
{ | ||
Id = "Microsoft.Azure.WebJobs.Extensions.DurableTask", | ||
Version = "1.8.2" | ||
} | ||
}; | ||
} | ||
|
||
protected CustomHeadersMiddlewareTestFixture(string rootPath, string testId, string language) : | ||
base(rootPath, testId, language) | ||
{ | ||
} | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
test/WebJobs.Script.Tests.Integration/Middleware/CustomHeadersMiddlewareNodeEndToEndTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the MIT License. See License.txt in the project root for license information. | ||
|
||
using System.Threading.Tasks; | ||
using Microsoft.Azure.WebJobs.Script.Rpc; | ||
using Xunit; | ||
|
||
namespace Microsoft.Azure.WebJobs.Script.Tests.Middleware | ||
{ | ||
public class CustomHeadersMiddlewareNodeEndToEndTests : | ||
CustomHeadersMiddlewareEndToEndTestsBase<CustomHeadersMiddlewareNodeEndToEndTests.TestFixture> | ||
{ | ||
public CustomHeadersMiddlewareNodeEndToEndTests(TestFixture fixture) : base(fixture) | ||
{ | ||
} | ||
|
||
[Fact] | ||
public Task CustomHeadersMiddlewareRootUrl() | ||
{ | ||
return CustomHeadersMiddlewareRootUrlTest(); | ||
} | ||
|
||
[Fact] | ||
public Task CustomHeadersMiddlewareAdminUrl() | ||
{ | ||
return CustomHeadersMiddlewareAdminUrlTest(); | ||
} | ||
|
||
[Fact] | ||
public Task CustomHeadersMiddlewareHttpTriggerUrl() | ||
{ | ||
return CustomHeadersMiddlewareHttpTriggerUrlTest(); | ||
} | ||
|
||
[Fact] | ||
public Task CustomHeadersMiddlewareExtensionWebhookUrl() | ||
{ | ||
return CustomHeadersMiddlewareExtensionWebhookUrlTest(); | ||
} | ||
|
||
public class TestFixture : CustomHeadersMiddlewareTestFixture | ||
{ | ||
private const string ScriptRoot = @"TestScripts\CustomHeadersMiddleware\Node"; | ||
|
||
public TestFixture() : base(ScriptRoot, "node", LanguageWorkerConstants.NodeLanguageWorkerName) | ||
{ | ||
} | ||
} | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
...pt.Tests.Integration/TestScripts/CustomHeadersMiddleware/CSharp/HttpTrigger/function.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"bindings": [ | ||
{ | ||
"type": "httpTrigger", | ||
"name": "req", | ||
"direction": "in", | ||
"methods": [ "get" ], | ||
"authLevel": "anonymous" | ||
}, | ||
{ | ||
"type": "http", | ||
"name": "$return", | ||
"direction": "out" | ||
} | ||
] | ||
} |
10 changes: 10 additions & 0 deletions
10
...s.Script.Tests.Integration/TestScripts/CustomHeadersMiddleware/CSharp/HttpTrigger/run.csx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using System.Net; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.Extensions.Primitives; | ||
|
||
public static IActionResult Run(HttpRequest req, TraceWriter log) | ||
{ | ||
log.Info("C# HTTP trigger function processed a request."); | ||
|
||
return new OkObjectResult("Success"); | ||
} |
11 changes: 11 additions & 0 deletions
11
test/WebJobs.Script.Tests.Integration/TestScripts/CustomHeadersMiddleware/CSharp/host.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"version": "2.0", | ||
"customHeaders": { | ||
"X-Content-Type-Options": "nosniff" | ||
}, | ||
"extensions": { | ||
"durableTask": { | ||
"hubName": "CustomHeadersMiddlewareCSharpTestHub" | ||
} | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
...ript.Tests.Integration/TestScripts/CustomHeadersMiddleware/Node/HttpTrigger/function.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"bindings": [ | ||
{ | ||
"type": "httpTrigger", | ||
"name": "req", | ||
"direction": "in", | ||
"methods": [ "get" ], | ||
"authLevel": "anonymous" | ||
}, | ||
{ | ||
"type": "http", | ||
"name": "$return", | ||
"direction": "out" | ||
} | ||
] | ||
} |
9 changes: 9 additions & 0 deletions
9
...bs.Script.Tests.Integration/TestScripts/CustomHeadersMiddleware/Node/HttpTrigger/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
module.exports = function (context, req) { | ||
context.log('Node.js HTTP trigger function processed a request.'); | ||
|
||
const res = { | ||
status: 200, | ||
}; | ||
|
||
context.done(null, res); | ||
}; |
11 changes: 11 additions & 0 deletions
11
test/WebJobs.Script.Tests.Integration/TestScripts/CustomHeadersMiddleware/Node/host.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"version": "2.0", | ||
"customHeaders": { | ||
"X-Content-Type-Options": "nosniff" | ||
}, | ||
"extensions": { | ||
"durableTask": { | ||
"hubName": "CustomHeadersMiddlewareNodeTestHub" | ||
} | ||
} | ||
} |
Oops, something went wrong.