views.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. from __future__ import unicode_literals
  2. import contextlib
  3. import hashlib
  4. import json
  5. import os
  6. from django.core.files.uploadedfile import UploadedFile
  7. from django.http import HttpResponse, HttpResponseServerError
  8. from django.utils import six
  9. from django.utils.encoding import force_bytes, force_str
  10. from .models import FileModel
  11. from .tests import UNICODE_FILENAME, UPLOAD_TO
  12. from .uploadhandler import ErroringUploadHandler, QuotaUploadHandler
  13. def file_upload_view(request):
  14. """
  15. Check that a file upload can be updated into the POST dictionary without
  16. going pear-shaped.
  17. """
  18. form_data = request.POST.copy()
  19. form_data.update(request.FILES)
  20. if isinstance(form_data.get('file_field'), UploadedFile) and isinstance(form_data['name'], six.text_type):
  21. # If a file is posted, the dummy client should only post the file name,
  22. # not the full path.
  23. if os.path.dirname(form_data['file_field'].name) != '':
  24. return HttpResponseServerError()
  25. return HttpResponse('')
  26. else:
  27. return HttpResponseServerError()
  28. def file_upload_view_verify(request):
  29. """
  30. Use the sha digest hash to verify the uploaded contents.
  31. """
  32. form_data = request.POST.copy()
  33. form_data.update(request.FILES)
  34. for key, value in form_data.items():
  35. if key.endswith('_hash'):
  36. continue
  37. if key + '_hash' not in form_data:
  38. continue
  39. submitted_hash = form_data[key + '_hash']
  40. if isinstance(value, UploadedFile):
  41. new_hash = hashlib.sha1(value.read()).hexdigest()
  42. else:
  43. new_hash = hashlib.sha1(force_bytes(value)).hexdigest()
  44. if new_hash != submitted_hash:
  45. return HttpResponseServerError()
  46. # Adding large file to the database should succeed
  47. largefile = request.FILES['file_field2']
  48. obj = FileModel()
  49. obj.testfile.save(largefile.name, largefile)
  50. return HttpResponse('')
  51. def file_upload_unicode_name(request):
  52. # Check to see if unicode name came through properly.
  53. if not request.FILES['file_unicode'].name.endswith(UNICODE_FILENAME):
  54. return HttpResponseServerError()
  55. response = None
  56. # Check to make sure the exotic characters are preserved even
  57. # through file save.
  58. uni_named_file = request.FILES['file_unicode']
  59. obj = FileModel.objects.create(testfile=uni_named_file)
  60. full_name = '%s/%s' % (UPLOAD_TO, uni_named_file.name)
  61. if not os.path.exists(full_name):
  62. response = HttpResponseServerError()
  63. # Cleanup the object with its exotic file name immediately.
  64. # (shutil.rmtree used elsewhere in the tests to clean up the
  65. # upload directory has been seen to choke on unicode
  66. # filenames on Windows.)
  67. obj.delete()
  68. os.unlink(full_name)
  69. if response:
  70. return response
  71. else:
  72. return HttpResponse('')
  73. def file_upload_echo(request):
  74. """
  75. Simple view to echo back info about uploaded files for tests.
  76. """
  77. r = {k: f.name for k, f in request.FILES.items()}
  78. return HttpResponse(json.dumps(r))
  79. def file_upload_echo_content(request):
  80. """
  81. Simple view to echo back the content of uploaded files for tests.
  82. """
  83. def read_and_close(f):
  84. with contextlib.closing(f):
  85. return f.read().decode('utf-8')
  86. r = {k: read_and_close(f) for k, f in request.FILES.items()}
  87. return HttpResponse(json.dumps(r))
  88. def file_upload_quota(request):
  89. """
  90. Dynamically add in an upload handler.
  91. """
  92. request.upload_handlers.insert(0, QuotaUploadHandler())
  93. return file_upload_echo(request)
  94. def file_upload_quota_broken(request):
  95. """
  96. You can't change handlers after reading FILES; this view shouldn't work.
  97. """
  98. response = file_upload_echo(request)
  99. request.upload_handlers.insert(0, QuotaUploadHandler())
  100. return response
  101. def file_upload_getlist_count(request):
  102. """
  103. Check the .getlist() function to ensure we receive the correct number of files.
  104. """
  105. file_counts = {}
  106. for key in request.FILES.keys():
  107. file_counts[key] = len(request.FILES.getlist(key))
  108. return HttpResponse(json.dumps(file_counts))
  109. def file_upload_errors(request):
  110. request.upload_handlers.insert(0, ErroringUploadHandler())
  111. return file_upload_echo(request)
  112. def file_upload_filename_case_view(request):
  113. """
  114. Check adding the file to the database will preserve the filename case.
  115. """
  116. file = request.FILES['file_field']
  117. obj = FileModel()
  118. obj.testfile.save(file.name, file)
  119. return HttpResponse('%d' % obj.pk)
  120. def file_upload_content_type_extra(request):
  121. """
  122. Simple view to echo back extra content-type parameters.
  123. """
  124. params = {}
  125. for file_name, uploadedfile in request.FILES.items():
  126. params[file_name] = {
  127. k: force_str(v) for k, v in uploadedfile.content_type_extra.items()
  128. }
  129. return HttpResponse(json.dumps(params))
  130. def file_upload_fd_closing(request, access):
  131. if access == 't':
  132. request.FILES # Trigger file parsing.
  133. return HttpResponse('')