示例#1
0
    def __call__(self, env, start_response):
        req = Request(env)

        # Get request parameters
        req_method = req.method
        req_path = req.path
        req_headers = req.headers
        req_body = req.body
        self._calls.append((req_method, req_path, req_headers, req_body))
        try:
            resp_cls, raw_headers, body = \
                self._responses[(req_method, req_path)]
            headers = HeaderKeyDict(raw_headers)
        except KeyError:
            if req_method == 'HEAD' and ('GET', req_path) in self._responses:
                resp_cls, raw_headers, _ = self._responses[('GET', req_path)]
                body = None
                headers = HeaderKeyDict(raw_headers)
            else:
                raise
        resp = resp_cls(req=req,
                        headers=headers,
                        body=body,
                        conditional_response=True)
        return resp(env, start_response)
示例#2
0
    def test_206_multiple_ranges(self):
        fr = FakeResponse(
            206,
            {'Content-Type': 'multipart/byteranges; boundary=asdfasdfasdf'},
            (b"--asdfasdfasdf\r\n"
             b"Content-Type: application/lunch\r\n"
             b"Content-Range: bytes 0-3/10\r\n"
             b"\r\n"
             b"sand\r\n"
             b"--asdfasdfasdf\r\n"
             b"Content-Type: application/lunch\r\n"
             b"Content-Range: bytes 6-9/10\r\n"
             b"\r\n"
             b"ches\r\n"
             b"--asdfasdfasdf--"))

        doc_iters = rh.http_response_to_document_iters(fr)

        first_byte, last_byte, length, headers, body = next(doc_iters)
        self.assertEqual(first_byte, 0)
        self.assertEqual(last_byte, 3)
        self.assertEqual(length, 10)
        header_dict = HeaderKeyDict(headers)
        self.assertEqual(header_dict.get('Content-Type'), 'application/lunch')
        self.assertEqual(body.read(), b'sand')

        first_byte, last_byte, length, headers, body = next(doc_iters)
        self.assertEqual(first_byte, 6)
        self.assertEqual(last_byte, 9)
        self.assertEqual(length, 10)
        header_dict = HeaderKeyDict(headers)
        self.assertEqual(header_dict.get('Content-Type'), 'application/lunch')
        self.assertEqual(body.read(), b'ches')

        self.assertRaises(StopIteration, next, doc_iters)
示例#3
0
    def test_200(self):
        fr = FakeResponse(200, {
            'Content-Length': '10',
            'Content-Type': 'application/lunch'
        }, b'sandwiches')

        doc_iters = rh.http_response_to_document_iters(fr)
        first_byte, last_byte, length, headers, body = next(doc_iters)
        self.assertEqual(first_byte, 0)
        self.assertEqual(last_byte, 9)
        self.assertEqual(length, 10)
        header_dict = HeaderKeyDict(headers)
        self.assertEqual(header_dict.get('Content-Length'), '10')
        self.assertEqual(header_dict.get('Content-Type'), 'application/lunch')
        self.assertEqual(body.read(), b'sandwiches')

        self.assertRaises(StopIteration, next, doc_iters)

        fr = FakeResponse(200, {
            'Transfer-Encoding': 'chunked',
            'Content-Type': 'application/lunch'
        }, b'sandwiches')

        doc_iters = rh.http_response_to_document_iters(fr)
        first_byte, last_byte, length, headers, body = next(doc_iters)
        self.assertEqual(first_byte, 0)
        self.assertIsNone(last_byte)
        self.assertIsNone(length)
        header_dict = HeaderKeyDict(headers)
        self.assertEqual(header_dict.get('Transfer-Encoding'), 'chunked')
        self.assertEqual(header_dict.get('Content-Type'), 'application/lunch')
        self.assertEqual(body.read(), b'sandwiches')

        self.assertRaises(StopIteration, next, doc_iters)
