예제 #1
0
    def get_test_vars(sender=None):
        if not RestSetup.__test_vars:
            r = ably.http.post("/apps", headers=HttpUtils.default_post_headers(),
                    body=app_spec_text, skip_auth=True)
            AblyException.raise_for_response(r)
            
            app_spec = r.json()
            
            app_id = app_spec.get("appId", "")

            test_vars = {
                "app_id": app_id,
                "host": host,
                "port": port,
                "tls_port": tls_port,
                "tls": tls,
                "keys": [{
                    "key_id": "%s.%s" % (app_id, k.get("id", "")),
                    "key_value": k.get("value", ""),
                    "key_str": "%s.%s:%s" % (app_id,  k.get("id", ""), k.get("value", "")),
                    "capability": Capability(json.loads(k.get("capability", "{}"))),
                } for k in app_spec.get("keys", [])]
            }

            RestSetup.__test_vars = test_vars
            log.debug([(app_id, k.get("id", ""), k.get("value", "")) 
                  for k in app_spec.get("keys", [])])
        return RestSetup.__test_vars
예제 #2
0
    def make_request(self, method, url, headers=None, body=None, skip_auth=False, timeout=None, scheme=None, host=None, port=0):
        scheme = scheme or self.preferred_scheme
        host = host or self.preferred_host
        port = port or self.preferred_port
        base_url = "%s://%s:%d" % (scheme, host, port)
        url = urljoin(base_url, url)

        hdrs = headers or {}
        headers = HttpUtils.default_get_headers(not self.options.use_text_protocol)
        headers.update(hdrs)

        if not skip_auth:
            headers.update(self.auth._get_auth_headers())

        request = requests.Request(method, url, data=body, headers=headers)
        prepped = self.__session.prepare_request(request)

        # log.debug("Method: %s" % method)
        # log.debug("Url: %s" % url)
        # log.debug("Headers: %s" % headers)
        # log.debug("Body: %s" % body)
        # log.debug("Prepped: %s" % prepped)
        
        # TODO add timeouts from options here
        response = self.__session.send(prepped)

        AblyException.raise_for_response(response)

        return Response(response)
예제 #3
0
    def make_request(self, method, path, headers=None, body=None,
                     skip_auth=False, timeout=None, raise_on_error=True):

        if body is not None and type(body) not in (bytes, str):
            body = self.dump_body(body)

        if body:
            all_headers = HttpUtils.default_post_headers(
                self.options.use_binary_protocol, self.__ably.variant)
        else:
            all_headers = HttpUtils.default_get_headers(
                self.options.use_binary_protocol, self.__ably.variant)

        if not skip_auth:
            if self.auth.auth_mechanism == Auth.Method.BASIC and self.preferred_scheme.lower() == 'http':
                raise AblyException(
                    "Cannot use Basic Auth over non-TLS connections",
                    401,
                    40103)
            all_headers.update(self.auth._get_auth_headers())
        if headers:
            all_headers.update(headers)

        timeout = (self.http_open_timeout, self.http_request_timeout)
        http_max_retry_duration = self.http_max_retry_duration
        requested_at = time.time()

        hosts = self.get_rest_hosts()
        for retry_count, host in enumerate(hosts):
            base_url = "%s://%s:%d" % (self.preferred_scheme,
                                       host,
                                       self.preferred_port)
            url = urljoin(base_url, path)
            request = requests.Request(method, url, data=body, headers=all_headers)
            prepped = self.__session.prepare_request(request)
            try:
                response = self.__session.send(prepped, timeout=timeout)
            except Exception as e:
                # Need to catch `Exception`, see:
                # https://github.com/kennethreitz/requests/issues/1236#issuecomment-133312626

                # if last try or cumulative timeout is done, throw exception up
                time_passed = time.time() - requested_at
                if retry_count == len(hosts) - 1 or \
                   time_passed > http_max_retry_duration:
                    raise e
            else:
                try:
                    if raise_on_error:
                        AblyException.raise_for_response(response)

                    # Keep fallback host for later (RSC15f)
                    if retry_count > 0 and host != self.options.get_rest_host():
                        self.__host = host
                        self.__host_expires = time.time() + (self.options.fallback_retry_timeout / 1000.0)

                    return Response(response)
                except AblyException as e:
                    if not e.is_server_error:
                        raise e
