5

I have a problem viewing incoming custom headers from requests when I'm creating a new API view via the @api_view decorator.

My custom API view looks like this:

 @api_view(['GET'])
 def TestView(request):
   print(request.META)
   return Response({'message': 'test'})

What I'm expecting is doing something like

curl --request GET \ --url http://localhost:8000/test \ --header 'custom: test'

I'd see my custom header called custom to appear in the output. Instead, it's not there at all. From the documentation, it says the following for the request.META field:

A dictionary containing all available HTTP headers. Available headers depend on the client and server, but here are some examples:

Whereas, they don't appear at all in my output. Am I missing something here?

If it's relevant, I register my URL as such:

urlpatterns = [url(r'test', views.TestView, name='test'), ...]

My end goal is to write a custom permission class that will parse the custom header and do something related to authentication with it, and either allow or deny the request. My POC here is just to show the basic example of what I'm dealing with. I can provide the output of the print(request.META) but it's just a wall of text without my expected header present.

3
  • Wrong. Not a duplicate, I explicitly state in my question I am aware of how to access the header and that it isn't present. Commented Dec 27, 2017 at 23:10
  • @rosenthal, duplicates are not bad, not to me, at least. I even wrote an answer (which you kindly chose, which is appreciated) even though I though it was a duplicate. To me, at least, they're just ways of saying "Hey, there might be more info here" :) Commented Dec 28, 2017 at 0:57
  • Left my comment and didn't want to delete it. I was wrong, it honestly was a duplicate and a reminder to keep myself in check sometimes. Commented Dec 29, 2017 at 6:05

1 Answer 1

6

Django prepends HTTP_ to the custom headers. I think (not sure, though) that it might be related to some security issues described here. It also capitalizes them, so your custom header becomes HTTP_CUSTOM

from rest_framework.decorators import api_view
from rest_framework.response import Response

import logging

logger = logging.getLogger('django.test')

@api_view(['GET'])
def TestView(request):
    logger.info('Meta: %s' % request.META['HTTP_CUSTOM'])
    return Response({'message': 'test'})

Correctly outputs (if the logging has been properly configured as described here):

Django version 2.0, using settings 'django_server.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
"GET /test HTTP/1.1" 301 0
Meta: test
"GET /test/ HTTP/1.1" 200 18

Also, as you can see in the output above, Django gives a 301 redirect when the API is hit (I believe this is for authentication purposes? Not sure either) so you'll have to tell your cURL to follow the redirects using --location:

curl --location --request GET \
     --header 'custom: test' http://localhost:8000/test

Also note that all the hyphens (-) in your header's name are transformed to underline symbols (_) so if you call your header something like my-custom, Django will transform it to HTTP_MY_CUSTOM

Sign up to request clarification or add additional context in comments.

2 Comments

Your answer is pretty much exactly what the documentation says that I already read, yet somehow I still missed that it was ending up in the dump. I could've SWORN I didn't see it, but I'm seeing it appear now. Appreciate the extra pair of eyes
Haha... Yep, it happens to all/many of us: stackoverflow.com/questions/45827690/…

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.