示例#1
0
 def test_create_http_exception(self):
     """Test that create_http_exception creates specific exceptions."""
     for code, (cls_name, cls_parent) in gcs_errors.http_errors.items():
         exc = gcs_errors.create_http_exception(code, mock.sentinel.message)
         self.assertEqual(code, exc.code)
         self.assertTrue(isinstance(exc, getattr(gcs_errors, cls_name)))
         self.assertEqual(mock.sentinel.message, exc.message)
示例#2
0
    def _get_data(self, size, begin=0):
        if not size:
            return ''

        end = begin + size - 1
        headers = {'Authorization': self._credentials.authorization,
                   'Range': 'bytes=%d-%d' % (begin, end)}
        params = {'alt': 'media'}
        r = requests.get(self._location, params=params, headers=headers)
        expected = (requests.codes.ok, requests.codes.partial_content,
                    requests.codes.requested_range_not_satisfiable)

        if r.status_code not in expected:
            raise errors.create_http_exception(
                r.status_code,
                'Error reading object %s in bucket %s: %s-%s' %
                (self.name, self.bucket, r.status_code, r.content))

        if r.status_code == requests.codes.requested_range_not_satisfiable:
            return ('', True)

        content_range = r.headers.get('Content-Range')
        total_size = None
        if content_range:
            try:
                total_size = int(content_range.split('/')[-1])
                eof = total_size <= begin + len(r.content)
                self.size = total_size
            except Exception:
                eof = len(r.content) < size
        if total_size is None:
            eof = len(r.content) < size

        return (r.content, eof)
示例#3
0
    def _open(self):
        safe_bucket = requests.utils.quote(self.bucket, safe='')
        safe_name = requests.utils.quote(self.name, safe='')
        if self._is_readable():
            self._location = self._URL % (safe_bucket, safe_name)
            params = {'fields': 'size', 'generation': self._generation}
            headers = {'Authorization': self._credentials.authorization}
            r = requests.get(self._location, params=params, headers=headers)
            if r.status_code == requests.codes.ok:
                try:
                    self.size = int(json.loads(r.content)['size'])
                except Exception as exc:
                    raise errors.Error('Bad data returned by GCS %s' % exc)

        else:
            self.size = 0
            initial_url = self._URL_UPLOAD % safe_bucket
            params = {'uploadType': 'resumable', 'name': self.name}
            headers = {'x-goog-resumable': 'start',
                       'Authorization': self._credentials.authorization,
                       'Content-type': 'application/octet-stream'}
            r = requests.post(initial_url, params=params, headers=headers)
            if r.status_code == requests.codes.ok:
                self._location = r.headers['Location']

        if r.status_code != requests.codes.ok:
            raise errors.create_http_exception(
                r.status_code,
                'Error opening object %s in bucket %s: %s-%s' %
                (self.name, self.bucket, r.status_code, r.content))
        self.closed = False
示例#4
0
    def _send_data(self, data, begin=0, finalize=False):
        if not (data or finalize):
            return

        if not data:
            size = self.size
            data_range = 'bytes */%s' % size
        else:
            end = begin + len(data) - 1
            size = self.size if finalize else '*'
            data_range = 'bytes %s-%s/%s' % (begin, end, size)

        headers = {'Authorization': self._credentials.authorization,
                   'Content-Range': data_range}
        r = requests.put(self._location, data=data, headers=headers)

        if size == '*':
            expected = requests.codes.resume_incomplete
        else:
            expected = requests.codes.ok

        if r.status_code != expected:
            raise errors.create_http_exception(
                r.status_code,
                'Error writting to object %s in bucket %s: %s-%s' %
                (self.name, self.bucket, r.status_code, r.content))