예제 #4
0
파일: auth.py 프로젝트: ably/ably-python
    async def token_request_from_auth_url(self, method, url, token_params,
                                          headers, auth_params):
        body = None
        params = None
        if method == 'GET':
            body = {}
            params = dict(auth_params, **token_params)
        elif method == 'POST':
            params = {}
            body = dict(auth_params, **token_params)

        from ably.http.http import Response
        async with httpx.AsyncClient(http2=True) as client:
            resp = await client.request(method=method,
                                        url=url,
                                        headers=headers,
                                        params=params,
                                        data=body)
            response = Response(resp)

        AblyException.raise_for_response(response)
        try:
            token_request = response.to_native()
        except ValueError:
            token_request = response.text
        return token_request
예제 #5
0
파일: http.py 프로젝트: ably/ably-python
    def make_request(self, method, path, headers=None, body=None,
                     skip_auth=False, timeout=None, raise_on_error=True):

        if body is not None and type(body) not in (bytes, str):
            body = self.dump_body(body)

        if body:
            all_headers = HttpUtils.default_post_headers(
                self.options.use_binary_protocol, self.__ably.variant)
        else:
            all_headers = HttpUtils.default_get_headers(
                self.options.use_binary_protocol, self.__ably.variant)

        if not skip_auth:
            if self.auth.auth_mechanism == Auth.Method.BASIC and self.preferred_scheme.lower() == 'http':
                raise AblyException(
                    "Cannot use Basic Auth over non-TLS connections",
                    401,
                    40103)
            all_headers.update(self.auth._get_auth_headers())
        if headers:
            all_headers.update(headers)

        http_open_timeout = self.http_open_timeout
        http_request_timeout = self.http_request_timeout
        http_max_retry_duration = self.http_max_retry_duration
        requested_at = time.time()

        hosts = self.options.get_rest_hosts()
        for retry_count, host in enumerate(hosts):
            base_url = "%s://%s:%d" % (self.preferred_scheme,
                                       host,
                                       self.preferred_port)
            url = urljoin(base_url, path)
            request = requests.Request(method, url, data=body, headers=all_headers)
            prepped = self.__session.prepare_request(request)
            try:
                timeout = (http_open_timeout, http_request_timeout)
                response = self.__session.send(prepped, timeout=timeout)
            except Exception as e:
                # Need to catch `Exception`, see:
                # https://github.com/kennethreitz/requests/issues/1236#issuecomment-133312626

                # if last try or cumulative timeout is done, throw exception up
                time_passed = time.time() - requested_at
                if retry_count == len(hosts) - 1 or \
                   time_passed > http_max_retry_duration:
                    raise e
            else:
                try:
                    if raise_on_error:
                        AblyException.raise_for_response(response)
                    return Response(response)
                except AblyException as e:
                    if not e.is_server_error:
                        raise e
예제 #6
0
파일: auth.py 프로젝트: jdavid/ably-python
    def create_token_request(self,
                             token_params=None,
                             key_name=None,
                             key_secret=None,
                             query_time=None):
        token_params = token_params or {}
        token_request = {}

        key_name = key_name or self.auth_options.key_name
        key_secret = key_secret or self.auth_options.key_secret
        if not key_name or not key_secret:
            log.debug('key_name or key_secret blank')
            raise AblyException(
                "No key specified: no means to generate a token", 401, 40101)

        token_request['key_name'] = key_name
        if token_params.get('timestamp'):
            token_request['timestamp'] = token_params['timestamp']
        else:
            if query_time is None:
                query_time = self.auth_options.query_time
            if query_time:
                token_request['timestamp'] = self.ably.time()
            else:
                token_request['timestamp'] = self._timestamp()

        token_request['timestamp'] = int(token_request['timestamp'])

        ttl = token_params.get('ttl')
        if ttl is not None:
            if isinstance(ttl, timedelta):
                ttl = ttl.total_seconds() * 1000
            token_request['ttl'] = int(ttl)

        capability = token_params.get('capability')
        if capability is not None:
            token_request['capability'] = six.text_type(Capability(capability))

        token_request["client_id"] = (token_params.get('client_id')
                                      or self.client_id)

        # Note: There is no expectation that the client
        # specifies the nonce; this is done by the library
        # However, this can be overridden by the client
        # simply for testing purposes
        token_request["nonce"] = token_params.get(
            'nonce') or self._random_nonce()

        token_request = TokenRequest(**token_request)

        if token_params.get('mac') is None:
            # Note: There is no expectation that the client
            # specifies the mac; this is done by the library
            # However, this can be overridden by the client
            # simply for testing purposes.
            token_request.sign_request(key_secret.encode('utf8'))
        else:
            token_request.mac = token_params['mac']

        return token_request
