Example #1
0
 def GETorHEAD(self, req):
     """Handler for HTTP GET/HEAD requests."""
     partition, nodes = self.app.account_ring.get_nodes(self.account_name)
     nodes = self.app.sort_nodes(nodes)
     resp = self.GETorHEAD_base(
         req, _('Account'), partition, nodes, req.path_info.rstrip('/'),
         len(nodes))
     if resp.status_int == HTTP_NOT_FOUND and self.app.account_autocreate:
         if len(self.account_name) > MAX_ACCOUNT_NAME_LENGTH:
             resp = HTTPBadRequest(request=req)
             resp.body = 'Account name length of %d longer than %d' % \
                         (len(self.account_name), MAX_ACCOUNT_NAME_LENGTH)
             return resp
         headers = {'X-Timestamp': normalize_timestamp(time.time()),
                    'X-Trans-Id': self.trans_id,
                    'Connection': 'close'}
         resp = self.make_requests(
             Request.blank('/v1/' + self.account_name),
             self.app.account_ring, partition, 'PUT',
             '/' + self.account_name, [headers] * len(nodes))
         if not is_success(resp.status_int):
             self.app.logger.warning('Could not autocreate account %r' %
                                     self.account_name)
             return resp
         resp = self.GETorHEAD_base(
             req, _('Account'), partition, nodes, req.path_info.rstrip('/'),
             len(nodes))
     return resp
Example #2
0
 def POST(self, req):
     """HTTP POST request handler."""
     error_response = check_metadata(req, 'account')
     if error_response:
         return error_response
     account_partition, accounts = \
         self.app.account_ring.get_nodes(self.account_name)
     headers = {'X-Timestamp': normalize_timestamp(time.time()),
                'X-Trans-Id': self.trans_id,
                'Connection': 'close'}
     self.transfer_headers(req.headers, headers)
     if self.app.memcache:
         self.app.memcache.delete(
             get_account_memcache_key(self.account_name))
     resp = self.make_requests(
         req, self.app.account_ring, account_partition, 'POST',
         req.path_info, [headers] * len(accounts))
     if resp.status_int == HTTP_NOT_FOUND and self.app.account_autocreate:
         if len(self.account_name) > MAX_ACCOUNT_NAME_LENGTH:
             resp = HTTPBadRequest(request=req)
             resp.body = 'Account name length of %d longer than %d' % \
                         (len(self.account_name), MAX_ACCOUNT_NAME_LENGTH)
             return resp
         resp = self.make_requests(
             Request.blank('/v1/' + self.account_name),
             self.app.account_ring, account_partition, 'PUT',
             '/' + self.account_name, [headers] * len(accounts))
         if not is_success(resp.status_int):
             self.app.logger.warning('Could not autocreate account %r' %
                                     self.account_name)
             return resp
     return resp
Example #3
0
def make_pre_authed_request(env,
                            method=None,
                            path=None,
                            body=None,
                            headers=None,
                            agent='Gate',
                            gate_source=None):
    """
    Makes a new swob.Request based on the current env but with the
    parameters specified. Note that this request will be preauthorized.

    :param env: The WSGI environment to base the new request on.
    :param method: HTTP method of new request; default is from
                   the original env.
    :param path: HTTP path of new request; default is from the
                 original env. path should be compatible with what you
                 would send to Request.blank. path should be quoted and it
                 can include a query string. for example:
                 '/a%20space?unicode_str%E8%AA%9E=y%20es'
    :param body: HTTP body of new request; empty by default.
    :param headers: Extra HTTP headers of new request; None by
                    default.
    :param agent: The HTTP user agent to use; default 'Gate'. You
                  can put %(orig)s in the agent to have it replaced
                  with the original env's HTTP_USER_AGENT, such as
                  '%(orig)s StaticWeb'. You also set agent to None to
                  use the original env's HTTP_USER_AGENT or '' to
                  have no HTTP_USER_AGENT.
    :param gate_source: Used to mark the request as originating out of
                         middleware. Will be logged in proxy logs.
    :returns: Fresh swob.Request object.
    """
    query_string = None
    if path and '?' in path:
        path, query_string = path.split('?', 1)
    newenv = make_pre_authed_env(env,
                                 method,
                                 path=unquote(path),
                                 agent=agent,
                                 query_string=query_string,
                                 gate_source=gate_source)
    if not headers:
        headers = {}
    if body:
        return Request.blank(path, environ=newenv, body=body, headers=headers)
    else:
        return Request.blank(path, environ=newenv, headers=headers)
