Skip to content

Commit 58cf779

Browse files
authored
allow modifying response directly in function when calling from proxy (#5444)
* allow modifying response directly in function when calling from proxy * some tests changes
1 parent ddc8539 commit 58cf779

File tree

6 files changed

+79
-5
lines changed

6 files changed

+79
-5
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
<PackageReference Include="DotNetTI.BreakingChangeAnalysis" Version="1.0.5-preview" />
6767
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.0" />
6868
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.0" />
69-
<PackageReference Include="Microsoft.Azure.AppService.Proxy.Client" Version="2.0.10120001-f33e57bd" />
69+
<PackageReference Include="Microsoft.Azure.AppService.Proxy.Client" Version="2.0.11020001-fabe022e" />
7070
<PackageReference Include="Microsoft.Azure.Services.AppAuthentication" Version="1.0.3" />
7171
<PackageReference Include="Microsoft.Azure.WebJobs" Version="3.0.15" />
7272
<PackageReference Include="Microsoft.Azure.KeyVault" Version="3.0.3" />

src/WebJobs.Script/WebJobs.Script.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
<PackageReference Include="Google.Protobuf" Version="3.7.0" />
4040
<PackageReference Include="Grpc.Core" Version="1.20.1" />
4141
<PackageReference Include="Microsoft.AspNetCore.Http.Features" Version="3.1.0" />
42-
<PackageReference Include="Microsoft.Azure.AppService.Proxy.Client" Version="2.0.10120001-f33e57bd" />
42+
<PackageReference Include="Microsoft.Azure.AppService.Proxy.Client" Version="2.0.11020001-fabe022e" />
4343
<PackageReference Include="Microsoft.Azure.Functions.JavaWorker" Version="1.5.2-SNAPSHOT" />
4444
<PackageReference Include="Microsoft.Azure.Functions.NodeJsWorker" Version="2.0.1" />
4545
<PackageReference Include="Microsoft.Azure.Functions.PowerShellWorker" Version="1.0.201" />
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"bindings": [
3+
{
4+
"authLevel": "anonymous",
5+
"name": "req",
6+
"type": "httpTrigger",
7+
"direction": "in",
8+
"route": "pingMakeResponse"
9+
},
10+
{
11+
"name": "$return",
12+
"type": "http",
13+
"direction": "out"
14+
}
15+
],
16+
"disabled": false
17+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
public static string Run(HttpRequest req)
2+
{
3+
if (req.Headers.ContainsKey("return_test_header"))
4+
{
5+
req.HttpContext.Response.Headers.Add("test_header_from_function", "test_header_from_function_value");
6+
}
7+
if (req.Headers.ContainsKey("return_201"))
8+
{
9+
req.HttpContext.Response.StatusCode = 201;
10+
}
11+
if (req.Headers.ContainsKey("redirect"))
12+
{
13+
req.HttpContext.Response.Redirect("http://www.redirects-regardless.com/"); ;
14+
}
15+
return "Pong";
16+
}

test/WebJobs.Script.Tests.Integration/TestScripts/Proxies/proxies.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,11 +199,23 @@
199199
"response.headers.Content-Length": "888",
200200
"response.headers.Test": "test"
201201
}
202-
202+
},
203+
"pingMakeResponseProxy": {
204+
"matchCondition": {
205+
"route": "pingMakeResponseProxy"
206+
},
207+
"backendUri": "http://localhost/api/pingMakeResponse",
208+
"requestOverrides": {
209+
"backend.request.headers.accept": "text/plain"
210+
},
211+
"responseOverrides": {
212+
"response.headers.test_header_from_override": "test_header_from_override_value"
213+
}
203214
}
204215

205216

206217

218+
207219
}
208220
}
209221

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

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public async Task ListFunctions_Proxies_Succeeds()
4545
var response = await _fixture.HttpClient.SendAsync(request);
4646
var metadata = (await response.Content.ReadAsAsync<IEnumerable<FunctionMetadataResponse>>()).ToArray();
4747

48-
Assert.Equal(22, metadata.Length);
48+
Assert.Equal(24, metadata.Length);
4949
var function = metadata.Single(p => p.Name == "PingRoute");
5050
Assert.Equal("https://localhost/api/myroute/mysubroute", function.InvokeUrlTemplate.AbsoluteUri);
5151

@@ -55,14 +55,17 @@ public async Task ListFunctions_Proxies_Succeeds()
5555
function = metadata.Single(p => p.Name == "LocalFunctionCall");
5656
Assert.Equal("https://localhost/api/myhttptrigger", function.InvokeUrlTemplate.AbsoluteUri);
5757

58+
function = metadata.Single(p => p.Name == "PingMakeResponse");
59+
Assert.Equal("https://localhost/api/pingmakeresponse", function.InvokeUrlTemplate.AbsoluteUri);
60+
5861
// get functions omitting proxies
5962
uri = "admin/functions";
6063
request = new HttpRequestMessage(HttpMethod.Get, uri);
6164
request.Headers.Add(AuthenticationLevelHandler.FunctionsKeyHeaderName, "1234");
6265
response = await _fixture.HttpClient.SendAsync(request);
6366
metadata = (await response.Content.ReadAsAsync<IEnumerable<FunctionMetadataResponse>>()).ToArray();
6467
Assert.False(metadata.Any(p => p.IsProxy));
65-
Assert.Equal(3, metadata.Length);
68+
Assert.Equal(4, metadata.Length);
6669
}
6770

6871
[Fact]
@@ -111,6 +114,32 @@ public async Task LocalFunctionCall()
111114
Assert.Equal("Pong", content);
112115
}
113116

117+
[Fact]
118+
public async Task LocalFunctionCall_ModifyResponse()
119+
{
120+
HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Get, $"pingMakeResponseProxy");
121+
req.Headers.Add("return_test_header", "1");
122+
req.Headers.Add("return_201", "1");
123+
HttpResponseMessage response = await _fixture.HttpClient.SendAsync(req);
124+
string content = await response.Content.ReadAsStringAsync();
125+
Assert.Equal("201", response.StatusCode.ToString("D"));
126+
Assert.Equal("test_header_from_function_value", response.Headers.GetValues("test_header_from_function").First());
127+
Assert.Equal("test_header_from_override_value", response.Headers.GetValues("test_header_from_override").First());
128+
Assert.Equal(@"Pong", content);
129+
}
130+
131+
[Fact]
132+
public async Task LocalFunctionCall_Redirect()
133+
{
134+
HttpRequestMessage req = new HttpRequestMessage(HttpMethod.Get, $"pingMakeResponseProxy");
135+
req.Headers.Add("redirect", "1");
136+
HttpResponseMessage response = await _fixture.HttpClient.SendAsync(req);
137+
string content = await response.Content.ReadAsStringAsync();
138+
Assert.Equal("302", response.StatusCode.ToString("D"));
139+
Assert.Equal("http://www.redirects-regardless.com/", response.Headers.Location.ToString());
140+
Assert.Equal(@"Pong", content);
141+
}
142+
114143
[Fact]
115144
public async Task LocalFunctionCallWithAuth()
116145
{

0 commit comments

Comments
 (0)