Exemple #1
0
 def new_file(self, field_name, file_name, content_type, *args, **kwargs):
     if content_type == WavUploadHander.mimeType:
         MemoryFileUploadHandler.new_file(self, field_name, file_name,
                                          content_type, *args, **kwargs)
     else:
         raise TypeError(
             f"Audio file has wrong format, {content_type}. Requires a Wav file instead"
         )
Exemple #2
0
 def test_parse_missing_filename_multiple_upload_handlers(self):
     """
     Parse raw file upload with multiple handlers when filename is missing.
     Regression test for #2109.
     """
     parser = FileUploadParser()
     self.stream.seek(0)
     self.parser_context['request'].upload_handlers = (
         MemoryFileUploadHandler(), MemoryFileUploadHandler())
     self.parser_context['request'].META['HTTP_CONTENT_DISPOSITION'] = ''
     with self.assertRaises(ParseError):
         parser.parse(self.stream, None, self.parser_context)
Exemple #3
0
 def handle_raw_input(self,
                      input_data,
                      META,
                      content_length,
                      boundary,
                      encoding=None):
     if content_length > WavUploadHander.maxSize:
         raise ValueError(
             f"File exceeds maximum length, {WavUploadHander.maxSize} bytes"
         )
     else:
         MemoryFileUploadHandler.handle_raw_input(self, input_data, META,
                                                  content_length, boundary,
                                                  encoding)
 def test_parse_missing_filename_multiple_upload_handlers(self):
     """
     Parse raw file upload with multiple handlers when filename is missing.
     Regression test for #2109.
     """
     parser = FileUploadParser()
     self.stream.seek(0)
     self.parser_context['request'].upload_handlers = (
         MemoryFileUploadHandler(), MemoryFileUploadHandler())
     self.parser_context['request'].META['HTTP_CONTENT_DISPOSITION'] = ''
     with pytest.raises(ParseError) as excinfo:
         parser.parse(self.stream, None, self.parser_context)
     assert str(
         excinfo.value
     ) == 'Missing filename. Request should include a Content-Disposition header with a filename parameter.'
Exemple #5
0
def parse_headers_and_body_with_django(headers, body):
    """Parse `headers` and `body` with Django's :class:`MultiPartParser`.

    `MultiPartParser` is a curiously ugly and RFC non-compliant concoction.

    Amongst other things, it coerces all field names, field data, and
    filenames into Unicode strings using the "replace" error strategy, so be
    warned that your data may be silently mangled.

    It also, in 1.3.1 at least, does not recognise any transfer encodings at
    *all* because its header parsing code was broken.

    I'm also fairly sure that it'll fall over on headers than span more than
    one line.

    In short, it's a piece of code that inspires little confidence, yet we
    must work with it, hence we need to round-trip test multipart handling
    with it.
    """
    handler = MemoryFileUploadHandler()
    meta = {
        "CONTENT_TYPE": headers["Content-Type"],
        "CONTENT_LENGTH": headers["Content-Length"],
    }
    parser = MultiPartParser(
        META=meta, input_data=BytesIO(body),
        upload_handlers=[handler])
    return parser.parse()
Exemple #6
0
    def test_camel_case_multi_part_parser_underscoreize_ignore(self):
        s = """------test_boundary
Content-Disposition: form-data; name="jsonData"\r\n\r\n{"aBc": {"dEf": {"hIj": {"kLm": "nOp"}}}}"""

        class MockRequest:
            pass

        request = MockRequest()
        request.upload_handlers = (MemoryFileUploadHandler(), )
        request.META = {
            "CONTENT_LENGTH": len(s),
            "CONTENT_TYPE": "multipart/form-data; boundary=----test_boundary",
            "HTTP_X_MULTIPART_JSON": "1",
        }
        parser_context = {"request": request}

        class CustomCamelCaseJSONRenderer(CamelCaseMultiPartJSONParser):
            def underscoreize(self, data, **kwargs):
                return super().underscoreize(data,
                                             ignore=["*", "*.dEf.hIj"],
                                             **kwargs)

        parser = CustomCamelCaseJSONRenderer()
        r = self.bytes(s)
        r.META = request.META
        result = parser.parse(
            r,
            "multipart/form-data; boundary=----test_boundary",
            parser_context=parser_context,
        )
        self.assertEqual(result, {"aBc": {"d_ef": {"hIj": {"k_lm": "nOp"}}}})
