コード例 #1
0
 def __call__(self, env, start_response):
     req = Request(env)
     if env['REQUEST_METHOD'] == 'GET' or env['REQUEST_METHOD'] == 'HEAD':
         if self.status == 200:
             if 'HTTP_RANGE' in env:
                 resp = Response(request=req, body=self.object_body,
                                 conditional_response=True)
                 return resp(env, start_response)
             start_response(Response(request=req).status,
                            self.response_headers.items())
             if env['REQUEST_METHOD'] == 'GET':
                 return self.object_body
         elif self.status == 401:
             start_response(HTTPUnauthorized(request=req).status, [])
         elif self.status == 403:
             start_response(HTTPForbidden(request=req).status, [])
         elif self.status == 404:
             start_response(HTTPNotFound(request=req).status, [])
         else:
             start_response(HTTPBadRequest(request=req).status, [])
     elif env['REQUEST_METHOD'] == 'PUT':
         if self.status == 201:
             start_response(HTTPCreated(request=req).status,
                            [('etag', self.response_headers['etag'])])
         elif self.status == 401:
             start_response(HTTPUnauthorized(request=req).status, [])
         elif self.status == 403:
             start_response(HTTPForbidden(request=req).status, [])
         elif self.status == 404:
             start_response(HTTPNotFound(request=req).status, [])
         elif self.status == 413:
             start_response(HTTPRequestEntityTooLarge(request=req).status,
                            [])
         else:
             start_response(HTTPBadRequest(request=req).status, [])
     elif env['REQUEST_METHOD'] == 'DELETE':
         if self.status == 204:
             start_response(HTTPNoContent(request=req).status, [])
         elif self.status == 401:
             start_response(HTTPUnauthorized(request=req).status, [])
         elif self.status == 403:
             start_response(HTTPForbidden(request=req).status, [])
         elif self.status == 404:
             start_response(HTTPNotFound(request=req).status, [])
         else:
             start_response(HTTPBadRequest(request=req).status, [])
     return []
コード例 #2
0
 def __call__(self, env, start_response):
     print "account server __call__"
     start_time = time.time()
     req = Request(env)
     self.logger.txn_id = req.headers.get('x-trans-id', None)
     if not check_utf8(req.path_info):
         res = HTTPPreconditionFailed(body='Invalid UTF8 or contains NULL')
     else:
         try:
             # disallow methods which are not publicly accessible
             try:
                 method = getattr(self, req.method)
                 getattr(method, 'publicly_accessible')
                 replication_method = getattr(method, 'replication', False)
                 if (self.replication_server is not None
                         and self.replication_server != replication_method):
                     raise AttributeError('Not allowed method.')
             except AttributeError:
                 res = HTTPMethodNotAllowed()
             else:
                 res = method(req)
         except HTTPException as error_response:
             res = error_response
         except (Exception, Timeout):
             self.logger.exception(
                 _('ERROR __call__ error with %(method)s'
                   ' %(path)s '), {
                       'method': req.method,
                       'path': req.path
                   })
             res = HTTPInternalServerError(body=traceback.format_exc())
     trans_time = '%.4f' % (time.time() - start_time)
     additional_info = ''
     if res.headers.get('x-container-timestamp') is not None:
         additional_info += 'x-container-timestamp: %s' % \
             res.headers['x-container-timestamp']
     log_message = '%s - - [%s] "%s %s" %s %s "%s" "%s" "%s" %s "%s"' % (
         req.remote_addr,
         time.strftime('%d/%b/%Y:%H:%M:%S +0000', time.gmtime()),
         req.method, req.path, res.status.split()[0], res.content_length
         or '-', req.headers.get('x-trans-id', '-'), req.referer
         or '-', req.user_agent or '-', trans_time, additional_info)
     if req.method.upper() == 'REPLICATE':
         self.logger.debug(log_message)
     else:
         self.logger.info(log_message)
     return res(env, start_response)
