I would like my flask app to set multiple headers with the same key and different values, like this:
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
I already know that this is equivalent to a single header whose value is a comma-separated list (only for headers that support a list value, of course), but I would rather do it as above. But headers are stored in a dict, so I can't just add a duplicate key.
I am also aware of this question and answer, which says that the requests
module cannot send multiple headers with the same key. But that question is about requests
, and flask
sometimes has extra goodies; also the question is over seven years old, and things happen.
Is that answer up to date? Does it also apply to flask?
You can have duplicated header keys, however, Flask turns them into a text, values separated with comma,
The easiest example would be:
from flask import Flask, request
app = Flask(__name__)
@app.route('/')
def index():
print(request.headers)
return "Hello"
with the following curl
:
curl http://127.0.0.1:5000 -H 'X-HEADER: 1' -H 'X-HEADER: 2'
Flask would print X-Header: 1,2
for X-Header
in headers
Also, you can get a list of values using request.headers.getlist('X-Header')
, but it still sticks the values together and returns a list with only one element. ['1,2']
The request.headers
is an instance of werkzeug.datastructures.EnvironHeaders
Surely you can modify it to use your own headers class.
You can inherit flask.Request
class and create your own request
instance with customized Headers
class
You can read more about EnvironHeaders
here: https://werkzeug.palletsprojects.com/en/1.0.x/datastructures/#werkzeug.datastructures.EnvironHeaders
About the response headers:
All flask responses come from flask.Response
class.
You can return your response from your view like:
from flask import Flask, Response
app = Flask(__name__)
@app.route('/')
def index():
return Response('Hello', headers={'X-Headers': [1, 2]})
You can test this with the following curl
:
curl http://127.0.0.1:5000 -vvv
I added -vvv
to increase verbosity and show Headers
The following will show up in response headers:
< X-Headers: 1
< X-Headers: 2
Also if you don't want to use Response
class,
You can return multiple values from a view
@app.route('/')
def index():
return '<h1>Hello!</h1>', 200, {'X-Headers': [1, 2]}
The first value is the body of your response, the second one is the status code, and the last one is the headers of your response.