Django + Nginx X-Accel-Redirect Not Working

Viewed 160

I've been trying to make this work on my own for months now, but I just couldn't figure out what is wrong with my code, I'm running django + gunicorn + nginx, nginx it's set as a reverse proxy to gunicorn and I want download files using nginx which is the best way instead of leaving all the work to django backend which is slow. Anyway here is my sites-available config:

server {
listen 8080;
server_name 127.0.0.1;
client_max_body_size 10M;

location = /favicon.ico { access_log off; log_not_found off; }

location /static/ {
        root /home/myuser/Dev/myproject/src;
}

location / {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://unix:/home/myuser/Dev/myproject/src/myproject.sock;
}

location /attachments/ {
    internal;
    alias /home/myuser/Dev/myproject/src/media/files;
}
}

I tried adding ~^ and ^~ to the location block, changing the name, using absolute paths, nothing worked

my urls.py (here the important url is 'attachment/download/int:id'):

from django.urls import path
from .views import (
    issue_detail_view,
    issue_update_view,
    issue_list_view,
    issue_upload_attachment,
    issue_download_attachment,
    issue_delete_attachment
)

app_name = 'issues'
urlpatterns = [
    path('<int:id>', issue_detail_view, name='issues_detail'),
    path('<int:id>/update', issue_update_view, name='issues_update'),
    path('<int:id>/list', issue_list_view, name='issues_list'),
    path('<int:id>/attachment', issue_upload_attachment, name='issues_upload_attachment'),
    path('<int:id>/attachment/delete', issue_delete_attachment, name='issues_delete_attachment'),
    path('attachment/download/<int:id>', issue_download_attachment, name='issues_download_attachment')
]

and my views.py:

def issue_download_attachment(request, *args, **kwargs):
    id_ = kwargs.get('id')
    attachment = Attachment.objects.get(id=id_)
    filename = attachment.file.name.split('/')[2] #this line gets the filename only ('example.jpg')
    response = HttpResponse()
    # Let NGINX handle it
    #it's inefficient to let django backend handle file downloads
    #response.content = attachment.file.read()
    response["Content-Disposition"] = "attachment; filename={0}".format(filename)
    #I could'n make this next line work to serve files using nginx
    response["X-Accel-Redirect"] = "/attachments/{0}".format(filename)
    return response

files are stored at /home/myuser/Dev/myproject/src/media/files and the uploaded files seem to be owned by the root user and group and other just have read-only permissions (at this point I don't even know if this is important). When I try to download the file, it just shows at my downloads tab the id of the attachment and "interrupted: No file"

I've been following this tutorial on serving files with django and many many others perfectly but I can't get it to work (even all the previous answers here on stackoverflow didn't help me so I'm just thinking this might be an environment error idk)

0 Answers
Related