Ejemplo n.º 1
0
    def __call__(self, callback, request):
        """
        :X-RateLimit-Limit:
            <number of request>/<time unit>
            the current rate limit for this API key
        :X-RateLimit-Used:
            the number of method calls used on this API key this timespan
        :X-RateLimit-Remaining:
            the estimated number of remaining calls allowed by this API key this minute
        """

        criteria = self.get_criteria(request)
        if criteria is None:
            return callback(request)

        used = self.get_rate_used(criteria)

        headers = {
            'x-ratelimit-limit': '{0}/{1}s'.format(self._max, self._timespan),
            'x-ratelimit-used': used,
            'x-ratelimit-remaining': max(self._max - used, 0),
        }

        if used >= self._max:
            logger.warning('Rejecting request of %s, quota maxed', criteria)
            return HTTPResponse(429, headers, 'You exceeded your quota')

        return HTTPResponse(headers, callback(request))
Ejemplo n.º 2
0
    def serialize(self, result):
        if self.method == 'HEAD':
            return None
        elif self.method == 'POST':
            if result is None:
                raise ValueError('create_resource method must return the id.')
            url = self.make_url(result)
            return HTTPResponse(201, {'Location': url}, None)
        elif self.method.startswith('getall'):
            if not isinstance(result, collections.Iterable):
                raise ValueError('get_all_resources returned a non-iterable object')

            pairs = list(result)
            if not all(len(pair) == 2 for pair in pairs):
                raise ValueError('get_all_resources must return a iterable of tuples')

            return dict(
                (self.make_url(id), self.manager.serialize(resource))
                for id, resource in result)
        elif self.method == 'GET' or self.method == 'filter':
            if not isinstance(result, collections.Iterable):
                raise ValueError(
                    'list_resource returned a non-iterable object')
            return map(self.make_url, result)
        else:
            return result
Ejemplo n.º 3
0
    def authorize(self, callback, request):
        """
        Calls :meth:`authenticate` and the *callback*

        If :meth:`authenticate` returns a callable, it will call it
        with the result of the callback.

        When the *timed* option is enabled, the time spend in :meth:`authenticate`
        will be calculated and returned in the **x-auth-time** header.
        """
        content = self.extract(request)
        if 'login' in content:
            request.environ['napixd.auth.username'] = content['login']

        with Chrono() as chrono:
            check = self.authenticate(request, content)

        logger.debug('Authenticate took %s', chrono.total)

        if not check:
            raise HTTPError(403, 'Access Denied')

        resp = callback(request)
        if callable(check):
            resp = check(resp)

        if self._timed:
            return HTTPResponse({'x-auth-time': chrono.total}, resp)
        return resp
Ejemplo n.º 4
0
 def test_cast_response_text(self):
     r = HTTPResponse({'Content-Type': 'text/yaml'},
                      '''base:\n  '*':\n    webserver''')
     resp = self.cast(r)
     self.assertEqual(resp.headers['content-length'], '26')
     self.assertEqual(resp.headers['content-type'], 'text/yaml')
     self.assertEqual(resp.body, ['''base:\n  '*':\n    webserver'''])
Ejemplo n.º 5
0
    def test_3_args(self):
        body = mock.Mock()
        r = HTTPResponse(304, {'content_type': 'application/pdf'}, body)

        self.assertEqual(r.status, 304)
        self.assertEqual(r.headers['content-type'], 'application/pdf')
        self.assertEqual(r.body, body)
Ejemplo n.º 6
0
    def test_0_args(self):
        r = HTTPResponse()

        self.assertEqual(r.status, 200)
        self.assertEqual(len(r.headers), 0)
        self.assertTrue(isinstance(r.headers, HeadersDict))
        self.assertEqual(r.body, None)
Ejemplo n.º 7
0
    def cast(self, request, response):
        """
        Translates a response in a :class:`napixd.http.response.HTTPResponse`
        object.
        """
        if isinstance(response, Response):
            return HTTPResponse(200, response.headers, response)
        elif isinstance(response, (HTTPError, HTTPResponse)):
            status = response.status
            body = response.body
            headers = response.headers
        else:
            status = 200
            headers = HeadersDict()
            body = response

        if request.method == 'HEAD':
            body = None
            headers['Content-Length'] = 0

        content_type = headers.get('Content-Type', '')
        content_length = headers.get('Content-Length', None)

        if isinstance(body, basestring):
            if not content_type:
                content_type = 'text/plain'
            if isinstance(body, unicode):
                content_type += '; charset=utf-8'
                body = body.encode('utf-8')
        elif hasattr(body, 'read'):
            body = file_wrapper(request.environ, body)
        elif body is not None:
            content_type = 'application/json'
            body = self._json_provider.dumps(body)
        else:
            content_type = ''
            body = []

        if isinstance(body, str):
            content_length = len(body)
            body = [body]

        headers.setdefault('Content-Type', content_type)
        if content_length is not None:
            headers.setdefault('Content-Length', content_length)
        return HTTPResponse(status, headers, body)
Ejemplo n.º 8
0
    def test_2_args(self):
        body = mock.Mock()
        r = HTTPResponse({'content_type': 'application/pdf'}, body)

        self.assertEqual(r.status, 200)
        self.assertEqual(r.headers['content-type'], 'application/pdf')
        self.assertTrue(isinstance(r.headers, HeadersDict))
        self.assertEqual(r.body, body)