示例#4
0
    def generate_request_headers(self,
                                 orig_req=None,
                                 additional=None,
                                 transfer=False):
        """
        Create a list of headers to be used in backend requets

        :param orig_req: the original request sent by the client to the proxy
        :param additional: additional headers to send to the backend
        :param transfer: If True, transfer headers from original client request
        :returns: a dictionary of headers
        """
        # Use the additional headers first so they don't overwrite the headers
        # we require.
        headers = HeaderKeyDict(additional) if additional else HeaderKeyDict()
        if transfer:
            self.transfer_headers(orig_req.headers, headers)
        headers.setdefault('x-timestamp', normalize_timestamp(time.time()))
        if orig_req:
            referer = orig_req.as_referer()
        else:
            referer = ''
        headers['x-trans-id'] = self.trans_id
        headers['connection'] = 'close'
        headers['user-agent'] = 'proxy-server %s' % os.getpid()
        headers['referer'] = referer
        return headers
示例#5
0
    def test_clean_outgoing_headers(self):
        orh = ''
        oah = ''
        hdrs = {'test-header': 'value'}
        hdrs = HeaderKeyDict(tempurl.TempURL(
            None,
            {'outgoing_remove_headers': orh, 'outgoing_allow_headers': oah}
        )._clean_outgoing_headers(hdrs.items()))
        self.assertTrue('test-header' in hdrs)

        orh = 'test-header'
        oah = ''
        hdrs = {'test-header': 'value'}
        hdrs = HeaderKeyDict(tempurl.TempURL(
            None,
            {'outgoing_remove_headers': orh, 'outgoing_allow_headers': oah}
        )._clean_outgoing_headers(hdrs.items()))
        self.assertTrue('test-header' not in hdrs)

        orh = 'test-header-*'
        oah = ''
        hdrs = {'test-header-one': 'value',
                'test-header-two': 'value'}
        hdrs = HeaderKeyDict(tempurl.TempURL(
            None,
            {'outgoing_remove_headers': orh, 'outgoing_allow_headers': oah}
        )._clean_outgoing_headers(hdrs.items()))
        self.assertTrue('test-header-one' not in hdrs)
        self.assertTrue('test-header-two' not in hdrs)

        orh = 'test-header-*'
        oah = 'test-header-two'
        hdrs = {'test-header-one': 'value',
                'test-header-two': 'value'}
        hdrs = HeaderKeyDict(tempurl.TempURL(
            None,
            {'outgoing_remove_headers': orh, 'outgoing_allow_headers': oah}
        )._clean_outgoing_headers(hdrs.items()))
        self.assertTrue('test-header-one' not in hdrs)
        self.assertTrue('test-header-two' in hdrs)

        orh = 'test-header-* test-other-header'
        oah = 'test-header-two test-header-yes-*'
        hdrs = {'test-header-one': 'value',
                'test-header-two': 'value',
                'test-other-header': 'value',
                'test-header-yes': 'value',
                'test-header-yes-this': 'value'}
        hdrs = HeaderKeyDict(tempurl.TempURL(
            None,
            {'outgoing_remove_headers': orh, 'outgoing_allow_headers': oah}
        )._clean_outgoing_headers(hdrs.items()))
        self.assertTrue('test-header-one' not in hdrs)
        self.assertTrue('test-header-two' in hdrs)
        self.assertTrue('test-other-header' not in hdrs)
        self.assertTrue('test-header-yes' not in hdrs)
        self.assertTrue('test-header-yes-this' in hdrs)
示例#6
0
 def test_transfer_headers_with_sysmeta(self):
     base = Controller(self.app)
     good_hdrs = {'x-base-sysmeta-foo': 'ok',
                  'X-Base-sysmeta-Bar': 'also ok'}
     bad_hdrs = {'x-base-sysmeta-': 'too short'}
     hdrs = dict(good_hdrs)
     hdrs.update(bad_hdrs)
     dst_hdrs = HeaderKeyDict()
     base.transfer_headers(hdrs, dst_hdrs)
     self.assertEqual(HeaderKeyDict(good_hdrs), dst_hdrs)