예제 #7
0
 def parse_key(self, key):
     try:
         key_name, key_secret = key.split(':')
         return key_name, key_secret
     except ValueError:
         raise AblyException("key of not len 2 parameters: {0}"
                             .format(key.split(':')),
                             401, 40101)
예제 #8
0
def get_cipher(cipher_params):
    if cipher_params is None:
        params = get_default_params()
    elif isinstance(cipher_params, CipherParams):
        params = cipher_params
    else:
        raise AblyException("ChannelOptions not supported", 400, 40000)
    return CbcChannelCipher(params)
예제 #9
0
    def __unpad(self, data):
        padding_size = six.indexbytes(data, -1)

        if padding_size > len(data):
            # Too short
            raise AblyException('invalid-padding', 0, 0)

        if padding_size == 0:
            # Missing padding
            raise AblyException('invalid-padding', 0, 0)

        for i in range(padding_size):
            # Invalid padding bytes
            if padding_size != six.indexbytes(data, -i - 1):
                raise AblyException('invalid-padding', 0, 0)

        return data[:-padding_size]
예제 #10
0
    def as_dict(self, binary=False):
        data = self.data
        data_type = None
        encoding = self._encoding_array[:]

        if isinstance(data, dict) or isinstance(data, list):
            encoding.append('json')
            data = json.dumps(data)
        elif isinstance(data, six.text_type) and not binary:
            # text_type is always a unicode string
            pass
        elif (not binary and isinstance(data, bytearray) or
              # bytearray is always bytes
              isinstance(data, six.binary_type) and six.binary_type != str):
            # in py3k we will understand <class 'bytes'> as bytes
            data = base64.b64encode(data).decode('ascii')
            encoding.append('base64')
        elif isinstance(data, CipherData):
            encoding.append(data.encoding_str)
            data_type = data.type
            if not binary:
                data = base64.b64encode(data.buffer).decode('ascii')
                encoding.append('base64')
            else:
                data = data.buffer
        elif binary and isinstance(data, bytearray):
            data = six.binary_type(data)

        if not (isinstance(data, (six.binary_type, six.text_type, list, dict,
                                  bytearray)) or data is None):
            raise AblyException("Invalid data payload", 400, 40011)

        request_body = {
            'name': self.name,
            'data': data,
            'timestamp': self.timestamp or int(time.time() * 1000.0),
        }
        request_body = {
            k: v
            for (k, v) in request_body.items() if v is not None
        }  # None values aren't included

        if encoding:
            request_body['encoding'] = '/'.join(encoding).strip('/')

        if data_type:
            request_body['type'] = data_type

        if self.client_id:
            request_body['clientId'] = self.client_id

        if self.id:
            request_body['id'] = self.id

        if self.connection_id:
            request_body['connectionId'] = self.connection_id

        return request_body
예제 #11
0
    def token_request_from_auth_url(self, method, url, token_params,
                                    headers, auth_params):
        if method == 'GET':
            body = {}
            params = dict(auth_params, **token_params)
        elif method == 'POST':
            params = {}
            body = dict(auth_params, **token_params)

        from ably.http.http import Response
        response = Response(requests.request(
            method, url, headers=headers, params=params, data=body))

        AblyException.raise_for_response(response)
        try:
            token_request = response.to_native()
        except ValueError:
            token_request = response.text
        return token_request
예제 #12
0
    def token_request_from_auth_url(self, method, url, token_params,
                                    headers, auth_params):
        if method == 'GET':
            body = {}
            params = dict(auth_params, **token_params)
        elif method == 'POST':
            params = {}
            body = dict(auth_params, **token_params)

        from ably.http.http import Response
        response = Response(requests.request(
            method, url, headers=headers, params=params, data=body))

        AblyException.raise_for_response(response)
        try:
            token_request = response.to_native()
        except ValueError:
            token_request = response.text
        return token_request