Ejemplo n.º 9
0
    def test_1_arg(self):
        body = mock.Mock()
        r = HTTPResponse(body)

        self.assertEqual(r.status, 200)
        self.assertEqual(len(r.headers), 0)
        self.assertTrue(isinstance(r.headers, HeadersDict))
        self.assertEqual(r.body, body)
Ejemplo n.º 10
0
 def test_second_request(self):
     self.pipe.zcount.return_value = 1
     resp = self.call()
     self.assertEqual(resp, HTTPResponse({
         'x-ratelimit-remaining': '1',
         'x-ratelimit-limit': '2/60s',
         'x-ratelimit-used': '1',
     }, self.cb.return_value))
     self.criteria.assert_called_once_with(self.req)
Ejemplo n.º 11
0
 def test_cast_response(self):
     r = HTTPResponse(302, {'Location': '/pim/pam/poum'},
                      u'See /pim/pam/poum')
     resp = self.cast(r)
     self.assertEqual(resp.status, 302)
     self.assertEqual(resp.headers['Location'], '/pim/pam/poum')
     self.assertEqual(resp.headers['content-type'],
                      'text/plain; charset=utf-8')
     self.assertEqual(resp.headers['content-length'], '17')
     self.assertEqual(resp.body, ['See /pim/pam/poum'])
Ejemplo n.º 12
0
    def __call__(self, callback, request):
        with Chrono() as timing:
            proc = Greenlet.spawn(callback, request)
            resp = proc.get()

        return HTTPResponse(
            {
                'x-total-time': timing.total,
                'x-running-time': proc.get_running_time()
            }, resp)
Ejemplo n.º 13
0
 def test_first_req(self):
     self.pipe.zcount.return_value = 0
     resp = self.call()
     self.pipe.assert_has_calls([
         mock.call.watch('rate_limit:123'),
         mock.call.zcount('rate_limit:123', 1140, 1200),
         mock.call.multi(),
         mock.call.zadd('rate_limit:123', 1200, 1200),
         mock.call.expireat('rate_limit:123', 1260),
     ])
     self.assertEqual(resp, HTTPResponse({
         'x-ratelimit-remaining': '2',
         'x-ratelimit-limit': '2/60s',
         'x-ratelimit-used': '0',
     }, self.cb.return_value))
Ejemplo n.º 14
0
    def serialize(self, result):
        """
        Serialize the request.

        Also applies the *format* if asked in the parameters.
        """
        if self.method == 'HEAD':
            return None
        if self.method == 'PUT':
            if result is not None and result != self.resource.id:
                self.path.pop()
                new_url = self.make_url(result)
                return HTTPError(205, None, Location=new_url)
            return HTTPError(204)

        if self.method != 'GET':
            return result

        if result is None:
            raise ValueError('resource cannot be None')

        format_ = self.context.parameters.get('format', None)
        if not format_:
            return self.default_formatter(result)
        try:
            formatter = self.manager.get_formatter(format_)
        except KeyError:
            message = 'Cannot render %s.' % format_
            all_formats = self.service.collection.get_all_formats()
            if all_formats:
                message = '{0} Available formats {1}: {2} '.format(
                    message, 'is' if len(all_formats) <= 1 else 'are',
                    ', '.join(all_formats.keys()))
            return HTTPError(406, message)

        response = Response()
        result = formatter(self.resource, response)
        if result is None or result is response:
            return response
        else:
            return HTTPResponse(response.headers, result)
Ejemplo n.º 15
0
 def test_status_line(self):
     r = HTTPResponse(204, {}, None)
     self.assertEqual(r.status_line, '204 No Content')
Ejemplo n.º 16
0
 def test_override_status(self):
     r = HTTPResponse(200, {}, self.r)
     self.assertEqual(r.status, 200)
Ejemplo n.º 17
0
 def test_with_response(self):
     resp = Response({'header2': 'value2'})
     r = HTTPResponse({'header1': 'value1'}, resp)
     self.assertEqual(r.headers['header1'], 'value1')
     self.assertEqual(r.body, resp)
Ejemplo n.º 18
0
 def test_status_line_unknown(self):
     r = HTTPResponse(198, {}, None)
     self.assertEqual(r.status_line, '198 Unknown')
Ejemplo n.º 19
0
 def setUp(self):
     self.body = body = mock.Mock()
     self.r = HTTPResponse(201, {'header1': 'value1'}, body)
Ejemplo n.º 20
0
    def test_with_respons_length(self):
        resp = Response()
        resp.write('1234')

        r = HTTPResponse(resp)
        self.assertEqual(r.headers['Content-Length'], '4')
Ejemplo n.º 21
0
 def test_keep_status(self):
     r = HTTPResponse(self.r)
     self.assertEqual(r.status, 201)
Ejemplo n.º 22
0
    def __call__(self, callback, request):
        with Chrono() as chrono:
            resp = callback(request)

        return HTTPResponse({self.header_name: chrono.total}, resp)
Ejemplo n.º 23
0
 def test_keep_body(self):
     r = HTTPResponse(self.r)
     self.assertEqual(r.body, self.body)
Ejemplo n.º 24
0
    def test_override_header(self):
        r = HTTPResponse({'header1': 'value2'}, self.r)

        self.assertEqual(r.headers['header1'], 'value2')
Ejemplo n.º 25
0
    def test_merge_headers(self):
        r = HTTPResponse({'header2': 'value2'}, self.r)

        self.assertEqual(r.headers['header1'], 'value1')
        self.assertEqual(r.headers['header2'], 'value2')