示例#7
0
def direct_head_object(node,
                       part,
                       account,
                       container,
                       obj,
                       conn_timeout=5,
                       response_timeout=15,
                       headers=None):
    """
    Request object information directly from the object server.

    :param node: node dictionary from the ring
    :param part: partition the container is on
    :param account: account name
    :param container: container name
    :param obj: object name
    :param conn_timeout: timeout in seconds for establishing the connection
    :param response_timeout: timeout in seconds for getting the response
    :param headers: dict to be passed into HTTPConnection headers
    :returns: a dict containing the response's headers in a HeaderKeyDict
    :raises ClientException: HTTP HEAD request failed
    """
    if headers is None:
        headers = {}

    headers = gen_headers(headers)

    path = '/%s/%s/%s' % (account, container, obj)
    resp = _make_req(node, part, 'HEAD', path, headers, 'Object', conn_timeout,
                     response_timeout)

    resp_headers = HeaderKeyDict()
    for header, value in resp.getheaders():
        resp_headers[header] = value
    return resp_headers
示例#8
0
def direct_head_container(node,
                          part,
                          account,
                          container,
                          conn_timeout=5,
                          response_timeout=15):
    """
    Request container information directly from the container server.

    :param node: node dictionary from the ring
    :param part: partition the container is on
    :param account: account name
    :param container: container name
    :param conn_timeout: timeout in seconds for establishing the connection
    :param response_timeout: timeout in seconds for getting the response
    :returns: a dict containing the response's headers in a HeaderKeyDict
    :raises ClientException: HTTP HEAD request failed
    """
    path = '/%s/%s' % (account, container)
    resp = _make_req(node, part, 'HEAD', path, gen_headers(), 'Container',
                     conn_timeout, response_timeout)

    resp_headers = HeaderKeyDict()
    for header, value in resp.getheaders():
        resp_headers[header] = value
    return resp_headers
示例#9
0
def _get_direct_account_container(path, stype, node, part,
                                  account, marker=None, limit=None,
                                  prefix=None, delimiter=None, conn_timeout=5,
                                  response_timeout=15):
    """Base class for get direct account and container.

    Do not use directly use the get_direct_account or
    get_direct_container instead.
    """
    qs = 'format=json'
    if marker:
        qs += '&marker=%s' % quote(marker)
    if limit:
        qs += '&limit=%d' % limit
    if prefix:
        qs += '&prefix=%s' % quote(prefix)
    if delimiter:
        qs += '&delimiter=%s' % quote(delimiter)
    with Timeout(conn_timeout):
        conn = http_connect(node['ip'], node['port'], node['device'], part,
                            'GET', path, query_string=qs,
                            headers=gen_headers())
    with Timeout(response_timeout):
        resp = conn.getresponse()
    if not is_success(resp.status):
        resp.read()
        raise DirectClientException(stype, 'GET', node, part, path, resp)
    resp_headers = HeaderKeyDict()
    for header, value in resp.getheaders():
        resp_headers[header] = value
    if resp.status == HTTP_NO_CONTENT:
        resp.read()
        return resp_headers, []
    return resp_headers, json.loads(resp.read())
示例#10
0
def direct_head_object(node, part, account, container, obj, conn_timeout=5,
                       response_timeout=15, headers=None):
    """
    Request object information directly from the object server.

    :param node: node dictionary from the ring
    :param part: partition the container is on
    :param account: account name
    :param container: container name
    :param obj: object name
    :param conn_timeout: timeout in seconds for establishing the connection
    :param response_timeout: timeout in seconds for getting the response
    :param headers: dict to be passed into HTTPConnection headers
    :returns: a dict containing the response's headers in a HeaderKeyDict
    :raises ClientException: HTTP HEAD request failed
    """
    if headers is None:
        headers = {}

    headers = gen_headers(headers)

    path = '/%s/%s/%s' % (account, container, obj)
    with Timeout(conn_timeout):
        conn = http_connect(node['ip'], node['port'], node['device'], part,
                            'HEAD', path, headers=headers)
    with Timeout(response_timeout):
        resp = conn.getresponse()
        resp.read()
    if not is_success(resp.status):
        raise DirectClientException('Object', 'HEAD',
                                    node, part, path, resp)
    resp_headers = HeaderKeyDict()
    for header, value in resp.getheaders():
        resp_headers[header] = value
    return resp_headers
