File Downloader in django

In this article, We will learn how can you download a file from the url in django.

Problem

Two days back, I was working on my office project and there was a link of pdf file. pdf file was at another server and that server was running on http and my website was in https. So when I was downloading the file on that time I was facing following error in the browser's console.  

So basically the problem was of mixed content I am running my website in https and was downloading a file from a server that is http

Here is more about this

https://security.googleblog.com/2020/02/protecting-users-from-insecure_6.html

How I solved this issue

To solve this issue I created one downloader in my same web application(that is in django and ssl enabled)

I created a new view in django which looks like this

Code

import urllib3
from django.http import HttpResponse, HttpResponseNotFound, HttpResponseBadRequest

def download_pdf_by_url(request):
    file_url = request.GET.get("url")
    if file_url:
        arr = file_url.split('/')
        if len(arr)>1:
            http_pool_manager = urllib3.PoolManager()
            res_from_url = http_pool_manager.request("GET", file_url)
            if res_from_url.status != 200:
                return HttpResponseNotFound("File Not Found")
            response = HttpResponse(content_type='application/pdf')
            response['Content-Disposition'] = f'attachment; filename="{arr[-1]}"'
            response.write(res_from_url.data)
            return response
    return HttpResponseBadRequest('Bad Request "url" is required')

Explanation

  1. Above code first checks that url exists in request's querystring or not. If that is not then it returns HttpResponseBadRequest('Bad Request "url" is required')
  2. If that have url then I am just splitting it by / to get the file name
  3. Checking that url is valid or not.
  4. res_from_url = http_pool_manager.request("GET", file_url) line actually requests to the other server and get the results
  5. res_from_url.status != 200 This line I am using because I want to check the status that file is acually exists or not on the other server.
  6. After then I am just getting the data and sending back in the resoponse using following line
    response.write(res_from_url.data)

I have created following line in urls.py file to access this end point

path('download/pdf-by-url/', <my_app>.views.download_pdf.download_pdf_by_url, name='download_pdf_by_url')

I am requesting to the server like as follows

https://<something.com>/my_app/download/pdf-by-url/?url=[my_url]

Note

Make sure you are escaping your url before sending in the query string

Thank You. Happy Coding 😊😊😊

Sourabh Somani
He is Microsoft MVP & C# Corner MVP. His core competencies include Mobile and web applications development using .NET, Python, Node.js, C#, JavaScript, jQuery, SQL Server, NoSQL, MongoDB, and Angular.
Chittorgarh, Rajasthan, India