예제 #1
0
 def test_POST_multipart_with_content_length_zero(self):
     """
     Multipart POST requests with Content-Length >= 0 are valid and need to be handled.
     """
     # According to:
     # https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.13
     # Every request.POST with Content-Length >= 0 is a valid request,
     # this test ensures that we handle Content-Length == 0.
     payload = FakePayload("\r\n".join([
         '--boundary',
         'Content-Disposition: form-data; name="name"',
         '',
         'value',
         '--boundary--'
         '']))
     request = WSGIRequest({
         'REQUEST_METHOD': 'POST',
         'CONTENT_TYPE': 'multipart/form-data; boundary=boundary',
         'CONTENT_LENGTH': 0,
         'wsgi.input': payload,
     })
     self.assertEqual(request.POST, {})
예제 #2
0
 def test_POST_after_body_read_and_stream_read_multipart(self):
     """
     POST should be populated even if body is read first, and then
     the stream is read second. Using multipart/form-data instead of urlencoded.
     """
     payload = FakePayload("\r\n".join([
         '--boundary',
         'Content-Disposition: form-data; name="name"',
         '',
         'value',
         '--boundary--'
         '']))
     request = WSGIRequest({
         'REQUEST_METHOD': 'POST',
         'CONTENT_TYPE': 'multipart/form-data; boundary=boundary',
         'CONTENT_LENGTH': len(payload),
         'wsgi.input': payload,
     })
     request.body  # evaluate
     # Consume enough data to mess up the parsing:
     self.assertEqual(request.read(13), b'--boundary\r\nC')
     self.assertEqual(request.POST, {'name': ['value']})
예제 #3
0
파일: tests.py 프로젝트: ngreloaded/ENV
 def test_body_after_POST_multipart_related(self):
     """
     Reading body after parsing multipart that isn't form-data is allowed
     """
     # Ticket #9054
     # There are cases in which the multipart data is related instead of
     # being a binary upload, in which case it should still be accessible
     # via body.
     payload_data = b"\r\n".join([
         b'--boundary', b'Content-ID: id; name="name"', b'', b'value',
         b'--boundary--'
         b''
     ])
     payload = FakePayload(payload_data)
     request = WSGIRequest({
         'REQUEST_METHOD': 'POST',
         'CONTENT_TYPE': 'multipart/related; boundary=boundary',
         'CONTENT_LENGTH': len(payload),
         'wsgi.input': payload
     })
     self.assertEqual(request.POST, {})
     self.assertEqual(request.body, payload_data)
    def setUp(self):
        """initialize a basic djagno wsgi request."""

        # copied from django.test.client
        self.environ = {
            'HTTP_COOKIE': '',
            'PATH_INFO': '/',
            'REMOTE_ADDR': '127.0.0.1',
            'REQUEST_METHOD': 'GET',
            'SCRIPT_NAME': '',
            'SERVER_NAME': 'testserver',
            'SERVER_PORT': '80',
            'SERVER_PROTOCOL': 'HTTP/1.1',
            'wsgi.version': (1, 0),
            'wsgi.url_scheme': 'http',
            'wsgi.input': FakePayload(b''),
            'wsgi.errors': '',
            'wsgi.multiprocess': True,
            'wsgi.multithread': False,
            'wsgi.run_once': False,
        }
        self.request = WSGIRequest(self.environ)
 def test_body_after_POST_multipart_form_data(self):
     """
     Reading body after parsing multipart/form-data is not allowed
     """
     # Because multipart is used for large amounts of data i.e. file uploads,
     # we don't want the data held in memory twice, and we don't want to
     # silence the error by setting body = '' either.
     for method in HTTP_METHODS_WITH_BODY:
         payload = FakePayload("\r\n".join([
             '--boundary', 'Content-Disposition: form-data; name="name"',
             '', 'value', '--boundary--'
             ''
         ]))
         request = WSGIRequest({
             'REQUEST_METHOD': method,
             'CONTENT_TYPE': 'multipart/form-data; boundary=boundary',
             'CONTENT_LENGTH': len(payload),
             'wsgi.input': payload
         })
         self.assertEqual(request.POST, {'name': ['value']})
         with self.assertRaises(RawPostDataException):
             request.body
