Exemplo n.º 1
0
    def __call__(self, input_stream, env, output_stream=None):
        """See `zope.app.publication.interfaces.IPublicationRequestFactory`"""
        # BBB: This is backward-compatibility support for the deprecated
        # output stream.
        try:
            env.get
        except AttributeError:
            import warnings
            warnings.warn("Can't pass output streams to requests anymore. "
                          "This will go away in Zope 3.4.",
                          DeprecationWarning,
                          2)
            env, output_stream = output_stream, env


        method = env.get('REQUEST_METHOD', 'GET').upper()
        request_class, publication_class = chooseClasses(method, env)

        publication = self._publication_cache.get(publication_class)
        if publication is None:
            publication = publication_class(self._db)
            self._publication_cache[publication_class] = publication

        request = request_class(input_stream, env)
        request.setPublication(publication)
        if IBrowserRequest.providedBy(request):
            # only browser requests have skins
            setDefaultSkin(request)
        return request
Exemplo n.º 2
0
    def __bobo_traverse__(self, REQUEST, name):
        """Hook for Zope 2 traversal

        This method is called by Zope 2's ZPublisher upon traversal.
        It allows us to trick it into faking the Zope 3 traversal system
        by using an ITraverser adapter.
        """
        if not IBrowserRequest.providedBy(REQUEST):
            # Try to get the REQUEST by acquisition
            REQUEST = getattr(self, 'REQUEST', None)
            if not IBrowserRequest.providedBy(REQUEST):
                REQUEST = FakeRequest()

        # set the default skin on the request if it doesn't have any
        # layers set on it yet
        if queryType(REQUEST, ILayer) is None:
            setDefaultSkin(REQUEST)

        # con Zope 3 into using Zope 2's checkPermission
        newInteraction()
        try:
            return ITraverser(self).traverse(path=[name],
                                             request=REQUEST).__of__(self)
        except (ComponentLookupError, LookupError, AttributeError, KeyError,
                NotFound):
            pass
        try:
            return getattr(self, name)
        except AttributeError:
            pass
        try:
            return self[name]
        except (AttributeError, KeyError):
            pass
        return self.__fallback_traverse__(REQUEST, name)
Exemplo n.º 3
0
def publish_module_standard(module_name,
                   stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr,
                   environ=os.environ, debug=0, request=None, response=None):
    must_die=0
    status=200
    after_list=[None]
    try:
        try:
            if response is None:
                response=Response(stdout=stdout, stderr=stderr)
            else:
                stdout=response.stdout

            if request is None:
                request=Request(stdin, environ, response)

            # make sure that the request we hand over has the
            # default layer/skin set on it; subsequent code that
            # wants to look up views will likely depend on it
            setDefaultSkin(request)

            response = publish(request, module_name, after_list, debug=debug)
        except SystemExit, v:
            must_die=sys.exc_info()
            request.response.exception(must_die)
        except ImportError, v:
            if isinstance(v, tuple) and len(v)==3: must_die=v
            elif hasattr(sys, 'exc_info'): must_die=sys.exc_info()
            else: must_die = SystemExit, v, sys.exc_info()[2]
            request.response.exception(1, v)
    def __bobo_traverse__(self, REQUEST, name):
        parent = aq_parent(self)
        proxy = self.__of__(parent)
        val = getattr(proxy, name, _marker)
        if val is not _marker:
            return val
        else:
            # try for a Zope 3-type view. see code in Five/traversable.py
            target = self.getTarget()

            if not IBrowserRequest.providedBy(REQUEST):
                # Try to get the REQUEST by acquisition
                REQUEST = getattr(self, 'REQUEST', None)
                if not IBrowserRequest.providedBy(REQUEST):
                    REQUEST = FakeRequest()
                    setDefaultSkin(REQUEST)
            Products.Five.security.newInteraction()
            try:
                # note use of 'target' instead of 'self'...
                return ITraverser(target).traverse(
                    path=[name], request=REQUEST).__of__(target)
            except (ComponentLookupError, LookupError, AttributeError,
                    KeyError, NotFound):
                pass

        raise AttributeError, "name"
