def _QueryServiceState(self, conn, file_length):
    """Queries service to find out state of given upload.

    Note that this method really just makes special case use of the
    fact that the upload service always returns the current start/end
    state whenever a PUT doesn't complete.

    Args:
      conn: HTTPConnection to use for the query.
      file_length: Total length of the file.

    Returns:
      HTTP response from sending request.

    Raises:
      ResumableUploadException if problem querying service.
    """
    # Send an empty PUT so that service replies with this resumable
    # transfer's state.
    put_headers = {
        'Content-Range': (self._BuildContentRangeHeader('*', file_length)),
        'Content-Length': '0'
    }
    return AWSAuthConnection.make_request(conn,
                                          'PUT',
                                          path=self.upload_url_path,
                                          auth_path=self.upload_url_path,
                                          headers=put_headers,
                                          host=self.upload_url_host)
Beispiel #2
0
 def make_request(self,
                  method,
                  bucket='',
                  key='',
                  headers=None,
                  data='',
                  query_args=None,
                  sender=None,
                  override_num_retries=None,
                  retry_handler=None):
     if isinstance(bucket, self.bucket_class):
         bucket = bucket.name
     if isinstance(key, Key):
         key = key.name
     path = self.calling_format.build_path_base(bucket, key)
     boto.log.debug('path=%s' % path)
     auth_path = self.calling_format.build_auth_path(bucket, key)
     boto.log.debug('auth_path=%s' % auth_path)
     host = self.calling_format.build_host(self.server_name(), bucket)
     if query_args:
         path += '?' + query_args
         boto.log.debug('path=%s' % path)
         auth_path += '?' + query_args
         boto.log.debug('auth_path=%s' % auth_path)
     return AWSAuthConnection.make_request(
         self,
         method,
         path,
         headers,
         data,
         host,
         auth_path,
         sender,
         override_num_retries=override_num_retries,
         retry_handler=retry_handler)
    def _QueryServiceState(self, conn, file_length):
        """Queries service to find out state of given upload.

    Note that this method really just makes special case use of the
    fact that the upload service always returns the current start/end
    state whenever a PUT doesn't complete.

    Args:
      conn: HTTPConnection to use for the query.
      file_length: Total length of the file.

    Returns:
      HTTP response from sending request.

    Raises:
      ResumableUploadException if problem querying service.
    """
        # Send an empty PUT so that service replies with this resumable
        # transfer's state.
        put_headers = {
            'Content-Range': (self._BuildContentRangeHeader('*', file_length)),
            'Content-Length': '0'
        }
        return AWSAuthConnection.make_request(conn,
                                              'PUT',
                                              path=self.upload_url_path,
                                              auth_path=self.upload_url_path,
                                              headers=put_headers,
                                              host=self.upload_url_host)
Beispiel #4
0
    def set_user_quota(self,
                       uid,
                       tenant='',
                       enabled=False,
                       max_objects=-1,
                       max_size_kb=-1):
        """获取用户容量限制"""
        tenant = tenant or self.tenant
        if tenant:
            uid = '%s$%s' % (tenant, uid)

        parameters = {'uid': uid, 'quota-type': 'user', 'quota-scope': 'user'}
        data = {
            'uid': uid,
            'quota-scope': 'user',
            'enabled': enabled,
            'max_objects': max_objects,
            'max_size_kb': max_size_kb,
        }
        response = AWSAuthConnection.make_request(
            self.conn,
            'PUT',
            self.admin_endpoint + 'user?quota&' +
            urllib.parse.urlencode(parameters),
            data=json.dumps(data),
        )
        return self._handle_response(response)
Beispiel #5
0
 def make_request(self,
                  verb,
                  resource,
                  headers=None,
                  data='',
                  ok_responses=(200, ),
                  params=None,
                  sender=None,
                  response_headers=None):
     if headers is None:
         headers = {}
     headers['x-amz-glacier-version'] = self.Version
     uri = '/%s/%s' % (self.account_id, resource)
     response = AWSAuthConnection.make_request(self,
                                               verb,
                                               uri,
                                               params=params,
                                               headers=headers,
                                               sender=sender,
                                               data=data)
     if response.status in ok_responses:
         return GlacierResponse(response, response_headers)
     else:
         # create glacier-specific exceptions
         raise UnexpectedHTTPResponseError(ok_responses, response)
