How can I set custom Server header with Tornado? - python

I noticed that my app returns this HTTP response header:
Server: TornadoServer/4.5.2
Is it possible to change it to custom?

Use RequestHandler.set_default_headers()
Do note that setting such headers in the normal flow of request processing may not do what you want, since headers may be reset during error handling.
Here is the source from the documentation.

You can use the RequestHandler.set_header() for the headers you want to add or change.
Here is an example
RequestHandler.set_header('Access-Control-Allow-Origin', '*')
RequestHandler.set_header('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS')
RequestHandler.set_header('Access-Control-Max-Age', 1000)

you also can use RequestHandler.set_header().
this method will change the finally return response header.

Related

Redirect to OAuth URL with headers

I'm trying to write a Python 3.5 Flask application that redirects a user to an OAuth URL, for authentication / authorization. As part of that redirection, I have to include the Authorization header. The built-in redirect() method in Flask doesn't seem to support adding HTTP headers.
What's the proper way of handling this in such an application?
You will need to build your own response object to add headers. You can check out the docs here: http://docs.python-requests.org/en/master/api/#requests.Response
A simple example for your use case would be something like:
response = Response(headers={'Authorization': 'whatever'},
is_redirect=True,
url="https://your-redirected-url.com")
return response
Edit: Further info
Also, I would check out https://github.com/lepture/flask-oauthlib if you are interested in using a library. It has support for oAuth1 and oAuth2 and it is relatively easy to setup with a standard Flask app.
Edit: Another way of doing it
This morning I remembered a simpler way to do this. You can call the redirect function and it will return a flask Response object. Then you are able to set the headers on that newly created object.
response = redirect('https://url')
response.headers = {'authorization': 'whatever'}
return response

Flask/Eve + WSGI and HTTP_X_HTTP_METHOD_OVERRIDE

I am trying to understand how and when the WSGI environment HTTP Header(s) get renamed in an app's request object.
I am trying Eve and I am sending a POST or a PUT with X-HTTP-Method-Override.
The code, within Eve, is trying to access the request headers using the following code (here):
return request.headers.get('X-HTTP-Method-Override', request.method)
In my WSGI Environment I have a HTTP_X_HTTP_METHOD_OVERRIDE with value PATCH.
When I try to do a request.headers dump, I get:
Request Header: ('X-Http-Method-Override', u'PATCH')
Request Header: ('Origin', u'http://localhost:9000')
Request Header: ('Content-Length', u'622')
Request Header: ('Host', u'localhost:24435')
Request Header: ('Accept', u'application/json;charset=UTF-8')
Request Header: ('Content-Type', u'application/json')
Request Header: ('Accept-Encoding', u'identity')
I checked online and other Python applications are trying to access this specific request header with the case:
X-HTTP-Method-Override and not X-Http-Method-Override (which I get in request)
Flask takes care of extracting the headers from the WSGI environment variables for you, in the process removing the initial HTTP_ prefix. The prefix is there in the WSGI environment to distinguish the headers from other WSGI information, but that prefix is entirely redundant once you extracted the headers into a dedicated structure.
The request object also provides you with a specialised dictionary where keys are matched case insensitively. It doesn't matter what case you use here, as long as the lowercased version matches the lowercased header key; http, Http, HTTP and HtTp all are valid case variations. That's because the HTTP standard explicitly states that case should be ignored when handling headers.
See the Headers class reference in the Werkzeug documentation, it is the bases for the request.headers object. It in turn is compatible with the wsgiref.headers.Headers class, including this:
For each of these methods, the key is the header name (treated case-insensitively), and the value is the first value associated with that header name.
Emphasis mine.

Specify request method with urllib2?

This code produces a POST request:
urllib2.urlopen("http://somedomain.com/", data)
I would like to produce a GET request - any ideas on how to do that?
Thanks for the help!
Try:
urllib2.urlopen("http://somedomain.com/?" + data)
[edited]
If you want to send xml/json/etc data in the body, use something like:
urllib2.urlopen("http://somedomain.com/?" + parameters, data)
This will use the POST method, but any "GET" parameters will also be available to your application.
Alternatively, you also use requests that has a more explicit API:
Make a GET request:
r = requests.get('https://github.com/timeline.json')
Make a POST request:
r = requests.post("http://httpbin.org/post")

Flask/Werkzeug how to attach HTTP content-length header to file download

I am using Flask (based on Werkzeug) which uses Python.
The user can download a file, I'm using the send_from_directory-function.
However when actually downloading the file, the HTTP header content-length is not set. So the user has no idea how big the file being downloaded is.
I can use os.path.getsize(FILE_LOCATION) in Python to get the file size (in bytes), but cannot find a way to set the content-length header in Flask.
Any ideas?
I needed this also, but for every requests, so here's what I did (based on the doc) :
#app.after_request
def after_request(response):
response.headers.add('Access-Control-Allow-Origin', '*')
return response
Since version 0.6 the canonical way to add headers to a response object is via the make_response method (see Flask docs).
def index():
response = make_response(render_template('index.html', foo=42))
response.headers['X-Parachutes'] = 'parachutes are cool'
return response
I believe you'd do something like this (untested):
from flask import Response
response = Response()
response.headers.add('content-length', str(os.path.getsize(FILE_LOCATION)))
See: Werkzug's Headers object and Flask's Response object.

Really weird Cookie header behaviour? - Cookies

I'm using Firefox 3.6.8 for these tests.
I'm setting a cookie within the response headers of my web app using:
Set-Cookie: session=7878dfdsfjsdf89sd89f8df9
This does not seem to override the session Cookie.
When a request is performed instead Firefox even sends duplicate cookies:
Cookie: session=7d75cd8f55895cbccb0d31ee07c7afc0;
session=671e8448a5cebda0442005a186cf69a3;
4cb6f2d75c9ffc8916cb55bcbaafecd8
What is going on??
Any ideas would be great!! =)
This is quite disastrous in my case... if someone could explain what's going on it would really help me out!
If you don't specify the path or domain for a cookie when setting it, it defaults to the current path and current hostname. If you then go ahead and try setting the same cookie name from a URL with a different path or hostname, it will add a new cookie instead of replacing the old one.
I suspect what you want to do is just set a cookie with a global path for your site and for your entire domain. So something like this:
Set-Cookie: session=7878dfdsfjsdf89sd89f8df9; path=/; domain=.mysite.com
You can delete the previous cookie using the response object.
response.delete_cookie(cookie_key)
The set of cookies is available via the request object in the request.COOKIES dictionary, and you can obtain the key from there.
Since you're using Django, here's how you might do this in the view function:
def my_view(request):
# do some work and create a response object
response = HttpResponse(some_content)
# first delete any previously set cookie named "session"
if 'session' in request.COOKIES:
response.delete_cookie('session')
# set the new cookie
response.set_cookie('session', <cookie value goes here>')
return response

Categories