3

i am using django-rest framework and i am able to get and set the custom headers using the below META information,

class log_middleware:
def __init__(self, get_response):
    self.get_response = get_response
    # One-time configuration and initialization.

def __call__(self,request):
    # set thread local values
    # This will execute before every request
    correlation_id = request.META['HTTP_X_REQUEST_ID'] if 'HTTP_X_REQUEST_ID' in request.META else str(uuid.uuid4())
    request.META['HTTP_X_REQUEST_ID'] = correlation_id

    #logger.debug("Entered service")

    response = self.get_response(request)

    response['HTTP_X_REQUEST_ID'] = correlation_id

    #logger.debug("Processed response")
    return response

Now in my views.py i am able to get this header as request.META['HTTP_X_REQUEST_ID']. and it is available in the response header

But when I try to log the http header values in uwsgi using the below config,it has '-' empty value field. Because uwsgi has only actual request headers in %var.XXX variable and response headers goes to %headers and it shows only count and the actual values. Issue: https://github.com/unbit/uwsgi/issues/1407

So Is there any way in django to append the data in actual request header instead of response header?

[uwsgi]
master = 1
memory-report = true
module = my_service.wsgi
http = 0.0.0.0:8080
max-requests = 50
processes = 16
log-format = { "ctime": "%(ctime)", "addr": "%(addr)", "method": "%(method)", "uri": "%(uri)", "correlation_id": "%(var.HTTP_X_REQUEST_ID)" }

But the same thing works if i set the header HTTP_X_REQUEST while sending the request itself from the rest client utils.

Naggappan Ramukannan
  • 2,564
  • 9
  • 36
  • 59

1 Answers1

2

If you need middleware, you can use this:

middlewares.py:

def add_header_middleware(get_response):
    def middleware(request):
        request.META['hello'] = 'world'
        response = get_response(request)
        response['world'] = 'hello'
        return response
    return middleware

views.py:

@api_view(['GET'])
def sample_view(request):
    return Response(request.META['hello'])

settings.py:

MIDDLEWARE = [
    # ...
    'your_app.middlewares.add_header_middleware'
]
Gasanov
  • 2,839
  • 1
  • 9
  • 21
  • OK I used MiddlewareMixin, but this seams to be in the updated version. So I need to do this at 2 times one is at process_request (the above will work) and the other is at process_response(because I need to send these headers in response also) so that uwsgi will log the data in the header. – Naggappan Ramukannan May 16 '19 at 10:16
  • @NaggappanRamukannan no, you don't have to make 2 middlewares. I added comments where you can modify response. Just read [official docs on middlewares](https://docs.djangoproject.com/en/2.2/topics/http/middleware/) – Gasanov May 16 '19 at 10:17
  • Thanks this is ok, but this lives only inside the django request. when it is sent out it is not available . when I use runserver it works. But when I use uwsgi it is not having the new header when It is capturing the response and logging that header. But when the header is sent from the client itself then it is available in the uwsgi logs – Naggappan Ramukannan May 16 '19 at 10:22
  • Provide your code - views, middleware and whole `MIDDLEWARE` stack. – Gasanov May 16 '19 at 10:26
  • At least mine gunicorn + nginx return custom header just fine. – Gasanov May 16 '19 at 10:38
  • I have updated my question with more info, and with my MIDDLEWARE stack – Naggappan Ramukannan May 16 '19 at 10:52
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/193458/discussion-between-gasanov-and-naggappan-ramukannan). – Gasanov May 16 '19 at 10:56
  • @NaggappanRamukannan check chat – Gasanov May 16 '19 at 13:05