Beispiel #6
0
    def _query_server_state(self, conn, file_length):
        """
        Queries server to find out state of given upload.

        Note that this method really just makes special case use of the
        fact that the upload server always returns the current start/end
        state whenever a PUT doesn't complete.

        Returns HTTP response from sending request.

        Raises ResumableUploadException if problem querying server.
        """
        # Send an empty PUT so that server replies with this resumable
        # transfer's state.
        put_headers = {}
        put_headers["Content-Range"] = self._build_content_range_header("*", file_length)
        put_headers["Content-Length"] = "0"
        return AWSAuthConnection.make_request(
            conn,
            "PUT",
            path=self.tracker_uri_path,
            auth_path=self.tracker_uri_path,
            headers=put_headers,
            host=self.tracker_uri_host,
        )
    def _query_server_state(self, conn, file_length):
        """
        Queries server to find out what bytes it currently has.

        Note that this method really just makes special case use of the
        fact that the upload server always returns the current start/end
        state whenever a PUT doesn't complete.

        Returns (server_start, server_end), where the values are inclusive.
        For example, (0, 2) would mean that the server has bytes 0, 1, *and* 2.

        Raises ResumableUploadException if problem querying server.
        """
        # Send an empty PUT so that server replies with this resumable
        # transfer's state.
        put_headers = {}
        put_headers['Content-Range'] = (self._build_content_range_header(
            '*', file_length))
        put_headers['Content-Length'] = '0'
        resp = AWSAuthConnection.make_request(conn,
                                              'PUT',
                                              path=self.tracker_uri_path,
                                              headers=put_headers,
                                              host=self.tracker_uri_host)
        if resp.status == 200:
            return (0, file_length)  # Completed upload.
        if resp.status != 308:
            # This means the server didn't have any state for the given
            # upload ID, which can happen (for example) if the caller saved
            # the tracker URI to a file and then tried to restart the transfer
            # after that upload ID has gone stale. In that case we need to
            # start a new transfer (and the caller will then save the new
            # tracker URI to the tracker file).
            raise ResumableUploadException(
                'Got non-308 response (%s) from server state query' %
                resp.status, ResumableTransferDisposition.START_OVER)
        got_valid_response = False
        range_spec = resp.getheader('range')
        if range_spec:
            # Parse 'bytes=<from>-<to>' range_spec.
            m = re.search('bytes=(\d+)-(\d+)', range_spec)
            if m:
                server_start = long(m.group(1))
                server_end = long(m.group(2))
                got_valid_response = True
        else:
            # No Range header, which means the server does not yet have
            # any bytes. Note that the Range header uses inclusive 'from'
            # and 'to' values. Since Range 0-0 would mean that the server
            # has byte 0, omitting the Range header is used to indicate that
            # the server doesn't have any bytes.
            return self.SERVER_HAS_NOTHING
        if not got_valid_response:
            raise ResumableUploadException(
                'Couldn\'t parse upload server state query response (%s)' %
                str(resp.getheaders()),
                ResumableTransferDisposition.START_OVER)
        if conn.debug >= 1:
            print 'Server has: Range: %d - %d.' % (server_start, server_end)
        return (server_start, server_end)