Example #4
0
File: wsgi.py Project: vindeka/gate
def make_pre_authed_request(env, method=None, path=None, body=None,
                            headers=None, agent='Gate', gate_source=None):
    """
    Makes a new swob.Request based on the current env but with the
    parameters specified. Note that this request will be preauthorized.

    :param env: The WSGI environment to base the new request on.
    :param method: HTTP method of new request; default is from
                   the original env.
    :param path: HTTP path of new request; default is from the
                 original env. path should be compatible with what you
                 would send to Request.blank. path should be quoted and it
                 can include a query string. for example:
                 '/a%20space?unicode_str%E8%AA%9E=y%20es'
    :param body: HTTP body of new request; empty by default.
    :param headers: Extra HTTP headers of new request; None by
                    default.
    :param agent: The HTTP user agent to use; default 'Gate'. You
                  can put %(orig)s in the agent to have it replaced
                  with the original env's HTTP_USER_AGENT, such as
                  '%(orig)s StaticWeb'. You also set agent to None to
                  use the original env's HTTP_USER_AGENT or '' to
                  have no HTTP_USER_AGENT.
    :param gate_source: Used to mark the request as originating out of
                         middleware. Will be logged in proxy logs.
    :returns: Fresh swob.Request object.
    """
    query_string = None
    if path and '?' in path:
        path, query_string = path.split('?', 1)
    newenv = make_pre_authed_env(env, method, path=unquote(path), agent=agent,
                                 query_string=query_string,
                                 gate_source=gate_source)
    if not headers:
        headers = {}
    if body:
        return Request.blank(path, environ=newenv, body=body, headers=headers)
    else:
        return Request.blank(path, environ=newenv, headers=headers)
Example #5
0
    def __call__(self, env, start_response):
        """
        WSGI entry point.
        Wraps env in swob.Request object and passes it down.

        :param env: WSGI environment dictionary
        :param start_response: WSGI callable
        """
        try:
            req = Request(env)
            return self.handle_request(req)(env, start_response)
        except UnicodeError:
            err = HTTPPreconditionFailed(request=req,
                                         body='Invalid UTF8 or contains NULL')
            return err(env, start_response)
        except (Exception, Timeout):
            start_response('500 Server Error',
                           [('Content-Type', 'text/plain')])
            return ['Internal server error.\n']
Example #6
0
File: base.py Project: vindeka/gate
    def case_info(self, case, autocreate=False):
        """
        Get case information, and also verify that the account exists.

        :param case: name of the case to get the info for
        :returns: tuple of (case id, evidence_count)
                  or (None, None) if it does not exist
        """
        partition, nodes = self.app.account_ring.get_nodes(account)
        account_info = {'status': 0,
                        'container_count': 0,
                        'total_object_count': None,
                        'bytes': None,
                        'meta': {}}
        # 0 = no responses, 200 = found, 404 = not found, -1 = mixed responses
        if self.app.memcache:
            cache_key = get_account_memcache_key(account)
            cache_value = self.app.memcache.get(cache_key)
            if not isinstance(cache_value, dict):
                result_code = cache_value
                container_count = 0
            else:
                result_code = cache_value['status']
                try:
                    container_count = int(cache_value['container_count'])
                except ValueError:
                    container_count = 0
            if result_code == HTTP_OK:
                return partition, nodes, container_count
            elif result_code == HTTP_NOT_FOUND and not autocreate:
                return None, None, None
        result_code = 0
        attempts_left = len(nodes)
        path = '/%s' % account
        headers = {'x-trans-id': self.trans_id, 'Connection': 'close'}
        iternodes = self.iter_nodes(partition, nodes, self.app.account_ring)
        while attempts_left > 0:
            try:
                node = iternodes.next()
            except StopIteration:
                break
            attempts_left -= 1
            try:
                start_node_timing = time.time()
                with ConnectionTimeout(self.app.conn_timeout):
                    conn = http_connect(node['ip'], node['port'],
                                        node['device'], partition, 'HEAD',
                                        path, headers)
                self.app.set_node_timing(node, time.time() - start_node_timing)
                with Timeout(self.app.node_timeout):
                    resp = conn.getresponse()
                    resp.read()
                    if is_success(resp.status):
                        result_code = HTTP_OK
                        account_info.update(
                            headers_to_account_info(resp.getheaders()))
                        break
                    elif resp.status == HTTP_NOT_FOUND:
                        if result_code == 0:
                            result_code = HTTP_NOT_FOUND
                        elif result_code != HTTP_NOT_FOUND:
                            result_code = -1
                    elif resp.status == HTTP_INSUFFICIENT_STORAGE:
                        self.error_limit(node)
                        continue
                    else:
                        result_code = -1
            except (Exception, Timeout):
                self.exception_occurred(node, _('Account'),
                                        _('Trying to get account info for %s')
                                        % path)
        if result_code == HTTP_NOT_FOUND and autocreate:
            if len(account) > MAX_ACCOUNT_NAME_LENGTH:
                return None, None, None
            headers = {'X-Timestamp': normalize_timestamp(time.time()),
                       'X-Trans-Id': self.trans_id,
                       'Connection': 'close'}
            resp = self.make_requests(Request.blank('/v1' + path),
                                      self.app.account_ring, partition, 'PUT',
                                      path, [headers] * len(nodes))
            if not is_success(resp.status_int):
                self.app.logger.warning('Could not autocreate account %r' %
                                        path)
                return None, None, None
            result_code = HTTP_OK
        if self.app.memcache and result_code in (HTTP_OK, HTTP_NOT_FOUND):
            if result_code == HTTP_OK:
                cache_timeout = self.app.recheck_account_existence
            else:
                cache_timeout = self.app.recheck_account_existence * 0.1
            account_info.update(status=result_code)
            self.app.memcache.set(cache_key,
                                  account_info,
                                  time=cache_timeout)
        if result_code == HTTP_OK:
            try:
                container_count = int(account_info['container_count'])
            except ValueError:
                container_count = 0
            return partition, nodes, container_count
        return None, None, None