def test_POST_after_body_read_and_stream_read(self):
     """
     POST should be populated even if body is read first, and then
     the stream is read second.
     """
     for method in HTTP_METHODS_WITH_BODY:
         payload = FakePayload('{"name": "佚名"}')
         request = WSGIRequest({
             'REQUEST_METHOD': 'POST',
             'CONTENT_TYPE': 'application/json',
             'CONTENT_LENGTH': len(payload),
             'wsgi.input': payload
         })
         request.body  # evaluate
         self.assertEqual(request.read(1), b'{')
         self.assertEqual(request.POST, {'name': '佚名'})
         self.assertEqual(request.data, {'name': '佚名'})
Пример #2
0
    def patch(self, uri, format='json', data=None, authentication=None, **kwargs):
        """
        Performs a simulated ``PATCH`` request to the provided URI.

        Optionally accepts a ``data`` kwarg. **Unlike** ``GET``, in ``PATCH`` the
        ``data`` gets serialized & sent as the body instead of becoming part of the URI.
        Example::

            from tastypie.test import TestApiClient
            client = TestApiClient()

            response = client.patch('/api/v1/entry/1/', data={
                'created': '2012-05-01T20:02:36',
                'slug': 'another-post',
                'title': 'Another Post',
                'user': '******',
            })

        Optionally accepts an ``authentication`` kwarg, which should be an HTTP header
        with the correct authentication data already setup.

        All other ``**kwargs`` passed in get passed through to the Django
        ``TestClient``. See https://docs.djangoproject.com/en/dev/topics/testing/#module-django.test.client
        for details.
        """
        content_type = self.get_content_type(format)
        kwargs['content_type'] = content_type

        if data is not None:
            kwargs['data'] = self.serializer.serialize(data, format=content_type)

        if authentication is not None:
            kwargs['HTTP_AUTHORIZATION'] = authentication

        # This hurts because Django doesn't support PATCH natively.
        parsed = urlparse(uri)
        r = {
            'CONTENT_LENGTH': len(kwargs['data']),
            'CONTENT_TYPE': content_type,
            'PATH_INFO': self.client._get_path(parsed),
            'QUERY_STRING': parsed[4],
            'REQUEST_METHOD': 'PATCH',
            'wsgi.input': FakePayload(str(kwargs['data'])),
        }
        r.update(kwargs)
        return self.client.request(**r)
Пример #3
0
 def generic(self, method, path,
         data='', content_type='application/octet-stream', **extra):
     parsed = _urlparse(path)
     data = force_bytes_or_smart_bytes(data, settings.DEFAULT_CHARSET)
     r = {
         'PATH_INFO': self._get_path(parsed),
         'QUERY_STRING': force_text(parsed[4]),
         'REQUEST_METHOD': six.text_type(method),
     }
     if data:
         r.update({
             'CONTENT_LENGTH': len(data),
             'CONTENT_TYPE': six.text_type(content_type),
             'wsgi.input': FakePayload(data),
         })
     r.update(extra)
     return self.request(**r)
Пример #4
0
 def test_patch(self):
     """PATCH should edit some attributes."""
     ci_count_before = CI.objects.count()
     ci_data = json.dumps({
         'business_owners':
         ['/api/v0.9/ciowners/{0}/'.format(self.owner1.id)],
         'technical_owners':
         ['/api/v0.9/ciowners/{0}/'.format(self.owner2.id)],
         'attributes': [
             {
                 'name': 'SLA value',
                 'value': 0.7,
             },
             {
                 'name':
                 'Documentation Link',
                 'value':
                 'http://www.gutenberg.org/files/27827/'
                 '27827-h/27827-h.htm',
             },
         ],
     })
     req_data = {
         'CONTENT_LENGTH': len(ci_data),
         'CONTENT_TYPE': 'application/json',
         'PATH_INFO': '/api/v0.9/ci/{0}/'.format(self.ci1.id),
         'REQUEST_METHOD': 'PATCH',
         'wsgi.input': FakePayload(ci_data),
     }
     req_data.update(self.headers)
     self.client.request(**req_data)
     self.assertEqual(CI.objects.count(), ci_count_before)
     edited = CI.objects.get(pk=self.ci1.id)
     self.assertEqual(edited.name, 'ciname1')
     self.assertEqual(edited.uid, 'uid-ci1')
     self.assertSetEqual(
         set(edited.business_owners.all()),
         {self.owner1},
     )
     self.assertSetEqual(
         set(av.value for av in edited.ciattributevalue_set.all()),
         {
             0.7,
             'http://www.gutenberg.org/files/27827/27827-h/27827-h.htm',
         },
     )
 def test_value_after_read(self):
     """
     Construction of POST or body is not allowed after reading
     from request.
     """
     for method in HTTP_METHODS_WITH_BODY:
         payload = FakePayload('{"name": "value"}')
         request = WSGIRequest({
             'REQUEST_METHOD': 'POST',
             'CONTENT_TYPE': 'application/json',
             'CONTENT_LENGTH': len(payload),
             'wsgi.input': payload
         })
         self.assertEqual(request.read(2), b'{"')
         with self.assertRaises(RawPostDataException):
             request.body
         self.assertEqual(request.data, {})