Exemplo n.º 5
0
 def traverse(self, name, furtherPath):
     context = self._subject
     __traceback_info__ = (context, name, furtherPath)
     # Find the REQUEST
     REQUEST = getattr(context, 'REQUEST', None)
     if not IBrowserRequest.providedBy(REQUEST):
         REQUEST = FakeRequest()
         setDefaultSkin(REQUEST)
     # Try to lookup a view
     try:
         return getMultiAdapter((context, REQUEST), Interface, name)
     except ComponentLookupError:
         pass
Exemplo n.º 6
0
 def traverse(self, name, furtherPath):
     context = self._subject
     __traceback_info__ = (context, name, furtherPath)
     # Find the REQUEST
     REQUEST = getattr(context, 'REQUEST', None)
     if not IBrowserRequest.providedBy(REQUEST):
         REQUEST = FakeRequest()
         setDefaultSkin(REQUEST)
     # Try to lookup a view
     try:
         return getMultiAdapter((context, REQUEST), Interface, name)
     except ComponentLookupError:
         pass
Exemplo n.º 7
0
def makerequest(app, stdout=stdout):
    resp = HTTPResponse(stdout=stdout)
    environ = os.environ.copy()
    environ['SERVER_NAME'] = 'foo'
    environ['SERVER_PORT'] = '80'
    environ['REQUEST_METHOD'] =  'GET'
    req = HTTPRequest(stdin, environ, resp)
    req._steps = ['noobject']  # Fake a published object.
    req['ACTUAL_URL'] = req.get('URL') # Zope 2.7.4
    
    # set Zope3-style default skin so that the request is usable for
    # Zope3-style view look-ups.
    from zope.app.publication.browser import setDefaultSkin
    setDefaultSkin(req)

    requestcontainer = RequestContainer(REQUEST = req)
    return app.__of__(requestcontainer)
Exemplo n.º 8
0
def publish_module(
    module_name,
    stdin=sys.stdin,
    stdout=sys.stdout,
    stderr=sys.stderr,
    environ=os.environ,
    debug=0,
    request=None,
    response=None,
    extra={},
):
    must_die = 0
    status = 200
    after_list = [None]
    from Response import Response
    from Request import Request
    from Publish import publish

    try:
        try:
            if response is None:
                response = Response(stdout=stdout, stderr=stderr)
            else:
                stdout = response.stdout
            if request is None:
                request = Request(stdin, environ, response)
                # make sure that the request we hand over has the
                # default layer/skin set on it; subsequent code that
                # wants to look up views will likely depend on it
                from zope.app.publication.browser import setDefaultSkin

                setDefaultSkin(request)

            for k, v in extra.items():
                request[k] = v
            response = publish(request, module_name, after_list, debug=debug)
        except SystemExit, v:
            must_die = sys.exc_info()
            response.exception(must_die)
        except ImportError, v:
            if isinstance(v, TupleType) and len(v) == 3:
                must_die = v
            else:
                must_die = sys.exc_info()
            response.exception(1, v)
Exemplo n.º 9
0
    def __bobo_traverse__(self, REQUEST, name):
        """Hook for Zope 2 traversal

        This method is called by Zope 2's ZPublisher upon traversal.
        It allows us to trick it into faking the Zope 3 traversal system
        by using an ITraverser adapter.
        """
        if not IBrowserRequest.providedBy(REQUEST):
            # Try to get the REQUEST by acquisition
            REQUEST = getattr(self, 'REQUEST', None)
            if not IBrowserRequest.providedBy(REQUEST):
                REQUEST = FakeRequest()

        # set the default skin on the request if it doesn't have any
        # layers set on it yet
        if queryType(REQUEST, ILayer) is None:
            setDefaultSkin(REQUEST)

        # con Zope 3 into using Zope 2's checkPermission
        newInteraction()
        try:
            return ITraverser(self).traverse(
                path=[name], request=REQUEST).__of__(self)
        except (ComponentLookupError, LookupError,
                AttributeError, KeyError, NotFound):
            pass
        try:
            return self.__fallback_traverse__(REQUEST, name)
        except NotImplementedError:
            pass
        # TODO: This should at least make an attempt to deal with
        # potential WebDAV issues, in particular we should not perform
        # acquisition for webdav requests. See BaseRequest.traverse for 
        # details.
        try:
            return getattr(self, name)
        except AttributeError:
            pass
        try:
            return self[name]
        except (AttributeError, KeyError):
            pass
        raise AttributeError, name