コード例 #3
0
ファイル: server.py プロジェクト: zhengjiaai2008/swift
    def __call__(self, env, start_response):
        """WSGI Application entry point for the Swift Object Server."""
        start_time = time.time()
        req = Request(env)
        self.logger.txn_id = req.headers.get('x-trans-id', None)

        if not check_utf8(req.path_info):
            res = HTTPPreconditionFailed(body='Invalid UTF8 or contains NULL')
        else:
            try:
                # disallow methods which have not been marked 'public'
                try:
                    method = getattr(self, req.method)
                    getattr(method, 'publicly_accessible')
                    replication_method = getattr(method, 'replication', False)
                    if (self.replication_server is not None
                            and self.replication_server != replication_method):
                        raise AttributeError('Not allowed method.')
                except AttributeError:
                    res = HTTPMethodNotAllowed()
                else:
                    res = method(req)
            except DiskFileCollision:
                res = HTTPForbidden(request=req)
            except HTTPException as error_response:
                res = error_response
            except (Exception, Timeout):
                self.logger.exception(
                    _('ERROR __call__ error with %(method)s'
                      ' %(path)s '), {
                          'method': req.method,
                          'path': req.path
                      })
                res = HTTPInternalServerError(body=traceback.format_exc())
        trans_time = time.time() - start_time
        if self.log_requests:
            log_line = get_log_line(req, res, trans_time, '')
            if req.method in ('REPLICATE', 'REPLICATION') or \
                    'X-Backend-Replication' in req.headers:
                self.logger.debug(log_line)
            else:
                self.logger.info(log_line)
        if req.method in ('PUT', 'DELETE'):
            slow = self.slow - trans_time
            if slow > 0:
                sleep(slow)
        return res(env, start_response)
コード例 #4
0
ファイル: server.py プロジェクト: zhanghua/swift
    def __call__(self, env, start_response):
        """WSGI Application entry point for the Swift Object Server."""
        start_time = time.time()
        req = Request(env)
        self.logger.txn_id = req.headers.get('x-trans-id', None)

        if not check_utf8(req.path_info):
            res = HTTPPreconditionFailed(body='Invalid UTF8 or contains NULL')
        else:
            try:
                # disallow methods which have not been marked 'public'
                try:
                    method = getattr(self, req.method)
                    getattr(method, 'publicly_accessible')
                    if req.method not in self.allowed_methods:
                        raise AttributeError('Not allowed method.')
                except AttributeError:
                    res = HTTPMethodNotAllowed()
                else:
                    res = method(req)
            except DiskFileCollision:
                res = HTTPForbidden(request=req)
            except (Exception, Timeout):
                self.logger.exception(
                    _('ERROR __call__ error with %(method)s'
                      ' %(path)s '), {
                          'method': req.method,
                          'path': req.path
                      })
                res = HTTPInternalServerError(body=traceback.format_exc())
        trans_time = time.time() - start_time
        if self.log_requests:
            log_line = '%s - - [%s] "%s %s" %s %s "%s" "%s" "%s" %.4f' % (
                req.remote_addr,
                time.strftime('%d/%b/%Y:%H:%M:%S +0000', time.gmtime()),
                req.method, req.path, res.status.split()[0], res.content_length
                or '-', req.referer or '-', req.headers.get(
                    'x-trans-id', '-'), req.user_agent or '-', trans_time)
            if req.method == 'REPLICATE':
                self.logger.debug(log_line)
            else:
                self.logger.info(log_line)
        if req.method in ('PUT', 'DELETE'):
            slow = self.slow - trans_time
            if slow > 0:
                sleep(slow)
        return res(env, start_response)
コード例 #5
0
 def __call__(self, env, start_response):
     if not self.storage_domain:
         return self.app(env, start_response)
     if 'HTTP_HOST' in env:
         given_domain = env['HTTP_HOST']
     else:
         given_domain = env['SERVER_NAME']
     port = ''
     if ':' in given_domain:
         given_domain, port = given_domain.rsplit(':', 1)
     if given_domain.endswith(self.storage_domain):
         parts_to_parse = given_domain[:-len(self.storage_domain)]
         parts_to_parse = parts_to_parse.strip('.').split('.')
         len_parts_to_parse = len(parts_to_parse)
         if len_parts_to_parse == 2:
             container, account = parts_to_parse
         elif len_parts_to_parse == 1:
             container, account = None, parts_to_parse[0]
         else:
             resp = HTTPBadRequest(request=Request(env),
                                   body='Bad domain in host header',
                                   content_type='text/plain')
             return resp(env, start_response)
         if '_' not in account and '-' in account:
             account = account.replace('-', '_', 1)
         account_reseller_prefix = account.split('_', 1)[0].lower()
         if account_reseller_prefix not in self.reseller_prefixes_lower:
             # account prefix is not in config list. bail.
             return self.app(env, start_response)
         prefix_index = self.reseller_prefixes_lower.index(
             account_reseller_prefix)
         real_prefix = self.reseller_prefixes[prefix_index]
         if not account.startswith(real_prefix):
             account_suffix = account[len(real_prefix):]
             account = real_prefix + account_suffix
         path = env['PATH_INFO'].strip('/')
         new_path_parts = ['', self.path_root, account]
         if container:
             new_path_parts.append(container)
         if path.startswith(self.path_root):
             path = path[len(self.path_root):].lstrip('/')
         if path:
             new_path_parts.append(path)
         new_path = '/'.join(new_path_parts)
         env['PATH_INFO'] = new_path
     return self.app(env, start_response)