Beispiel #8
0
 def make_request(self,
                  verb,
                  resource,
                  headers=None,
                  data='',
                  ok_responses=(200, )):
     if headers is None:
         headers = {}
     headers['x-amz-glacier-version'] = self.Version
     uri = '/%s/%s' % (self.account_id, resource)
     response = AWSAuthConnection.make_request(self,
                                               verb,
                                               uri,
                                               params=params,
                                               headers=headers,
                                               data=data)
     if response.status in ok_responses:
         is_json = response.getheader('Content-Type') == 'application/json'
         body = json.loads(response.read()) if is_json else response.read()
         return dict(response.getheaders()), body
     else:
         msg = 'Expected %s, got (%d, %s)' % (ok_responses, response.status,
                                              response.read())
         # create glacier-specific exceptions
         raise BaseException(msg)
    def _query_server_state(self, conn, file_length):
        """
        Queries server to find out what bytes it currently has.

        Note that this method really just makes special case use of the
        fact that the upload server always returns the current start/end
        state whenever a PUT doesn't complete.

        Returns (server_start, server_end), where the values are inclusive.
        For example, (0, 2) would mean that the server has bytes 0, 1, *and* 2.

        Raises ResumableUploadException if problem querying server.
        """
        # Send an empty PUT so that server replies with this resumable
        # transfer's state.
        put_headers = {}
        put_headers['Content-Range'] = (
            self._build_content_range_header('*', file_length))
        put_headers['Content-Length'] = '0'
        resp = AWSAuthConnection.make_request(conn, 'PUT',
                                              path=self.tracker_uri_path,
                                              auth_path=self.tracker_uri_path,
                                              headers=put_headers,
                                              host=self.tracker_uri_host)
        if resp.status == 200:
            return (0, file_length)  # Completed upload.
        if resp.status != 308:
            # This means the server didn't have any state for the given
            # upload ID, which can happen (for example) if the caller saved
            # the tracker URI to a file and then tried to restart the transfer
            # after that upload ID has gone stale. In that case we need to
            # start a new transfer (and the caller will then save the new
            # tracker URI to the tracker file).
            raise ResumableUploadException(
                'Got non-308 response (%s) from server state query' %
                resp.status, ResumableTransferDisposition.START_OVER)
        got_valid_response = False
        range_spec = resp.getheader('range')
        if range_spec:
            # Parse 'bytes=<from>-<to>' range_spec.
            m = re.search('bytes=(\d+)-(\d+)', range_spec)
            if m:
                server_start = long(m.group(1))
                server_end = long(m.group(2))
                got_valid_response = True
        else:
            # No Range header, which means the server does not yet have
            # any bytes. Note that the Range header uses inclusive 'from'
            # and 'to' values. Since Range 0-0 would mean that the server
            # has byte 0, omitting the Range header is used to indicate that
            # the server doesn't have any bytes.
            return self.SERVER_HAS_NOTHING
        if not got_valid_response:
            raise ResumableUploadException(
                'Couldn\'t parse upload server state query response (%s)' %
                str(resp.getheaders()), ResumableTransferDisposition.START_OVER)
        if conn.debug >= 1:
            print 'Server has: Range: %d - %d.' % (server_start, server_end)
        return (server_start, server_end)
Beispiel #10
0
 def make_request(self, action, path, headers=None, data='', params=None):
     if params:
         pairs = []
         for key, val in params.iteritems():
             if val is None: continue
             pairs.append(key + '=' + urllib.quote(str(val)))
         path += '?' + '&'.join(pairs)
     return AWSAuthConnection.make_request(self, action, path, headers, data)
Beispiel #11
0
 def make_request(self, action, path, headers=None, data='', params=None):
     if params:
         pairs = []
         for key, val in params.iteritems():
             if val is None: continue
             pairs.append(key + '=' + urllib.quote(str(val)))
         path += '?' + '&'.join(pairs)
     return AWSAuthConnection.make_request(self, action, path, headers, data)
 def make_request(self, action, path, headers=None, data="", params=None):
     if params:
         pairs = []
         for key, val in params.iteritems():
             if val is None:
                 continue
             pairs.append(key + "=" + urllib.quote(str(val)))
         path += "?" + "&".join(pairs)
     return AWSAuthConnection.make_request(self, action, path, headers, data, retry_handler=self._retry_handler)
Beispiel #13
0
 def make_request(self, verb, resource, headers=None, data='',
                  expected_status=None, params=None):
     if headers is None:
         headers = {}
     response = AWSAuthConnection.make_request(
         self, verb, resource, headers=headers, data=data, params=params)
     body = json.loads(response.read().decode('utf-8'))
     if response.status == expected_status:
         return body
     else:
         raise JSONResponseError(response.status, response.reason, body)
Beispiel #14
0
 def make_request(self, method, bucket="", key="", headers=None, data="", query_args=None, sender=None):
     if isinstance(bucket, Bucket):
         bucket = bucket.name
     if isinstance(key, Key):
         key = key.name
     path = self.calling_format.build_path_base(bucket, key)
     auth_path = self.calling_format.build_auth_path(bucket, key)
     host = self.calling_format.build_host(self.server, bucket)
     if query_args:
         path += "?" + query_args
         auth_path += "?" + query_args
     return AWSAuthConnection.make_request(self, method, path, headers, data, host, auth_path, sender)
Beispiel #15
0
 def make_request(self, verb, resource, headers=None, data='',
                  expected_status=None, params=None):
     if headers is None:
         headers = {}
     response = AWSAuthConnection.make_request(
         self, verb, resource, headers=headers, data=data, params=params)
     body = json.loads(response.read().decode('utf-8'))
     if response.status == expected_status:
         return body
     else:
         error_type = response.getheader('x-amzn-ErrorType').split(':')[0]
         error_class = self._faults.get(error_type, self.ResponseError)
         raise error_class(response.status, response.reason, body)