示例#5
0
    def _get_data(self, size, begin=0):
        if not size:
            return ''

        end = begin + size - 1
        headers = {
            'Authorization': self._credentials.authorization,
            'Range': 'bytes=%d-%d' % (begin, end)
        }
        params = {'alt': 'media'}
        r = requests.get(self._location, params=params, headers=headers)
        expected = (requests.codes.ok, requests.codes.partial_content,
                    requests.codes.requested_range_not_satisfiable)

        if r.status_code not in expected:
            raise errors.create_http_exception(
                r.status_code, 'Error reading object %s in bucket %s: %s-%s' %
                (self.name, self.bucket, r.status_code, r.content))

        if r.status_code == requests.codes.requested_range_not_satisfiable:
            return ('', True)

        content_range = r.headers.get('Content-Range')
        total_size = None
        if content_range:
            try:
                total_size = int(content_range.split('/')[-1])
                eof = total_size <= begin + len(r.content)
                self.size = total_size
            except Exception:
                eof = len(r.content) < size
        if total_size is None:
            eof = len(r.content) < size

        return (r.content, eof)
示例#6
0
    def _request(self,
                 op='GET',
                 headers=None,
                 body=None,
                 parse=False,
                 ok=(requests.codes.ok, ),
                 url=None,
                 format_url=True,
                 **params):
        """Request actions on a GCS resource.

        :param op: Operation to perform (GET, PUT, POST, HEAD, DELETE).
        :type op: six.string_types
        :param headers: Headers to send in the request.  Authentication will be
                        added.
        :type headers: dict
        :param body: Body to send in the request.
        :type body: Dictionary, bytes or file-like object.
        :param parse: If we want to check that response body is JSON.
        :type parse: bool
        :param ok: Response status codes to consider as OK.
        :type ok: Iterable of integer numbers
        :param url: Alternative url to use
        :type url: six.string_types
        :param format_url: If we want provided url to be formatted with params
        :type format_url: bool
        :param params: All params to send as URL params in the request.
        :returns: requests.Request
        :"""
        headers = {} if not headers else headers.copy()
        headers['Authorization'] = self._credentials.authorization

        if not url:
            url = self._URL

        if format_url:
            format_args = {
                x: requests.utils.quote(six.text_type(getattr(self, x)),
                                        safe='')
                for x in self._required_attributes
            }
            url = url.format(**format_args)

        r = requests.request(op,
                             url,
                             params=params,
                             headers=headers,
                             json=body)

        if r.status_code not in ok:
            raise gcs_errors.create_http_exception(r.status_code, r.content)

        if parse:
            try:
                r.json()
            except Exception:
                raise gcs_errors.Error('GCS response is not JSON: %s' %
                                       r.content)

        return r
示例#7
0
    def _send_data(self, data, begin=0, finalize=False):
        if not (data or finalize):
            return

        if not data:
            size = self.size
            data_range = 'bytes */%s' % size
        else:
            end = begin + len(data) - 1
            size = self.size if finalize else '*'
            data_range = 'bytes %s-%s/%s' % (begin, end, size)

        headers = {
            'Authorization': self._credentials.authorization,
            'Content-Range': data_range
        }
        r = requests.put(self._location, data=data, headers=headers)

        if size == '*':
            expected = requests.codes.resume_incomplete
        else:
            expected = requests.codes.ok

        if r.status_code != expected:
            raise errors.create_http_exception(
                r.status_code,
                'Error writting to object %s in bucket %s: %s-%s' %
                (self.name, self.bucket, r.status_code, r.content))
示例#8
0
    def _open(self):
        safe_bucket = requests.utils.quote(self.bucket, safe='')
        safe_name = requests.utils.quote(self.name, safe='')
        if self._is_readable():
            self._location = self._URL % (safe_bucket, safe_name)
            params = {'fields': 'size', 'generation': self._generation}
            headers = {'Authorization': self._credentials.authorization}
            r = requests.get(self._location, params=params, headers=headers)
            if r.status_code == requests.codes.ok:
                try:
                    self.size = int(json.loads(r.content)['size'])
                except Exception as exc:
                    raise errors.Error('Bad data returned by GCS %s' % exc)

        else:
            self.size = 0
            initial_url = self._URL_UPLOAD % safe_bucket
            params = {'uploadType': 'resumable', 'name': self.name}
            headers = {
                'x-goog-resumable': 'start',
                'Authorization': self._credentials.authorization,
                'Content-type': 'application/octet-stream'
            }
            r = requests.post(initial_url, params=params, headers=headers)
            if r.status_code == requests.codes.ok:
                self._location = r.headers['Location']

        if r.status_code != requests.codes.ok:
            raise errors.create_http_exception(
                r.status_code, 'Error opening object %s in bucket %s: %s-%s' %
                (self.name, self.bucket, r.status_code, r.content))
        self.closed = False