コード例 #6
0
ファイル: gatekeeper.py プロジェクト: yichuan0707/swift
    def __call__(self, env, start_response):
        req = Request(env)
        removed = remove_items(req.headers, self.inbound_condition)
        if removed:
            self.logger.debug('removed request headers: %s' % removed)

        if 'X-Timestamp' in req.headers and self.shunt_x_timestamp:
            ts = req.headers.pop('X-Timestamp')
            req.headers['X-Backend-Inbound-X-Timestamp'] = ts
            # log in a similar format as the removed headers
            self.logger.debug('shunted request headers: %s' %
                              [('X-Timestamp', ts)])

        def gatekeeper_response(status, response_headers, exc_info=None):
            def fixed_response_headers():
                def relative_path(value):
                    parsed = urlsplit(value)
                    new_path = parsed.path
                    if parsed.query:
                        new_path += ('?%s' % parsed.query)
                    if parsed.fragment:
                        new_path += ('#%s' % parsed.fragment)
                    return new_path

                if not env.get('swift.leave_relative_location'):
                    return response_headers
                else:
                    return [
                        (k, v) if k.lower() != 'location' else
                        (k, relative_path(v)) for (k, v) in response_headers
                    ]

            response_headers = fixed_response_headers()
            removed = filter(
                lambda h: self.outbound_condition(h[0]),
                response_headers)

            if removed:
                self.logger.debug('removed response headers: %s' % removed)
                new_headers = filter(
                    lambda h: not self.outbound_condition(h[0]),
                    response_headers)
                return start_response(status, new_headers, exc_info)
            return start_response(status, response_headers, exc_info)
        return self.app(env, gatekeeper_response)
コード例 #7
0
    def __call__(self, env, start_response):
        req = Request(env)
        removed = remove_items(req.headers, self.inbound_condition)
        if removed:
            self.logger.debug('removed request headers: %s' % removed)

        def gatekeeper_response(status, response_headers, exc_info=None):
            removed = filter(
                lambda h: self.outbound_condition(h[0]),
                response_headers)
            if removed:
                self.logger.debug('removed response headers: %s' % removed)
                new_headers = filter(
                    lambda h: not self.outbound_condition(h[0]),
                    response_headers)
                return start_response(status, new_headers, exc_info)
            return start_response(status, response_headers, exc_info)
        return self.app(env, gatekeeper_response)
コード例 #8
0
ファイル: keymaster.py プロジェクト: jsw2065/swift
    def __call__(self, env, start_response):
        req = Request(env)

        try:
            parts = req.split_path(2, 4, True)
        except ValueError:
            return self.app(env, start_response)

        if req.method in ('PUT', 'POST', 'GET', 'HEAD'):
            # handle only those request methods that may require keys
            km_context = KeyMasterContext(self, *parts[1:])
            try:
                return km_context.handle_request(req, start_response)
            except HTTPException as err_resp:
                return err_resp(env, start_response)

        # anything else
        return self.app(env, start_response)
コード例 #9
0
    def __call__(self, env, start_response):
        req = Request(env)

        try:
            parts = req.split_path(2, 4, True)
        except ValueError:
            return self.app(env, start_response)

        if hasattr(KeyMasterContext, req.method):
            # handle only those request methods that may require keys
            km_context = KeyMasterContext(self, *parts[1:])
            try:
                return getattr(km_context, req.method)(req, start_response)
            except HTTPException as err_resp:
                return err_resp(env, start_response)

        # anything else
        return self.app(env, start_response)