Beispiel #16
0
    def make_request(self, method, path, headers=None, data=''):
        # add auth header
        if headers == None:
            headers = {}

        if not headers.has_key('AWS-Version'):
            headers['AWS-Version'] = self.APIVersion

        if not headers.has_key('Content-Type'):
            headers['Content-Type'] = self.DefaultContentType

        return AWSAuthConnection.make_request(self, method, path, headers,
                                              data)
Beispiel #17
0
    def make_request(self, method, path, headers=None, data=''):
        # add auth header
        if headers == None:
            headers = {}

        if not headers.has_key('AWS-Version'):
            headers['AWS-Version'] = self.APIVersion

        if not headers.has_key('Content-Type'):
            headers['Content-Type'] = self.DefaultContentType

        return AWSAuthConnection.make_request(self, method, path,
                                              headers, data)
Beispiel #18
0
 def make_request(self, verb, resource, headers=None, data='',
                  expected_status=None, params=None):
     if headers is None:
         headers = {}
     response = AWSAuthConnection.make_request(
         self, verb, resource, headers=headers, data=data)
     body = json.load(response)
     if response.status == expected_status:
         return body
     else:
         error_type = response.getheader('x-amzn-ErrorType').split(':')[0]
         error_class = self._faults.get(error_type, self.ResponseError)
         raise error_class(response.status, response.reason, body)
Beispiel #19
0
 def make_request(self, method, bucket='', key='', headers=None, data='',
         query_args=None, sender=None):
     if isinstance(bucket, Bucket):
         bucket = bucket.name
     if isinstance(key, Key):
         key = key.name
     path = self.calling_format.build_path_base(bucket, key)
     auth_path = self.calling_format.build_auth_path(bucket, key)
     host = self.calling_format.build_host(self.server_name, bucket)
     if query_args:
         path += '?' + query_args
         auth_path += '?' + query_args
     return AWSAuthConnection.make_request(self, method, path, headers,
             data, host, auth_path, sender)
Beispiel #20
0
    def get_user_quota(self, uid, tenant=''):
        """获取用户容量限制"""
        tenant = tenant or self.tenant
        if tenant:
            uid = '%s$%s' % (tenant, uid)

        parameters = {'uid': uid, 'quota-type': 'user'}
        response = AWSAuthConnection.make_request(
            self.conn,
            'GET',
            self.admin_endpoint + 'user?quota&' +
            urllib.parse.urlencode(parameters),
        )
        return self._handle_response(response)
Beispiel #21
0
 def make_request(self, method, bucket='', key='', headers=None, data='',
         query_args=None, sender=None, override_num_retries=None):
     if isinstance(bucket, self.bucket_class):
         bucket = bucket.name
     if isinstance(key, Key):
         key = key.name
     path = self.calling_format.build_path_base(bucket, key)
     auth_path = self.calling_format.build_auth_path(bucket, key)
     host = self.calling_format.build_host(self.server_name(), bucket)
     if query_args:
         path += '?' + query_args
         auth_path += '?' + query_args
     return AWSAuthConnection.make_request(self, method, path, headers,
             data, host, auth_path, sender,
             override_num_retries=override_num_retries)
Beispiel #22
0
 def make_request(self, method, bucket='', key='', extra_headers={}, data='',
         query_args=None, sender=None):
     if isinstance(bucket, Bucket):
         bucket = bucket.name
     if isinstance(key, Key):
         key = key.name
     path = self.calling_format.build_path_base(bucket, key)
     auth_path = self.calling_format.build_auth_path(bucket, key)
     host = self.calling_format.build_host(self.server_name(), bucket)
     if query_args:
         path += '?' + query_args
         auth_path += '?' + query_args
     headers = self.headers.copy()
     headers.update(extra_headers)
     return AWSAuthConnection.make_request(self, method, path, headers,
             data, host, auth_path, sender)
Beispiel #23
0
 def make_request(self, verb, resource, headers=None,
                  data='', ok_responses=(200,), params=None,
                  response_headers=None):
     if headers is None:
         headers = {}
     headers['x-amz-glacier-version'] = self.Version
     uri = '/%s/%s' % (self.account_id, resource)
     response = AWSAuthConnection.make_request(self, verb, uri,
                                               params=params,
                                               headers=headers,
                                               data=data)
     if response.status in ok_responses:
         return GlacierResponse(response, response_headers)
     else:
         # create glacier-specific exceptions
         raise UnexpectedHTTPResponseError(ok_responses, response)