Exemplo n.º 10
0
def makerequest(app, stdout=sys.stdout):
    '''Wraps the app into a fresh REQUEST.'''
    from ZPublisher.BaseRequest import RequestContainer
    from ZPublisher.Request import Request
    from ZPublisher.Response import Response
    response = Response(stdout=stdout)
    environ = {}
    environ['SERVER_NAME'] = _Z2HOST or 'nohost'
    environ['SERVER_PORT'] = '%d' % (_Z2PORT or 80)
    environ['REQUEST_METHOD'] = 'GET'
    request = Request(sys.stdin, environ, response)
    request._steps = ['noobject'] # Fake a published object
    request['ACTUAL_URL'] = request.get('URL') # Zope 2.7.4

    # set Zope3-style default skin so that the request is usable for
    # Zope3-style view look-ups
    from zope.app.publication.browser import setDefaultSkin
    setDefaultSkin(request)

    return app.__of__(RequestContainer(REQUEST=request))
Exemplo n.º 11
0
    def _request(self,
                 path='/', stdin='', basic=None,
                 environment = None, form=None,
                 request=None, publication=BrowserPublication):
        """Create a request
        """

        env = {}

        if type(stdin) is str:
            stdin = StringIO(stdin)

        p=path.split('?')
        if len(p)==1:
            env['PATH_INFO'] = p[0]
        elif len(p)==2:
            env['PATH_INFO'], env['QUERY_STRING'] = p
        else:
            raise ValueError("Too many ?s in path", path)

        if environment is not None:
            env.update(environment)

        if basic:
            env['HTTP_AUTHORIZATION']="Basic %s" % base64.encodestring(basic)


        pub = publication(self.db)

        if request is not None:
            request = request(stdin, env)
        else:
            request = TestRequest(stdin, env)
            setDefaultSkin(request)
        request.setPublication(pub)
        if form:
            # This requires that request class has an attribute 'form'
            # (BrowserRequest has, TestRequest hasn't)
            request.form.update(form)

        return request
Exemplo n.º 12
0
    def getSubObject(self, name, REQUEST, RESPONSE=None):
        obj = self.__p4a_z2utils_orig_getSubObject(name, REQUEST, RESPONSE)
        if obj is not None:
            return obj

        # The following is a copy from Five's __bobo_traverse__ stuff,
        # see Products.Five.traversable for details.
        # Basically we're forcing Archetypes to look up the correct
        # Five way:
        #   1) check for data object first
        #   2) check for zope3 view 
        #   3) return nothing so that AT's default __bobo_traverse__ will use aq

        if not IBrowserRequest.providedBy(REQUEST):
            # Try to get the REQUEST by acquisition
            REQUEST = getattr(self, 'REQUEST', None)
            if not IBrowserRequest.providedBy(REQUEST):
                REQUEST = FakeRequest()
                setDefaultSkin(REQUEST)

        # Con Zope 3 into using Zope 2's checkPermission
        Products.Five.security.newInteraction()

        # Use the ITraverser adapter (which in turn uses ITraversable
       # adapters) to traverse to a view.  Note that we're mixing
        # object-graph and object-publishing traversal here, but Zope
        # 2 has no way to tell us when to use which...
        # TODO Perhaps we can decide on object-graph vs.
        # object-publishing traversal depending on whether REQUEST is
        # a stub or not?
        try:
            return ITraverser(self).traverse(
                path=[name], request=REQUEST).__of__(self)
        except (ComponentLookupError, LookupError, TypeError,
                AttributeError, KeyError, NotFound):
            pass

        return None
