How can I get http referrer in Tornado? - python

class HeaderHandler(tornado.web.RequestHandler):
def get(request):
print request.META.headers["HTTP_REFERER"]
the code doesn't work, tell me that HeaderHandler doesn't has the attribute of META. what wrong with my code ?

The attributes of Tornado's request object are documented at http://www.tornadoweb.org/en/stable/httputil.html#tornado.httputil.HTTPServerRequest
Headers are in self.request.headers, and they do not have the CGI-style HTTP_ prefix:
print(self.request.headers.get("Referer"))

Related

Override Falcon's default error handler when no route matches

When Falcon(-Framework) could not find a route for a specific request, 404 is returned. How can I override this default handler? I want to extend the handler with a custom response.
The default handler when no resource matches is the path_not_found responder:
But as you can see in the _get_responder method of falcon API, it can't be override without some monkey patching.
As far as I can see, there are two different ways to use a custom handler:
Subclass the API class, and overwrite the _get_responder method so it calls your custom handler
Use a default route that matches any route if none of the application ones are matched. You probably prefer to use a sink instead of a route, so you capture any HTTP method (GET, POST...) with the same function.
I would recommend the second option, as it looks much neater.
Your code would look like:
import falcon
class HomeResource:
def on_get(self, req, resp):
resp.body = 'Hello world'
def handle_404(req, resp):
resp.status = falcon.HTTP_404
resp.body = 'Not found'
application = falcon.API()
application.add_route('/', HomeResource())
# any other route should be placed before the handle_404 one
application.add_sink(handle_404, '')
There is a better solution here.
def custom_response_handler(req, resp, ex, params):
resp.status = falcon.HTTP_404
resp.text = "custom text response"
app = falcon.App()
app.add_error_handler(HTTPRouteNotFound, custom_response_handler)

Get request headers using GAE Protocol RPC service method

I am using Google App Engine's Protocol RPC library. I want to get the headers for a request and check that a certain header exists. I can't figure out how to get the requests headers?
The code basically looks like this:
class MyService(remote.Service):
#remote.method(MyRequest, MyResponse)
def my_request(self, request):
# TODO: Check that header exists in request
The passed in request object is of the type 'MyRequest' and doesn't have any header information attached to it.
There is a special method initialize_request_state that allows you to access all of the requests headers.
class MyService(remote.Service):
def initialize_request_state(self, state):
self.headers = state.headers
#remote.method(MyRequest, MyResponse)
def my_request(self, request):
logging.debug(self.headers)

Adding custom response Headers to APIException

I have created a custom exception referring to http://django-rest-framework.org/api-guide/exceptions.html.
Please know that I have my own authentication backend. Hence I am not using rest_framework's authentication module.
For authentication errors, I want to add 'WWW-Authenticate: Token' header to the response that is sent from the exception.
Any ideas will be very helpful.
Update:
Thanks #Pathétique,
This is what I ended up doing.
-Have a base view class named BaseView.
-override the handle_exception method to set appropriate headers, in my case 'WWW-Authenticate'.
Here is the code:
class BaseView(APIView):
def handle_exception(self, exc):
if isinstance(exc, MYEXCEPTION):
self.headers['WWW-Authenticate'] = "Token"
return Response({'detail': exc.detail,
status=exc.status_code, exception=True)
Your thoughts?
Try overriding finalize_response in your rest framework view:
def finalize_response(self, request, *args, **kwargs):
response = super(SomeAPIView, self).finalize_response(request, *args, **kwargs)
response['WWW-Authenticate'] = 'Token'
return response
Edit:
After seeing your update, I think your override of handle_exception should work, I would only add an else statement to call the parent method to cover other exceptions. One thing I noticed in overriding dispatch, which may not be an issue here, is that setting a new key/value for self.headers resulted in a server error that I didn't take the time to track down. Anyways, it seems you are on the right track.
Use the authenticate_header method on your authentication class.
Additionally that'll ensure your responses also have the right 401 Unauthorized status code set, instead of 403 Forbidden.
See here: http://django-rest-framework.org/api-guide/authentication.html#custom-authentication
Your solution is quite correct, in my case I found it more appropiate to add the header and then call the method on the super instance, to maintain default behaviour:
class BaseView(APIView):
def handle_exception(self, exc):
if isinstance(exc, MYEXCEPTION):
self.headers['WWW-Authenticate'] = "Token"
return super().handle_exception(excepto)

http PUT method in python mechanize

I am using python mechanize lib and I am trying to use http PUT method on some url - but I cant find any option for this. I see only GET and POST methods...
If the PUT method is not working maybe some1 can tell me a better lib for doing this?
One possible solution:
class PutRequest(mechanize.Request):
"Extend the mechanize Request class to allow a http PUT"
def get_method(self):
return "PUT"
You can then use this when making a request like this:
browser.open(PutRequest(url,data=your_encoded_params,headers=your_headers))
NOTE: I arrived at this solution by digging into the mechanize code packages to find out where mechanize was setting the HTTP method. I noticed that when we call mechanize.Request, we are using the Request class in _request.py which in turn is extending the Request class in _urllib2_fork.py. The http method is actually set in get_method of the Request class in _urllib2_fork.py. Turns out get_method in _urllib2_fork.py was allowing only GET and POST methods. To get past this limitation, I ended up writing my own put and delete classes that extended mechanize. Request but over-rode get_method() only.
Use Requests:
>>> import requests
>>> result = requests.put("http://httpbin.org/put", data='hello')
>>> result.text
Per documentation:
requests.put(url, data=None, **kwargs)
Sends a PUT request. Returns Response object.
Parameters:
url – URL for the new Request object.
data – (optional) Dictionary or bytes to send in the body of the Request.
**kwargs – Optional arguments that request takes.
Via Mechanize:
import mechanize
import json
class PutRequest(mechanize.Request):
def get_method(self):
return 'PUT'
browser = mechanize.Browser()
browser.open(
PutRequest('http://example.com/',
data=json.dumps({'locale': 'en'}),
headers={'Content-Type': 'application/json'}))
See also http://qxf2.com/blog/python-mechanize-the-missing-manual/ (probably outdated).
Requests does it in a nicer way as Key Zhu said.

Python - Getting fields from http header on server side

I need to know the date/time of client requests.
[I suppose] these informations are embeded in header part of post http requests.
So, how do I get them in a webapp2.RequestHandler class?
class GetPostHeaderFields(webapp2.RequestHandler):
def post(self):
<date or time or datetime whatever> = ???
Tanks for any help.
It depends on the framework you are using. In case of webapp2 it is available as a dictionary object in request.headers . See link
class MyHandler(webapp2.RequestHandler):
def post(self):
name = self.request.get('name')
#Access request headers here
request.headers['Cookie'] = 'test=value' #Could be anything like Authorization, etc
In case of Django you can access it as a dictionary object in request.META, See here

Categories