Exemple #1
0
class Request:
    def __init__(self, addr, version, token=None, cert=None, verify=True):
        self.addr = addr
        self.version = version
        self._token = token

        cookies = {}
        if self._token:
            cookies.setdefault('token', self._token)

        connector, context, ca = None, None, None
        if verify:
            if isinstance(verify, str):
                verify, ca = True, verify
        else:
            verify = False

        if addr.startswith('https://') or cert:
            context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
            context.options |= ssl.OP_NO_SSLv2
            context.options |= ssl.OP_NO_SSLv3
            if cert:
                certfile, keyfile = cert
                context.load_cert_chain(certfile, keyfile)

            if ca:
                context.verify_mode = ssl.CERT_REQUIRED
                if os.path.isdir(ca):
                    context.load_verify_locations(capath=ca)
                else:
                    context.load_verify_locations(cafile=ca)
            else:
                context.verify_mode = ssl.CERT_NONE

        if verify:
            connector = TCPConnector(verify_ssl=True, ssl_context=context)
        else:
            connector = TCPConnector(verify_ssl=False)

        self.session = ClientSession(cookies=cookies, connector=connector)

    @property
    def token(self):
        return self._token

    @token.setter
    def token(self, value):
        self._token = value
        self.session._update_cookies({'token': value})

    @asyncio.coroutine
    def request(self, method, path, **kwargs):
        url = '%s/%s%s' % (self.addr, self.version, path)

        for field in ('params', 'data', 'json'):
            if field in kwargs and isinstance(kwargs[field], dict):
                kwargs[field] = no_null(kwargs[field])

        data = kwargs.pop('json', None)
        if data is not None:
            kwargs['data'] = json.dumps(data)
            headers = kwargs.setdefault('headers', {})
            headers['Content-Type'] = 'application/json'

        response = yield from self.session.request(method, url, **kwargs)

        if response.status in (200, 204):
            return response

        if response.headers['Content-Type'] == 'application/json':
            data = yield from response.json()
        else:
            data = yield from response.text()

        if response.status == 400:
            raise InvalidRequest(data)
        if response.status == 401:
            raise Unauthorized(data)
        if response.status == 403:
            raise BadToken(data)
        if response.status == 404:
            raise InvalidPath(data)
        if response.status == 429:
            raise RateLimitExceeded(data)
        if response.status == 500:
            raise InternalServerError(data)
        if response.status == 503:
            raise DownError(data)
        raise HTTPError(data, response.status)

    __call__ = request