예제 #13
0
    async def get_test_vars(sender=None):
        if not RestSetup.__test_vars:
            r = await ably.http.post("/apps",
                                     body=app_spec_local,
                                     skip_auth=True)
            AblyException.raise_for_response(r)

            app_spec = r.json()

            app_id = app_spec.get("appId", "")

            test_vars = {
                "app_id":
                app_id,
                "host":
                host,
                "port":
                port,
                "tls_port":
                tls_port,
                "tls":
                tls,
                "environment":
                environment,
                "keys": [{
                    "key_name":
                    "%s.%s" % (app_id, k.get("id", "")),
                    "key_secret":
                    k.get("value", ""),
                    "key_str":
                    "%s.%s:%s" % (app_id, k.get("id", ""), k.get("value", "")),
                    "capability":
                    Capability(json.loads(k.get("capability", "{}"))),
                } for k in app_spec.get("keys", [])]
            }

            RestSetup.__test_vars = test_vars
            log.debug([(app_id, k.get("id", ""), k.get("value", ""))
                       for k in app_spec.get("keys", [])])

        return RestSetup.__test_vars
예제 #14
0
    def set_key(self, key):
        if key is None:
            return

        try:
            key_name, key_secret = key.split(':')
            self.auth_options['key_name'] = key_name
            self.auth_options['key_secret'] = key_secret
        except ValueError:
            raise AblyException(
                "key of not len 2 parameters: {0}".format(key.split(':')), 401,
                40101)
예제 #15
0
    def as_dict(self, binary=False):
        data = self.data
        data_type = None
        encoding = self._encoding_array[:]

        if isinstance(data, (dict, list)):
            encoding.append('json')
            data = json.dumps(data)
            data = str(data)
        elif isinstance(data, str) and not binary:
            pass
        elif not binary and isinstance(data, (bytearray, bytes)):
            data = base64.b64encode(data).decode('ascii')
            encoding.append('base64')
        elif isinstance(data, CipherData):
            encoding.append(data.encoding_str)
            data_type = data.type
            if not binary:
                data = base64.b64encode(data.buffer).decode('ascii')
                encoding.append('base64')
            else:
                data = data.buffer
        elif binary and isinstance(data, bytearray):
            data = bytes(data)

        if not (isinstance(data, (bytes, str, list, dict, bytearray))
                or data is None):
            raise AblyException("Invalid data payload", 400, 40011)

        request_body = {
            'name': self.name,
            'data': data,
            'timestamp': self.timestamp or None,
            'type': data_type or None,
            'clientId': self.client_id or None,
            'id': self.id or None,
            'connectionId': self.connection_id or None,
            'connectionKey': self.connection_key or None,
            'extras': self.extras,
        }

        if encoding:
            request_body['encoding'] = '/'.join(encoding).strip('/')

        # None values aren't included
        request_body = {k: v for k, v in request_body.items() if v is not None}

        return request_body
예제 #16
0
 def raise_ably_exception(*args, **kwargs):
     raise AblyException(message="", status_code=500, code=50000)
예제 #17
0
파일: rest.py 프로젝트: avsd/ably-python
 def time(self, timeout=None):
     """Returns the current server time in ms since the unix epoch"""
     r = self.http.get('/time', skip_auth=True, timeout=timeout)
     AblyException.raise_for_response(r)
     return r.json()[0]
예제 #18
0
파일: rest.py 프로젝트: jdavid/ably-python
 def time(self, timeout=None):
     """Returns the current server time in ms since the unix epoch"""
     r = self.http.get('/time', skip_auth=True, timeout=timeout)
     AblyException.raise_for_response(r)
     return r.to_native()[0]