Exemplo n.º 13
0
    def makeRequest(self, path='', basic=None, form=None, env={}):
        """Creates a new request object.

        Arguments:
          path   -- the path to be traversed (e.g. "/folder1/index.html")
          basic  -- basic HTTP authentication credentials ("user:password")
          form   -- a dictionary emulating a form submission
                    (Note that field values should be Unicode strings)
          env    -- a dictionary of additional environment variables
                    (You can emulate HTTP request header
                       X-Header: foo
                     by adding 'HTTP_X_HEADER': 'foo' to env)
        """
        environment = {"HTTP_HOST": 'localhost',
                       "HTTP_REFERER": 'localhost',
                       "HTTP_COOKIE": self.httpCookie(path)}
        environment.update(env)
        app = FunctionalTestSetup().getApplication()
        request = app._request(path, '',
                               environment=environment,
                               basic=basic, form=form,
                               request=BrowserRequest)
        setDefaultSkin(request)
        return request
Exemplo n.º 14
0
    def __bobo_traverse__(self, REQUEST, name):
        """Hook for Zope 2 traversal

        This method is called by Zope 2's ZPublisher upon traversal.
        It allows us to trick it into faking the Zope 3 traversal system
        by using an ITraverser adapter.
        """
        # We are trying to be compatible with Zope 2 and 3 traversal
        # behaviour as much as possible.  Therefore the first part of
        # this method is based on BaseRequest.traverse's behaviour:
        # 1. If an object has __bobo_traverse__, use it.
        # 2. Otherwise do attribute look-up or, if that doesn't work,
        #    key item lookup.

        if zope.deprecation.__show__():
            warnings.warn("The view lookup done by Traversable." \
                          "__bobo_traverse__ is now done by the standard " \
                          "traversal. This class is no longer needed and "
                          "will be removed in Zope 2.12.",
                          DeprecationWarning, 2)

        if hasattr(self, '__fallback_traverse__'):
            try:
                return self.__fallback_traverse__(REQUEST, name)
            except (AttributeError, KeyError):
                pass
            except NotFound:
                # OFS.Application.__bobo_traverse__ calls
                # REQUEST.RESPONSE.notFoundError which sets the HTTP
                # status code to 404
                try:
                    REQUEST.RESPONSE.setStatus(200)
                except AttributeError:
                    pass
        else:
            try:
                return getattr(self, name)
            except AttributeError:
                pass

            try:
                return self[name]
            except (KeyError, IndexError, TypeError, AttributeError):
                pass

        # This is the part Five adds:
        # 3. If neither __bobo_traverse__ nor attribute/key look-up
        # work, we try to find a Zope 3-style view.

        # For that we need to make sure we have a good request
        # (sometimes __bobo_traverse__ gets a stub request)
        if not IBrowserRequest.providedBy(REQUEST):
            # Try to get the REQUEST by acquisition
            REQUEST = getattr(self, 'REQUEST', None)
            if not IBrowserRequest.providedBy(REQUEST):
                REQUEST = FakeRequest()
                setDefaultSkin(REQUEST)

        # Con Zope 3 into using Zope 2's checkPermission
        Products.Five.security.newInteraction()

        # Use the ITraverser adapter (which in turn uses ITraversable
        # adapters) to traverse to a view.  Note that we're mixing
        # object-graph and object-publishing traversal here, but Zope
        # 2 has no way to tell us when to use which...
        # TODO Perhaps we can decide on object-graph vs.
        # object-publishing traversal depending on whether REQUEST is
        # a stub or not?
        try:
            return ITraverser(self).traverse(
                path=[name], request=REQUEST).__of__(self)
        except (ComponentLookupError, LookupError,
                AttributeError, KeyError, NotFound):
            pass

        raise AttributeError(name)