示例#11
0
    def _check_failure_put_connections(self, conns, req, nodes):
        if req.if_none_match is not None and '*' in req.if_none_match:
            statuses = [conn.resp.status for conn in conns if conn.resp]
            if HTTP_PRECONDITION_FAILED in statuses:
                # If we find any copy of the file, it shouldn't be uploaded
                self.app.logger.debug(
                    _('Object PUT returning 412, %(statuses)r'),
                    {'statuses': statuses})
                raise HTTPPreconditionFailed(request=req)

        if any(conn for conn in conns
               if conn.resp and conn.resp.status == HTTP_CONFLICT):
            timestamps = [
                HeaderKeyDict(
                    conn.resp.getheaders()).get('X-Backend-Timestamp')
                for conn in conns if conn.resp
            ]
            self.app.logger.debug(
                _('Object PUT returning 202 for 409: '
                  '%(req_timestamp)s <= %(timestamps)r'), {
                      'req_timestamp': req.timestamp.internal,
                      'timestamps': ', '.join(timestamps)
                  })
            raise HTTPAccepted(request=req)

        min_conns = quorum_size(len(nodes))
        self._check_min_conn(req, conns, min_conns)
示例#12
0
 def cookie_resp(status, response_headers, exc_info=None):
     resp_headers = HeaderKeyDict(response_headers)
     if 'x-auth-token' in resp_headers:
         auth_token = resp_headers['x-auth-token']
         expires_in = int(resp_headers.get('x-auth-token-expires', 0))
         storage_url = resp_headers.get('x-storage-url', '')
         path_parts = urlparse(storage_url)
         domain = path_parts.netloc
         secure = False
         if path_parts.scheme == 'https':
             secure = True
         if auth_token and domain:
             new_cookie = create_auth_cookie('session',
                                             domain,
                                             token=auth_token,
                                             expires_in=expires_in,
                                             secure=secure,
                                             httponly=True)
             response_headers.append(('Set-Cookie', new_cookie))
             new_cookie = create_auth_cookie('storage',
                                             domain,
                                             token=storage_url,
                                             expires_in=expires_in,
                                             secure=secure)
             response_headers.append(('Set-Cookie', new_cookie))
     return start_response(status, response_headers, exc_info)
示例#13
0
def parse_mime_headers(doc_file):
    """
    Takes a file-like object containing a MIME document and returns a
    HeaderKeyDict containing the headers. The body of the message is not
    consumed: the position in doc_file is left at the beginning of the body.

    This function was inspired by the Python standard library's
    http.client.parse_headers.

    :param doc_file: binary file-like object containing a MIME document
    :returns: a swift.common.swob.HeaderKeyDict containing the headers
    """
    headers = []
    while True:
        line = doc_file.readline()
        done = line in (b'\r\n', b'\n', b'')
        if six.PY3:
            try:
                line = line.decode('utf-8')
            except UnicodeDecodeError:
                line = line.decode('latin1')
        headers.append(line)
        if done:
            break
    if six.PY3:
        header_string = ''.join(headers)
    else:
        header_string = b''.join(headers)
    headers = email.parser.Parser().parsestr(header_string)
    return HeaderKeyDict(headers)
示例#14
0
    def _read_metadata_footer(self, mime_documents_iter):
        try:
            with ChunkReadTimeout(self.client_timeout):
                footer_hdrs, footer_iter = next(mime_documents_iter)
        except ChunkReadTimeout:
            raise HTTPClientDisconnect()
        except StopIteration:
            raise HTTPBadRequest(body="couldn't find footer MIME doc")

        timeout_reader = self._make_timeout_reader(footer_iter)
        try:
            footer_body = ''.join(iter(timeout_reader, ''))
        except ChunkReadTimeout:
            raise HTTPClientDisconnect()

        footer_md5 = footer_hdrs.get('Content-MD5')
        if not footer_md5:
            raise HTTPBadRequest(body="no Content-MD5 in footer")
        if footer_md5 != md5(footer_body).hexdigest():
            raise HTTPUnprocessableEntity(body="footer MD5 mismatch")

        try:
            return HeaderKeyDict(json.loads(footer_body))
        except ValueError:
            raise HTTPBadRequest("invalid JSON for footer doc")
示例#15
0
def iter_mime_headers_and_bodies(wsgi_input, mime_boundary, read_chunk_size):
    mime_documents_iter = iter_multipart_mime_documents(
        wsgi_input, mime_boundary, read_chunk_size)

    for file_like in mime_documents_iter:
        hdrs = HeaderKeyDict(rfc822.Message(file_like, 0))
        yield (hdrs, file_like)