예제 #19
0
    def as_dict(self, binary=False):
        data = self.data
        data_type = None
        encoding = self._encoding_array[:]

        if isinstance(data, six.binary_type) and six.binary_type == str:
            # If using python 2, assume str payloads are intended as strings
            # if they decode to unicode. If it doesn't, treat as a binary
            try:
                data = six.text_type(data)
            except UnicodeDecodeError:
                pass

        if isinstance(data, dict) or isinstance(data, list):
            encoding.append('json')
            data = json.dumps(data)
            data = six.text_type(data)
        elif isinstance(data, six.text_type) and not binary:
            # text_type is always a unicode string
            pass
        elif (not binary and (isinstance(data, bytearray) or
                              # bytearray is always bytes
                              isinstance(data, six.binary_type))):
            # at this point binary_type is either a py3k bytes or a py2
            # str that failed to decode to unicode
            data = base64.b64encode(data).decode('ascii')
            encoding.append('base64')
        elif isinstance(data, CipherData):
            encoding.append(data.encoding_str)
            data_type = data.type
            if not binary:
                data = base64.b64encode(data.buffer).decode('ascii')
                encoding.append('base64')
            else:
                data = data.buffer
        elif binary and isinstance(data, bytearray):
            data = six.binary_type(data)

        if not (isinstance(data, (six.binary_type, six.text_type, list, dict,
                                  bytearray)) or data is None):
            raise AblyException("Invalid data payload", 400, 40011)

        request_body = {
            u'name': self.name,
            u'data': data,
            u'timestamp': self.timestamp or int(time.time() * 1000.0),
        }
        request_body = {
            k: v
            for (k, v) in request_body.items() if v is not None
        }  # None values aren't included

        if encoding:
            request_body[u'encoding'] = u'/'.join(encoding).strip(u'/')

        if data_type:
            request_body[u'type'] = data_type

        if self.client_id:
            request_body[u'clientId'] = self.client_id

        if self.id:
            request_body[u'id'] = self.id

        if self.connection_id:
            request_body[u'connectionId'] = self.connection_id

        if self.connection_key:
            request_body['connectionKey'] = self.connection_key

        if self.extras:
            request_body['extras'] = self.extras

        return request_body
예제 #20
0
    def request_token(
            self,
            token_params=None,
            # auth_options
            key_name=None,
            key_secret=None,
            auth_callback=None,
            auth_url=None,
            auth_method=None,
            auth_headers=None,
            auth_params=None,
            query_time=None):
        token_params = token_params or {}
        token_params = dict(self.auth_options.default_token_params,
                            **token_params)
        key_name = key_name or self.auth_options.key_name
        key_secret = key_secret or self.auth_options.key_secret

        log.debug("Auth callback: %s" % auth_callback)
        log.debug("Auth options: %s" % six.text_type(self.auth_options))
        if query_time is None:
            query_time = self.auth_options.query_time
        query_time = bool(query_time)
        auth_callback = auth_callback or self.auth_options.auth_callback
        auth_url = auth_url or self.auth_options.auth_url

        auth_params = auth_params or self.auth_options.auth_params or {}

        auth_method = (auth_method or self.auth_options.auth_method).upper()

        auth_headers = auth_headers or self.auth_options.auth_headers or {}

        log.debug("Token Params: %s" % token_params)
        if auth_callback:
            log.debug("using token auth with authCallback")
            token_request = auth_callback(token_params)
        elif auth_url:
            log.debug("using token auth with authUrl")

            token_request = self.token_request_from_auth_url(
                auth_method, auth_url, token_params, auth_headers, auth_params)
        else:
            token_request = self.create_token_request(token_params,
                                                      key_name=key_name,
                                                      key_secret=key_secret,
                                                      query_time=query_time)
        if isinstance(token_request, TokenDetails):
            return token_request
        elif isinstance(token_request, dict) and 'issued' in token_request:
            return TokenDetails.from_dict(token_request)
        elif isinstance(token_request, dict):
            token_request = TokenRequest(**token_request)
        elif isinstance(token_request, six.text_type):
            return TokenDetails(token=token_request)
        # python2
        elif isinstance(token_request,
                        six.binary_type) and six.binary_type == str:
            return TokenDetails(token=token_request)

        token_path = "/keys/%s/requestToken" % token_request.key_name

        response = self.ably.http.post(token_path,
                                       headers=auth_headers,
                                       native_data=token_request.to_dict(),
                                       skip_auth=True)

        AblyException.raise_for_response(response)
        response_dict = response.to_native()
        log.debug("Token: %s" % str(response_dict.get("token")))
        return TokenDetails.from_dict(response_dict)