Beispiel #24
0
    def link_bucket(self, uid, bucket, tenant=''):
        """将某个 bucket 绑定到指定 uid"""
        tenant = tenant or self.tenant
        if tenant:
            uid = '%s$%s' % (tenant, uid)

        parameters = {
            'uid': uid,
            'bucket': bucket,
        }
        response = AWSAuthConnection.make_request(
            self.conn,
            'PUT',
            self.admin_endpoint + 'bucket?' +
            urllib.parse.urlencode(parameters),
        )
        return self._handle_response(response)
Beispiel #25
0
    def get_user_info(self, uid, tenant=None):
        """根据 uin 获取用户信息"""
        tenant = tenant or self.tenant
        if tenant:
            uid = '%s$%s' % (tenant, uid)

        parameters = {'uid': uid}
        response = AWSAuthConnection.make_request(
            self.conn,
            'GET',
            self.admin_endpoint + 'user?' + urllib.parse.urlencode(parameters),
        )
        body = response.read()
        if response.status == 200:
            return json.loads(body)
        elif response.status == 404:
            return None
        else:
            raise StorageResponseError(response.status, response.reason, body)
Beispiel #26
0
def make_request(conn, method, basepath='', resource='', headers=None,
                 data=None, special_first_param=None, params=None, _retries=3):
    """
    Returns a ``AWSAuthConnection.make_request`` call with the preserving
    of the special params done by ``build``.
    """
    # request meta data
    md = build(
        conn,
        method,
        basepath=basepath,
        resource=resource,
        headers=headers,
        data=data,
        special_first_param=special_first_param,
        params=params,
    )

    if params:
        # we basically need to do this ourselves now. BOTO doesn't do it for us
        # in make_request
        result = []
        for k, vs in params.items():
            if isinstance(vs, basestring) or not hasattr(vs, '__iter__'):
                vs = [vs]
            for v in vs:
                if v is not None:
                    result.append(
                        (k.encode('utf-8') if isinstance(k, str) else k,
                         v.encode('utf-8') if isinstance(v, str) else v))
        appending_char = '&' if md.special_first_param else '?'
        md.path = '%s%s%s' % (md.path, appending_char, urlencode(result, doseq=True))

    return AWSAuthConnection.make_request(
        md.conn, md.method, md.path,
        headers=md.headers,
        data=md.data,
        host=md.host,
        auth_path=md.auth_path,
        params=md.params,
        override_num_retries=_retries
    )
Beispiel #27
0
 def make_request(
     self, method, bucket="", key="", headers=None, data="", query_args=None, sender=None, override_num_retries=None
 ):
     if isinstance(bucket, self.bucket_class):
         bucket = bucket.name
     if isinstance(key, Key):
         key = key.name
     path = self.calling_format.build_path_base(bucket, key)
     boto.log.debug("path=%s" % path)
     auth_path = self.calling_format.build_auth_path(bucket, key)
     boto.log.debug("auth_path=%s" % auth_path)
     host = self.calling_format.build_host(self.server_name(), bucket)
     if query_args:
         path += "?" + query_args
         boto.log.debug("path=%s" % path)
         auth_path += "?" + query_args
         boto.log.debug("auth_path=%s" % auth_path)
     return AWSAuthConnection.make_request(
         self, method, path, headers, data, host, auth_path, sender, override_num_retries=override_num_retries
     )
Beispiel #28
0
 def make_request(self, action, params=None, path='/', verb='GET'):
     """Overriden because we don't do the "Action" setting here"""
     headers = {}
     if params == None:
         params = {}
     params['Version'] = self.APIVersion
     params['AWSAccessKeyId'] = self.aws_access_key_id
     params['SignatureVersion'] = self.SignatureVersion
     params['Timestamp'] = time.strftime("%Y-%m-%dT%H:%M:%S", time.gmtime())
     qs, signature = self.get_signature(params, verb, self.get_path(path))
     if verb == 'POST':
         headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
         request_body = qs + '&Signature=' + urllib.quote(signature)
         qs = path
     else:
         request_body = ''
         qs = path + '?' + qs + '&Signature=' + urllib.quote(signature)
     return AWSAuthConnection.make_request(self, verb, qs,
                                           data=request_body,
                                           headers=headers)