示例#9
0
 def test_create_http_exception(self):
     """Test that create_http_exception creates specific exceptions."""
     for code, (cls_name, cls_parent) in gcs_errors.http_errors.items():
         exc = gcs_errors.create_http_exception(code, mock.sentinel.message)
         self.assertEqual(code, exc.code)
         self.assertTrue(isinstance(exc, getattr(gcs_errors, cls_name)))
         self.assertEqual(mock.sentinel.message, exc.message)
示例#10
0
 def test_create_http_exception_non_int_code(self):
     """Test create_http_exception creates exceptions from non int codes."""
     for code, (cls_name, cls_parent) in gcs_errors.http_errors.items():
         exc = gcs_errors.create_http_exception('code',
                                                mock.sentinel.message)
         self.assertEqual('code', exc.code)
         self.assertIs(gcs_errors.Http, type(exc))
         self.assertEqual(mock.sentinel.message, exc.message)
示例#11
0
 def test_create_http_exception_non_int_code(self):
     """Test create_http_exception creates exceptions from non int codes."""
     for code, (cls_name, cls_parent) in gcs_errors.http_errors.items():
         exc = gcs_errors.create_http_exception('code',
                                                mock.sentinel.message)
         self.assertEqual('code', exc.code)
         self.assertIs(gcs_errors.Http, type(exc))
         self.assertEqual(mock.sentinel.message, exc.message)
示例#12
0
文件: base.py 项目: Akrog/gcs-client
    def _request(self, op='GET', headers=None, body=None, parse=False,
                 ok=(requests.codes.ok,), url=None, format_url=True, **params):
        """Request actions on a GCS resource.

        :param op: Operation to perform (GET, PUT, POST, HEAD, DELETE).
        :type op: six.string_types
        :param headers: Headers to send in the request.  Authentication will be
                        added.
        :type headers: dict
        :param body: Body to send in the request.
        :type body: Dictionary, bytes or file-like object.
        :param parse: If we want to check that response body is JSON.
        :type parse: bool
        :param ok: Response status codes to consider as OK.
        :type ok: Iterable of integer numbers
        :param url: Alternative url to use
        :type url: six.string_types
        :param format_url: If we want provided url to be formatted with params
        :type format_url: bool
        :param params: All params to send as URL params in the request.
        :returns: requests.Request
        :"""
        headers = {} if not headers else headers.copy()
        headers['Authorization'] = self._credentials.authorization

        if not url:
            url = self._URL

        if format_url:
            format_args = {
                x: requests.utils.quote(six.text_type(getattr(self, x)),
                                        safe='')
                for x in self._required_attributes}
            url = url.format(**format_args)

        r = requests.request(op, url, params=params, headers=headers,
                             json=body)

        if r.status_code not in ok:
            raise gcs_errors.create_http_exception(r.status_code, r.content)

        if parse:
            try:
                r.json()
            except Exception:
                raise gcs_errors.Error('GCS response is not JSON: %s' %
                                       r.content)

        return r
示例#13
0
 def test_create_http_exception_non_specific(self):
     """Test create_http_exception creates non specific exceptions."""
     exc = gcs_errors.create_http_exception(1, mock.sentinel.message)
     self.assertEqual(1, exc.code)
     self.assertIs(gcs_errors.Http, type(exc))
     self.assertEqual(mock.sentinel.message, exc.message)
示例#14
0
 def test_create_http_exception_non_specific(self):
     """Test create_http_exception creates non specific exceptions."""
     exc = gcs_errors.create_http_exception(1, mock.sentinel.message)
     self.assertEqual(1, exc.code)
     self.assertIs(gcs_errors.Http, type(exc))
     self.assertEqual(mock.sentinel.message, exc.message)