Exemplo n.º 15
0
    def __bobo_traverse__(self, REQUEST, name):
        """Hook for Zope 2 traversal

        This method is called by Zope 2's ZPublisher upon traversal.
        It allows us to trick it into faking the Zope 3 traversal system
        by using an ITraverser adapter.
        """
        # We are trying to be compatible with Zope 2 and 3 traversal
        # behaviour as much as possible.  Therefore the first part of
        # this method is based on BaseRequest.traverse's behaviour:
        # 1. If an object has __bobo_traverse__, use it.
        # 2. Otherwise do attribute look-up or, if that doesn't work,
        #    key item lookup.

        if hasattr(self, '__fallback_traverse__'):
            try:
                return self.__fallback_traverse__(REQUEST, name)
            except (AttributeError, KeyError):
                pass
        else:
            try:
                return getattr(self, name)
            except AttributeError:
                pass

            try:
                return self[name]
            except (KeyError, IndexError, TypeError, AttributeError):
                pass

        # This is the part Five adds:
        # 3. If neither __bobo_traverse__ nor attribute/key look-up
        # work, we try to find a Zope 3-style view.

        # For that we need to make sure we have a good request
        # (sometimes __bobo_traverse__ gets a stub request)
        if not IBrowserRequest.providedBy(REQUEST):
            # Try to get the REQUEST by acquisition
            REQUEST = getattr(self, 'REQUEST', None)
            if not IBrowserRequest.providedBy(REQUEST):
                REQUEST = FakeRequest()
                setDefaultSkin(REQUEST)

        # Con Zope 3 into using Zope 2's checkPermission
        Products.Five.security.newInteraction()

        # Use the ITraverser adapter (which in turn uses ITraversable
        # adapters) to traverse to a view.  Note that we're mixing
        # object-graph and object-publishing traversal here, but Zope
        # 2 has no way to tell us when to use which...
        # TODO Perhaps we can decide on object-graph vs.
        # object-publishing traversal depending on whether REQUEST is
        # a stub or not?
        try:
            return ITraverser(self).traverse(path=[name],
                                             request=REQUEST).__of__(self)
        except (ComponentLookupError, LookupError, AttributeError, KeyError,
                NotFound):
            pass

        raise AttributeError(name)
Exemplo n.º 16
0
def publish(request, module_name, after_list, debug=0,
            # Optimize:
            call_object=call_object,
            missing_name=missing_name,
            dont_publish_class=dont_publish_class,
            mapply=mapply,
            ):

    (bobo_before, bobo_after, object, realm, debug_mode, err_hook,
     validated_hook, transactions_manager)= get_module_info(module_name)

    parents=None
    response=None

    try:
        request.processInputs()

        request_get=request.get
        response=request.response

        # First check for "cancel" redirect:
        if request_get('SUBMIT','').strip().lower()=='cancel':
            cancel=request_get('CANCEL_ACTION','')
            if cancel:
                raise Redirect, cancel

        after_list[0]=bobo_after
        if debug_mode:
            response.debug_mode=debug_mode
        if realm and not request.get('REMOTE_USER',None):
            response.realm=realm

        if bobo_before is not None:
            bobo_before()

        # Get the path list.
        # According to RFC1738 a trailing space in the path is valid.
        path=request_get('PATH_INFO')

        request['PARENTS']=parents=[object]

        if transactions_manager:
            transactions_manager.begin()

        object=request.traverse(path, validated_hook=validated_hook)

        if transactions_manager:
            transactions_manager.recordMetaData(object, request)

        result=mapply(object, request.args, request,
                      call_object,1,
                      missing_name,
                      dont_publish_class,
                      request, bind=1)

        if result is not response:
            response.setBody(result)

        if transactions_manager:
            transactions_manager.commit()

        return response
    except:

        # DM: provide nicer error message for FTP
        sm = None
        if response is not None:
            sm = getattr(response, "setMessage", None)

        if sm is not None:
            from asyncore import compact_traceback
            cl,val= sys.exc_info()[:2]
            sm('%s: %s %s' % (
                getattr(cl,'__name__',cl), val,
                debug_mode and compact_traceback()[-1] or ''))

        if err_hook is not None:
            if parents:
                parents=parents[0]
            try:
                try:
                    return err_hook(parents, request,
                                    sys.exc_info()[0],
                                    sys.exc_info()[1],
                                    sys.exc_info()[2],
                                    )
                except Retry:
                    if not request.supports_retry():
                        return err_hook(parents, request,
                                        sys.exc_info()[0],
                                        sys.exc_info()[1],
                                        sys.exc_info()[2],
                                        )
            finally:
                if transactions_manager:
                    transactions_manager.abort()

            # Only reachable if Retry is raised and request supports retry.
            newrequest=request.retry()
            request.close()  # Free resources held by the request.
            # Set the default layer/skin on the newly generated request
            setDefaultSkin(newrequest)
            try:
                return publish(newrequest, module_name, after_list, debug)
            finally:
                newrequest.close()

        else:
            if transactions_manager:
                transactions_manager.abort()
            raise