예제 #21
0
    def request_token(self, token_params=None,
                      # auth_options
                      key_name=None, key_secret=None, auth_callback=None,
                      auth_url=None, auth_method=None, auth_headers=None,
                      auth_params=None, query_time=None):
        token_params = token_params or {}
        token_params = dict(self.auth_options.default_token_params,
                            **token_params)
        key_name = key_name or self.auth_options.key_name
        key_secret = key_secret or self.auth_options.key_secret

        log.debug("Auth callback: %s" % auth_callback)
        log.debug("Auth options: %s" % six.text_type(self.auth_options))
        if query_time is None:
            query_time = self.auth_options.query_time
        query_time = bool(query_time)
        auth_callback = auth_callback or self.auth_options.auth_callback
        auth_url = auth_url or self.auth_options.auth_url

        auth_params = auth_params or self.auth_options.auth_params or {}

        auth_method = (auth_method or self.auth_options.auth_method).upper()

        auth_headers = auth_headers or self.auth_options.auth_headers or {}

        log.debug("Token Params: %s" % token_params)
        if auth_callback:
            log.debug("using token auth with authCallback")
            token_request = auth_callback(token_params)
        elif auth_url:
            log.debug("using token auth with authUrl")

            token_request = self.token_request_from_auth_url(
                auth_method, auth_url, token_params, auth_headers, auth_params)
        else:
            token_request = self.create_token_request(
                token_params, key_name=key_name, key_secret=key_secret,
                query_time=query_time)
        if isinstance(token_request, TokenDetails):
            return token_request
        elif isinstance(token_request, dict) and 'issued' in token_request:
            return TokenDetails.from_dict(token_request)
        elif isinstance(token_request, dict):
            token_request = TokenRequest(**token_request)
        elif isinstance(token_request, six.text_type):
            return TokenDetails(token=token_request)
        # python2
        elif isinstance(token_request, six.binary_type) and six.binary_type == str:
            return TokenDetails(token=token_request)

        token_path = "/keys/%s/requestToken" % token_request.key_name

        response = self.ably.http.post(
            token_path,
            headers=auth_headers,
            native_data=token_request.to_dict(),
            skip_auth=True
        )

        AblyException.raise_for_response(response)
        response_dict = response.to_native()
        log.debug("Token: %s" % str(response_dict.get("token")))
        return TokenDetails.from_dict(response_dict)
예제 #22
0
    def make_request(self, method, path, headers=None, body=None,
                     native_data=None, skip_auth=False, timeout=None):
        fallback_hosts = Defaults.get_fallback_rest_hosts(self.__options)
        if fallback_hosts:
            fallback_hosts.insert(0, self.preferred_host)
            fallback_hosts = itertools.cycle(fallback_hosts)
        if native_data is not None and body is not None:
            raise ValueError("make_request takes either body or native_data")
        elif native_data is not None:
            body = self.dump_body(native_data)
        if body:
            all_headers = HttpUtils.default_post_headers(
                self.options.use_binary_protocol)
        else:
            all_headers = HttpUtils.default_get_headers(
                self.options.use_binary_protocol)

        if not skip_auth:
            if self.auth.auth_mechanism == Auth.Method.BASIC and self.preferred_scheme.lower() == 'http':
                raise AblyException(
                    "Cannot use Basic Auth over non-TLS connections",
                    401,
                    40103)
            all_headers.update(self.auth._get_auth_headers())
        if headers:
            all_headers.update(headers)

        http_open_timeout = self.http_open_timeout
        http_request_timeout = self.http_request_timeout
        if fallback_hosts:
            http_max_retry_count = self.http_max_retry_count
        else:
            http_max_retry_count = 1
        http_max_retry_duration = self.http_max_retry_duration
        requested_at = time.time()
        for retry_count in range(http_max_retry_count):
            host = next(fallback_hosts) if fallback_hosts else self.preferred_host
            if self.options.environment:
                host = self.options.environment + '-' + host

            base_url = "%s://%s:%d" % (self.preferred_scheme,
                                       host,
                                       self.preferred_port)
            url = urljoin(base_url, path)
            request = requests.Request(method, url, data=body, headers=all_headers)
            prepped = self.__session.prepare_request(request)
            try:
                response = self.__session.send(
                    prepped,
                    timeout=(http_open_timeout,
                             http_request_timeout))
            except Exception as e:
                # Need to catch `Exception`, see:
                # https://github.com/kennethreitz/requests/issues/1236#issuecomment-133312626

                # if last try or cumulative timeout is done, throw exception up
                time_passed = time.time() - requested_at
                if retry_count == http_max_retry_count - 1 or \
                   time_passed > http_max_retry_duration:
                    raise e
            else:
                try:
                    AblyException.raise_for_response(response)
                    return Response(response)
                except AblyException as e:
                    if not e.is_server_error:
                        raise e