Пример #6
0
 def test_file_passes(self):
     payload = FakePayload("\r\n".join([
         "--boundary",
         'Content-Disposition: form-data; name="file1"; '
         'filename="test.file"',
         "",
         "value",
         "--boundary--",
     ]))
     request = WSGIRequest({
         "REQUEST_METHOD": "POST",
         "CONTENT_TYPE": "multipart/form-data; boundary=boundary",
         "CONTENT_LENGTH": len(payload),
         "wsgi.input": payload,
     })
     with self.settings(DATA_UPLOAD_MAX_MEMORY_SIZE=1):
         request._load_post_and_files()
         self.assertIn("file1", request.FILES, "Upload file not present")
Пример #7
0
 def setUp(self):
     payload = FakePayload("\r\n".join([
         "--boundary",
         'Content-Disposition: form-data; name="name1"',
         "",
         "value1",
         "--boundary",
         'Content-Disposition: form-data; name="name2"',
         "",
         "value2",
         "--boundary--",
     ]))
     self.request = WSGIRequest({
         "REQUEST_METHOD": "POST",
         "CONTENT_TYPE": "multipart/form-data; boundary=boundary",
         "CONTENT_LENGTH": len(payload),
         "wsgi.input": payload,
     })
Пример #8
0
def test_json_resonse_mixin():
    class ViewClass(JsonRequestMixin, View):
        def post(self, request):
            return self.data()

    view = ViewClass.as_view()
    data = u'\N{SNOWMAN}'
    encoded_data = json.dumps(data).encode('utf-16')
    # BBB: Just use RequestFactory.generic in Django >= 1.5
    params = {
        'wsgi.input': FakePayload(encoded_data),
        'CONTENT_TYPE': 'application/json',
        'CONTENT_LENGTH': len(encoded_data),
    }
    request = RequestFactory().post('/', **params)
    request.encoding = 'utf-16'
    response = view(request)
    assert response == data
Пример #9
0
    def patch(self, path, data={}, content_type=MULTIPART_CONTENT, **extra):
        "Construct a PATCH request."
        warn(
            "This custom patch method here is deprecated in Django 1.5 by the ``generic`` method."
        )
        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': parsed[4],
            'REQUEST_METHOD': 'PATCH',
            'wsgi.input': FakePayload(post_data),
        }
        r.update(extra)
        return self.request(**r)
Пример #10
0
 def test_POST_immutable_for_multipart(self):
     """
     MultiPartParser.parse() leaves request.POST immutable.
     """
     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.assertFalse(request.POST._mutable)
Пример #11
0
 def test_POST_immutable_for_multipart(self):
     """
     MultiPartParser.parse() leaves request.POST immutable.
     """
     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.assertFalse(request.POST._mutable)
Пример #12
0
def get_render_from_response(request, url, get_forwarding=False):
    path, query = url, ''

    if '?' in url:
        path, query = url.split('?', 1)
        query = query.encode('utf-8')

    if request and request.GET:

        try:
            requestpath = request.get_full_path()
            path2, query2 = requestpath.split('?', 1)
            query2 = query2.encode('utf-8')
            if query:
                query += '&' + query2
            else:
                query = query2
        except:
            pass

    if request:
        meta = dict(request.META, PATH_INFO=path, QUERY_STRING=query)
        if not get_forwarding:
            meta = dict(request.META, PATH_INFO=path, QUERY_STRING='')
    else:
        meta = dict(PATH_INFO=path)
        # this is because django 1.3 now checking wsgi.input attribute in
        # request https://code.djangoproject.com/changeset/14453
        meta['wsgi.input'] = FakePayload('')  # XXX maybe not needed since 1.4?
    response = Client().request(**meta)

    if isinstance(response, http.HttpResponseRedirect):
        url = response['Location']
        host = request.get_host()
        if host in url:
            url = url.split(host)[1]
        else:
            raise http.HttpResponseBadRequest(
                'Cross domain includes not allowed! %s' % response['Location'])
        return get_render_from_response(
            request, url, get_forwarding=get_forwarding)

    return response.content.decode('utf-8')