Exemplo n.º 17
0
    def __bobo_traverse__(self, REQUEST, name):
        """Hook for Zope 2 traversal

        This method is called by Zope 2's ZPublisher upon traversal.
        It allows us to trick it into faking the Zope 3 traversal system
        by using an ITraverser adapter.
        """
        # We are trying to be compatible with Zope 2 and 3 traversal
        # behaviour as much as possible.  Therefore the first part of
        # this method is based on BaseRequest.traverse's behaviour:
        # 1. If an object has __bobo_traverse__, use it.
        # 2. Otherwise do attribute look-up or, if that doesn't work,
        #    key item lookup.
        result = _marker
        if hasattr(self, '__fallback_traverse__'):
            try:
                return self.__fallback_traverse__(REQUEST, name)
            except (AttributeError, KeyError):
                pass
            except NotFound:
                # OFS.Application.__bobo_traverse__ calls
                # REQUEST.RESPONSE.notFoundError which sets the HTTP
                # status code to 404
                try:
                    REQUEST.RESPONSE.setStatus(200)
                except AttributeError:
                    pass
        else:
            # See if the object itself has the attribute, try acquisition
            # later
            if getattr(aq_base(self), name, _marker) is not _marker:
                return getattr(self, name)
            try:
                # item access should never acquire
                result = self[name]
                # WebDAV requests will always return something,
                # sometimes it's a NullResource, which we will ignore
                # and return later if necessary
                if not isinstance(result, NullResource):
                    return result
            except (KeyError, IndexError, TypeError, AttributeError):
                pass

        # This is the part Five adds:
        # 3. If neither __bobo_traverse__ nor attribute/key look-up
        # work, we try to find a Zope 3-style view.

        # For that we need to make sure we have a good request
        # (sometimes __bobo_traverse__ gets a stub request)
        if not IBrowserRequest.providedBy(REQUEST):
            # Try to get the REQUEST by acquisition
            REQUEST = getattr(self, 'REQUEST', None)
            if not IBrowserRequest.providedBy(REQUEST):
                REQUEST = FakeRequest()
                setDefaultSkin(REQUEST)

        # Con Zope 3 into using Zope 2's checkPermission
        Products.Five.security.newInteraction()

        # Use the ITraverser adapter (which in turn uses ITraversable
        # adapters) to traverse to a view.  Note that we're mixing
        # object-graph and object-publishing traversal here, but Zope
        # 2 has no way to tell us when to use which...
        # TODO Perhaps we can decide on object-graph vs.
        # object-publishing traversal depending on whether REQUEST is
        # a stub or not?
        try:
            return ITraverser(self).traverse(
                path=[name], request=REQUEST).__of__(self)
        except (ComponentLookupError, LookupError,
                AttributeError, KeyError, NotFound):
            pass

        # Fallback on acquisition, let it raise an AttributeError if it must
        try:
            return getattr(self, name)
        except AttributeError:
            if result is not _marker:
                return result
            raise