コード例 #10
0
        def iter_response(iterable):
            iterator = iter(iterable)
            try:
                chunk = iterator.next()
                while not chunk:
                    chunk = iterator.next()
            except StopIteration:
                chunk = ''
            for h, v in start_response_args[0][1]:
                if h.lower() in ('content-length', 'transfer-encoding'):
                    break
            else:
                if not chunk:
                    start_response_args[0][1].append(('content-length', '0'))
                elif isinstance(iterable, list):
                    start_response_args[0][1].append(
                        ('content-length', str(sum(len(i) for i in iterable))))
            start_response(*start_response_args[0])
            req = Request(env)

            # Log timing information for time-to-first-byte (GET requests only)
            method = self.method_from_req(req)
            if method == 'GET' and not self.req_already_logged(req):
                status_int = status_int_for_logging()
                metric_name = self.statsd_metric_name(req, status_int, method)
                if metric_name:
                    self.access_logger.timing_since(
                        metric_name + '.first-byte.timing', start_time)

            bytes_sent = 0
            client_disconnect = False
            try:
                while chunk:
                    bytes_sent += len(chunk)
                    yield chunk
                    chunk = iterator.next()
            except GeneratorExit:  # generator was closed before we finished
                client_disconnect = True
                raise
            finally:
                status_int = status_int_for_logging(client_disconnect)
                self.log_request(req, status_int, input_proxy.bytes_received,
                                 bytes_sent,
                                 time.time() - start_time)
コード例 #11
0
 def __call__(self, environ, start_response):
     request = Request(environ)
     path_entry = request.path_info.split('/')
     # hijack favicon request sent by browser so that it doesn't
     # invoke profiling hook and contaminate the data.
     if path_entry[1] == 'favicon.ico':
         start_response('200 OK', [])
         return ''
     elif path_entry[1] == self.path:
         try:
             self.dump_checkpoint()
             query_dict = self._combine_body_qs(request)
             content, headers = self.viewer.render(request.url,
                                                   request.method,
                                                   path_entry,
                                                   query_dict,
                                                   self.renew_profile)
             start_response('200 OK', headers)
             return [bytes_(content)]
         except MethodNotAllowed as mx:
             start_response('405 Method Not Allowed', [])
             return '%s' % mx
         except NotFoundException as nx:
             start_response('404 Not Found', [])
             return '%s' % nx
         except ProfileException as pf:
             start_response('500 Internal Server Error', [])
             return '%s' % pf
         except Exception as ex:
             start_response('500 Internal Server Error', [])
             return _('Error on render profiling results: %s') % ex
     else:
         try:
             _locals = locals()
             code = self.unwind and PROFILE_EXEC_EAGER or\
                 PROFILE_EXEC_LAZY
             self.profiler.runctx(code, globals(), _locals)
             app_iter = _locals['app_iter_']
             self.dump_checkpoint()
             return app_iter
         except:
             self.logger.exception(_('Error profiling code'))
         finally:
             pass
コード例 #12
0
    def __call__(self, env, start_response):
        if env['REQUEST_METHOD'] != 'GET':
            return self.app(env, start_response)
        req = Request(env)
        version, account, container, obj = req.split_path(1, 4, True)
        if None in [version, account, container, obj]:
            return self.app(env, start_response)
        if random.randint(1, self.max_range) > self.count_threshold:
            return self.app(env, start_response)

        return_status = [None, None]
        start_t = time.time()

        def start_response_wc(status, headers):
            return_status[0] = status
            content_len = 0
            for item in headers:
                if item[0] == "Content-Length":
                    content_len = long(item[1])
            headers.append(('objslo_start_time', start_t))
            headers.append(('objslo_end_time', time.time()))
            return_status[1] = content_len
            return start_response(status, headers)

        if env['REQUEST_METHOD'] == 'GET':
            server_ip = env['SERVER_NAME']
            server_port = str(env['SERVER_PORT'])
            device = ":".join([server_ip, server_port])
            self.redis_client.hincrby(self.incomingreqkey, device, 1 * self.sample_ratio)
            data = self.app(env, start_response_wc)
            duration = time.time() - start_t
            if self.durationswitch:
                self.redis_client.lpush("%s_duration" % (device), duration)
            if duration > self.slolatency:
                self.redis_client.hincrby(self.sloviolatecounter, device, 1 * self.sample_ratio)
            else:
                self.redis_client.hincrby(self.slomeetcounter, device, 1 * self.sample_ratio)
            content_len = return_status[1]
            self.redis_client.hincrby(self.returnreqkey, device, 1 * self.sample_ratio)
            self.redis_client.hincrby(self.returnreqsizekey, device, content_len * self.sample_ratio)
            self.redis_client.hincrby(self.returnreqlatencykey, device, int(duration*1000) * self.sample_ratio)
            self.redis_client.hincrby(self.readcountskey, device, (int(content_len/self.blocksize) + 1) * self.sample_ratio)
            return data