示例#16
0
文件: server.py 项目: sagarjha/swift
 def DELETE(self, request):
     """Handle HTTP DELETE requests for the Swift Object Server."""
     device, partition, account, container, obj, policy_idx = \
         get_name_and_placement(request, 5, 5, True)
     if 'x-timestamp' not in request.headers or \
             not check_float(request.headers['x-timestamp']):
         return HTTPBadRequest(body='Missing timestamp', request=request,
                               content_type='text/plain')
     try:
         disk_file = self.get_diskfile(
             device, partition, account, container, obj,
             policy_idx=policy_idx)
     except DiskFileDeviceUnavailable:
         return HTTPInsufficientStorage(drive=device, request=request)
     try:
         orig_metadata = disk_file.read_metadata()
     except DiskFileExpired as e:
         orig_timestamp = e.timestamp
         orig_metadata = e.metadata
         response_class = HTTPNotFound
     except DiskFileDeleted as e:
         orig_timestamp = e.timestamp
         orig_metadata = {}
         response_class = HTTPNotFound
     except (DiskFileNotExist, DiskFileQuarantined):
         orig_timestamp = 0
         orig_metadata = {}
         response_class = HTTPNotFound
     else:
         orig_timestamp = orig_metadata.get('X-Timestamp', 0)
         if orig_timestamp < request.headers['x-timestamp']:
             response_class = HTTPNoContent
         else:
             response_class = HTTPConflict
     orig_delete_at = int(orig_metadata.get('X-Delete-At') or 0)
     try:
         req_if_delete_at_val = request.headers['x-if-delete-at']
         req_if_delete_at = int(req_if_delete_at_val)
     except KeyError:
         pass
     except ValueError:
         return HTTPBadRequest(
             request=request,
             body='Bad X-If-Delete-At header value')
     else:
         if orig_delete_at != req_if_delete_at:
             return HTTPPreconditionFailed(
                 request=request,
                 body='X-If-Delete-At and X-Delete-At do not match')
     if orig_delete_at:
         self.delete_at_update('DELETE', orig_delete_at, account,
                               container, obj, request, device)
     req_timestamp = request.headers['X-Timestamp']
     if orig_timestamp < req_timestamp:
         disk_file.delete(req_timestamp)
         self.container_update(
             'DELETE', account, container, obj, request,
             HeaderKeyDict({'x-timestamp': req_timestamp}),
             device, policy_idx)
     return response_class(request=request)
示例#17
0
文件: tempurl.py 项目: nchazin/swift
    def _clean_outgoing_headers(self, headers):
        """
        Removes any headers as per the middleware configuration for
        outgoing responses.

        :param headers: A WSGI start_response style list of headers,
                        [('header1', 'value), ('header2', 'value),
                         ...]
        :returns: The same headers list, but with some headers
                  removed as per the middlware configuration for
                  outgoing responses.
        """
        headers = HeaderKeyDict(headers)
        for h in headers.keys():
            remove = h in self.outgoing_remove_headers
            if not remove:
                for p in self.outgoing_remove_headers_startswith:
                    if h.startswith(p):
                        remove = True
                        break
            if remove:
                if h in self.outgoing_allow_headers:
                    remove = False
            if remove:
                for p in self.outgoing_allow_headers_startswith:
                    if h.startswith(p):
                        remove = False
                        break
            if remove:
                del headers[h]
        return headers.items()