Exemplo n.º 18
0
def trustedTraverse(ob, path, ignored,):
  if not path: return self

  get = getattr
  has = hasattr
  N = None
  M = rebindFunction # artifical marker

  if isinstance(path, str): path = path.split('/')
  else: path=list(path)
  
  REQUEST = get(ob, 'REQUEST', None)
  if REQUEST is None:
    REQUEST=FakeRequest()
  setDefaultSkin(REQUEST)
  REQUEST['TraversalRequestNameStack'] = path
  path.reverse()
  pop=path.pop

  if len(path) > 1 and not path[0]:
    # Remove trailing slash
    path.pop(0)

  if not path[-1]:
    # If the path starts with an empty string, go to the root first.
    pop()
    self=ob.getPhysicalRoot()

  object = ob
  while path:
    name=pop()
    __traceback_info__ = path, name

    if name == '..':
      o=getattr(object, 'aq_parent', M)
      if o is not M:
        object=o
        continue

    if name and name[:1] in '@+':
      # Process URI segment parameters.
      ns, nm = nsParse(name)
      if ns:
        try:
          o = namespaceLookup(ns, nm, object, REQUEST).__of__(object)
        except TraversalError:
          raise KeyError(name)
        object = o
        continue
        
    t=get(object, '__bobo_traverse__', M)
    if t is not M: o=t(REQUEST, name)
    else:
      o = get(object, name, M)
      if o is M:
        try: o = object[name]
        except (AttributeError, TypeError): # better exception
            o = queryMultiAdapter((object, REQUEST), Interface, name)
            if o is not None:
                o = o.__of__(object)
            else:
                raise AttributeError(name)
    object = o

  return object
Exemplo n.º 19
0
def trustedTraverse(
    ob,
    path,
    ignored,
):
    if not path: return self

    get = getattr
    has = hasattr
    N = None
    M = rebindFunction  # artifical marker

    if isinstance(path, str): path = path.split('/')
    else: path = list(path)

    REQUEST = get(ob, 'REQUEST', None)
    if REQUEST is None:
        REQUEST = FakeRequest()
    setDefaultSkin(REQUEST)
    REQUEST['TraversalRequestNameStack'] = path
    path.reverse()
    pop = path.pop

    if len(path) > 1 and not path[0]:
        # Remove trailing slash
        path.pop(0)

    if not path[-1]:
        # If the path starts with an empty string, go to the root first.
        pop()
        self = ob.getPhysicalRoot()

    object = ob
    while path:
        name = pop()
        __traceback_info__ = path, name

        if name == '..':
            o = getattr(object, 'aq_parent', M)
            if o is not M:
                object = o
                continue

        if name and name[:1] in '@+':
            # Process URI segment parameters.
            ns, nm = nsParse(name)
            if ns:
                try:
                    o = namespaceLookup(ns, nm, object, REQUEST).__of__(object)
                except TraversalError:
                    raise KeyError(name)
                object = o
                continue

        t = get(object, '__bobo_traverse__', M)
        if t is not M: o = t(REQUEST, name)
        else:
            o = get(object, name, M)
            if o is M:
                try:
                    o = object[name]
                except (AttributeError, TypeError):  # better exception
                    o = queryMultiAdapter((object, REQUEST), Interface, name)
                    if o is not None:
                        o = o.__of__(object)
                    else:
                        raise AttributeError(name)
        object = o

    return object