예제 #23
0
파일: auth.py 프로젝트: avsd/ably-python
    def request_token(self, key_id=None, key_value=None, query_time=None,
                      auth_token=None, auth_callback=None, auth_url=None,
                      auth_headers=None, auth_params=None, token_params=None):
        key_id = key_id or self.auth_options.key_id
        key_value = key_value or self.auth_options.key_value

        log.debug("Auth callback: %s" % auth_callback)
        log.debug("Auth options: %s" % six.text_type(self.auth_options))
        query_time = bool(query_time)
        auth_token = auth_token or self.auth_options.auth_token
        auth_callback = auth_callback or self.auth_options.auth_callback
        auth_url = auth_url or self.auth_options.auth_url
        auth_headers = auth_headers or {
            "Content-Encoding": "utf-8",
            "Content-Type": "application/json",
        }
        auth_params = auth_params or self.auth_params

        token_params = token_params or {}

        token_params.setdefault("client_id", self.ably.client_id)

        signed_token_request = ""

        log.debug("Token Params: %s" % token_params)
        if auth_callback:
            log.debug("using token auth with authCallback")
            signed_token_request = auth_callback(**token_params)
        elif auth_url:
            log.debug("using token auth with authUrl")
            response = self.ably.http.post(
                auth_url,
                headers=auth_headers,
                body=json.dumps(token_params),
                skip_auth=True
            )

            AblyException.raise_for_response(response)

            signed_token_request = response.text
        elif key_value:
            log.debug("using token auth with client-side signing")
            signed_token_request = self.create_token_request(
                key_id=key_id,
                key_value=key_value,
                query_time=query_time,
                token_params=token_params)
        else:
            log.debug('No auth_callback, auth_url or key_value specified')
            raise AblyException(
                "Auth.request_token() must include valid auth parameters",
                400,
                40000)

        token_path = "/keys/%s/requestToken" % key_id
        response = self.ably.http.post(
            token_path,
            headers=auth_headers,
            body=signed_token_request,
            skip_auth=True
        )

        AblyException.raise_for_response(response)

        access_token = response.json()["access_token"]
        log.debug("Token: %s" % str(access_token))
        return TokenDetails.from_dict(access_token)
예제 #24
0
파일: http.py 프로젝트: ably/ably-python
    async def make_request(self,
                           method,
                           path,
                           headers=None,
                           body=None,
                           skip_auth=False,
                           timeout=None,
                           raise_on_error=True):

        if body is not None and type(body) not in (bytes, str):
            body = self.dump_body(body)

        if body:
            all_headers = HttpUtils.default_post_headers(
                self.options.use_binary_protocol)
        else:
            all_headers = HttpUtils.default_get_headers(
                self.options.use_binary_protocol)

        if not skip_auth:
            if self.auth.auth_mechanism == Auth.Method.BASIC and self.preferred_scheme.lower(
            ) == 'http':
                raise AblyException(
                    "Cannot use Basic Auth over non-TLS connections", 401,
                    40103)
            auth_headers = await self.auth._get_auth_headers()
            all_headers.update(auth_headers)
        if headers:
            all_headers.update(headers)

        timeout = (self.http_open_timeout, self.http_request_timeout)
        http_max_retry_duration = self.http_max_retry_duration
        requested_at = time.time()

        hosts = self.get_rest_hosts()
        for retry_count, host in enumerate(hosts):
            base_url = "%s://%s:%d" % (self.preferred_scheme, host,
                                       self.preferred_port)
            url = urljoin(base_url, path)

            request = self.__client.build_request(
                method=method,
                url=url,
                content=body,
                headers=all_headers,
                timeout=timeout,
            )
            try:
                response = await self.__client.send(request)
            except Exception as e:
                # if last try or cumulative timeout is done, throw exception up
                time_passed = time.time() - requested_at
                if retry_count == len(
                        hosts) - 1 or time_passed > http_max_retry_duration:
                    raise e
            else:
                try:
                    if raise_on_error:
                        AblyException.raise_for_response(response)

                    # Keep fallback host for later (RSC15f)
                    if retry_count > 0 and host != self.options.get_rest_host(
                    ):
                        self.__host = host
                        self.__host_expires = time.time() + (
                            self.options.fallback_retry_timeout / 1000.0)

                    return Response(response)
                except AblyException as e:
                    if not e.is_server_error:
                        raise e

                    # if last try or cumulative timeout is done, throw exception up
                    time_passed = time.time() - requested_at
                    if retry_count == len(
                            hosts
                    ) - 1 or time_passed > http_max_retry_duration:
                        raise e