Dedahujaev
Dedahujaev

Reputation: 18

nginx x-accel redirect to gcloud storage is returning empty HTML page

Stack: I am running django app (DRF) behind nginx proxy server. Media files are stored in Google Cloud Storage's private bucket. Django app along with nginx is hosted in cloud run and has all the necessary permissions to access the bucket. (It can upload files with no problem) Storage backend is django-storages library.

Problem: Server is returning empty html.

PS: I am not using signed urls, since my django app has the necessary permissions & credentials to access the bucket. But I am not sure if this is enough to stream the files to client and whether this is the problem.

My Code:

(django storage) settings.py

# STORAGES
# --------------------------------------------------------------
DOMAIN_NAME = env.str("DOMAIN_NAME")
SECRET_PATH = env.str("G_STORAGE_SECRET_PATH")
GS_CREDENTIALS = service_account.Credentials.from_service_account_file(SECRET_PATH)
GS_BUCKET_NAME = env("GS_BUCKET_NAME")
GS_PROJECT_ID = env.str("GS_PROJECT_ID")
GS_EXPIRATION = env.int("GS_EXPIRATION", 28800)  # 8 hours
GS_IS_GZIPPED = env.bool("GS_IS_GZIPPED", True)
GS_CUSTOM_ENDPOINT = "https://" + DOMAIN_NAME
GS_QUERYSTRING_AUTH = False
MEDIA_LOCATION = "my_project/media"

STORAGES = {
    "default": {
        "BACKEND": "storages.backends.gcloud.GoogleCloudStorage",
        "OPTIONS": {
            "location": MEDIA_LOCATION,
            "file_overwrite": True,           
        },
    },
    
}
MEDIA_URL = f"https://{DOMAIN_NAME}/{GS_BUCKET_NAME}/{MEDIA_LOCATION}/"

urls.py

re_path(
        r"^my_project/media/app/users/(?P<user_id>[^/]+)/files/(?P<filename>[^/]+)/$",
        gcloud_storage.gcloud_redirect,
        name="gcloud_storage_redirect",
    ),

view.py

def gcloud_redirect(request, user_id, filename):
    file_id = filename.split(".")[0]
    user_file = get_object_or_404(UserFile, id=file_id)
    file_URI = user_file.file   
    bucket_name = settings.GS_BUCKET_NAME
    media_prefix = settings.MEDIA_LOCATION
    # Create a response with the X-Accel-Redirect header
    response = HttpResponse(status=200)
    redirect_url = f"/protected/media/{bucket_name}/{media_prefix}/{file_URI}"
    response["X-Accel-Redirect"] = redirect_url
    return response


nginx.conf

 location  /protected/media/ {
      internal;
      proxy_pass https://storage.cloud.google.com/;
      proxy_max_temp_file_size 0;
    }

  
 location / {
          proxy_pass            http://127.0.0.1:$PORT;
          proxy_set_header      Host $host;
          # proxy_set_header Host $http_host;
          proxy_set_header      X-Forwarded-Proto $scheme;
          proxy_set_header      X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_redirect        off;
    }

PS: for proxy_pass I tried both https://storage.cloud.google.com/ and https://storage.googleapis.com/ urls but neither worked.

Django is generating the custom url (with my domain name) but when I make a request to it, It returns an empty html page.

Google Cloud Run logs didn't give any insight.

Desired State: To the client, my custom url should be exposed. To control the access to files, when user makes a request the custom url to get the files, the request goes through the django app, after making sure that user has the right permissions, user's request will be redirected to cloud storage using nginx's x-accel-redirect feature, the url on the url bar stays the same but the files will be streamed directly from google cloud storage.

Upvotes: 0

Views: 45

Answers (0)

Related Questions