示例#18
0
    def test_direct_get_account(self):
        stub_headers = HeaderKeyDict({
            'X-Account-Container-Count': '1',
            'X-Account-Object-Count': '1',
            'X-Account-Bytes-Used': '1',
            'X-Timestamp': '1234567890',
            'X-PUT-Timestamp': '1234567890'
        })

        body = '[{"count": 1, "bytes": 20971520, "name": "c1"}]'

        with mocked_http_conn(200, stub_headers, body) as conn:
            resp_headers, resp = direct_client.direct_get_account(
                self.node,
                self.part,
                self.account,
                marker='marker',
                prefix='prefix',
                delimiter='delimiter',
                limit=1000)
            self.assertEqual(conn.method, 'GET')
            self.assertEqual(conn.path, self.account_path)

        self.assertEqual(conn.req_headers['user-agent'], self.user_agent)
        self.assertEqual(resp_headers, stub_headers)
        self.assertEqual(json.loads(body), resp)
        self.assertTrue('marker=marker' in conn.query_string)
        self.assertTrue('delimiter=delimiter' in conn.query_string)
        self.assertTrue('limit=1000' in conn.query_string)
        self.assertTrue('prefix=prefix' in conn.query_string)
        self.assertTrue('format=json' in conn.query_string)
示例#19
0
def direct_get_object(node,
                      part,
                      account,
                      container,
                      obj,
                      conn_timeout=5,
                      response_timeout=15,
                      resp_chunk_size=None,
                      headers=None):
    """
    Get object directly from the object server.

    :param node: node dictionary from the ring
    :param part: partition the container is on
    :param account: account name
    :param container: container name
    :param obj: object name
    :param conn_timeout: timeout in seconds for establishing the connection
    :param response_timeout: timeout in seconds for getting the response
    :param resp_chunk_size: if defined, chunk size of data to read.
    :param headers: dict to be passed into HTTPConnection headers
    :returns: a tuple of (response headers, the object's contents) The response
              headers will be a HeaderKeyDict.
    :raises ClientException: HTTP GET request failed
    """
    if headers is None:
        headers = {}

    path = '/%s/%s/%s' % (account, container, obj)
    with Timeout(conn_timeout):
        conn = http_connect(node['ip'],
                            node['port'],
                            node['device'],
                            part,
                            'GET',
                            path,
                            headers=gen_headers(headers))
    with Timeout(response_timeout):
        resp = conn.getresponse()
    if not is_success(resp.status):
        resp.read()
        raise DirectClientException('Object', 'GET', node, part, path, resp)

    if resp_chunk_size:

        def _object_body():
            buf = resp.read(resp_chunk_size)
            while buf:
                yield buf
                buf = resp.read(resp_chunk_size)

        object_body = _object_body()
    else:
        object_body = resp.read()
    resp_headers = HeaderKeyDict()
    for header, value in resp.getheaders():
        resp_headers[header] = value
    return resp_headers, object_body
示例#20
0
 def __init__(self, stype, method, node, part, path, resp):
     full_path = quote('/%s/%s%s' % (node['device'], part, path))
     msg = '%s server %s:%s direct %s %r gave status %s' % (
         stype, node['ip'], node['port'], method, full_path, resp.status)
     headers = HeaderKeyDict(resp.getheaders())
     super(DirectClientException, self).__init__(
         msg, http_host=node['ip'], http_port=node['port'],
         http_device=node['device'], http_status=resp.status,
         http_reason=resp.reason, http_headers=headers)
    def test_get_response_headers_with_legacy_data(self):
        broker = backend.AccountBroker(':memory:', account='a')
        now = time.time()
        with mock.patch('time.time', new=lambda: now):
            broker.initialize(Timestamp(now).internal)
        # add some container data
        ts = (Timestamp(t).internal for t in itertools.count(int(now)))
        total_containers = 0
        total_objects = 0
        total_bytes = 0
        for policy in POLICIES:
            delete_timestamp = next(ts)
            put_timestamp = next(ts)
            object_count = int(policy)
            bytes_used = int(policy) * 10
            broker.put_container('c-%s' % policy.name, put_timestamp,
                                 delete_timestamp, object_count, bytes_used,
                                 int(policy))
            total_containers += 1
            total_objects += object_count
            total_bytes += bytes_used
        expected = HeaderKeyDict({
            'X-Account-Container-Count': total_containers,
            'X-Account-Object-Count': total_objects,
            'X-Account-Bytes-Used': total_bytes,
            'X-Timestamp': Timestamp(now).normal,
            'X-PUT-Timestamp': Timestamp(now).normal,
        })
        for policy in POLICIES:
            prefix = 'X-Account-Storage-Policy-%s-' % policy.name
            expected[prefix + 'Object-Count'] = int(policy)
            expected[prefix + 'Bytes-Used'] = int(policy) * 10
        orig_policy_stats = broker.get_policy_stats

        def stub_policy_stats(*args, **kwargs):
            policy_stats = orig_policy_stats(*args, **kwargs)
            for stats in policy_stats.values():
                # legacy db's won't return container_count
                del stats['container_count']
            return policy_stats

        broker.get_policy_stats = stub_policy_stats
        resp_headers = utils.get_response_headers(broker)
        per_policy_container_headers = [
            h for h in resp_headers
            if h.lower().startswith('x-account-storage-policy-')
            and h.lower().endswith('-container-count')
        ]
        self.assertFalse(per_policy_container_headers)
        for key, value in resp_headers.items():
            expected_value = expected.pop(key)
            self.assertEqual(
                expected_value, str(value),
                'value for %r was %r not %r' % (key, value, expected_value))
        self.assertFalse(expected)