예제 #6
0
    def put(self,
            url,
            consumer=None,
            token=None,
            callback=False,
            verifier=None,
            data={},
            content_type=MULTIPART_CONTENT,
            **kwargs):
        """
        Send a resource to the server using PUT.
        """
        # If data has come from JSON remove unicode keys.
        data = dict([(str(k), v) for k, v in data.items()])
        url = get_absolute_url(url)
        params = _get_args(consumer, callback=callback, verifier=verifier)
        params.update(data_keys(data))

        req = oauth.Request(method='PUT', url=url, parameters=params)
        req.sign_request(self.signature_method, consumer, token)
        post_data = encode_multipart(BOUNDARY, data)

        parsed = urlparse.urlparse(url)
        query_string = urllib.urlencode(req, doseq=True)
        r = {
            'CONTENT_LENGTH': len(post_data),
            'CONTENT_TYPE': content_type,
            'PATH_INFO': urllib.unquote(parsed[2]),
            'QUERY_STRING': query_string,
            'REQUEST_METHOD': 'PUT',
            'wsgi.input': FakePayload(post_data),
            'HTTP_HOST': 'api',
            'HTTP_AUTHORIZATION': 'OAuth realm=""',
        }
        r.update(req)

        response = self.request(**r)
        return response
예제 #7
0
    def _prepare_post_request(self, data, user=None):
        payload_content = '''
        {{
            "title": "{c[title]}",
            "summary": "{c[summary]}",
            "rating": {c[rating]},
            "company": "{c[company]}",
            "reviewer": "{c[reviewer]}"
        }}
        '''.format(c=data)

        payload = FakePayload(payload_content)
        request = WSGIRequest({
            'REQUEST_METHOD': 'POST',
            'REMOTE_ADDR': '127.0.0.1',
            'CONTENT_TYPE': 'application/json',
            'CONTENT_LENGTH': '{}'.format(len(payload)),
            'wsgi.input': payload
        })
        if user:
            request.user = user
        request._dont_enforce_csrf_checks = True
        return request
예제 #8
0
 def test_POST_after_body_read_and_stream_read_multipart(self):
     """
     POST should be populated even if body is read first, and then
     the stream is read second. Using multipart/form-data instead of urlencoded.
     """
     payload = FakePayload("\r\n".join([
         "--boundary",
         'Content-Disposition: form-data; name="name"',
         "",
         "value",
         "--boundary--"
         "",
     ]))
     request = WSGIRequest({
         "REQUEST_METHOD": "POST",
         "CONTENT_TYPE": "multipart/form-data; boundary=boundary",
         "CONTENT_LENGTH": len(payload),
         "wsgi.input": payload,
     })
     request.body  # evaluate
     # Consume enough data to mess up the parsing:
     self.assertEqual(request.read(13), b"--boundary\r\nC")
     self.assertEqual(request.POST, {"name": ["value"]})
예제 #9
0
 def test_body_after_POST_multipart_form_data(self):
     """
     Reading body after parsing multipart/form-data is not allowed
     """
     # Because multipart is used for large amounts of data i.e. file uploads,
     # we don't want the data held in memory twice, and we don't want to
     # silence the error by setting body = '' either.
     payload = FakePayload("\r\n".join([
         "--boundary",
         'Content-Disposition: form-data; name="name"',
         "",
         "value",
         "--boundary--",
     ]))
     request = WSGIRequest({
         "REQUEST_METHOD": "POST",
         "CONTENT_TYPE": "multipart/form-data; boundary=boundary",
         "CONTENT_LENGTH": len(payload),
         "wsgi.input": payload,
     })
     self.assertEqual(request.POST, {"name": ["value"]})
     with self.assertRaises(RawPostDataException):
         request.body
예제 #10
0
    def test_invalid_multipart_content_length(self):
        data = 'data'
        boundary = 'boundary'
        parsed = urlparse('/path/')
        environ = self.client._base_environ(**{
            'CONTENT_TYPE': 'multipart/form-data; boundary=%s' % boundary,
            'CONTENT_LENGTH': -1,
            'PATH_INFO': self.client._get_path(parsed),
            'QUERY_STRING': parsed[4],
            'REQUEST_METHOD': 'POST',
            'wsgi.input': FakePayload(data),
        })
        request = WSGIRequest(environ)

        for content_type in self.serializer.content_types.keys():
            if not content_type.startswith('multipart/'):
                continue
            self.assertRaises(
                ValueError,
                self.serializer.deserialize_request,
                request,
                request.META['CONTENT_TYPE']
            )