Exemplo n.º 20
0
    def __bobo_traverse__(self, REQUEST, name):
        """Hook for Zope 2 traversal

        This method is called by Zope 2's ZPublisher upon traversal.
        It allows us to trick it into faking the Zope 3 traversal system
        by using an ITraverser adapter.
        """
        # We are trying to be compatible with Zope 2 and 3 traversal
        # behaviour as much as possible.  Therefore the first part of
        # this method is based on BaseRequest.traverse's behaviour:
        # 1. If an object has __bobo_traverse__, use it.
        # 2. Otherwise do attribute look-up or, if that doesn't work,
        #    key item lookup.
        result = _marker
        if hasattr(self, '__fallback_traverse__'):
            try:
                return self.__fallback_traverse__(REQUEST, name)
            except (AttributeError, KeyError):
                pass
            except NotFound:
                # OFS.Application.__bobo_traverse__ calls
                # REQUEST.RESPONSE.notFoundError which sets the HTTP
                # status code to 404
                try:
                    REQUEST.RESPONSE.setStatus(200)
                except AttributeError:
                    pass
        else:
            # See if the object itself has the attribute, try acquisition
            # later
            if getattr(aq_base(self), name, _marker) is not _marker:
                return getattr(self, name)
            try:
                # item access should never acquire
                result = self[name]
                # WebDAV requests will always return something,
                # sometimes it's a NullResource, which we will ignore
                # and return later if necessary
                if not isinstance(result, NullResource):
                    return result
            except (KeyError, IndexError, TypeError, AttributeError):
                pass

        # This is the part Five adds:
        # 3. If neither __bobo_traverse__ nor attribute/key look-up
        # work, we try to find a Zope 3-style view.

        # For that we need to make sure we have a good request
        # (sometimes __bobo_traverse__ gets a stub request)
        if not IBrowserRequest.providedBy(REQUEST):
            # Try to get the REQUEST by acquisition
            REQUEST = getattr(self, 'REQUEST', None)
            if not IBrowserRequest.providedBy(REQUEST):
                REQUEST = FakeRequest()
                setDefaultSkin(REQUEST)

        # Con Zope 3 into using Zope 2's checkPermission
        Products.Five.security.newInteraction()

        # Use the ITraverser adapter (which in turn uses ITraversable
        # adapters) to traverse to a view.  Note that we're mixing
        # object-graph and object-publishing traversal here, but Zope
        # 2 has no way to tell us when to use which...
        # TODO Perhaps we can decide on object-graph vs.
        # object-publishing traversal depending on whether REQUEST is
        # a stub or not?
        try:
            return ITraverser(self).traverse(
                path=[name], request=REQUEST).__of__(self)
        except (ComponentLookupError, LookupError,
                AttributeError, KeyError, NotFound):
            pass

        # Fallback on acquisition, let it raise an AttributeError if it must
        try:
            return getattr(self, name)
        except AttributeError:
            if result is not _marker:
                return result
            raise
Exemplo n.º 21
0
    def __call__(self, request_string, handle_errors=True, form=None):
        # Commit work done by previous python code.
        commit()

        # Discard leading white space to make call layout simpler
        request_string = request_string.lstrip()

        # split off and parse the command line
        l = request_string.find('\n')
        command_line = request_string[:l].rstrip()
        request_string = request_string[l+1:]
        method, path, protocol = command_line.split()
        path = urllib.unquote(path)

        instream = StringIO(request_string)
        environment = {"HTTP_COOKIE": self.httpCookie(path),
                       "HTTP_HOST": 'localhost',
                       "HTTP_REFERER": 'localhost',
                       "REQUEST_METHOD": method,
                       "SERVER_PROTOCOL": protocol,
                       }

        headers = [split_header(header)
                   for header in rfc822.Message(instream).headers]
        for name, value in headers:
            name = ('_'.join(name.upper().split('-')))
            if name not in ('CONTENT_TYPE', 'CONTENT_LENGTH'):
                name = 'HTTP_' + name
            environment[name] = value.rstrip()

        auth_key = 'HTTP_AUTHORIZATION'
        if environment.has_key(auth_key):
            environment[auth_key] = auth_header(environment[auth_key])

        old_site = getSite()
        setSite(None)

        request_cls, publication_cls = self.chooseRequestClass(method, path,
                                                               environment)
        app = FunctionalTestSetup().getApplication()

        request = app._request(
            path, instream,
            environment=environment,
            request=request_cls, publication=publication_cls)
        if IBrowserRequest.providedBy(request):
            # only browser requests have skins
            setDefaultSkin(request)

        if form is not None:
            if request.form:
                raise ValueError("only one set of form values can be provided")
            request.form = form

        response = ResponseWrapper(
            request.response, path,
            omit=('x-content-type-warning', 'x-powered-by'),
            )

        publish(request, handle_errors=handle_errors)
        self.saveCookies(response)
        setSite(old_site)

        # sync Python connection:
        getRootFolder()._p_jar.sync()

        return response