Пример #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
 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 fo 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']})
     self.assertRaises(RawPostDataException, lambda: request.body)
Пример #15
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:
     # http://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, {})
Пример #16
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']})
Пример #17
0
def get_fake_request(meta):
    '''Retrieves a fake request using the given request.META.  This allows celery tasks to have a "request" to use in code.'''
    # if the body was cached in the meta, put it back as the wsgi.input
    if BODY_KEY in meta:
        meta['wsgi.input'] = FakePayload(meta[BODY_KEY])

    # create a basic request using the Django testing framework
    request = RequestFactory().request(**meta)

    # run middleware on it
    handler = BaseHandler()
    handler.load_middleware()
    for middleware_method in handler._request_middleware:
        response = middleware_method(request)
        if response:
            raise Exception(
                "Middleware cannot return a response with a FakeRequest.")

    # return the request
    return request
Пример #18
0
    def request(self, **request):
        """
        Similar to parent class, but returns the request object as soon as it
        has created it.
        """
        environ = {
            'HTTP_COOKIE': self.cookies.output(header='', sep='; '),
            'PATH_INFO': '/',
            'QUERY_STRING': '',
            'REQUEST_METHOD': 'GET',
            'SCRIPT_NAME': '',
            'SERVER_NAME': 'testserver',
            'SERVER_PORT': 80,
            'SERVER_PROTOCOL': 'HTTP/1.1',
            'wsgi.input': FakePayload(''),
        }
        environ.update(self.defaults)
        environ.update(request)

        return WSGIRequest(environ)
Пример #19
0
 def request(self, **request):
     environ = {
         'HTTP_COOKIE': self.cookies.output(header='', sep='; '),
         'PATH_INFO': str('/'),
         'REMOTE_ADDR': str('127.0.0.1'),
         'REQUEST_METHOD': str('GET'),
         'SCRIPT_NAME': str(''),
         'SERVER_NAME': str('testserver'),
         'SERVER_PORT': str('80'),
         'SERVER_PROTOCOL': str('HTTP/1.1'),
         'wsgi.version': (1, 0),
         'wsgi.url_scheme': str('http'),
         'wsgi.input': FakePayload(b''),
         'wsgi.errors': self.errors,
         'wsgi.multiprocess': True,
         'wsgi.multithread': False,
         'wsgi.run_once': False,
     }
     environ.update(self.defaults)
     environ.update(request)
     return WSGIRequest(environ)
Пример #20
0
    def post_raw_data(self, path, post_data):
        """
        The built-in test client's post() method assumes the data you pass
        is a dictionary and encodes it. If we just want to pass the data
        unmodified, we need our own version of post().
        """
        parsed = urlparse(path)
        r = {
            'CONTENT_LENGTH': len(post_data),
            'CONTENT_TYPE': "text/plain",
            'PATH_INFO': self.client._get_path(parsed),
            'QUERY_STRING': force_str(parsed[4]),
            'REQUEST_METHOD': str('POST'),
            'wsgi.input': FakePayload(post_data),
        }

        # Add the request signature to the headers being sent.
        r.update(self.get_signature(path, method='POST', body=post_data))

        # Make the actual request.
        return self.client.request(**r)
Пример #21
0
    def patch(self, path, data={}, content_type=MULTIPART_CONTENT, **extra):
        """
            Construct a PATCH request."
        :param path:
        :param data:
        :param content_type:
        :param extra:
        :return:
        """
        patch_data = self._encode_data(data, 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)
    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)
Пример #23
0
 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)
Пример #24
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
Пример #25
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"]})
Пример #26
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, {})
Пример #27
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)
Пример #28
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
Пример #29
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)
Пример #30
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']
            )
Пример #31
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')