示例#22
0
 def __init__(self, status, headers=None, body='', **kwargs):
     self.status = status
     try:
         self.reason = RESPONSE_REASONS[self.status][0]
     except Exception:
         self.reason = 'Fake'
     self.body = body
     self.resp_headers = HeaderKeyDict()
     if headers:
         self.resp_headers.update(headers)
     self.etag = None
示例#23
0
    def test_direct_get_container(self):
        headers = HeaderKeyDict({'key': 'value'})
        body = '[{"hash": "8f4e3", "last_modified": "317260", "bytes": 209}]'

        with mocked_http_conn(200, headers, body) as conn:
            resp_headers, resp = direct_client.direct_get_container(
                self.node, self.part, self.account, self.container)

        self.assertEqual(conn.req_headers['user-agent'],
                         'direct-client %s' % os.getpid())
        self.assertEqual(headers, resp_headers)
        self.assertEqual(json.loads(body), resp)
示例#24
0
    def test_direct_put_object_header_content_length(self):
        contents = six.StringIO('123456')
        stub_headers = HeaderKeyDict({
            'Content-Length': '6'})

        with mocked_http_conn(200) as conn:
            resp = direct_client.direct_put_object(
                self.node, self.part, self.account, self.container, self.obj,
                contents, headers=stub_headers)
            self.assertEqual('PUT', conn.method)
            self.assertEqual(conn.req_headers['Content-length'], '6')
        self.assertEqual(md5('123456').hexdigest(), resp)
示例#25
0
    def test_retry(self):
        headers = HeaderKeyDict({'key': 'value'})

        with mocked_http_conn(200, headers) as conn:
            attempts, resp = direct_client.retry(
                direct_client.direct_head_object, self.node, self.part,
                self.account, self.container, self.obj)
            self.assertEqual(conn.method, 'HEAD')
            self.assertEqual(conn.path, self.obj_path)
        self.assertEqual(conn.req_headers['user-agent'], self.user_agent)
        self.assertEqual(headers, resp)
        self.assertEqual(attempts, 1)
示例#26
0
    def test_direct_head_container(self):
        headers = HeaderKeyDict(key='value')

        with mocked_http_conn(200, headers) as conn:
            resp = direct_client.direct_head_container(self.node, self.part,
                                                       self.account,
                                                       self.container)
            self.assertEqual(conn.method, 'HEAD')
            self.assertEqual(conn.path, self.container_path)

        self.assertEqual(conn.req_headers['user-agent'], self.user_agent)
        self.assertEqual(headers, resp)
示例#27
0
 def generate_request_headers(self,
                              orig_req=None,
                              additional=None,
                              transfer=False):
     # Use the additional headers first so they don't overwrite the headers
     # we require.
     headers = HeaderKeyDict(additional) if additional else HeaderKeyDict()
     if transfer:
         self.transfer_headers(orig_req.headers, headers)
     if 'x-timestamp' not in headers:
         headers['x-timestamp'] = normalize_timestamp(time.time())
     if orig_req:
         referer = orig_req.as_referer()
     else:
         referer = ''
     headers.update({
         'x-trans-id': self.trans_id,
         'connection': 'close',
         'user-agent': 'proxy-server %s' % os.getpid(),
         'referer': referer
     })
     return headers