Beispiel #29
0
 def make_request(self,
                  verb,
                  resource,
                  headers=None,
                  data='',
                  expected_status=None,
                  params=None):
     if headers is None:
         headers = {}
     response = AWSAuthConnection.make_request(self,
                                               verb,
                                               resource,
                                               headers=headers,
                                               data=data,
                                               params=params)
     body = json.loads(response.read().decode('utf-8'))
     if response.status == expected_status:
         return body
     else:
         raise JSONResponseError(response.status, response.reason, body)
    def _query_server_state(self, conn, file_length):
        """
        Queries server to find out state of given upload.

        Note that this method really just makes special case use of the
        fact that the upload server always returns the current start/end
        state whenever a PUT doesn't complete.

        Returns HTTP response from sending request.

        Raises ResumableUploadException if problem querying server.
        """
        # Send an empty PUT so that server replies with this resumable
        # transfer's state.
        put_headers = {}
        put_headers['Content-Range'] = (
            self._build_content_range_header('*', file_length))
        put_headers['Content-Length'] = '0'
        return AWSAuthConnection.make_request(conn, 'PUT',
                                              path=self.tracker_uri_path,
                                              auth_path=self.tracker_uri_path,
                                              headers=put_headers,
                                              host=self.tracker_uri_host)
Beispiel #31
0
 def make_request(self, action, params=None, path='/', verb='GET'):
     """Overriden because we don't do the "Action" setting here"""
     headers = {}
     if params == None:
         params = {}
     params['Version'] = self.APIVersion
     params['AWSAccessKeyId'] = self.aws_access_key_id
     params['SignatureVersion'] = self.SignatureVersion
     params['Timestamp'] = time.strftime("%Y-%m-%dT%H:%M:%S", time.gmtime())
     qs, signature = self.get_signature(params, verb, self.get_path(path))
     if verb == 'POST':
         headers[
             'Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
         request_body = qs + '&Signature=' + urllib.quote(signature)
         qs = path
     else:
         request_body = ''
         qs = path + '?' + qs + '&Signature=' + urllib.quote(signature)
     return AWSAuthConnection.make_request(self,
                                           verb,
                                           qs,
                                           data=request_body,
                                           headers=headers)
Beispiel #32
0
 def _make_request(self, action, params=None):
     """
     Custom request method. SES uses a faux REST/RPC like interface. 
     
     :type action: string
     :param action: API action
     
     :type params: Dict
     :param params: Additional params that are added to the API request.
     
     :type return: type returned from _process_response
     :param return: Formatted response
     """
     params = params or {}
     params['Action'] = action
     headers = {'Content-Type': 'application/x-www-form-urlencoded'}
     path = '/%s' % self.Version
     pairs = []
     for key, val in params.iteritems():
         if val is None: continue
         pairs.append(key + '=' + urllib.quote(str(val)))
     data = '&' . join(pairs)
     response = AWSAuthConnection.make_request(self, 'POST', path, headers, data)
     return self._process_response(response)
Beispiel #33
0
    def update_or_modify_user(self,
                              method,
                              uid,
                              tenant=None,
                              display_name='',
                              email='',
                              max_buckets=100):
        tenant = tenant or self.tenant
        if tenant:
            uid = '%s$%s' % (tenant, uid)

        parameters = {
            'uid': uid,
            'display-name': display_name,
            'email': email,
            'max-buckets': max_buckets
        }
        response = AWSAuthConnection.make_request(
            self.conn,
            method,
            self.admin_endpoint + 'user?' + urllib.parse.urlencode(parameters),
            # data=urllib.urlencode(parameters)
        )
        return self._handle_response(response)
class TestMakeRequestRetriesWithCorrectHost(AWSMockServiceTestCase):
    def setUp(self):
        self.connection = AWSAuthConnection('s3.amazonaws.com')

        self.non_retriable_code = 404
        self.retry_status_codes = [301, 400]
        self.success_response = self.create_response(200)

        self.default_host = 'bucket.s3.amazonaws.com'
        self.retry_region = RETRY_REGION_BYTES.decode('utf-8')
        self.default_retried_host = ('bucket.s3.%s.amazonaws.com' %
                                     self.retry_region)
        self.test_headers = [('x-amz-bucket-region', self.retry_region)]

    def test_non_retriable_status_returns_original_response(self):
        with mock.patch.object(self.connection, '_mexe') as mocked_mexe:
            error_response = self.create_response(self.non_retriable_code)
            mocked_mexe.side_effect = [error_response]

            response = self.connection.make_request('HEAD',
                                                    '/',
                                                    host=self.default_host)

            self.assertEqual(response, error_response)
            # called_once_with does not compare equality correctly with
            # HTTPResponse objects.
            self.assertEqual(mocked_mexe.call_count, 1)
            self.assertEqual(mocked_mexe.call_args[0][0].host,
                             self.default_host)

    def test_non_retriable_host_returns_original_response(self):
        for code in self.retry_status_codes:
            with mock.patch.object(self.connection, '_mexe') as mocked_mexe:
                error_response = self.create_response(code)
                mocked_mexe.side_effect = [error_response]

                other_host = 'bucket.some-other-provider.com'
                response = self.connection.make_request('HEAD',
                                                        '/',
                                                        host=other_host)

                self.assertEqual(response, error_response)
                self.assertEqual(mocked_mexe.call_count, 1)
                self.assertEqual(mocked_mexe.call_args[0][0].host, other_host)

    def test_non_retriable_status_raises_original_exception(self):
        with mock.patch.object(self.connection, '_mexe') as mocked_mexe:
            error_response = S3ResponseError(self.non_retriable_code, 'reason')
            mocked_mexe.side_effect = [error_response]

            with self.assertRaises(S3ResponseError) as cm:
                self.connection.make_request('HEAD',
                                             '/',
                                             host=self.default_host)

            self.assertEqual(cm.exception, error_response)
            self.assertEqual(mocked_mexe.call_count, 1)
            self.assertEqual(mocked_mexe.call_args[0][0].host,
                             self.default_host)

    def test_non_retriable_host_raises_original_exception(self):
        with mock.patch.object(self.connection, '_mexe') as mocked_mexe:
            error_response = S3ResponseError(self.non_retriable_code, 'reason')
            mocked_mexe.side_effect = [error_response]

            other_host = 'bucket.some-other-provider.com'
            with self.assertRaises(S3ResponseError) as cm:
                self.connection.make_request('HEAD', '/', host=other_host)

            self.assertEqual(cm.exception, error_response)
            self.assertEqual(mocked_mexe.call_count, 1)
            self.assertEqual(mocked_mexe.call_args[0][0].host, other_host)

    def test_response_retries_from_callable_headers(self):
        for code in self.retry_status_codes:
            with mock.patch.object(self.connection, '_mexe') as mocked_mexe:
                mocked_mexe.side_effect = [
                    self.create_response(code, header=self.test_headers),
                    self.success_response
                ]

                response = self.connection.make_request('HEAD',
                                                        '/',
                                                        host=self.default_host)

                self.assertEqual(response, self.success_response)
                self.assertEqual(mocked_mexe.call_count, 2)
                self.assertEqual(mocked_mexe.call_args[0][0].host,
                                 self.default_retried_host)

    def test_retry_changes_host_with_region(self):
        with mock.patch.object(self.connection, '_mexe') as mocked_mexe:
            # Assume 400 with callable headers results uses the same url
            # manipulation as all of the other successful cases.
            mocked_mexe.side_effect = [
                self.create_response(400, header=self.test_headers),
                self.success_response
            ]

            response = self.connection.make_request('HEAD',
                                                    '/',
                                                    host=self.default_host)

            self.assertEqual(response, self.success_response)
            self.assertEqual(mocked_mexe.call_count, 2)
            self.assertEqual(mocked_mexe.call_args[0][0].host,
                             self.default_retried_host)

    def test_retry_changes_host_with_multiple_s3_occurrences(self):
        with mock.patch.object(self.connection, '_mexe') as mocked_mexe:
            # Assume 400 with callable headers results uses the same url
            # manipulation as all of the other successful cases.
            mocked_mexe.side_effect = [
                self.create_response(400, header=self.test_headers),
                self.success_response
            ]

            response = self.connection.make_request(
                'HEAD', '/', host='a.s3.a.s3.amazonaws.com')

            self.assertEqual(response, self.success_response)
            self.assertEqual(mocked_mexe.call_count, 2)
            self.assertEqual(mocked_mexe.call_args[0][0].host,
                             'a.s3.a.s3.us-east-2.amazonaws.com')

    def test_retry_changes_host_with_s3_in_region(self):
        with mock.patch.object(self.connection, '_mexe') as mocked_mexe:
            # Assume 400 with callable headers results uses the same url
            # manipulation as all of the other successful cases.
            mocked_mexe.side_effect = [
                self.create_response(400, header=self.test_headers),
                self.success_response
            ]

            response = self.connection.make_request(
                'HEAD', '/', host='bucket.s3.asdf-s3.amazonaws.com')

            self.assertEqual(response, self.success_response)
            self.assertEqual(mocked_mexe.call_count, 2)
            self.assertEqual(mocked_mexe.call_args[0][0].host,
                             self.default_retried_host)

    def test_response_body_parsed_for_region(self):
        for code, body in ERRORS_WITH_REGION_IN_BODY:
            with mock.patch.object(self.connection, '_mexe') as mocked_mexe:
                mocked_mexe.side_effect = [
                    self.create_response(code, body=body),
                    self.success_response
                ]

                response = self.connection.make_request('HEAD',
                                                        '/',
                                                        host=self.default_host)

                self.assertEqual(response, self.success_response)
                self.assertEqual(mocked_mexe.call_count, 2)
                self.assertEqual(mocked_mexe.call_args[0][0].host,
                                 self.default_retried_host)

    def test_error_body_parsed_for_region(self):
        for code, body in ERRORS_WITH_REGION_IN_BODY:
            with mock.patch.object(self.connection, '_mexe') as mocked_mexe:
                mocked_mexe.side_effect = [
                    S3ResponseError(code, 'reason', body=body),
                    self.success_response
                ]

                response = self.connection.make_request('HEAD',
                                                        '/',
                                                        host=self.default_host)

                self.assertEqual(response, self.success_response)
                self.assertEqual(mocked_mexe.call_count, 2)
                self.assertEqual(mocked_mexe.call_args[0][0].host,
                                 self.default_retried_host)

    def test_response_without_region_header_retries_from_bucket_head(self):
        for code in self.retry_status_codes:
            with mock.patch.object(self.connection, '_mexe') as mocked_mexe:
                mocked_mexe.side_effect = [
                    self.create_response(code),
                    self.create_response(200, header=self.test_headers),
                    self.success_response
                ]

                response = self.connection.make_request('HEAD',
                                                        '/',
                                                        host=self.default_host)

                self.assertEqual(response, self.success_response)
                self.assertEqual(mocked_mexe.call_count, 3)
                self.assertEqual(mocked_mexe.call_args[0][0].host,
                                 self.default_retried_host)

    def test_response_body_without_region_sends_bucket_head(self):
        for code, body in ERRORS_WITHOUT_REGION_IN_BODY:
            with mock.patch.object(self.connection, '_mexe') as mocked_mexe:
                mocked_mexe.side_effect = [
                    self.create_response(code, body=body),
                    self.create_response(200, header=self.test_headers),
                    self.success_response
                ]

                response = self.connection.make_request('HEAD',
                                                        '/',
                                                        host=self.default_host)

                self.assertEqual(response, self.success_response)
                self.assertEqual(mocked_mexe.call_count, 3)
                self.assertEqual(mocked_mexe.call_args[0][0].host,
                                 self.default_retried_host)

    def test_error_body_without_region_retries_from_bucket_head_request(self):
        for code, body in ERRORS_WITHOUT_REGION_IN_BODY:
            with mock.patch.object(self.connection, '_mexe') as mocked_mexe:
                mocked_mexe.side_effect = [
                    S3ResponseError(code, 'reason', body=body),
                    self.create_response(200, header=self.test_headers),
                    self.success_response
                ]

                response = self.connection.make_request('HEAD',
                                                        '/',
                                                        host=self.default_host)

                self.assertEqual(response, self.success_response)
                self.assertEqual(mocked_mexe.call_count, 3)
                self.assertEqual(mocked_mexe.call_args[0][0].host,
                                 self.default_retried_host)

    def test_retry_head_request_lacks_region_returns_original_response(self):
        for code in self.retry_status_codes:
            with mock.patch.object(self.connection, '_mexe') as mocked_mexe:
                error_response = self.create_response(code)
                mocked_mexe.side_effect = [
                    error_response,
                    self.create_response(200,
                                         header=[])  # no region in header.
                ]

                response = self.connection.make_request('HEAD',
                                                        '/',
                                                        host=self.default_host)

                self.assertEqual(response, error_response)
                self.assertEqual(mocked_mexe.call_count, 2)
                self.assertEqual(mocked_mexe.call_args[0][0].host,
                                 self.default_host)

    def test_retry_head_request_lacks_region_raises_original_exception(self):
        for code in self.retry_status_codes:
            with mock.patch.object(self.connection, '_mexe') as mocked_mexe:
                error_response = S3ResponseError(code, 'reason')
                mocked_mexe.side_effect = [
                    error_response,
                    self.create_response(200, header=[])
                ]

                with self.assertRaises(S3ResponseError) as cm:
                    response = self.connection.make_request(
                        'HEAD', '/', host=self.default_host)

                self.assertEqual(cm.exception, error_response)
                self.assertEqual(mocked_mexe.call_count, 2)
                self.assertEqual(mocked_mexe.call_args[0][0].host,
                                 self.default_host)
Beispiel #35
0
 def make_request(self, params):
     data = '&'.join(k + '=' + urllib.quote(v) for k, v in params.iteritems())
     return AWSAuthConnection.make_request(self, 'GET', '/?' + data)