예제 #11
0
 def request(self, method, path, data='', content_type=None, status=OK):
     if not path.startswith('/'):
         path = '/' + path
     if not isinstance(data, str):
         data = json.dumps(data)
         content_type = content_type or 'application/json'
     parsed = urlparse(path)
     request = {
         'REQUEST_METHOD': method,
         'PATH_INFO': urllib.unquote(parsed[2]),
         'QUERY_STRING': parsed[4],
         'wsgi.input': FakePayload(data),
         'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest',
     }
     if data:
         request['CONTENT_LENGTH'] = len(data)
     if content_type:
         request['CONTENT_TYPE'] = content_type
     response = self.client.request(**request)
     self.assertEqual(response.status_code, status, response.content)
     return (json.loads(response.content)
             if response['Content-Type'].startswith('application/json') else
             response.content)
예제 #12
0
def request_factory_patch(self,
                          path,
                          data=None,
                          content_type=MULTIPART_CONTENT,
                          **extra):
    """
    Construct a PATCH request.
    """
    # pylint: disable=invalid-name

    patch_data = self._encode_data(data or {}, content_type)

    parsed = urlparse(path)
    r = {
        'CONTENT_LENGTH': len(patch_data),
        'CONTENT_TYPE': content_type,
        'PATH_INFO': self._get_path(parsed),
        'QUERY_STRING': parsed[4],
        'REQUEST_METHOD': 'PATCH',
        'wsgi.input': FakePayload(patch_data),
    }
    r.update(extra)
    return self.request(**r)
예제 #13
0
    def move(self,
             path,
             data={},
             content_type=MULTIPART_CONTENT,
             follow=False,
             **extra):
        """
        Send a resource to the server using MOVE.
        """
        parsed = urlparse(path)
        r = {
            'CONTENT_TYPE': 'text/html; charset=utf-8',
            'PATH_INFO': self._get_path(parsed),
            'QUERY_STRING': urlencode(data, doseq=True) or parsed[4],
            'REQUEST_METHOD': 'MOVE',
            'wsgi.input': FakePayload('')
        }
        r.update(extra)

        response = self.request(**r)
        if follow:
            response = self._handle_redirects(response, **extra)
        return response
예제 #14
0
파일: base.py 프로젝트: dlamotte/krankshaft
    def make_request(self,
                     method='GET',
                     path='/',
                     data=None,
                     content_type=None,
                     **extra):
        if data is None:
            data = {}

        payload = None
        content_length = None
        if method not in ('DELETE', 'GET', 'HEAD', 'OPTIONS'):
            if content_type is None:
                content_type = MULTIPART_CONTENT
            encoded = self.client._encode_data(data, content_type)
            content_length = len(encoded)
            payload = FakePayload(encoded)
            data = {}

        if content_type is None:
            content_type = 'text/html; charset=utf-8'

        parsed = urlparse(path)
        environ = self.client._base_environ(
            **{
                'CONTENT_TYPE': content_type,
                'PATH_INFO': self.client._get_path(parsed),
                'QUERY_STRING': urlencode(data, doseq=True) or parsed[4],
                'REQUEST_METHOD': method,
            })

        if payload:
            environ['CONTENT_LENGTH'] = content_length
            environ['wsgi.input'] = payload

        environ.update(extra)
        return WSGIRequest(environ)
예제 #15
0
    def put(self,
            url,
            consumer=None,
            token=None,
            callback=False,
            verifier=None,
            data={},
            content_type=MULTIPART_CONTENT,
            **kwargs):
        """
        Send a resource to the server using PUT.
        """
        url = get_absolute_url(url)
        params = _get_args(consumer, callback=callback, verifier=verifier)
        req = oauth.Request(method='PUT', url=url, parameters=params)

        signature_method = oauth.SignatureMethod_HMAC_SHA1()
        req.sign_request(signature_method, consumer, token)

        post_data = encode_multipart(BOUNDARY, data)

        parsed = urlparse.urlparse(url)
        query_string = urllib.urlencode(req, doseq=True)
        r = {
            'CONTENT_LENGTH': len(post_data),
            'CONTENT_TYPE': content_type,
            'PATH_INFO': urllib.unquote(parsed[2]),
            'QUERY_STRING': query_string,
            'REQUEST_METHOD': 'PUT',
            'wsgi.input': FakePayload(post_data),
            'HTTP_HOST': 'api',
        }
        r.update(req)

        response = self.request(**r)
        return response
예제 #16
0
 def patch(self,
           path,
           data={},
           content_type='application/json',
           follow=False,
           **extra):
     """
     Requests a response from the server using PATH.
     """
     post_data = self._encode_data(data, content_type)
     parsed = urlparse(path)
     r = {
         'CONTENT_LENGTH': len(post_data),
         'CONTENT_TYPE': content_type,
         'PATH_INFO': self._get_path(parsed),
         'QUERY_STRING': force_str(parsed[4]),
         'REQUEST_METHOD': str('PATCH'),
         'wsgi.input': FakePayload(post_data),
     }
     r.update(extra)
     response = self.request(**r)
     if follow:
         response = self._handle_redirects(response, **extra)
     return response