Exemple #7
0
    def test_camel_case_multi_part_parser(self):
        s = """------test_boundary
Content-Disposition: form-data; name="jsonData"\r\n\r\n{"keyWithNumeric_1":{"keyWithNumeric2":1,"key":2}}"""

        class MockRequest:
            pass

        request = MockRequest()
        request.upload_handlers = (MemoryFileUploadHandler(), )
        request.META = {
            "CONTENT_LENGTH": len(s),
            "CONTENT_TYPE": "multipart/form-data; boundary=----test_boundary",
            "HTTP_X_MULTIPART_JSON": "1",
        }
        parser_context = {"request": request}
        parser = CamelCaseMultiPartJSONParser()
        r = self.bytes(s)
        r.META = request.META
        result = parser.parse(
            r,
            "multipart/form-data; boundary=----test_boundary",
            parser_context=parser_context,
        )
        self.assertEqual(
            result, {"key_with_numeric_1": {
                "key_with_numeric2": 1,
                "key": 2
            }})
Exemple #8
0
 def post(self, request, *args, **kwargs):
     request.upload_handlers = [
         EncryptedFileUploadHandler(request=request),
         MemoryFileUploadHandler(request=request),
         TemporaryFileUploadHandler(request=request)
     ]
     return self._post(request)
Exemple #9
0
    def generic_import_csv(self, request, import_info):
        log_object_change(
            request.user.id,
            f"Import CSV: '{import_info.form_title}'",
        )

        header_list = import_info.header_list
        form_title = import_info.form_title

        # because the files are small, upload them to memory
        # instead of using S3
        request.upload_handlers.insert(0, TemporaryFileUploadHandler(request))
        request.upload_handlers.insert(0, MemoryFileUploadHandler(request))

        if request.method == "POST":
            form = CsvImportForm(
                header_list,
                form_title,
                request.POST,
                request.FILES,
            )
            if form.is_valid():
                success, message = self.process_csv(request, import_info)
                if success:
                    return redirect("..")
        else:
            form = CsvImportForm(header_list, form_title)
        payload = {"form": form}
        return render(request, "admin/csv_form.html", payload)
Exemple #10
0
    def kwargs_update(self, request, kwargs):
        handler = MemoryFileUploadHandler()
        data = MultiPartParser(META=request.META, input_data=BytesIO(request.body), upload_handlers=[handler]).parse()

        # myDict = dict(data.iterlists())
        # qd = QueryDict(str(data[0]))

        kwargs.update(json.loads(data))
