alexis
alexis

Reputation: 50190

Can flask send duplicate headers in a response?

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?

Upvotes: 2

Views: 1469

Answers (1)

DarkSuniuM
DarkSuniuM

Reputation: 2582

Request Headers

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

Response Headers

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.

Upvotes: 5

Related Questions