コード例 #13
0
ファイル: key_manager.py プロジェクト: udaykd09/swift-encrypt
    def __call__(self, env, start_response):
        """
        Get Request object from variable env, then get account name.
        Further generate or get associated key_id from key_manage_base
        and add this information in Headears of request.

        :param env: WSGI environment dictionary
        :param start_response: WSGI callable

        :return self.app: standart next WSGI app in the pipeline
        """
        req = Request(env)
        if req.method in ('PUT', 'POST'):
            _, account, container, obj = split_path(req.path, 1, 4, True)
            if account and container and obj:
                key_id = self.get_key_id(account)
                req.headers['X-Object-Meta-Key-Id'] = key_id
                env = req.environ
        return self.app(env, start_response)
コード例 #14
0
 def __call__(self, env, start_response):
     if 'swift.authorize' in env:
         aresp = env['swift.authorize'](Request(env))
         if aresp:
             return aresp(env, start_response)
     if env['REQUEST_METHOD'] == "HEAD" and \
             env['PATH_INFO'] == '/v1/a/c2/o2':
         env_key = get_object_env_key('a', 'c2', 'o2')
         env[env_key] = headers_to_object_info(self.headers, 200)
         start_response('200 OK', self.headers)
     elif env['REQUEST_METHOD'] == "HEAD" and \
             env['PATH_INFO'] == '/v1/a/c2/o3':
         start_response('404 Not Found', [])
     else:
         # Cache the account_info (same as a real application)
         cache_key, env_key = _get_cache_key('a', None)
         env[env_key] = headers_to_account_info(self.headers, 200)
         start_response('200 OK', self.headers)
     return []
コード例 #15
0
    def __call__(self, env, start_response):
        def _start_response(status, headers, exc_info=None):
            """start_response wrapper to add request status to env"""
            env['informant.status'] = int(status.split(' ', 1)[0])
            env['informant.start_response_time'] = time()
            start_response(status, headers, exc_info)

        req = Request(env)
        try:
            if 'eventlet.posthooks' in env:
                env['informant.start_time'] = time()
                env['eventlet.posthooks'].append(
                    (self.statsd_event, (req, ), {}))
            return self.app(env, _start_response)
        except Exception:
            self.logger.exception('WSGI EXCEPTION:')
            _start_response('500 Internal Server Error',
                            [('Content-Length', '0')])
            return []
コード例 #16
0
ファイル: dlo.py プロジェクト: yinyalan/swift
    def __call__(self, env, start_response):
        """
        WSGI entry point
        """
        req = Request(env)
        try:
            vrs, account, container, obj = req.split_path(4, 4, True)
        except ValueError:
            return self.app(env, start_response)

        if ((req.method == 'GET' or req.method == 'HEAD')
                and req.params.get('multipart-manifest') != 'get'):
            return GetContext(self, self.logger).\
                handle_request(req, start_response)
        elif req.method == 'PUT':
            error_response = self._validate_x_object_manifest_header(req)
            if error_response:
                return error_response(env, start_response)
        return self.app(env, start_response)
コード例 #17
0
ファイル: symlink.py プロジェクト: stephdgenius/swift
    def __call__(self, env, start_response):
        req = Request(env)
        try:
            version, acc, cont, obj = req.split_path(3, 4, True)
        except ValueError:
            return self.app(env, start_response)

        try:
            if obj:
                # object context
                context = SymlinkObjectContext(self.app, self.logger,
                                               self.symloop_max)
                return context.handle_object(req, start_response)
            else:
                # container context
                context = SymlinkContainerContext(self.app, self.logger)
                return context.handle_container(req, start_response)
        except HTTPException as err_resp:
            return err_resp(env, start_response)
