Editing Response Headers on Linux App Service
Sometimes when working with applications, you may want to customize the response headers - maybe the application you’re working with depends on it, or another service or application that is calling it depends on that header in the response.
On Linux App Services, there is no ‘turn-key’ solution to customizing response headers, but there are other ways that this can be done. Either programatically or through other products that can be used with it.
Programmatically
A quick way that response headers can be changed as needed is through the application itself. With some bit of code added into the functions handling the response, we can append new response headers. It also may be possible to write this so all requests programatically send back custom response headers.
NOTE: There is multiple ways to add response headers for each language. Below is just a select few ways.
Node
Headers can easily be added to any controllers or routes that are set up. The below example uses express
and can be added like the following:
const headerController = router.get("/", (req, res) => {
res.header("Foo", "Bar");
res.json({ message: "Adding a custom header.." });
});
You can also set response headers for all routes by passing a custom function to middleware (app.use()
) before application routes in the middleware chain - via code. Below is an example:
const updateHeadersForAllRoutes = (_req, res, next) => {
res.header("Foo", "Bar");
next();
}
app.use(updateHeadersForAllRoutes);
app.use("/", homeController);
app.use("/api/cpu", fibonacciController);
In plain Node, the following can be done to set headers - the below can be further abstracted into seperate routes:
const server = http.createServer((req, res) => {
res.setHeader('Content-Type', 'text/html');
res.setHeader('Foo', 'bar');
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('ok');
});
We can now see the added header:
Here is documentation for plain Node.
Here is documentation for Express.
Static Javascript applications/SPA’s
- For Static Javascript applications/SPA’s being hosted on a Linux App Service - like Angular, React, Vue, etc. - either something such as an AppGateway would need to be placed in front of the application, ran ontop of a Node server, a custom Docker Image (bringing your own Web Server to serve the static files), or served through a Web Server on a PHP Blessed Image to accomplish this.
This is because SPA’s are typically client-side code, executed in the browser, and have no notation of anything server side - which means they can’t change headers without additional configuration. This concept is nothing Azure specific, but rather programmatic in general.
NOTE: Node Blessed Images on App Service Linux comes with PM2 as a process-manager, but this does not handle changes to request or response headers.
Python
Adding a new response header with Flask:
@app.route('/api/headers')
def headers():
json_res = jsonify({ "message": "Adding custom header.." })
res = make_response(json_res)
res.headers['Foo'] = 'bar'
return res
Flask documentation on response headers.
Django documentation on response headers.
Since Python applications are, by default, served with Gunicorn on App Service given Gunicorn is apart of the Python “Blessed Image” - you can use Gunicorn to set response headers. You can follow this blog post on how to accomplish this - Gunicorn Update HTTP Headers on Azure App Service
Java
Using Spring Boot, we can add them like the below:
@RestController
public class HeadersController {
@GetMapping("/api/headers")
public ResponseEntity<String> addCustomerHeader() {
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("Foo", "Bar");
ResponseEntity<String> responseEntity = new ResponseEntity<String>("Adding a custom header..", responseHeaders,
HttpStatus.OK);
return responseEntity;
}
}
Spring documentation on adding headers to a Response Entity.
ASP NET Core (6)
In a ASP NET Core 6 MVC based project, you can add response headers like the below:
public class HeaderModel : PageModel
{
private readonly ILogger<HeaderModel> _logger;
public HeaderModel(ILogger<HeaderModel> logger)
{
_logger = logger;
}
public void OnGet()
{
Response.Headers.Add("Foo", "Bar");
}
}
Documentation on the ResponseHeaders class can be found here.
PHP
Using Laravel a simple example, we can add response headers like the below:
Route::get('/', function () {
$content = view('welcome');
return response($content)->header('Foo', 'Bar');
});
With plain PHP we do it like this:
<?php
header('Foo: Bar');
echo('Adding a custom header..');
Laravel’s response object documentation can be found here
PHP header documentation
Azure Application Gateway
Response headers can be rewritten by following this guide. Note that using an Application Gateway would place this infront of your application and header rewriting would happen through here.
Further information on editing headers (adding, deleting, or others) with Azure Application Gateway can be seen here.
Some programatic examples seen here can be found in this GitHub repo.
Web Servers
Blessed Images
-
If using the PHP 7.4 or PHP 8.0 Blessed Images, these will come with Apache and NGINX as its respective Web Servers.
If you’d rather add or change response headers through here, a custom startup script would need to be used. This can be done following either of this blog posts:
- PHP Custom Startup Script - App Service Linux - Apache - this post also includes a way to include headers into Apache.
- How to set Nginx headers -
- For the current PHP 8.x Blessed Images - NGINX is the default, but adding the App Setting
WEBSITES_DISABLE_FPM
will pull a PHP 8.x image using Apache as the Web Server.
-
For Tomcat containers - bringing your own
web.xml
or custom Tomcat Installation may need to be done to do this through the Web Server itself. Embedded Tomcat in Spring Boot applications would be able to do this without the need for a custom installation.
NOTE:
web.config
files would NOT work in any of these scenarios since this is specific to IIS. Additionally, Apache and NGINX are only available on PHP Blessed Images and not available in any other images.
Custom Docker Images
If you’d rather have more control over how to set up a Web Server to change response headers, rather than programatically, or through an additional service in front like App Gateway, another recommendation would be to bring your own Custom Docker Image.
You have more of a choice on which Web Server to use and additional configuration through this.
Application Gateway
If one is not able to do a “programmatic” or code-related configuration approach, then it’s possible to follow what’s here - Application Gateway - Rewrite HTTP headers and URL with Application Gateway.
This applies to both request and response headers. See the above link for more information.