Skip to content

Commit 51d6ac5

Browse files
committed
Several proxy fixes as described in:
#2161 Azure/Azure-Functions#614 Azure/Azure-Functions#596
1 parent 54aa088 commit 51d6ac5

File tree

15 files changed

+101
-110
lines changed

15 files changed

+101
-110
lines changed

src/WebJobs.Script.NuGet/WebJobs.Script.nuspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<dependency id="FSharp.Core" version="4.0.0.1" />
2020
<dependency id="Microsoft.Azure.WebJobs" version="2.1.0-beta4-11100" />
2121
<dependency id="Microsoft.ApplicationInsights.WindowsServer" version="2.4.1" />
22-
<dependency id="Microsoft.Azure.AppService.Proxy" version="0.3.2.20" />
22+
<dependency id="Microsoft.Azure.AppService.Proxy" version="1.0.0.1" />
2323
<dependency id="Microsoft.Azure.ServiceBus.EventProcessorHost" version="2.2.10" />
2424
<dependency id="Microsoft.Azure.WebJobs.Extensions.ApiHub" version="1.0.0-beta6-10554" />
2525
<dependency id="Microsoft.Azure.WebJobs.Extensions.BotFramework" version="1.0.15-beta" />

src/WebJobs.Script.WebHost/ProxyFunctionExecutor.cs

