Reputation: 952
I have a view that after authentication/permissions serves a file as saved in a FileField.
from django.http import StreamingHttpResponse
from rest_framework import viewsets
from rest_framework.decorators import detail_route
from wsgiref.util import FileWrapper
import mimetypes
from myapp.models import MyModel
class ExampleViewSet(viewsets.ViewSet):
# Normal crud (retrive, list, etc.)
@detail_route(methods=['GET'])
def download(self, *args, **kwargs):
pk = self.request.parser_context['kwargs'].get('pk', None)
if pk is None:
raise exceptions.ParseError('no pk')
instance = MyModel.objects.get(pk=pk)
filename = instance.file_field.name.split('/')[-1]
mime = mimetypes.guess_type(filename)[0]
file = instance.file_field.file
response = StreamingHttpResponse(
FileWrapper(open(file, 'rb'), 10240))
response['Content-Type'] = "{0}; charset=utf-8".format(mime)
response['Content-Length'] = file.size
response[
'Content-Disposition'] = 'attachment; filename={0}'.format(filename)
return response
The file itself is a 3.7MB file jpeg that was previously uploaded by the user. Under the upload directory the file is 3.7MB and opens correctly. when downloaded via the browser (Firefox or Chrome) the file is 7.0MB and corrupted (does not have the correct header for jpegs which should start with two specific bytes) when downloaded from curl or wget the file is 3.7MB and opens correctly
The following is curl's output of the response fields using curl -v
curl -v http://localhost:3000/api/school_admin/posters/7/download?token=ZXlKaGJHY2lPaUpJVXpVeE1pSXNJblI1Y0NJNklrcFhWQ0o5LmV5SndhR0Z6YUNJNkltSmpjbmx3ZEY5emFHRXlOVFlrSkRKaUpERXlKR2hzVlUxd2QyOWpTM1pMTnk1VlRuSXZPR1ZNVWs5aFJEVjBVbmR2V21FeVVGVlZiWGhxTTJWb1UzZFhla1JNU3k5RmFqZFRJaXdpY0hKdlptbHNaVjl3YXlJNk15d2laWGh3SWpveE5EY3lOalUyTWpFMGZRLmV6OGg5SWVwLUozYjdQcHJLVGJCZWlSSjJPN1JRdnItaFVuLVg0dmdLZGdtRGdQV0s2ZzkzdktialN2Uy1EVTVkM1hRc2hRZ3YxeVZmQlJhUDBBVlhB -o test.jpeg
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET /api/school_admin/posters/7/download?token=ZXlKaGJHY2lPaUpJVXpVeE1pSXNJblI1Y0NJNklrcFhWQ0o5LmV5SndhR0Z6YUNJNkltSmpjbmx3ZEY5emFHRXlOVFlrSkRKaUpERXlKR2hzVlUxd2QyOWpTM1pMTnk1VlRuSXZPR1ZNVWs5aFJEVjBVbmR2V21FeVVGVlZiWGhxTTJWb1UzZFhla1JNU3k5RmFqZFRJaXdpY0hKdlptbHNaVjl3YXlJNk15d2laWGh3SWpveE5EY3lOalUyTWpFMGZRLmV6OGg5SWVwLUozYjdQcHJLVGJCZWlSSjJPN1JRdnItaFVuLVg0dmdLZGdtRGdQV0s2ZzkzdktialN2Uy1EVTVkM1hRc2hRZ3YxeVZmQlJhUDBBVlhB HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< date: Mon, 29 Aug 2016 18:31:30 GMT
< server: WSGIServer/0.2 CPython/3.4.3
< allow: GET, DELETE, HEAD, OPTIONS
< content-type: image/jpeg; charset=utf-8
< vary: Accept
< content-length: 3947925
< content-disposition: attachment; filename=poster_28F7bdD4caAbCc583831c9E7C9baDaEC88Ecbde6FBAA6aE71cAdC09fd8EFCF7BD515155bec1C3FC6f01c6FEf5Ba76e41952E_Colosseum_in_Rome_Italy_-_April_2007.jpg
< x-frame-options: SAMEORIGIN
< via: 1.1 fedora
< Connection: keep-alive
<
{ [15913 bytes data]
100 3855k 100 3855k 0 0 141M 0 --:--:-- --:--:-- --:--:-- 144M
* Connection #0 to host localhost left intact
Upvotes: 4
Views: 935
Reputation: 952
The problem was solved when I used nginx + uwsgi. I think it has to do with some of the 'Hop-by-hop' headers that django's runserver refuses to add and errors out if I add them manually. Which are generally related to reverse proxies.
Upvotes: 2
Reputation: 213
This is typically caused while uploading files/data through FTP as ASCII file transfer type. The "ASCII transfer type" will transfer the files as regular text files and so no problem. but, the "Binary transfer type" will transfer the data in binary mode which handles the files as binary data instead of text data. Setting your FTP client to Binary will prevent your files from becoming corrupted through ftp transit. Please see the following on how to switch your FTP program to Binary.
Here you should be trying the Binary data as in terms of ASCII.
Upvotes: 0