예제 #17
0
 def _base_environ(self, **request):
     result = super(Client, self)._base_environ(**request)
     result["HTTP_USER_AGENT"] = "Django Unittest"
     result["HTTP_REFERER"] = "dummy"
     result["wsgi.input"] = FakePayload("")
     return result
 def _base_environ(self, **request):
     result = super(Client, self)._base_environ(**request)
     result['HTTP_USER_AGENT'] = 'Django Unittest'
     result['HTTP_REFERER'] = 'dummy'
     result['wsgi.input'] = FakePayload('')
     return result
예제 #19
0
 def test_write_after_read(self):
     payload = FakePayload()
     payload.read()
     msg = "Unable to write a payload after it's been read"
     with self.assertRaisesMessage(ValueError, msg):
         payload.write(b"abc")
예제 #20
0
def test_alter_old_distutils_request():
    data = ('\n----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n'
            'Content-Disposition: form-data; name="license"\n\n'
            'BSD\n'
            '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n'
            'Content-Disposition: form-data; name="name"\n\nlocalshop\n'
            '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n'
            'Content-Disposition: form-data; name="metadata_version"\n\n'
            '1.0\n'
            '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n'
            'Content-Disposition: form-data; name="author"\n\n'
            'Michael van Tellingen\n'
            '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n'
            'Content-Disposition: form-data; name="home_page"\n\n'
            'http://github.com/mvantellingen/localshop\n'
            '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n'
            'Content-Disposition: form-data; name=":action"\n\n'
            'submit\n'
            '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n'
            'Content-Disposition: form-data; name="download_url"\n\n'
            'UNKNOWN\n'
            '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n'
            'Content-Disposition: form-data; name="summary"\n\n'
            'A private pypi server including auto-mirroring of pypi.\n'
            '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n'
            'Content-Disposition: form-data; name="author_email"\n\n'
            '[email protected]\n'
            '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n'
            'Content-Disposition: form-data; name="version"\n\n'
            '0.1\n'
            '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n'
            'Content-Disposition: form-data; name="platform"\n\n'
            'UNKNOWN\n'
            '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n'
            'Content-Disposition: form-data; name="classifiers"\n\n'
            'Development Status :: 2 - Pre-Alpha\n'
            '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n'
            'Content-Disposition: form-data; name="classifiers"\n\n'
            'Framework :: Django\n'
            '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n'
            'Content-Disposition: form-data; name="classifiers"\n\n'
            'Intended Audience :: Developers\n'
            '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n'
            'Content-Disposition: form-data; name="classifiers"\n\n'
            'Intended Audience :: System Administrators\n'
            '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n'
            'Content-Disposition: form-data; name="classifiers"\n\n'
            'Operating System :: OS Independent\n'
            '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n'
            'Content-Disposition: form-data; name="classifiers"\n\n'
            'Topic :: Software Development\n'
            '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254\n'
            'Content-Disposition: form-data; name="description"\n\n'
            'UNKNOWN\n'
            '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254--\n')
    content_type = 'multipart/form-data; boundary=--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'

    request = WSGIRequest({
        'REQUEST_METHOD': 'POST',
        'CONTENT_LENGTH': len(data),
        'CONTENT_TYPE': content_type,
        'wsgi.input': FakePayload(data.encode('utf-8')),
    })
    alter_old_distutils_request(request)

    expected_post = MultiValueDict({
        'name': ['localshop'],
        'license': ['BSD'],
        'author': ['Michael van Tellingen'],
        'home_page': ['http://github.com/mvantellingen/localshop'],
        ':action': ['submit'],
        'download_url': ['UNKNOWN'],
        'summary': ['A private pypi server including auto-mirroring of pypi.'],
        'author_email': ['*****@*****.**'],
        'metadata_version': ['1.0'],
        'version': ['0.1'],
        'platform': ['UNKNOWN'],
        'classifiers': [
            'Development Status :: 2 - Pre-Alpha', 'Framework :: Django',
            'Intended Audience :: Developers',
            'Intended Audience :: System Administrators',
            'Operating System :: OS Independent',
            'Topic :: Software Development'
        ],
        'description': ['UNKNOWN']
    })
    expected_files = MultiValueDict()

    assert request.POST == expected_post
    assert request.FILES == expected_files