How to check contents of incoming HTTP header request - python

I'm playing around with some APIs and I'm trying to figure this out.
I am making a basic HTTP authenticated request to my server via the API. As part of this request, the authenticated key is stored in the HTTP header as username.
So my question is, how do I get the contents of the incoming request such that I can perform a check against it?
What I am trying to do:
if incoming request has header == 'myheader':
do some stuff
else:
return ('not authorised')
For those interested, I am trying to get this to work.
UPDATE
I am using Django

http://docs.djangoproject.com/en/dev/ref/request-response/
HttpRequest.META
A standard Python dictionary containing all available HTTP headers.
Available headers depend on the client and server, but here are some examples:
CONTENT_LENGTH
CONTENT_TYPE
HTTP_ACCEPT_ENCODING
HTTP_ACCEPT_LANGUAGE
HTTP_HOST -- The HTTP Host header sent by the client.
HTTP_REFERER -- The referring page, if any.
HTTP_USER_AGENT -- The client's user-agent string.
QUERY_STRING -- The query string, as a single (unparsed) string.
REMOTE_ADDR -- The IP address of the client.
REMOTE_HOST -- The hostname of the client.
REMOTE_USER -- The user authenticated by the Web server, if any.
REQUEST_METHOD -- A string such as "GET" or "POST".
SERVER_NAME -- The hostname of the server.
SERVER_PORT -- The port of the server.
With the exception of CONTENT_LENGTH and CONTENT_TYPE, as
given above, any HTTP headers in the
request are converted to META keys by
converting all characters to
uppercase, replacing any hyphens with
underscores and adding an HTTP_ prefix
to the name. So, for example, a header
called X-Bender would be mapped to the
META key HTTP_X_BENDER.
So:
if request.META['HTTP_USERNAME']:
blah
else:
blah

The headers are stored in os.environ. So you can access the HTTP headers like this:
import os
if os.environ.haskey("SOME_HEADER"):
# do something with the header, i.e. os.environ["SOME_HEADER"]

Related

osTicket API: create a new ticket in python

I'm trying to use python to create a new ticket, but I can't make osticket accept my API key.
Here is my code:
def post_ticket(json):
headers = {'API-Key': 'mykey'}
response = requests.post("http://mydomani.com/api/tickets.json", data=create_json_ticket(json), headers=headers)
for r in response:
print(r)
I'm getting error 'Valid API key required'.
If I use the PHP script given as example (using same url, key and JSON data) it works fine.
The header key should be "X-API-Key" and not "API-Key".
From osTicket API page:
HTTP Access
Access to the HTTP API is restricted to valid API keys. An X-API-Key
HTTP header must be sent to indicate which API key is to be used with
the request.
The API key must match the remote IP of the connected
HTTP client. The remote IP is checked as usual. If the osTicket server
is sitting behind a reverse proxy, the original IP of the client will
be retrieved from the X-Forwarded-For header, if provided by your
proxy.
Example:
X-API-Key: BA00B76BAA30F62E1940B46CC1C3C73C
Command line Example with Curl:
curl -d "{}" -H "X-API-Key: BA00B76BAA30F62E1940B46CC1C3C73C" https://support.you.tld/api/tickets.json

All http header keys coming as lower case in ConnectionRequest.headers of Autobahn websocket server

Why does autobahn web socket server change all http header keys to lower case? I need to implement authentication token in header with OAuth2 standard with custom header 'Authorization:Bearer $token'. But it seems from autobahn 'request.headers' in onConnect method of WebSocketServerProtocol class all the keys are changed to lower case. What is the reason behind this? Can I use 'authorization' instead of 'Authorization' as the key to fetch auth token from request in this scenario?
According to the HTTP RFC, "HTTP header ... field names are case-insensitive." In your example, any of the following incoming header spellings are equivalent: "Authorization", "authorization", "AuThOrIzAtIoN".
The software in question lower-casifies the header to make lookups easier. You should always use the lower-case version as the key.

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.

How to get Authentication header to persist

I am trying to setup token based authentication in python. using Django/DRF. but this is more about http in general i think.
When users put in username/password I return to them their token via JSON.
The client then can post the token in HTTP Header for me to check.
My problem is I want the token to persist in the header automatically, just like cookies.
When the server says "set-cookie" to browser (Chrome/FF), the browser will automatically send up the cookie without me actually doing anything. Is there something I can do with this token?
I have tried storing it in header: "Authorization", but the browser didn't return it. Is there something like "Set-Authorization"?
thanks
No, only cookies stored in browser persistently. All other headers are transient by HTTP protocol definition.

Should a webserver ignore the request body when request method is not POST or PUT?

I was working on a simple API server using tornado and all requests require the parameter access_token. I was playing with curl, and was surprised to find that DELETE and GET requests will not extract this value from the request body--they only allow this param to be passed via the query string.
ie, when I do
curl -i -X DELETE -d access_token=1234 http://localhost:8888/
In the delete method of my web handler, this returns None:
self.get_argument('access_token', None)
However, when I do
curl -i -X DELETE http://localhost:8888/?access_token=1234
This yields "1234" as expected:
self.get_argument('access_token', None)
I examined the tornado source, and found that the body is only parsed for POST and PUT requests: https://github.com/facebook/tornado/blob/4b346bdde80c1e677ca0e235e04654f8d64b365c/tornado/httpserver.py#L258
Is it correct to ignore the request body for GET, HEAD, and DELETE requests, or is this a choice made by the authors of tornado?
This is correct per the HTTP/1.1 protocol specification.
DELETE and GET requests do not accept entity data enclosed in the request.
According to the definition, get requests retrieve their entity data from the request URI.
HEAD requests are defined as identical to GET requests except that the server should not return a message body in the response.
Therefore the authors of tornado were correct to ignore the "post" data for GET, HEAD, and DELETE.
See HTTP/1.1 Method Definitions
It is a good idea to not to accept requests with the payload if they are not POST or PUT. Just because of security reasons. Some servers, e.g. lighttpd, return server error in this case.

Categories