Skip to content

Commit 5e3c7cb

Browse files
committed
#2 add options, #19 fix IP parser, update extensions.
1 parent 82f1561 commit 5e3c7cb

17 files changed

+371
-51
lines changed

BasicMiddleware.sln

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio 14
4-
VisualStudioVersion = 14.0.23107.0
4+
VisualStudioVersion = 14.0.24720.0
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.HttpOverrides", "src\Microsoft.AspNet.HttpOverrides\Microsoft.AspNet.HttpOverrides.xproj", "{517308C3-B477-4B01-B461-CAB9C10B6928}"
77
EndProject
@@ -24,6 +24,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{9587
2424
EndProject
2525
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ResponseBufferingSample", "samples\ResponseBufferingSample\ResponseBufferingSample.xproj", "{E5C55B80-7827-40EB-B661-32B0E0E431CA}"
2626
EndProject
27+
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "HttpOverridesSample", "samples\HttpOverridesSample\HttpOverridesSample.xproj", "{7F95478D-E1D4-4A64-BA42-B041591A96EB}"
28+
EndProject
2729
Global
2830
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2931
Debug|Any CPU = Debug|Any CPU
@@ -50,6 +52,10 @@ Global
5052
{E5C55B80-7827-40EB-B661-32B0E0E431CA}.Debug|Any CPU.Build.0 = Debug|Any CPU
5153
{E5C55B80-7827-40EB-B661-32B0E0E431CA}.Release|Any CPU.ActiveCfg = Release|Any CPU
5254
{E5C55B80-7827-40EB-B661-32B0E0E431CA}.Release|Any CPU.Build.0 = Release|Any CPU
55+
{7F95478D-E1D4-4A64-BA42-B041591A96EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
56+
{7F95478D-E1D4-4A64-BA42-B041591A96EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
57+
{7F95478D-E1D4-4A64-BA42-B041591A96EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
58+
{7F95478D-E1D4-4A64-BA42-B041591A96EB}.Release|Any CPU.Build.0 = Release|Any CPU
5359
EndGlobalSection
5460
GlobalSection(SolutionProperties) = preSolution
5561
HideSolutionNode = FALSE
@@ -60,5 +66,6 @@ Global
6066
{2363D0DD-A3BF-437E-9B64-B33AE132D875} = {A5076D28-FA7E-4606-9410-FEDD0D603527}
6167
{F5F1D123-9C81-4A9E-8644-AA46B8E578FB} = {8437B0F3-3894-4828-A945-A9187F37631D}
6268
{E5C55B80-7827-40EB-B661-32B0E0E431CA} = {9587FE9F-5A17-42C4-8021-E87F59CECB98}
69+
{7F95478D-E1D4-4A64-BA42-B041591A96EB} = {9587FE9F-5A17-42C4-8021-E87F59CECB98}
6370
EndGlobalSection
6471
EndGlobal
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<PropertyGroup>
4+
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
5+
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
6+
</PropertyGroup>
7+
8+
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
9+
<PropertyGroup Label="Globals">
10+
<ProjectGuid>7f95478d-e1d4-4a64-ba42-b041591a96eb</ProjectGuid>
11+
<RootNamespace>HttpOverridesSample</RootNamespace>
12+
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
13+
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
14+
</PropertyGroup>
15+
16+
<PropertyGroup>
17+
<SchemaVersion>2.0</SchemaVersion>
18+
</PropertyGroup>
19+
<ItemGroup>
20+
<DnxInvisibleContent Include="bower.json" />
21+
<DnxInvisibleContent Include=".bowerrc" />
22+
<DnxInvisibleContent Include="package.json" />
23+
</ItemGroup>
24+
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
25+
</Project>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"iisSettings": {
3+
"windowsAuthentication": false,
4+
"anonymousAuthentication": true,
5+
"iisExpress": {
6+
"applicationUrl": "http://localhost:1658/",
7+
"sslPort": 0
8+
}
9+
},
10+
"profiles": {
11+
"IIS Express": {
12+
"commandName": "IISExpress",
13+
"launchBrowser": true,
14+
"environmentVariables": {
15+
"ASPNET_ENVIRONMENT": "Development"
16+
}
17+
},
18+
"web": {
19+
"commandName": "web",
20+
"environmentVariables": {
21+
"ASPNET_ENVIRONMENT": "Development"
22+
}
23+
}
24+
}
25+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using Microsoft.AspNet.Builder;
2+
using Microsoft.AspNet.Hosting;
3+
using Microsoft.AspNet.Http;
4+
using Microsoft.AspNet.HttpOverrides;
5+
6+
namespace HttpOverridesSample
7+
{
8+
public class Startup
9+
{
10+
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
11+
public void Configure(IApplicationBuilder app)
12+
{
13+
app.UseIISPlatformHandler();
14+
app.UseOverrideHeaders(options =>
15+
{
16+
options.ForwardedOptions = ForwardedHeaders.All;
17+
});
18+
app.UseHttpMethodOverride();
19+
20+
app.Run(async (context) =>
21+
{
22+
foreach (var header in context.Request.Headers)
23+
{
24+
await context.Response.WriteAsync($"{header.Key}: {header.Value}\r\n");
25+
}
26+
await context.Response.WriteAsync($"Method: {context.Request.Method}\r\n");
27+
await context.Response.WriteAsync($"Scheme: {context.Request.Scheme}\r\n");
28+
await context.Response.WriteAsync($"RemoteIP: {context.Connection.RemoteIpAddress}\r\n");
29+
await context.Response.WriteAsync($"RemotePort: {context.Connection.RemotePort}\r\n");
30+
});
31+
}
32+
33+
// Entry point for the application.
34+
public static void Main(string[] args) => WebApplication.Run<Startup>(args);
35+
}
36+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"server": "Microsoft.AspNet.Server.Kestrel"
3+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"version": "1.0.0-*",
3+
"compilationOptions": {
4+
"emitEntryPoint": true
5+
},
6+
"dependencies": {
7+
"Microsoft.AspNet.IISPlatformHandler": "1.0.0-*",
8+
"Microsoft.AspNet.Server.Kestrel": "1.0.0-*",
9+
"Microsoft.AspNet.HttpOverrides": "1.0.0-*"
10+
},
11+
"commands": {
12+
"web": "HttpOverridesSample"
13+
},
14+
"frameworks": {
15+
"dnx451": { },
16+
"dnxcore50": { }
17+
},
18+
"exclude": [
19+
"wwwroot",
20+
"node_modules"
21+
],
22+
"publishExclude": [
23+
"**.user",
24+
"**.vspscc"
25+
]
26+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<configuration>
3+
<system.webServer>
4+
<handlers>
5+
<add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified"/>
6+
</handlers>
7+
<httpPlatform processPath="%DNX_PATH%" arguments="%DNX_ARGS%" stdoutLogEnabled="false" startupTimeLimit="3600"/>
8+
</system.webServer>
9+
</configuration>

src/Microsoft.AspNet.HttpOverrides/HttpMethodOverrideExtensions.cs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

4+
using System;
45
using Microsoft.AspNet.HttpOverrides;
56

67
namespace Microsoft.AspNet.Builder
@@ -14,7 +15,11 @@ public static class HttpMethodOverrideExtensions
1415
/// <returns></returns>
1516
public static IApplicationBuilder UseHttpMethodOverride(this IApplicationBuilder builder)
1617
{
17-
return builder.Use(next => new HttpMethodOverrideMiddleware(next).Invoke);
18+
if (builder == null)
19+
{
20+
throw new ArgumentNullException(nameof(builder));
21+
}
22+
return builder.Use(next => new HttpMethodOverrideMiddleware(next, new HttpMethodOverrideOptions()).Invoke);
1823
}
1924

2025
/// <summary>
@@ -23,9 +28,19 @@ public static IApplicationBuilder UseHttpMethodOverride(this IApplicationBuilder
2328
/// <param name="builder"></param>
2429
/// <param name="formFieldInput">Denotes the element that contains the name of the resulting method type.</param>
2530
/// <returns></returns>
26-
public static IApplicationBuilder UseHttpMethodOverride(this IApplicationBuilder builder, string formFieldInput)
31+
public static IApplicationBuilder UseHttpMethodOverride(this IApplicationBuilder builder, Action<HttpMethodOverrideOptions> configureOptions)
2732
{
28-
return builder.Use(next => new HttpMethodOverrideMiddleware(next, formFieldInput).Invoke);
33+
if (builder == null)
34+
{
35+
throw new ArgumentNullException(nameof(builder));
36+
}
37+
if (configureOptions == null)
38+
{
39+
throw new ArgumentNullException(nameof(configureOptions));
40+
}
41+
var options = new HttpMethodOverrideOptions();
42+
configureOptions(options);
43+
return builder.Use(next => new HttpMethodOverrideMiddleware(next, options).Invoke);
2944
}
3045
}
3146
}

src/Microsoft.AspNet.HttpOverrides/HttpMethodOverrideMiddleware.cs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
using System;
55
using System.Threading.Tasks;
6-
using Microsoft.AspNet.Builder;
76
using Microsoft.AspNet.Http;
87

98
namespace Microsoft.AspNet.HttpOverrides
@@ -12,24 +11,32 @@ public class HttpMethodOverrideMiddleware
1211
{
1312
private const string xHttpMethodOverride = "X-Http-Method-Override";
1413
private readonly RequestDelegate _next;
15-
private readonly string _formFieldName;
14+
private readonly HttpMethodOverrideOptions _options;
1615

17-
public HttpMethodOverrideMiddleware(RequestDelegate next, string formFieldName = null)
16+
public HttpMethodOverrideMiddleware(RequestDelegate next, HttpMethodOverrideOptions options)
1817
{
18+
if (next == null)
19+
{
20+
throw new ArgumentNullException(nameof(next));
21+
}
22+
if (options == null)
23+
{
24+
throw new ArgumentNullException(nameof(options));
25+
}
1926
_next = next;
20-
_formFieldName = formFieldName;
27+
_options = options;
2128
}
2229

2330
public async Task Invoke(HttpContext context)
2431
{
2532
if (string.Equals(context.Request.Method,"POST", StringComparison.OrdinalIgnoreCase))
2633
{
27-
if (_formFieldName != null)
34+
if (_options.FormFieldName != null)
2835
{
2936
if (context.Request.HasFormContentType)
3037
{
3138
var form = await context.Request.ReadFormAsync();
32-
var methodType = form[_formFieldName];
39+
var methodType = form[_options.FormFieldName];
3340
if (!string.IsNullOrEmpty(methodType))
3441
{
3542
context.Request.Method = methodType;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
namespace Microsoft.AspNet.HttpOverrides
5+
{
6+
public class HttpMethodOverrideOptions
7+
{
8+
/// <summary>
9+
/// Denotes the form element that contains the name of the resulting method type.
10+
/// If not set the X-Http-Method-Override header will be used.
11+
/// </summary>
12+
public string FormFieldName { get; set; }
13+
}
14+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System.Net;
5+
6+
namespace Microsoft.AspNet.HttpOverrides
7+
{
8+
public static class IPEndPointParser
9+
{
10+
public static bool TryParse(string addressWithPort, out IPEndPoint endpoint)
11+
{
12+
string addressPart = null;
13+
string portPart = null;
14+
IPAddress address;
15+
endpoint = null;
16+
17+
var lastColonIndex = addressWithPort.LastIndexOf(':');
18+
if (lastColonIndex > 0)
19+
{
20+
// IPv4 with port or IPv6
21+
var closingIndex = addressWithPort.LastIndexOf(']');
22+
if (closingIndex > 0)
23+
{
24+
// IPv6 with brackets
25+
addressPart = addressWithPort.Substring(1, closingIndex - 1);
26+
if (closingIndex < lastColonIndex)
27+
{
28+
// IPv6 with port [::1]:80
29+
portPart = addressWithPort.Substring(lastColonIndex + 1);
30+
}
31+
}
32+
else
33+
{
34+
// IPv6 without port or IPv4
35+
var firstColonIndex = addressWithPort.IndexOf(':');
36+
if (firstColonIndex != lastColonIndex)
37+
{
38+
// IPv6 ::1
39+
addressPart = addressWithPort;
40+
}
41+
else
42+
{
43+
// IPv4 with port 127.0.0.1:123
44+
addressPart = addressWithPort.Substring(0, firstColonIndex);
45+
portPart = addressWithPort.Substring(firstColonIndex + 1);
46+
}
47+
}
48+
}
49+
else
50+
{
51+
// IPv4 without port
52+
addressPart = addressWithPort;
53+
}
54+
55+
if (IPAddress.TryParse(addressPart, out address))
56+
{
57+
if (portPart != null)
58+
{
59+
int port;
60+
if (int.TryParse(portPart, out port))
61+
{
62+
endpoint = new IPEndPoint(address, port);
63+
return true;
64+
}
65+
return false;
66+
}
67+
endpoint = new IPEndPoint(address, 0);
68+
return true;
69+
}
70+
return false;
71+
}
72+
}
73+
}

src/Microsoft.AspNet.HttpOverrides/OverrideHeaderExtensions.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

4+
using System;
45
using Microsoft.AspNet.HttpOverrides;
56

67
namespace Microsoft.AspNet.Builder
@@ -13,8 +14,18 @@ public static class OverrideHeaderExtensions
1314
/// <param name="builder"></param>
1415
/// <param name="options">Enables the different override options.</param>
1516
/// <returns></returns>
16-
public static IApplicationBuilder UseOverrideHeaders(this IApplicationBuilder builder, OverrideHeaderMiddlewareOptions options)
17+
public static IApplicationBuilder UseOverrideHeaders(this IApplicationBuilder builder, Action<OverrideHeaderOptions> configureOptions)
1718
{
19+
if (builder == null)
20+
{
21+
throw new ArgumentNullException(nameof(builder));
22+
}
23+
if (configureOptions == null)
24+
{
25+
throw new ArgumentNullException(nameof(configureOptions));
26+
}
27+
var options = new OverrideHeaderOptions();
28+
configureOptions(options);
1829
return builder.Use(next => new OverrideHeaderMiddleware(next, options).Invoke);
1930
}
2031
}

0 commit comments

Comments
 (0)