Exemple #11
0
    def test_upload(self):
        #   Pretend to upload a file
        file_data = "here is some test data"
        file_size = len(file_data)
        handler = MemoryFileUploadHandler()
        handler.handle_raw_input(file_data, None, file_size, None)
        try:
            handler.new_file('test', 'test_file.txt', 'text/plain', file_size)
        except StopFutureHandlers:
            pass
        file = handler.file_complete(file_size)
        media = Media(friendly_name='Test QSD Media')
        media.handle_file(file, file.name)
        media.save()

        #   Check that the file can be downloaded from the proper link
        url = '/download/%s' % media.hashed_name
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        #   Delete the QSD Media object
        media.delete()

        #   Check that the file can no longer be downloaded
        response = self.client.get(url)
        self.assertEqual(response.status_code, 404)
    def test_upload(self):
        #   Pretend to upload a file
        file_data = "here is some test data"
        file_size = len(file_data)
        handler = MemoryFileUploadHandler()
        handler.handle_raw_input(file_data, None, file_size, None)
        try:
            handler.new_file('test', 'test_file.txt', 'text/plain', file_size)
        except StopFutureHandlers:
            pass
        file = handler.file_complete(file_size)
        media = Media(friendly_name = 'Test QSD Media')
        media.handle_file(file, file.name)
        media.save()

        #   Check that the file can be downloaded from the proper link
        url = '/download/%s' % media.hashed_name
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        #   Delete the QSD Media object
        media.delete()

        #   Check that the file can no longer be downloaded
        response = self.client.get(url)
        self.assertEqual(response.status_code, 404)
    def setUp(self):
        class MockRequest(object):
            pass

        self.stream = io.BytesIO("Test text file".encode('utf-8'))
        request = MockRequest()
        request.upload_handlers = (MemoryFileUploadHandler(), )
        request.META = {
            'HTTP_CONTENT_DISPOSITION':
            'Content-Disposition: inline; filename=file.txt',
            'HTTP_CONTENT_LENGTH': 14,
        }
        self.parser_context = {'request': request, 'kwargs': {}}
Exemple #14
0
def upload(request):
    url = request.POST.get("url", None)
    if not url:
        form = UploadedFileForm(data=request.POST, files=request.FILES)
        if form.is_valid():
            uploaded_file = form.save()
            file_url = uploaded_file.file.url
            try:
                UploadedFile.objects.get(file=uploaded_file.file)
            except UploadedFile.MultipleObjectsReturned:
                uploaded_file.delete()

            data = {
                'path': file_url,
            }
            return HttpResponse(json.dumps(data))
        else:
            return HttpResponseBadRequest(json.dumps({'errors': form.errors}))
    else:
        try:
            # We open the url of the distant file
            distant_file = urllib2.urlopen(url)

            # We check the length of the content (size of the file)
            content_length = int(distant_file.headers.getheader('content-length', settings.FILE_UPLOAD_MAX_MEMORY_SIZE + 1))

            # We get the maximum file upload size
            max_upload_size = getattr(settings, 'AJAX_UPLOAD_MAX_FILESIZE', upload_settings.DEFAULT_MAX_FILESIZE)

            # We check the length of the content
            if 0 < max_upload_size < content_length:
                return HttpResponseBadRequest(json.dumps({'errors': "File too big"}))

            # If it's too big, we store the file on the disk
            if content_length > settings.FILE_UPLOAD_MAX_MEMORY_SIZE:
                handler = TemporaryFileUploadHandler()
            # Else, we put it in memory
            else:
                handler = MemoryFileUploadHandler()
                # Attribute activated needed because of the class implementation
                handler.activated = True

            # try/except needed because of the class implementation
            try:
                # Init the file upload handler
                handler.new_file("url", url.split('/')[-1].split('?')[0],
                    distant_file.headers.getheader('content-type'),
                    content_length
                )
            except StopFutureHandlers:
                pass

            def read_in_chunks(file_object, chunk_size=1024):
                """Lazy function to read a file piece by piece."""
                while True:
                    data = file_object.read(chunk_size)
                    if not data:
                        break
                    yield len(data), data

            # We pass all chunks to the file upload handler
            size = 0
            for read, data in read_in_chunks(distant_file, handler.chunk_size):
                handler.receive_data_chunk(data, None)
                size += read

            # We end the handler and save the file to the model
            uploaded_file = UploadedFile()
            uploaded_file.file.save(handler.file_name, handler.file_complete(size))
            uploaded_file.save()
            file_url = uploaded_file.file.url
            try:
                UploadedFile.objects.get(file=uploaded_file.file)
            except UploadedFile.MultipleObjectsReturned:
                uploaded_file.delete()

            data = {
                'path': file_url,
            }
            return HttpResponse(json.dumps(data))
        except Exception:
            return HttpResponseBadRequest(json.dumps({'errors': "An error occured"}))