Lines changed: 2 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ public class ProxyFunctionExecutor : IFuncExecutor
2222
{
2323
private readonly WebScriptHostManager _scriptHostManager;
2424
private readonly ISecretManager _secretManager;
25-
private readonly string _httpPrefix;
2625

2726
private WebHookReceiverManager _webHookReceiverManager;
2827

@@ -31,82 +30,16 @@ internal ProxyFunctionExecutor(WebScriptHostManager scriptHostManager, WebHookRe
3130
_scriptHostManager = scriptHostManager;
3231
_webHookReceiverManager = webHookReceiverManager;
3332
_secretManager = secretManager;
34-
35-
_httpPrefix = HttpExtensionConstants.DefaultRoutePrefix;
36-
37-
if (_scriptHostManager.Instance != null)
38-
{
39-
var json = _scriptHostManager.Instance.ScriptConfig.HostConfig.HostConfigMetadata;
40-
41-
if (json != null && json["http"] != null && json["http"]["routePrefix"] != null)
42-
{
43-
_httpPrefix = json["http"]["routePrefix"].ToString().Trim(new char[] { '/' });
44-
}
45-
}
4633
}
4734

4835
public async Task ExecuteFuncAsync(string funcName, Dictionary<string, object> arguments, CancellationToken cancellationToken)
4936
{
5037
HttpRequestMessage request = arguments[ScriptConstants.AzureFunctionsHttpRequestKey] as HttpRequestMessage;
5138

5239
FunctionDescriptor function = null;
53-
var path = request.RequestUri.AbsolutePath.Trim(new char[] { '/' });
54-
55-
if (path.StartsWith(_httpPrefix))
56-
{
57-
path = path.Remove(0, _httpPrefix.Length);
58-
}
5940

60-
path = path.Trim(new char[] { '/' });
61-
62-
// This is a call to the local function app, before handing the route to asp.net to pick the FunctionDescriptor the following will be run:
63-
// 1. If the request maps to a local http trigger function name then that function will be picked.
64-
// 2. Else if the request maps to a custom route of a local http trigger function then that function will be picked
65-
// 3. Otherwise the request will be given to asp.net to pick the appropriate route.
66-
foreach (var route in _scriptHostManager.Routes)
67-
{
68-
var func = (FunctionDescriptor)route.DataTokens[ScriptConstants.AzureFunctionsHttpFunctionKey];
69-
if (!func.Metadata.IsProxy)
70-
{
71-
if (path.Equals(func.Metadata.Name, StringComparison.OrdinalIgnoreCase))
72-
{
73-
function = func;
74-
break;
75-
}
76-
else
77-
{
78-
foreach (var binding in func.InputBindings)
79-
{
80-
if (binding.Metadata.IsTrigger)
81-
{
82-
string functionRoute = null;
83-
var jsonContent = binding.Metadata.Raw;
84-
if (jsonContent != null && jsonContent["route"] != null)
85-
{
86-
functionRoute = jsonContent["route"].ToString();
87-
}
88-
89-
// BUG: Known issue, This does not work on dynamic routes like products/{category:alpha}/{id:int?}
90-
if (!string.IsNullOrEmpty(functionRoute) && path.Equals(functionRoute, StringComparison.OrdinalIgnoreCase))
91-
{
92-
function = func;
93-
break;
94-
}
95-
}
96-
}
97-
98-
if (function != null)
99-
{
100-
break;
101-
}
102-
}
103-
}
104-
}
105-
106-
if (function == null)
107-
{
108-
function = _scriptHostManager.GetHttpFunctionOrNull(request);
109-
}
41+
// This is a call to the local function app from proxy, in this scenario first match will be against local http triggers then rest of the proxies to avoid infinite redirect for * mappings in proxies.
42+
function = _scriptHostManager.GetHttpFunctionOrNull(request, proxyRoutesFirst: false);
11043

11144
var functionRequestInvoker = new FunctionRequestInvoker(function, _secretManager);
11245
var response = await functionRequestInvoker.PreprocessRequestAsync(request);

src/WebJobs.Script.WebHost/WebJobs.Script.WebHost.csproj

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@
8181
<HintPath>..\..\packages\Microsoft.ApplicationInsights.2.4.0\lib\net46\Microsoft.ApplicationInsights.dll</HintPath>
8282
</Reference>
8383
<Reference Include="Microsoft.AspNet.Razor, Version=4.0.0.0, Culture=neutral, processorArchitecture=MSIL">
84-
<HintPath>..\..\packages\Microsoft.Azure.AppService.Proxy.0.3.2.20\lib\net461\Microsoft.AspNet.Razor.dll</HintPath>
84+
<HintPath>..\..\packages\Microsoft.Azure.AppService.Proxy.1.0.0.1\lib\net461\Microsoft.AspNet.Razor.dll</HintPath>
8585
</Reference>
8686
<Reference Include="Microsoft.AspNet.WebHooks.Common, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
8787
<HintPath>..\..\packages\Microsoft.AspNet.WebHooks.Common.1.2.0\lib\net45\Microsoft.AspNet.WebHooks.Common.dll</HintPath>
@@ -176,14 +176,14 @@
176176
<HintPath>..\..\packages\Microsoft.Azure.ApiHub.Sdk.0.7.2-alpha\lib\net45\Microsoft.Azure.ApiHub.Sdk.dll</HintPath>
177177
<Private>True</Private>
178178
</Reference>
179-
<Reference Include="Microsoft.Azure.AppService.Proxy.Client, Version=0.3.0.0, Culture=neutral, processorArchitecture=MSIL">
180-
<HintPath>..\..\packages\Microsoft.Azure.AppService.Proxy.0.3.2.20\lib\net461\Microsoft.Azure.AppService.Proxy.Client.dll</HintPath>
179+
<Reference Include="Microsoft.Azure.AppService.Proxy.Client, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
180+
<HintPath>..\..\packages\Microsoft.Azure.AppService.Proxy.1.0.0.1\lib\net461\Microsoft.Azure.AppService.Proxy.Client.dll</HintPath>
181181
</Reference>
182-
<Reference Include="Microsoft.Azure.AppService.Proxy.Common, Version=0.3.0.0, Culture=neutral, processorArchitecture=MSIL">
183-
<HintPath>..\..\packages\Microsoft.Azure.AppService.Proxy.0.3.2.20\lib\net461\Microsoft.Azure.AppService.Proxy.Common.dll</HintPath>
182+
<Reference Include="Microsoft.Azure.AppService.Proxy.Common, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
183+
<HintPath>..\..\packages\Microsoft.Azure.AppService.Proxy.1.0.0.1\lib\net461\Microsoft.Azure.AppService.Proxy.Common.dll</HintPath>
184184
</Reference>
185-
<Reference Include="Microsoft.Azure.AppService.Proxy.Runtime, Version=0.3.0.0, Culture=neutral, processorArchitecture=MSIL">
186-
<HintPath>..\..\packages\Microsoft.Azure.AppService.Proxy.0.3.2.20\lib\net461\Microsoft.Azure.AppService.Proxy.Runtime.dll</HintPath>
185+
<Reference Include="Microsoft.Azure.AppService.Proxy.Runtime, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
186+
<HintPath>..\..\packages\Microsoft.Azure.AppService.Proxy.1.0.0.1\lib\net461\Microsoft.Azure.AppService.Proxy.Runtime.dll</HintPath>
187187
</Reference>
188188
<Reference Include="Microsoft.Azure.Documents.ChangeFeedProcessor, Version=1.14.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
189189
<HintPath>..\..\packages\Microsoft.Azure.DocumentDB.ChangeFeedProcessor.1.0.0\lib\net45\Microsoft.Azure.Documents.ChangeFeedProcessor.dll</HintPath>

src/WebJobs.Script.WebHost/WebScriptHostManager.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
using Microsoft.Azure.WebJobs.Script.Eventing;
2727
using Microsoft.Azure.WebJobs.Script.Scale;
2828
using Microsoft.Azure.WebJobs.Script.WebHost.Diagnostics;
29+
using Microsoft.Azure.WebJobs.Script.WebHost.Extensions;
2930
using Microsoft.Extensions.Logging;
3031

3132
namespace Microsoft.Azure.WebJobs.Script.WebHost
@@ -275,7 +276,7 @@ private static object GetWebHookData(Type dataType, WebHookHandlerContext contex
275276
return getDataMethod.Invoke(null, new object[] { context });
276277
}
277278

278-
public FunctionDescriptor GetHttpFunctionOrNull(HttpRequestMessage request)
279+
public FunctionDescriptor GetHttpFunctionOrNull(HttpRequestMessage request, bool proxyRoutesFirst = true)
279280
{
280281
if (request == null)
281282
{
@@ -288,7 +289,7 @@ public FunctionDescriptor GetHttpFunctionOrNull(HttpRequestMessage request)
288289
}
289290

290291
FunctionDescriptor function = null;
291-
var routeData = _httpRoutes.GetRouteData(request);
292+
var routeData = _httpRoutes.GetRouteData(request, proxyRoutesFirst);
292293
if (routeData != null)
293294
{
294295
function = (FunctionDescriptor)routeData.Route.DataTokens[ScriptConstants.AzureFunctionsHttpFunctionKey];

src/WebJobs.Script.WebHost/packages.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
<package id="Microsoft.AspNetCore.Http.Features" version="1.0.2" targetFramework="net46" />
3939
<package id="Microsoft.AspNetCore.WebUtilities" version="1.0.0" targetFramework="net46" />
4040
<package id="Microsoft.Azure.ApiHub.Sdk" version="0.7.2-alpha" targetFramework="net46" />
41-
<package id="Microsoft.Azure.AppService.Proxy" version="0.3.2.20" targetFramework="net461" />
41+
<package id="Microsoft.Azure.AppService.Proxy" version="1.0.0.1" targetFramework="net461" />
4242
<package id="Microsoft.Azure.DocumentDB" version="1.13.2" targetFramework="net46" />
4343
<package id="Microsoft.Azure.DocumentDB.ChangeFeedProcessor" version="1.0.0" targetFramework="net46" />
4444
<package id="Microsoft.Azure.KeyVault.Core" version="1.0.0" targetFramework="net46" />

src/WebJobs.Script/Description/Proxies/ProxyFunctionInvoker.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ internal class ProxyFunctionInvoker : FunctionInvokerBase
1414
private ProxyClientExecutor _proxyClient;
1515

1616
public ProxyFunctionInvoker(ScriptHost host, FunctionMetadata functionMetadata, ProxyClientExecutor proxyClient)
17-
: base(host, functionMetadata, logDirName: "Proxy")
17+
: base(host, functionMetadata)
1818
{
1919
_proxyClient = proxyClient;
2020
}

src/WebJobs.Script/WebJobs.Script.csproj

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,20 +81,20 @@
8181
<HintPath>..\..\packages\Microsoft.ApplicationInsights.2.4.0\lib\net46\Microsoft.ApplicationInsights.dll</HintPath>
8282
</Reference>
8383
<Reference Include="Microsoft.AspNet.Razor, Version=4.0.0.0, Culture=neutral, processorArchitecture=MSIL">
84-
<HintPath>..\..\packages\Microsoft.Azure.AppService.Proxy.0.3.2.20\lib\net461\Microsoft.AspNet.Razor.dll</HintPath>
84+
<HintPath>..\..\packages\Microsoft.Azure.AppService.Proxy.1.0.0.1\lib\net461\Microsoft.AspNet.Razor.dll</HintPath>
8585
</Reference>
8686
<Reference Include="Microsoft.Azure.ApiHub.Sdk, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
8787
<HintPath>..\..\packages\Microsoft.Azure.ApiHub.Sdk.0.7.2-alpha\lib\net45\Microsoft.Azure.ApiHub.Sdk.dll</HintPath>
8888
<Private>True</Private>
8989
</Reference>
90-
<Reference Include="Microsoft.Azure.AppService.Proxy.Client, Version=0.3.0.0, Culture=neutral, processorArchitecture=MSIL">
91-
<HintPath>..\..\packages\Microsoft.Azure.AppService.Proxy.0.3.2.20\lib\net461\Microsoft.Azure.AppService.Proxy.Client.dll</HintPath>
90+
<Reference Include="Microsoft.Azure.AppService.Proxy.Client, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
91+
<HintPath>..\..\packages\Microsoft.Azure.AppService.Proxy.1.0.0.1\lib\net461\Microsoft.Azure.AppService.Proxy.Client.dll</HintPath>
9292
</Reference>
93-
<Reference Include="Microsoft.Azure.AppService.Proxy.Common, Version=0.3.0.0, Culture=neutral, processorArchitecture=MSIL">
94-
<HintPath>..\..\packages\Microsoft.Azure.AppService.Proxy.0.3.2.20\lib\net461\Microsoft.Azure.AppService.Proxy.Common.dll</HintPath>
93+
<Reference Include="Microsoft.Azure.AppService.Proxy.Common, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
94+
<HintPath>..\..\packages\Microsoft.Azure.AppService.Proxy.1.0.0.1\lib\net461\Microsoft.Azure.AppService.Proxy.Common.dll</HintPath>
9595
</Reference>
96-
<Reference Include="Microsoft.Azure.AppService.Proxy.Runtime, Version=0.3.0.0, Culture=neutral, processorArchitecture=MSIL">
97-
<HintPath>..\..\packages\Microsoft.Azure.AppService.Proxy.0.3.2.20\lib\net461\Microsoft.Azure.AppService.Proxy.Runtime.dll</HintPath>
96+
<Reference Include="Microsoft.Azure.AppService.Proxy.Runtime, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
97+
<HintPath>..\..\packages\Microsoft.Azure.AppService.Proxy.1.0.0.1\lib\net461\Microsoft.Azure.AppService.Proxy.Runtime.dll</HintPath>
9898
</Reference>
9999
<Reference Include="Microsoft.Azure.Documents.ChangeFeedProcessor, Version=1.14.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
100100
<HintPath>..\..\packages\Microsoft.Azure.DocumentDB.ChangeFeedProcessor.1.0.0\lib\net45\Microsoft.Azure.Documents.ChangeFeedProcessor.dll</HintPath>

src/WebJobs.Script/packages.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
1515
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net45" />
1616
<package id="Microsoft.Azure.ApiHub.Sdk" version="0.7.2-alpha" targetFramework="net46" />
17-
<package id="Microsoft.Azure.AppService.Proxy" version="0.3.2.20" targetFramework="net461" />
17+
<package id="Microsoft.Azure.AppService.Proxy" version="1.0.0.1" targetFramework="net461" />
1818
<package id="Microsoft.Azure.DocumentDB" version="1.13.2" targetFramework="net46" />
1919
<package id="Microsoft.Azure.DocumentDB.ChangeFeedProcessor" version="1.0.0" targetFramework="net46" />
2020
<package id="Microsoft.Azure.KeyVault.Core" version="1.0.0" targetFramework="net46" />

test/WebJobs.Script.Tests.Integration/ProxyEndToEndTests.cs

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,26 @@ public async Task LocalFunctionCall()
7373
Assert.Equal("Pong", content);
7474
}
7575

76+
[Fact]
77+
public async Task LocalFunctionCallWithoutProxy()
78+
{
79+
HttpResponseMessage response = await _fixture.HttpClient.GetAsync($"api/Ping");
80+
81+
string content = await response.Content.ReadAsStringAsync();
82+
Assert.Equal("200", response.StatusCode.ToString("D"));
83+
Assert.Equal("\"Pong\"", content);
84+
}
85+
86+
[Fact]
87+
public async Task LocalFunctionRouteCallWithoutProxy()
88+
{
89+
HttpResponseMessage response = await _fixture.HttpClient.GetAsync($"api/myroute/mysubroute");
90+
91+
string content = await response.Content.ReadAsStringAsync();
92+
Assert.Equal("200", response.StatusCode.ToString("D"));
93+
Assert.Equal("\"Pong\"", content);
94+
}
95+
7696
[Fact]
7797
public async Task LocalFunctionCallForNonAlphanumericProxyName()
7898
{
@@ -94,15 +114,23 @@ public async Task CatchAllApis()
94114
}
95115

96116
[Fact]
97-
public async Task CatchAll()
117+
public async Task CatchAllWithCustomRoutes()
98118
{
99-
HttpResponseMessage response = await _fixture.HttpClient.GetAsync($"proxy/blahblah");
119+
HttpResponseMessage response = await _fixture.HttpClient.GetAsync($"proxy/api/myroute/mysubroute");
100120

101121
string content = await response.Content.ReadAsStringAsync();
102122
Assert.Equal("200", response.StatusCode.ToString("D"));
103123
Assert.Equal("Pong", content);
104124
}
105125

126+
[Fact]
127+
public async Task CatchAllWithCustomRoutesWithInvalidVerb()
128+
{
129+
HttpResponseMessage response = await _fixture.HttpClient.PutAsync($"proxy/api/myroute/mysubroute", null);
130+
131+
Assert.Equal("404", response.StatusCode.ToString("D"));
132+
}
133+
106134
[Fact]
107135
public async Task LongRoute()
108136
{
@@ -116,6 +144,16 @@ public async Task LongRoute()
116144
Assert.Equal("200", response.StatusCode.ToString("D"));
117145
}
118146

147+
[Fact]
148+
public async Task ProxyCallingLocalProxy()
149+
{
150+
HttpResponseMessage response = await _fixture.HttpClient.GetAsync($"/pr1/api/Ping");
151+
152+
string content = await response.Content.ReadAsStringAsync();
153+
Assert.Equal("200", response.StatusCode.ToString("D"));
154+
Assert.Equal("Pong", content);
155+
}
156+
119157
public class TestFixture : IDisposable
120158
{
121159
private readonly ScriptSettingsManager _settingsManager;

test/WebJobs.Script.Tests.Integration/TestScripts/Proxies/PingRoute/function.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"name": "req",
66
"type": "httpTrigger",
77
"direction": "in",
8-
"route": "myroute"
8+
"route": "myroute/mysubroute"
99
},
1010
{
1111
"name": "$return",

0 commit comments

Comments
 (0)