コード例 #18
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 = self.update_request(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 [b'Internal server error.\n']
コード例 #19
0
    def __call__(self, env, start_response):
        req = Request(env)
        try:
            parts = req.split_path(3, 4, True)
        except ValueError:
            return self.app(env, start_response)

        if parts[3] and req.method in ('GET', 'HEAD'):
            handler = DecrypterObjContext(self, self.logger).handle
        elif parts[2] and req.method == 'GET':
            handler = DecrypterContContext(self, self.logger).handle
        else:
            # url and/or request verb is not handled by decrypter
            return self.app(env, start_response)

        try:
            return handler(req, start_response)
        except HTTPException as err_resp:
            return err_resp(env, start_response)
コード例 #20
0
ファイル: server.py プロジェクト: elligottmc/swift
 def __call__(self, env, start_response):
     start_time = time.time()
     req = Request(env)
     self.logger.txn_id = req.headers.get('x-trans-id', None)
     if not check_utf8(req.path_info):
         res = HTTPPreconditionFailed(body='Invalid UTF8 or contains NULL')
     else:
         try:
             # disallow methods which are not publicly accessible
             try:
                 method = getattr(self, req.method)
                 getattr(method, 'publicly_accessible')
                 replication_method = getattr(method, 'replication', False)
                 if (self.replication_server is not None
                         and self.replication_server != replication_method):
                     raise AttributeError('Not allowed method.')
             except AttributeError:
                 res = HTTPMethodNotAllowed()
             else:
                 res = method(req)
         except HTTPException as error_response:
             res = error_response
         except (Exception, Timeout):
             self.logger.exception(
                 _('ERROR __call__ error with %(method)s'
                   ' %(path)s '), {
                       'method': req.method,
                       'path': req.path
                   })
             res = HTTPInternalServerError(body=traceback.format_exc())
     if self.log_requests:
         trans_time = time.time() - start_time
         additional_info = ''
         if res.headers.get('x-container-timestamp') is not None:
             additional_info += 'x-container-timestamp: %s' % \
                 res.headers['x-container-timestamp']
         log_msg = get_log_line(req, res, trans_time, additional_info)
         if req.method.upper() == 'REPLICATE':
             self.logger.debug(log_msg)
         else:
             self.logger.info(log_msg)
     return res(env, start_response)
コード例 #21
0
    def __call__(self, env, start_response):
        """
        Accepts a standard WSGI application call.
        There are 2 types of requests that this middleware will affect.
        1. Requests to CDN 'database' that will enable, list, etc. containers
           for the CDN.
        2. Requests (GETs, HEADs) from CDN provider to publicly available
           containers.
        The types of requests can be determined by looking at the hostname of
        the incoming call.
        Wraps env in swob.Request object and passes it down.

        :param env: WSGI environment dictionary
        :param start_response: WSGI callable
        """
        env['sos.start_time'] = time()
        host = env.get('HTTP_HOST', '').split(':')[0]
        try:
            handler = None
            request_type = 'SOS_LOG'
            if host in self.origin_db_hosts:
                handler = OriginDbHandler(self.app, self.conf, self.logger)
                request_type = 'SOS_DB'
            for cdn_host_suffix in self.origin_cdn_host_suffixes:
                if host.endswith(cdn_host_suffix) and \
                        host not in self.ignore_hosts:
                    handler = CdnHandler(self.app, self.conf, self.logger)
                    request_type = 'SOS_ORIGIN'
                    break
            if env['PATH_INFO'].startswith(self.origin_prefix):
                handler = AdminHandler(self.app, self.conf, self.logger)
                request_type = 'SOS_ADMIN'
            if handler:
                req = Request(env)
                resp = handler.handle_request(env, req)
                if request_type != 'SOS_ORIGIN':
                    self._log_request(env, resp, request_type)
                return resp(env, start_response)

        except InvalidConfiguration, e:
            self.logger.exception(e)
            return HTTPInternalServerError(body=str(e))(env, start_response)
コード例 #22
0
ファイル: read_only.py プロジェクト: kaisimmons81/swift-2
    def __call__(self, env, start_response):
        req = Request(env)

        if req.method not in self.write_methods:
            return self.app(env, start_response)

        try:
            version, account, container, obj = req.split_path(1, 4, True)
        except ValueError:
            return self.app(env, start_response)

        if req.method == 'COPY' and 'Destination-Account' in req.headers:
            dest_account = req.headers.get('Destination-Account')
            account = check_account_format(req, dest_account)

        if self.account_read_only(req, account):
            msg = 'Writes are disabled for this account.'
            return HTTPMethodNotAllowed(body=msg)(env, start_response)

        return self.app(env, start_response)
コード例 #23
0
ファイル: staticweb.py プロジェクト: metaphor10/swift-2
    def handle_container(self, env, start_response):
        """
        Handles a possible static web request for a container.

        :param env: The original WSGI environment dict.
        :param start_response: The original WSGI start_response hook.
        """
        container_info = self._get_container_info(env)
        req = Request(env)
        req.acl = container_info['read_acl']
        # we checked earlier that swift.authorize is set in env
        aresp = env['swift.authorize'](req)
        if aresp:
            resp = aresp(env, self._start_response)
            return self._error_response(resp, env, start_response)

        if not self._listings and not self._index:
            if config_true_value(env.get('HTTP_X_WEB_MODE', 'f')):
                return HTTPNotFound()(env, start_response)
            return self.app(env, start_response)
        if not env['PATH_INFO'].endswith('/'):
            resp = HTTPMovedPermanently(
                location=(env['PATH_INFO'] + '/'))
            return resp(env, start_response)
        if not self._index:
            return self._listing(env, start_response)
        tmp_env = dict(env)
        tmp_env['HTTP_USER_AGENT'] = \
            '%s StaticWeb' % env.get('HTTP_USER_AGENT')
        tmp_env['swift.source'] = 'SW'
        tmp_env['PATH_INFO'] += self._index
        resp = self._app_call(tmp_env)
        status_int = self._get_status_int()
        if status_int == HTTP_NOT_FOUND:
            return self._listing(env, start_response)
        elif not is_success(self._get_status_int()) and \
                not is_redirection(self._get_status_int()):
            return self._error_response(resp, env, start_response)
        start_response(self._response_status, self._response_headers,
                       self._response_exc_info)
        return resp
コード例 #24
0
    def __call__(self, env, start_response):
        # making a duplicate, because if this is a COPY request, we will
        # modify the PATH_INFO to find out if the 'Destination' is in a
        # versioned container
        req = Request(env.copy())
        try:
            (version, account, container, obj) = req.split_path(3, 4, True)
        except ValueError:
            return self.app(env, start_response)

        # In case allow_versioned_writes is set in the filter configuration,
        # the middleware becomes the authority on whether object
        # versioning is enabled or not. In case it is not set, then
        # the option in the container configuration is still checked
        # for backwards compatibility

        # For a container request, first just check if option is set,
        # can be either true or false.
        # If set, check if enabled when actually trying to set container
        # header. If not set, let request be handled by container server
        # for backwards compatibility.
        # For an object request, also check if option is set (either T or F).
        # If set, check if enabled when checking versions container in
        # sysmeta property. If it is not set check 'versions' property in
        # container_info
        allow_versioned_writes = self.conf.get('allow_versioned_writes')
        if allow_versioned_writes and container and not obj:
            try:
                return self.container_request(req, start_response,
                                              allow_versioned_writes)
            except HTTPException as error_response:
                return error_response(env, start_response)
        elif obj and req.method in ('PUT', 'COPY', 'DELETE'):
            try:
                return self.object_request(req, version, account, container,
                                           obj, allow_versioned_writes)(
                                               env, start_response)
            except HTTPException as error_response:
                return error_response(env, start_response)
        else:
            return self.app(env, start_response)
コード例 #25
0
 def __call__(self, env, start_response):
     req = Request(env)
     new_service = env.get('liteauth.new_service', None)
     if new_service:
         account_id = env.get('REMOTE_USER', '')
         if not account_id:
             return HTTPInternalServerError()
         if not self.activate_service(account_id, new_service, req.environ):
             return HTTPInternalServerError()
     if req.method in ['PUT', 'POST'
                       ] and not 'x-zerovm-execute' in req.headers:
         account_info = get_account_info(req.environ,
                                         self.app,
                                         swift_source='litequota')
         service_plan = assemble_from_partial(self.metadata_key,
                                              account_info['meta'])
         if service_plan:
             try:
                 service_plan = json.loads(service_plan)
                 path_parts = req.split_path(2, 4, rest_with_last=True)
             except ValueError:
                 return self.app(env, start_response)
             if len(path_parts) == 3:
                 quota = service_plan['storage']['containers']
                 new_size = int(account_info['container_count'])
                 if 0 <= quota < new_size:
                     return HTTPRequestEntityTooLarge(
                         body='Over quota: containers')(env, start_response)
             else:
                 new_size = int(account_info['bytes']) + (req.content_length
                                                          or 0)
                 quota = service_plan['storage']['bytes']
                 if 0 <= quota < new_size:
                     return HTTPRequestEntityTooLarge(
                         body='Over quota: bytes')(env, start_response)
                 quota = service_plan['storage']['objects']
                 new_size = int(account_info['total_object_count'])
                 if 0 <= quota < new_size:
                     return HTTPRequestEntityTooLarge(
                         body='Over quota: objects')(env, start_response)
     return self.app(env, start_response)
コード例 #26
0
    def __call__(self, env, start_response):
        request = Request(env)

        if request.method == 'PUT':
            try:
                version, account, container, obj = \
                    request.split_path(1, 4, True)
            except ValueError:
                return self.app(env, start_response)

            # check container creation request
            if account and container and not obj:
                policy_name = request.headers.get('X-Storage-Policy', '')
                default_policy = POLICIES.default.name
                if (policy_name in self.policies) or \
                   (policy_name == '' and default_policy in self.policies):

                    container = unquote(container)
                    if len(container) > constraints. \
                            SOF_MAX_CONTAINER_NAME_LENGTH:
                        resp = HTTPBadRequest(request=request)
                        resp.body = \
                            'Container name length of %d longer than %d' % \
                            (len(container),
                                constraints.SOF_MAX_CONTAINER_NAME_LENGTH)
                        return resp(env, start_response)
            elif account and container and obj:
                # check object creation request
                obj = unquote(obj)

                container_info = get_container_info(env, self.app)
                policy = POLICIES.get_by_index(
                    container_info['storage_policy'])

                if policy.name in self.policies:
                    error_response = sof_check_object_creation(request, obj)
                    if error_response:
                        self.logger.warn("returning error: %s", error_response)
                        return error_response(env, start_response)

        return self.app(env, start_response)
コード例 #27
0
    def __call__(self, env, start_response):
        req = Request(env)
        try:
            (api_version, account, container, obj) = req.split_path(3, 4, True)
        except ValueError:
            return self.app(env, start_response)

        # In case allow_versioned_writes is set in the filter configuration,
        # the middleware becomes the authority on whether object
        # versioning is enabled or not. In case it is not set, then
        # the option in the container configuration is still checked
        # for backwards compatibility

        # For a container request, first just check if option is set,
        # can be either true or false.
        # If set, check if enabled when actually trying to set container
        # header. If not set, let request be handled by container server
        # for backwards compatibility.
        # For an object request, also check if option is set (either T or F).
        # If set, check if enabled when checking versions container in
        # sysmeta property. If it is not set check 'versions' property in
        # container_info
        allow_versioned_writes = self.conf.get('allow_versioned_writes')
        if allow_versioned_writes and container and not obj:
            try:
                return self.container_request(req, start_response,
                                              allow_versioned_writes)
            except HTTPException as error_response:
                return error_response(env, start_response)
        elif (obj and (req.method in ('PUT', 'DELETE') and
                       not req.environ.get('swift.post_as_copy') or
                       req.method in ('HEAD', 'GET'))):
            try:
                return self.object_request(
                    req, api_version, account, container, obj,
                    allow_versioned_writes)(env, start_response)
            except HTTPException as error_response:
                return error_response(env, start_response)
        else:
            return self.app(env, start_response)
コード例 #28
0
ファイル: catch_errors.py プロジェクト: waiterZen/swift
    def __call__(self, env, start_response):
        """
        If used, this should be the first middleware in pipeline.
        """
        trans_id = 'tx' + uuid.uuid4().hex
        env['swift.trans_id'] = trans_id
        self.logger.txn_id = trans_id
        try:

            def my_start_response(status, response_headers, exc_info=None):
                trans_header = ('x-trans-id', trans_id)
                response_headers.append(trans_header)
                return start_response(status, response_headers, exc_info)

            return self.app(env, my_start_response)
        except (Exception, Timeout), err:
            self.logger.exception(_('Error: %s'), err)
            resp = HTTPServerError(request=Request(env),
                                   body='An error occurred',
                                   content_type='text/plain')
            resp.headers['x-trans-id'] = trans_id
            return resp(env, start_response)
コード例 #29
0
    def handle_request(self, env, start_response):
        trans_id = generate_trans_id(self.trans_id_suffix)
        env['swift.trans_id'] = trans_id
        self.logger.txn_id = trans_id
        try:
            # catch any errors in the pipeline
            resp = self._app_call(env)
        except (Exception, Timeout) as err:
            self.logger.exception(_('Error: %s'), err)
            resp = HTTPServerError(request=Request(env),
                                   body='An error occurred',
                                   content_type='text/plain')
            resp.headers['X-Trans-Id'] = trans_id
            return resp(env, start_response)

        # make sure the response has the trans_id
        if self._response_headers is None:
            self._response_headers = []
        self._response_headers.append(('X-Trans-Id', trans_id))
        start_response(self._response_status, self._response_headers,
                       self._response_exc_info)
        return resp
コード例 #30
0
    def __call__(self, env, start_response):
        req = Request(env)

        if self.check_character(req):
            return HTTPBadRequest(
                request=req,
                body=("Object/Container name contains forbidden chars from %s"
                      % self.forbidden_chars))(env, start_response)
        elif self.check_length(req):
            return HTTPBadRequest(
                request=req,
                body=("Object/Container name longer than the allowed maximum "
                      "%s" % self.maximum_length))(env, start_response)
        elif self.check_regexp(req):
            return HTTPBadRequest(
                request=req,
                body=("Object/Container name contains a forbidden substring "
                      "from regular expression %s"
                      % self.forbidden_regexp))(env, start_response)
        else:
            # Pass on to downstream WSGI component
            return self.app(env, start_response)