示例#28
0
文件: server.py 项目: zhanghua/swift
    def delete_at_update(self, op, delete_at, account, container, obj, request,
                         objdevice):
        """
        Update the expiring objects container when objects are updated.

        :param op: operation performed (ex: 'PUT', or 'DELETE')
        :param account: account name for the object
        :param container: container name for the object
        :param obj: object name
        :param request: the original request driving the update
        :param objdevice: device name that the object is in
        """
        # Quick cap that will work from now until Sat Nov 20 17:46:39 2286
        # At that time, Swift will be so popular and pervasive I will have
        # created income for thousands of future programmers.
        delete_at = max(min(delete_at, 9999999999), 0)
        updates = [(None, None)]

        partition = None
        hosts = contdevices = [None]
        headers_in = request.headers
        headers_out = HeaderKeyDict({
            'x-timestamp':
            headers_in['x-timestamp'],
            'x-trans-id':
            headers_in.get('x-trans-id', '-'),
            'referer':
            request.as_referer()
        })
        if op != 'DELETE':
            partition = headers_in.get('X-Delete-At-Partition', None)
            hosts = headers_in.get('X-Delete-At-Host', '')
            contdevices = headers_in.get('X-Delete-At-Device', '')
            updates = [
                upd for upd in zip((h.strip() for h in hosts.split(',')), (
                    c.strip() for c in contdevices.split(',')))
                if all(upd) and partition
            ]
            if not updates:
                updates = [(None, None)]
            headers_out['x-size'] = '0'
            headers_out['x-content-type'] = 'text/plain'
            headers_out['x-etag'] = 'd41d8cd98f00b204e9800998ecf8427e'

        for host, contdevice in updates:
            self.async_update(
                op, self.expiring_objects_account,
                str(delete_at / self.expiring_objects_container_divisor *
                    self.expiring_objects_container_divisor),
                '%s-%s/%s/%s' % (delete_at, account, container, obj), host,
                partition, contdevice, headers_out, objdevice)
示例#29
0
    def test_206_single_range(self):
        fr = FakeResponse(
            206, {
                'Content-Length': '8',
                'Content-Type': 'application/lunch',
                'Content-Range': 'bytes 1-8/10'
            }, b'andwiche')

        doc_iters = rh.http_response_to_document_iters(fr)
        first_byte, last_byte, length, headers, body = next(doc_iters)
        self.assertEqual(first_byte, 1)
        self.assertEqual(last_byte, 8)
        self.assertEqual(length, 10)
        header_dict = HeaderKeyDict(headers)
        self.assertEqual(header_dict.get('Content-Length'), '8')
        self.assertEqual(header_dict.get('Content-Type'), 'application/lunch')
        self.assertEqual(body.read(), b'andwiche')

        self.assertRaises(StopIteration, next, doc_iters)

        # Chunked response should be treated in the same way as non-chunked one
        fr = FakeResponse(
            206, {
                'Transfer-Encoding': 'chunked',
                'Content-Type': 'application/lunch',
                'Content-Range': 'bytes 1-8/10'
            }, b'andwiche')

        doc_iters = rh.http_response_to_document_iters(fr)
        first_byte, last_byte, length, headers, body = next(doc_iters)
        self.assertEqual(first_byte, 1)
        self.assertEqual(last_byte, 8)
        self.assertEqual(length, 10)
        header_dict = HeaderKeyDict(headers)
        self.assertEqual(header_dict.get('Content-Type'), 'application/lunch')
        self.assertEqual(body.read(), b'andwiche')

        self.assertRaises(StopIteration, next, doc_iters)
示例#30
0
    def test_fake_swift_sysmeta(self):
        swift = FakeSwift()
        orig_headers = HeaderKeyDict()
        orig_headers.update({sysmeta_header('container', 'acl'): 'test',
                             'x-container-meta-foo': 'bar'})

        swift.register(self.method, self.path, MagicMock(), orig_headers, None)

        self._check_headers(swift, self.method, self.path, orig_headers)

        new_headers = orig_headers.copy()
        del new_headers[sysmeta_header('container', 'acl').title()]
        swift.register(self.method, self.path, MagicMock(), new_headers, None)

        self._check_headers(swift, self.method, self.path, orig_headers)