I've created an Azure Function and hosted it in Azure. It accepts "post" and "get" requests and I can run this locally and get some log output when I either GET or POST to it.
When I host this in Azure, I can get the output the same if I do a GET or POST, which is what I expect (via postman).
I'm using a third party tool for a callback to my Azure Function URL. When this callback gets sent, I don't get any output in the Azure CLI for logs. It is using the exact same address as I was using to get my output in the portal.
The third party tool is saying its getting an HTTP 301 response.
Why would the callback be getting an HTTP 301 when I can post/get to the same address from Postman and get a 200 back?
Function code:
[FunctionName("AddressNotification")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation($"Address Callback function hit from req: {req.Host.ToString()}");
var content = await new StreamReader(req.Body).ReadToEndAsync();
log.LogInformation($"Request body: {content}");
return new OkResult();
}
Third party tool saying I'm getting a 301:
I would assume you have https only enabled in your function
Related
I am running an azure function app with runtime 4, .NET 6.0.
When I call the function app in a locally running environment the req.HttpContext.GetServerVariable() always returns null because the IServerVariablesFeature is not supported in the list of context.Features.
When I deploy this to an azure hosted instance of the function app, the variables are populated correctly. I have done extensive research and have been unable to find out if this is intentionally not supported or if I am missing some form of additional configuration in my local environment.
Here is a test function that attempts to read 3 different server variables and returns them as a string and can be called using a get request in postman or via a browser http://localhost:7071/api/GetServerVariable:
public static class TestFunction
{
[FunctionName("GetServerVariable")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "GetServerVariable")] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
var url = req.HttpContext.GetServerVariable("URL");
var remoteAddr = req.HttpContext.GetServerVariable("REMOTE_ADDR");
var https = req.HttpContext.GetServerVariable("HTTPS");
var response = $"Current server variables: URL: {url} - REMOTE_ADDR: {remoteAddr} - HTTPS: {https}";
log.LogWarning(response);
return new OkObjectResult(response);
}
}
According to this document, GetServerVariable returns
null if the server does not support the IServerVariablesFeature feature. May return null or empty if the variable does not exist or is not set.
One of the workaround is to include Forwarded headers Middleware:
Before the request reaches the app, proxy servers, load balancers, and other network appliances usually hide information about the request. The original scheme is lost when HTTPS requests are proxied via HTTP and must be transmitted in a header. The originating client IP address must also be forwarded in a header because an app receives a request from the proxy rather than its true source on the Internet or corporate network.
From the MSDN article:
Although retrieving just the REMOTE_ADDR server variable should be enough, I found resources online that suggested that code like this should also check the HTTP_X_FORWARDED_FOR variable; if the request comes through a proxy server that translates the address, it's this variable that contains the correct address. If you request a server variable that doesn't exist, the ServerVariables property returns an empty string. Therefore, even though this property doesn't appear in my tests, attempting to retrieve its value doesn't cause trouble.
The Forwarded Headers Middleware reads the headers X-Forwarded-For, X-Forwarded-Host and X-Forwarded-Proto and fills in the associated fields on HttpContext.
REFERENCES:- How to access server variables in ASP.Net Core
I have a REST API built in an Azure function. My PUT endpoints are returning the 202 async pattern, but all other endpoints are returning 200s.
This returns a 200 after updating the user's profile image
public async Task<IActionResult> PutProfileImage(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = "profileimage")] HttpRequest req,
ILogger log)
This returns a 202 Accepted and never completes
[FunctionName("PutProfileImage")]
public async Task<IActionResult> PutProfileImage(
[HttpTrigger(AuthorizationLevel.Function, "put", Route = "profileimage")] HttpRequest req,
ILogger log)
Windows 10, VS 2019 16.9.4, Azure Functions V3, .NET Core 3.1. Happy to gather any more info that might help to understand this behavior.
Update 5/8/2021
This is a known issue being tracked here: https://github.com/Azure/Azure-Functions/issues/1878 and here https://github.com/Azure/azure-functions-host/issues/7260
If anyone else finds this, it's a known issue in the Azure Functions runtime. The issue being tracked here: https://github.com/Azure/Azure-Functions/issues/1878 and here https://github.com/Azure/azure-functions-host/issues/7260
I'm creating an Azure Durable function app where the orchestrator run for a while but I need an option to cancel the orchestrator if needed. I'm trying to use the "terminatePostUri" from Postman but it gives me a 404 response.
Other instance management uris like statusQueryGetUri are working as expected.
Here's a code snippet of my Terminate Function.
[FunctionName("klaviyo_terminate_instance")]
public static Task Run([DurableClient(TaskHub = "%KlaviyoTaskHub%")] IDurableOrchestrationClient client,
[QueueTrigger("terminate-queue")] string instanceId)
{
return client.TerminateAsync(instanceId, "Called for terminate instance");
}
Here's the postman response.
So apparently the terminate uri works as a POST request (but not GET) despite not having any payload. Not sure what the reason for that is.
Source: https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-http-api
When I cancel my request from browser to a HTTP Trigger it does not cancel and continues execution when hosted on Azure.
My function example:
[FunctionName("Test")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req,
CancellationToken cancellationToken,
ILogger log)
{
var allCancellationTokens = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, req.HttpContext.RequestAborted);
await Task.Delay(30000, allCancellationTokens.Token);
if (allCancellationTokens.IsCancellationRequested) {
log.LogInformation("Request was cancelled!");
return new StatusCodeResult(499);
}
return new OkObjectResult("Complete");
}
I have been testing the cancellation through Postman and axios cancel tokens.
It works when I run the project locally and cancel it, but does not seem to cancel once it's published to azure.
My expected result would be that it throws an OperationCanceledException if I cancel the request during the await Task.Delay(30000, allCancellationTokens.Token); However when checking logs on Azure Functions, just seems to carry on execution and complete the function.
Steps to reproduce:
Create a HTTP Trigger like the one defined above.
Publish the app to Azure.
Open the functions logs on Azure in the monitor section.
Using Postman, send a request to this function and cancel the request (within the timeout period of 30 seconds).
Won't cancel the request and will still execute.
CancellationToken is helpful for implementing graceful shutdown of your Functions runtime host when it is notified by the Operating System that something has gone wrong to terminate it, please see the following answer for more: https://stackoverflow.com/a/63439515/528779
Using Visual Studio 2017, I created a Function App with a Generic WebHook:
public static class FunctionWebHook
{
[FunctionName("FunctionWebHook")]
public static async Task<object> Run([HttpTrigger(WebHookType = "genericJson")]HttpRequestMessage request, TraceWriter log)
{
log.Info($"Webhook was triggered!");
string jsonContent = await request.Content.ReadAsStringAsync();
log.Info(jsonContent);
return request.CreateResponse(HttpStatusCode.NoContent);
}
}
The code is little more than the default template. I deployed this to my Azure account and tried to invoke it. I used the 'Get function url' link on the portal to get the correct URL, this included both the code and clientId parameters. When I try to POST JSON to the function (with content type set to application/json) I receive a 400 Bad Request:
{"Message":"The 'code' query parameter provided in the HTTP request did not match the expected value."}
I've check the code parameter and it is correct. I've also re-created the Function App several times, however I continue to receive the error. When I invoke the function using the Portal's Run command it executes correctly.
Has anyone come across this issue before?
So I use Restlet Client for any API work and it seems it has a strange issue. I copied the default (Host Key) from the Portal and pasted the URL into the Restlet Client and for some reason the last '==' of the code parameter is dropped. I tried the request using Postman and that request worked!
Thanks for all of the comments and the reply!
Which key did you choose to authenticate your request? There are 3 types of keys. Please choose the default(Function key) and use the generated URL and the key. I tested it on my side and the function key could pass the validation from server.
For more information of function key and host key, link below is for your reference.
Azure Function WebHook API Keys