def manage_FTPget(self, REQUEST=None, RESPONSE=None):
     """Return the body of the content item in an FTP or WebDAV response.
     
     This adapts self to IRawReadFile(), which is then returned as an
     iterator. The adapter should provide IStreamIterator.
     """
     reader = IRawReadFile(self, None)
     if reader is None:
         return ''
     
     request = REQUEST is not None and REQUEST or self.REQUEST
     response = RESPONSE is not None and RESPONSE or request.response
     
     mimeType = reader.mimeType
     encoding = reader.encoding
     
     if mimeType is not None:
         if encoding is not None:
             response.setHeader('Content-Type', '%s; charset="%s"' % (mimeType, encoding,))
         else:
             response.setHeader('Content-Type', mimeType)
     
     size = reader.size()
     if size is not None:
         response.setHeader('Content-Length', str(size))
     
     # if the reader is an iterator that the publisher can handle, return
     # it as-is. Otherwise, read the full contents
     
     if ((IInterface.providedBy(IStreamIterator) and IStreamIterator.providedBy(reader))
      or (not IInterface.providedBy(IStreamIterator) and IStreamIterator.isImplementedBy(reader))
     ):
         return reader
     else:
         return reader.read()
示例#2
0
def setBody(self, body, *args, **kw):
    if IInterface.providedBy(IStreamIterator):  # is this zope 2.12?
        stream = IStreamIterator.providedBy(body)
    else:
        stream = IStreamIterator.isImplementedBy(body)
    if stream:
        body = ''.join(body)  # read from iterator
    return self._original_setBody(body, *args, **kw)
def setBody(self, body, *args, **kw):
    if IInterface.providedBy(IStreamIterator):  # is this zope 2.12?
        stream = IStreamIterator.providedBy(body)
    else:
        stream = IStreamIterator.isImplementedBy(body)
    if stream:
        body = ''.join(body)    # read from iterator
    return original_setBody(self, body, *args, **kw)
    def test_my_avatar(self):
        self.login(self.profile1.username)
        my_avatar = MyAvatar(self.profile1, self.request)
        data = my_avatar()
        self.assertTrue(IStreamIterator.providedBy(data))

        profile_data = my_avatar.avatar_profile()
        self.assertTrue(IStreamIterator.providedBy(profile_data))

        avatar = MyAvatar(self.profile2, self.request)

        self.assertEqual(avatar(), self.default_avatar)
    def test_my_avatar(self):
        self.login(self.profile1.username)
        my_avatar = MyAvatar(self.profile1, self.request)
        data = my_avatar()
        self.assertTrue(IStreamIterator.providedBy(data))

        profile_data = my_avatar.avatar_profile()
        self.assertTrue(IStreamIterator.providedBy(profile_data))

        no_avatar = MyAvatar(self.profile2, self.request)
        data = no_avatar()
        self.assertIsNone(data)
    def test_my_avatar(self):
        self.login(self.profile1.username)
        my_avatar = MyAvatar(self.profile1, self.request)
        data = my_avatar()
        self.assertTrue(IStreamIterator.providedBy(data))

        profile_data = my_avatar.avatar_profile()
        self.assertTrue(IStreamIterator.providedBy(profile_data))

        avatar = MyAvatar(self.profile2, self.request)

        self.assertEqual(avatar(), self.default_avatar)
示例#7
0
    def setBody(self, body, title='', is_error=False, lock=None):
        # allow locking of the body in the same way as the status
        if self._locked_body:
            return

        if isinstance(body, IOBase):
            body.seek(0, 2)
            length = body.tell()
            body.seek(0)
            self.setHeader('Content-Length', '%d' % length)
            self.body = body
        elif IStreamIterator.providedBy(body):
            self.body = body
            super(WSGIResponse, self).setBody(b'', title, is_error)
        elif IUnboundStreamIterator.providedBy(body):
            self.body = body
            self._streaming = 1
            super(WSGIResponse, self).setBody(b'', title, is_error)
        else:
            super(WSGIResponse, self).setBody(body, title, is_error)

        # Have to apply the lock at the end in case the super class setBody
        # is called, which will observe the lock and do nothing
        if lock:
            self._locked_body = 1
示例#8
0
 def testIndexHtmlWithPdata(self):
     from ZPublisher.Iterators import IStreamIterator
     self.file.manage_upload('a' * (2 << 16))  # 128K
     result = self.file.index_html(self.app.REQUEST,
                                   self.app.REQUEST.RESPONSE)
     self.failUnless(IStreamIterator.isImplementedBy(result))
     self.failIf(self.app.REQUEST.RESPONSE._wrote)
示例#9
0
    def test_defaultreadfile_verify_iface(self):

        dummy = DefaultReadFile(ItemDummy())
        self.assertTrue(IStreamIterator.providedBy(dummy))
        self.assertTrue(verifyObject(IStreamIterator, dummy))
        self.assertEqual(b"".join(dummy), b"Portal-Type: foo\n\n")
        self.assertEqual(len(dummy), 18)
示例#10
0
    def setBody(self, body, title='', is_error=False, lock=None):
        # allow locking of the body in the same way as the status
        if self._locked_body:
            return

        if isinstance(body, IOBase):
            body.seek(0, 2)
            length = body.tell()
            body.seek(0)
            self.setHeader('Content-Length', '%d' % length)
            self.body = body
        elif IStreamIterator.providedBy(body):
            self.body = body
            super().setBody(b'', title, is_error)
        elif IUnboundStreamIterator.providedBy(body):
            self.body = body
            self._streaming = 1
            super().setBody(b'', title, is_error)
        else:
            super().setBody(body, title, is_error)

        # Have to apply the lock at the end in case the super class setBody
        # is called, which will observe the lock and do nothing
        if lock:
            self._locked_body = 1
def applyTransformOnSuccess(event):
    """Apply the transform after a successful request
    """
    transformed = applyTransform(event.request)
    if transformed is not None:
        response = event.request.response

        # horrid check to deal with Plone 3/Zope 2.10, where this is still an old-style interface
        if ((IInterface.providedBy(IStreamIterator)     and IStreamIterator.providedBy(transformed))
         or (not IInterface.providedBy(IStreamIterator) and IStreamIterator.isImplementedBy(transformed))
        ):
            response.setBody(transformed)
        # setBody() can deal with byte and unicode strings (and will encode as necessary)...
        elif isinstance(transformed, basestring):
            response.setBody(transformed)
        # ... but not with iterables
        else:
            response.setBody(''.join(transformed))
 def setBody(self, body, title='', is_error=0):
     if isinstance(body, file) or IStreamIterator.providedBy(body):
         body.seek(0, 2)
         length = body.tell()
         body.seek(0)
         self.setHeader('Content-Length', '%d' % length)
         self.body = body
     else:
         HTTPResponse.setBody(self, body, title, is_error)
示例#13
0
 def setBody(self, body, title='', is_error=0):
     if isinstance(body, file) or IStreamIterator.providedBy(body):
         body.seek(0, 2)
         length = body.tell()
         body.seek(0)
         self.setHeader('Content-Length', '%d' % length)
         self.body = body
     else:
         HTTPResponse.setBody(self, body, title, is_error)
示例#14
0
def manage_FTPget(self, REQUEST=None, RESPONSE=None):
    """Get the raw content for this object (also used for the WebDAV source)
    """

    if REQUEST is None:
        REQUEST = self.REQUEST

    if RESPONSE is None:
        RESPONSE = REQUEST.RESPONSE

    if not self.Schema().hasLayer('marshall'):
        RESPONSE.setStatus(501)  # Not implemented
        return RESPONSE

    self.dav__init(REQUEST, RESPONSE)
    collection_check(self)

    marshaller = self.Schema().getLayerImpl('marshall')
    ddata = marshaller.marshall(self, REQUEST=REQUEST, RESPONSE=RESPONSE)
    if (shasattr(self, 'marshall_hook') and self.marshall_hook):
        ddata = self.marshall_hook(ddata)

    content_type, length, data = ddata

    RESPONSE.setHeader('Content-Type', content_type)
    # Only set Content-Length header length is not None. If we want to
    # support 'chunked' Transfer-Encoding we shouldn't set
    # this. However ExternalEditor *expects* it to be set if we return
    # a StreamIterator, so until that gets fixed we must set it.
    if length is not None:
        RESPONSE.setHeader('Content-Length', length)

    if type(data) is type(''):
        return data

    # We assume 'data' is a 'Pdata chain' as used by OFS.File and
    # return a StreamIterator.
    assert length is not None, 'Could not figure out length of Pdata chain'
    if (issubclass(IStreamIterator, Interface)
            and IStreamIterator.providedBy(data)
            or not issubclass(IStreamIterator, Interface)
            and IStreamIterator.IsImplementedBy(data)):
        return data
    return PdataStreamIterator(data, length)
示例#15
0
def applyTransformOnSuccess(event):
    """Apply the transform after a successful request
    """
    transformed = applyTransform(event.request)
    if transformed is not None:
        response = event.request.response

        # horrid check to deal with Plone 3/Zope 2.10, where this is still an old-style interface
        if ((IInterface.providedBy(IStreamIterator)
             and IStreamIterator.providedBy(transformed))
                or (not IInterface.providedBy(IStreamIterator)
                    and IStreamIterator.isImplementedBy(transformed))):
            response.setBody(transformed)
        # setBody() can deal with byte and unicode strings (and will encode as necessary)...
        elif isinstance(transformed, basestring):
            response.setBody(transformed)
        # ... but not with iterables
        else:
            response.setBody(''.join(transformed))
示例#16
0
 def setBody(self, body, title='', is_error=0, **kw):
     """ Accept either a stream iterator or a string as the body """
     if IStreamIterator.providedBy(body):
         assert (self.headers.has_key('content-length'))
         # wrap the iterator up in a producer that medusa can understand
         self._bodyproducer = iterator_producer(body)
         HTTPResponse.setBody(self, '', title, is_error, **kw)
         return self
     else:
         HTTPResponse.setBody(self, body, title, is_error, **kw)
示例#17
0
 def setBody(self, body, title='', is_error=0, **kw):
     """ Accept either a stream iterator or a string as the body """
     if IStreamIterator.isImplementedBy(body):
         assert(self.headers.has_key('content-length'))
         # wrap the iterator up in a producer that medusa can understand
         self._bodyproducer = iterator_producer(body)
         HTTPResponse.setBody(self, '', title, is_error, **kw)
         return self
     else:
         HTTPResponse.setBody(self, body, title, is_error, **kw)
    def manage_FTPget(self, REQUEST=None, RESPONSE=None):
        """Return the body of the content item in an FTP or WebDAV response.
        
        This adapts self to IRawReadFile(), which is then returned as an
        iterator. The adapter should provide IStreamIterator.
        """
        reader = IRawReadFile(self, None)
        if reader is None:
            return ''

        request = REQUEST is not None and REQUEST or self.REQUEST
        response = RESPONSE is not None and RESPONSE or request.response

        mimeType = reader.mimeType
        encoding = reader.encoding

        if mimeType is not None:
            if encoding is not None:
                response.setHeader('Content-Type', '%s; charset="%s"' % (
                    mimeType,
                    encoding,
                ))
            else:
                response.setHeader('Content-Type', mimeType)

        size = reader.size()
        if size is not None:
            response.setHeader('Content-Length', str(size))

        # if the reader is an iterator that the publisher can handle, return
        # it as-is. Otherwise, read the full contents

        if ((IInterface.providedBy(IStreamIterator)
             and IStreamIterator.providedBy(reader))
                or (not IInterface.providedBy(IStreamIterator)
                    and IStreamIterator.isImplementedBy(reader))):
            return reader
        else:
            return reader.read()
示例#19
0
    def test_avatars_view(self):
        self.login(self.profile1.username)
        avatars_view = AvatarsView(self.portal, self.request)
        avatars_view.publishTraverse(self.request, self.profile1.username)

        data = avatars_view()
        self.assertTrue(IStreamIterator.providedBy(data))

        avatars_view.publishTraverse(self.request, self.profile2.username)
        self.assertEqual(avatars_view(), self.default_avatar)

        avatars_view.publishTraverse(self.request, 'not-a-username')
        self.assertEqual(avatars_view(), self.default_avatar)
示例#20
0
 def __init__(self, data):
     self.fname = tempfile.mktemp()
     out = open(self.fname, 'w+b')
     if isinstance(data, str):
         out.write(data)
         out.flush()
         return
     from ZPublisher.Iterators import IStreamIterator
     if IStreamIterator.isImplementedBy(data):
         for block in data:
             out.write(block)
             block._p_deactivate()
         out.flush()
     else:
         raise ValueError("Don't know how to write data!")
示例#21
0
    def test_avatars_view(self):
        self.login(self.profile1.username)
        avatars_view = AvatarsView(self.portal, self.request)
        avatars_view.publishTraverse(self.request, self.profile1.username)

        data = avatars_view()
        self.assertTrue(IStreamIterator.providedBy(data))

        avatars_view.publishTraverse(self.request, self.profile2.username)
        data = avatars_view()
        self.assertIsNone(data)

        avatars_view.publishTraverse(self.request, "not-a-username")
        with self.assertRaises(NotFound):
            avatars_view()
示例#22
0
 def getWSGIResponse(self):
     # This return a tuple (data_sent, data_to_send_to_WSGI)
     result = self.body
     if result is not None:
         # If we have an iterator, we say that data have been sent
         # in order not to commit the transaction finish consuming
         # the iterator.
         if IStreamIterator.providedBy(result):
             return (True, StreamIteratorIterator(result))
         elif IResult.providedBy(result):
             return (True, result)
         if not isinstance(result, str):
             log_invalid_response_data(result, self.__environ)
         return (self.__started, [result,])
     return (self.__started, [])
示例#23
0
    def test_avatars_view(self):
        self.login(self.profile1.username)
        avatars_view = AvatarsView(self.portal, self.request)
        avatars_view.publishTraverse(self.request,
                                     self.profile1.username)

        data = avatars_view()
        self.assertTrue(IStreamIterator.providedBy(data))

        avatars_view.publishTraverse(self.request,
                                     self.profile2.username)
        self.assertEqual(avatars_view(), self.default_avatar)

        avatars_view.publishTraverse(self.request,
                                     'not-a-username')
        self.assertEqual(avatars_view(), self.default_avatar)
示例#24
0
 def setBody(self, body, title='', is_error=False):
     if isinstance(body, IOBase):
         body.seek(0, 2)
         length = body.tell()
         body.seek(0)
         self.setHeader('Content-Length', '%d' % length)
         self.body = body
     elif IStreamIterator.providedBy(body):
         self.body = body
         super(WSGIResponse, self).setBody(b'', title, is_error)
     elif IUnboundStreamIterator.providedBy(body):
         self.body = body
         self._streaming = 1
         super(WSGIResponse, self).setBody(b'', title, is_error)
     else:
         super(WSGIResponse, self).setBody(body, title, is_error)
示例#25
0
    def __init__(self, data):
        self.fname = tempfile.mktemp()
        out = open(self.fname, "w+b")
        if isinstance(data, str):
            out.write(data)
            out.flush()
            return
        from ZPublisher.Iterators import IStreamIterator

        if IStreamIterator.isImplementedBy(data):
            for block in data:
                out.write(block)
                block._p_deactivate()
            out.flush()
        else:
            raise ValueError("Don't know how to write data!")
示例#26
0
def applyTransformOnSuccess(event):
    """Apply the transform after a successful request
    """
    transformed = applyTransform(event.request)
    if transformed is None:
        return
    response = event.request.response

    if IStreamIterator.providedBy(transformed):
        response.setBody(transformed)
    # setBody() can deal with byte and unicode strings (and will encode as
    # necessary)...
    elif isinstance(transformed, six.string_types):
        response.setBody(transformed)
    # ... but not with iterables
    else:
        response.setBody(''.join(transformed))
示例#27
0
def applyTransformOnSuccess(event):
    """Apply the transform after a successful request
    """
    transformed = applyTransform(event.request)
    if transformed is None:
        return
    response = event.request.response

    if IStreamIterator.providedBy(transformed):
        response.setBody(transformed)
    # setBody() can deal with byte and unicode strings (and will encode as
    # necessary)...
    elif isinstance(transformed, basestring):
        response.setBody(transformed)
    # ... but not with iterables
    else:
        response.setBody(''.join(transformed))
示例#28
0
 def setBody(self, body, title='', is_error=0, **kw):
     """ Accept either a stream iterator or a string as the body """
     if not IStreamIterator.providedBy(body):
         return HTTPResponse.setBody(self, body, title, is_error, **kw)
     assert not self._wrote
     if isinstance(body, BlobStreamIterator):
         body = body.blob # A BlobFile
     if hasattr(body, 'seek') and hasattr(body, 'read') and hasattr(body, 'close'):
         self.stdout = body
         self._wrote = 1
         return
     try:
         while True:
             chunk = body.next()
             self.write(chunk)
     except StopIteration:
         pass
示例#29
0
 def setBody(self, body, title='', is_error=0, **kw):
     """ Accept either a stream iterator or a string as the body """
     if not IStreamIterator.providedBy(body):
         return HTTPResponse.setBody(self, body, title, is_error, **kw)
     assert not self._wrote
     if isinstance(body, BlobStreamIterator):
         body = body.blob  # A BlobFile
     if hasattr(body, 'seek') \
        and hasattr(body, 'read') and \
        hasattr(body, 'close'):
         self.stdout = body
         self._wrote = 1
         return
     try:
         while True:
             chunk = body.next()
             self.write(chunk)
     except StopIteration:
         pass
def manage_FTPget(self, REQUEST=None, RESPONSE=None):
    """Get the raw content for this object (also used for the WebDAV source)
    """

    if REQUEST is None:
        REQUEST = self.REQUEST

    if RESPONSE is None:
        RESPONSE = REQUEST.RESPONSE

    if not self.Schema().hasLayer('marshall'):
        RESPONSE.setStatus(501)  # Not implemented
        return RESPONSE

    self.dav__init(REQUEST, RESPONSE)
    collection_check(self)

    marshaller = self.Schema().getLayerImpl('marshall')
    ddata = marshaller.marshall(self, REQUEST=REQUEST, RESPONSE=RESPONSE)
    if (shasattr(self, 'marshall_hook') and self.marshall_hook):
        ddata = self.marshall_hook(ddata)

    content_type, length, data = ddata

    RESPONSE.setHeader('Content-Type', content_type)
    # Only set Content-Length header length is not None. If we want to
    # support 'chunked' Transfer-Encoding we shouldn't set
    # this. However ExternalEditor *expects* it to be set if we return
    # a StreamIterator, so until that gets fixed we must set it.
    if length is not None:
        RESPONSE.setHeader('Content-Length', length)

    if type(data) is type(''):
        return data

    # We assume 'data' is a 'Pdata chain' as used by OFS.File and
    # return a StreamIterator.
    assert length is not None, 'Could not figure out length of Pdata chain'
    if (issubclass(IStreamIterator, Interface) and IStreamIterator.providedBy(data)
            or not issubclass(IStreamIterator, Interface) and IStreamIterator.IsImplementedBy(data)):
        return data
    return PdataStreamIterator(data, length)
示例#31
0
def applyTransformOnSuccess(event):
    """Apply the transform after a successful request
    """
    transformed = applyTransform(event.request)
    if transformed is None:
        return
    response = event.request.response

    if IStreamIterator.providedBy(transformed):
        response.setBody(transformed)
    # setBody() can deal with byte and unicode strings (and will encode as
    # necessary)...
    elif isinstance(transformed, six.string_types)\
            or isinstance(transformed, six.binary_type):
        response.setBody(transformed)
    # ... but not with iterables
    else:
        transformed = map(
            lambda it: it.decode('utf-8')
            if isinstance(it, six.binary_type)
            else it,
            transformed
        )
        response.setBody(''.join(transformed))
示例#32
0
 def __init__(self, stream):
     assert IStreamIterator.providedBy(stream)
     self.__stream = stream
示例#33
0
def getResourceContent(item, context=None, request=None):
        """Fetch resource content for delivery."""
        id = item

        output = u""

        portal = getSite()

        if context is None:
            context = portal
        
        if request is None:
            request = getRequest()

        default_charset = 'utf-8'

        id = item
        # skip external resources that look like //netdna.bootstrapcdn.com/etc... 
        if id[0:2] == '//':
            return output

        # original_request = getRequest()
        # import pdb; pdb.set_trace()
        # if original_request != request:
        #     setRequest(request)

        try:
            if portal is not None:
                obj = context.restrictedTraverse(id)
            else:
                # Can't do anything other than attempt a getattr
                obj = getattr(context, id)
        except (AttributeError, KeyError):
            output += u"\n/* XXX ERROR -- could not find '%s'*/\n" % id
            content = u''
            obj = None
        except Unauthorized:
            # If we're just returning a single resource, raise an Unauthorized,
            # otherwise we're merging resources in which case just log an error
            raise

        if obj is not None:
            if isinstance(obj, z3_Resource):
                # z3 resources
                # XXX this is a temporary solution, we wrap the five resources
                # into our mechanism, where it should be the other way around.
                #
                # First thing we must be aware of: resources give a complete
                # response so first we must save the headers.
                # Especially, we must delete the If-Modified-Since, because
                # otherwise we might get a 30x response status in some cases.
                original_headers, if_modified = _removeCachingHeaders(request)
                # Now, get the content.
                try:
                    method = obj.__browser_default__(request)[1][0]
                except AttributeError: # zope.app.publisher.browser.fileresource
                    try:
                        method = obj.browserDefault(request)[1][0]
                    except (AttributeError, IndexError):
                        try:
                            method = obj.browserDefault(request)[0].__name__
                        except AttributeError:
                            # The above can all fail if request.method is
                            # POST.  We can still at least try to use the
                            # GET method, as we prefer that anyway.
                            method = getattr(obj, 'GET').__name__

                method = method in ('HEAD', 'POST') and 'GET' or method
                content = getattr(obj, method)()
                import pdb; pdb.set_trace()
                if not isinstance(content, unicode):
                    contenttype = request.RESPONSE.headers.get('content-type', '')
                    contenttype = getCharsetFromContentType(contenttype, default_charset)
                    content = unicode(content, contenttype)
                _restoreCachingHeaders(request, original_headers, if_modified)
            elif hasattr(aq_base(obj), 'meta_type') and obj.meta_type in ['DTML Method', 'Filesystem DTML Method']:
                content = obj(client=context, REQUEST=request,
                              RESPONSE=request.RESPONSE)
                contenttype = request.RESPONSE.headers.get('content-type', '')
                contenttype = getCharsetFromContentType(contenttype, default_charset)
                content = unicode(content, contenttype)
            elif hasattr(aq_base(obj), 'meta_type') and obj.meta_type == 'Filesystem File':
                obj._updateFromFS()
                content = obj._readFile(0)
                contenttype = getCharsetFromContentType(obj.content_type, default_charset)
                content = unicode(content, contenttype)
            elif hasattr(aq_base(obj), 'meta_type') and obj.meta_type in ('ATFile', 'ATBlob'):
                f = obj.getFile()
                contenttype = getCharsetFromContentType(f.getContentType(), default_charset)
                content = unicode(str(f), contenttype)
            # We should add more explicit type-matching checks
            elif hasattr(aq_base(obj), 'index_html') and callable(obj.index_html):
                original_headers, if_modified = _removeCachingHeaders(request)
                # "index_html" may use "RESPONSE.write" (e.g. for OFS.Image.Pdata)
                tmp = StringIO()
                response_write = request.RESPONSE.write
                request.RESPONSE.write = tmp.write
                try:
                    content = obj.index_html(request,
                                             request.RESPONSE)
                finally:
                    request.RESPONSE.write = response_write
                content = tmp.getvalue() or content
                if not isinstance(content, unicode):
                    content = unicode(content, default_charset)
                _restoreCachingHeaders(request, original_headers, if_modified)
            elif callable(obj):
                try:
                    content = obj(request, request.RESPONSE)
                except TypeError:
                    # Could be a view or browser resource
                    content = obj()

                if IStreamIterator.providedBy(content):
                    content = content.read()

                if not isinstance(content, unicode):
                    content = unicode(content, default_charset)
            else:
                content = str(obj)
                content = unicode(content, default_charset)

        # Add start/end notes to the resource for better
        # understanding and debugging
        if content:
            output += u'\n/* - %s - */\n' % (id,)
            output += content
            output += u'\n'

        # if original_request != request:
        #     setRequest(original_request)

        return output
示例#34
0
    def index_html(self, REQUEST, RESPONSE, path=None):
        """Publish the object to the external editor helper app"""

        security = getSecurityManager()
        if path is None:
            parent = self.aq_parent
            try:
                ob = parent[REQUEST['target']]  # Try getitem
            except KeyError:
                ob = getattr(parent, REQUEST['target'])  # Try getattr
            except AttributeError:
                # Handle objects that are methods in ZClasses
                ob = parent.propertysheets.methods[REQUEST['target']]
        else:
            ob = self.restrictedTraverse(path)

        r = []
        r.append('url:%s' % ob.absolute_url())
        r.append('meta_type:%s' % ob.meta_type)

        title = getattr(aq_base(ob), 'title', None)
        if title is not None:
            if callable(title):
                title = title()
            if isinstance(title, types.UnicodeType):
                title = unicode.encode(title, 'utf-8')
            r.append('title:%s' % title)

        if hasattr(aq_base(ob), 'content_type'):
            if callable(ob.content_type):
                r.append('content_type:%s' % ob.content_type())
            else:
                r.append('content_type:%s' % ob.content_type)

        if REQUEST._auth:
            if REQUEST._auth[-1] == '\n':
                auth = REQUEST._auth[:-1]
            else:
                auth = REQUEST._auth

            r.append('auth:%s' % auth)

        r.append('cookie:%s' % REQUEST.environ.get('HTTP_COOKIE', ''))

        if wl_isLocked(ob):
            # Object is locked, send down the lock token
            # owned by this user (if any)
            user_id = security.getUser().getId()
            for lock in ob.wl_lockValues():
                if not lock.isValid():
                    continue  # Skip invalid/expired locks
                creator = lock.getCreator()
                if creator and creator[1] == user_id:
                    # Found a lock for this user, so send it
                    r.append('lock-token:%s' % lock.getLockToken())
                    if REQUEST.get('borrow_lock'):
                        r.append('borrow_lock:1')
                    break

        # Apply any extra callbacks that might have been registered.
        applyCallbacks(ob, r, REQUEST, RESPONSE)

        # Finish metadata with an empty line.
        r.append('')
        metadata = join(r, '\n')
        metadata_len = len(metadata)

        # Check if we should send the file's data down the response.
        if REQUEST.get('skip_data'):
            # We've been requested to send only the metadata. The
            # client will presumably fetch the data itself.
            self._write_metadata(RESPONSE, metadata, metadata_len)
            return ''

        ob_data = getattr(aq_base(ob), 'data', None)
        if (ob_data is not None and isinstance(ob_data, Image.Pdata)):
            # We have a File instance with chunked data, lets stream it.
            #
            # Note we are setting the content-length header here. This
            # is a simplification. Read comment below.
            #
            # We assume that ob.get_size() will return the exact size
            # of the PData chain. If that assumption is broken we
            # might have problems. This is mainly an optimization. If
            # we read the whole PData chain just to compute the
            # correct size that could cause the whole file to be read
            # into memory.
            RESPONSE.setHeader('Content-Length', ob.get_size())
            # It is safe to use this PDataStreamIterator here because
            # it is consumed right below. This is only used to
            # simplify the code below so it only has to deal with
            # stream iterators or plain strings.
            body = PDataStreamIterator(ob.data)
        elif hasattr(ob, 'manage_FTPget'):
            # Calling manage_FTPget *might* have side-effects. For
            # example, in Archetypes it does set the 'content-type'
            # response header, which would end up overriding our own
            # content-type header because we've set it 'too
            # early'. We've moved setting the content-type header to
            # the '_write_metadata' method since, and any manipulation
            # of response headers should happen there, if possible.
            try:
                body = ob.manage_FTPget()
            except TypeError:  # some need the R/R pair!
                body = ob.manage_FTPget(REQUEST, RESPONSE)
        elif hasattr(ob, 'EditableBody'):
            body = ob.EditableBody()
        elif hasattr(ob, 'document_src'):
            body = ob.document_src(REQUEST, RESPONSE)
        elif hasattr(ob, 'read'):
            body = ob.read()
        else:
            # can't read it!
            raise 'BadRequest', 'Object does not support external editing'

        if (HAVE_Z3_IFACE and IStreamIterator.providedBy(body) or
            (not HAVE_Z3_IFACE) and IStreamIterator.isImplementedBy(body)):
            # We need to manage our content-length because we're streaming.
            # The content-length should have been set in the response by
            # the method that returns the iterator, but we need to fix it up
            # here because we insert metadata before the body.
            clen = RESPONSE.headers.get('content-length', None)
            assert clen is not None
            self._write_metadata(RESPONSE, metadata, metadata_len + int(clen))
            for data in body:
                RESPONSE.write(data)
            return ''

        # If we reached this point, body *must* be a string. We *must*
        # set the headers ourselves since _write_metadata won't get
        # called.
        self._set_headers(RESPONSE)
        return join((metadata, body), '\n')
示例#35
0
    setDefaultSkin(request)

    try:
        response = _publish(request, 'Zope2')
    except Unauthorized, v:
        response._unauthorized()
    except Redirect, v:
        response.redirect(v)

    # Start the WSGI server response
    status, headers = response.finalize()
    start_response(status, headers)

    body = response.body

    if isinstance(body, file) or IStreamIterator.providedBy(body):
        result = body
    else:
        # If somebody used response.write, that data will be in the
        # stdout StringIO, so we put that before the body.
        # XXX This still needs verification that it really works.
        result = (stdout.getvalue(), response.body)

    if 'repoze.tm.active' not in environ:
        request.close() # this aborts the transation!

    stdout.close()

    for callable in response.after_list:
        callable()
示例#36
0
 def setBody(self, body, title='', is_error=0, **kw):
     if IStreamIterator.providedBy(body):
         body = ''.join(body)
     Response.setBody(self, body, title, is_error, **kw)
    def getResourceContent(self, item, context, original=False, theme=None):
        """Fetch resource content for delivery."""
        
        if theme is None:
            theme = self.getCurrentSkinName()

        ids = self.concatenatedResourcesByTheme.get(theme, {}).get(item, None)
        resources = self.getResourcesDict()
        if ids is not None:
            ids = ids[:]
        output = u""
        if len(ids) > 1:
            output = output + self.merged_output_prefix

        portal = getToolByName(context, 'portal_url').getPortalObject()

        if context == self and portal is not None:
            context = portal

        default_charset = 'utf-8'

        for id in ids:
            try:
                if portal is not None:
                    obj = context.restrictedTraverse(id)
                else:
                    #Can't do anything other than attempt a getattr
                    obj = getattr(context, id)
            except (AttributeError, KeyError):
                output += u"\n/* XXX ERROR -- could not find '%s'*/\n" % id
                content = u''
                obj = None
            except Unauthorized:
                #If we're just returning a single resource, raise an Unauthorized,
                #otherwise we're merging resources in which case just log an error
                if len(ids) > 1:
                    #Object probably isn't published yet
                    output += u"\n/* XXX ERROR -- access to '%s' not authorized */\n" % id
                    content = u''
                    obj = None
                else:
                    raise

            if obj is not None:
                if isinstance(obj, z3_Resource):
                    # z3 resources
                    # XXX this is a temporary solution, we wrap the five resources
                    # into our mechanism, where it should be the other way around.
                    #
                    # First thing we must be aware of: resources give a complete
                    # response so first we must save the headers.
                    # Especially, we must delete the If-Modified-Since, because
                    # otherwise we might get a 30x response status in some cases.
                    original_headers, if_modified = self._removeCachingHeaders()
                    # Now, get the content.
                    try:
                        method = obj.__browser_default__(self.REQUEST)[1][0]
                    except AttributeError: # zope.app.publisher.browser.fileresource
                        try:
                            method = obj.browserDefault(self.REQUEST)[1][0]
                        except (AttributeError, IndexError):
                            try:
                                method = obj.browserDefault(self.REQUEST)[0].__name__
                            except AttributeError:
                                # The above can all fail if request.method is
                                # POST.  We can still at least try to use the
                                # GET method, as we prefer that anyway.
                                method = getattr(obj, 'GET').__name__
                    method = method in ('HEAD','POST') and 'GET' or method
                    content = getattr(obj, method)()
                    if not isinstance(content, unicode): 
                        contenttype = self.REQUEST.RESPONSE.headers.get('content-type', '')
                        contenttype = getCharsetFromContentType(contenttype, default_charset)
                        content = unicode(content, contenttype)
                    self._restoreCachingHeaders(original_headers, if_modified)
                elif hasattr(aq_base(obj),'meta_type') and  obj.meta_type in ['DTML Method', 'Filesystem DTML Method']:
                    content = obj(client=self.aq_parent, REQUEST=self.REQUEST,
                                  RESPONSE=self.REQUEST.RESPONSE)
                    contenttype = self.REQUEST.RESPONSE.headers.get('content-type', '')
                    contenttype = getCharsetFromContentType(contenttype, default_charset)
                    content = unicode(content, contenttype)
                elif hasattr(aq_base(obj),'meta_type') and obj.meta_type == 'Filesystem File':
                    obj._updateFromFS()
                    content = obj._readFile(0)
                    contenttype = getCharsetFromContentType(obj.content_type, default_charset)
                    content = unicode(content, contenttype)
                elif hasattr(aq_base(obj),'meta_type') and obj.meta_type in ('ATFile', 'ATBlob'):
                    f = obj.getFile()
                    contenttype = getCharsetFromContentType(f.getContentType(), default_charset)
                    content = unicode(str(f), contenttype)
                # We should add more explicit type-matching checks
                elif hasattr(aq_base(obj), 'index_html') and callable(obj.index_html):
                    original_headers, if_modified = self._removeCachingHeaders()
                    # "index_html" may use "RESPONSE.write" (e.g. for OFS.Image.Pdata)
                    tmp = StringIO()
                    response_write = self.REQUEST.RESPONSE.write
                    self.REQUEST.RESPONSE.write = tmp.write
                    try:
                        content = obj.index_html(self.REQUEST,
                                                 self.REQUEST.RESPONSE)
                    finally:
                        self.REQUEST.RESPONSE.write = response_write
                    content = tmp.getvalue() or content
                    if not isinstance(content, unicode):
                        content = unicode(content, default_charset)
                    self._restoreCachingHeaders(original_headers, if_modified)
                elif callable(obj):
                    try:
                        content = obj(self.REQUEST, self.REQUEST.RESPONSE)
                    except TypeError:
                        # Could be a view or browser resource
                        content = obj()
                    
                    if IStreamIterator.providedBy(content):
                        content = content.read()
                    
                    if not isinstance(content, unicode):
                        content = unicode(content, default_charset)
                else:
                    content = str(obj)
                    content = unicode(content, default_charset)

            # Add start/end notes to the resource for better
            # understanding and debugging
            if content:
                output += u'\n/* - %s - */\n' % (id,)
                if original:
                    output += content
                else:
                    output += self.finalizeContent(resources[id], content)
                output += u'\n'
        return output
示例#38
0
 def __call__(self):
     self.request.response.setHeader("Content-Type", "application/json")
     result = self.render()
     if IStreamIterator.providedBy(result):
         return result
     return json.dumps(result, indent=2, sort_keys=True)
示例#39
0
 def testDownloadReturnsIterator(self):
     result=self.view()
     self.failUnless(IStreamIterator.providedBy(result))
示例#40
0
    def startWSGIResponse(self, stream=False):
        if self.__started:
            return self.__write
        self.__started = True

        # If the body is an IResult, it is a case of streaming where
        # we don't fix headers.
        if IResult.providedBy(self.body):
            stream = True

        if not stream:
            # If we are not streaming, we try to set Content-Length,
            # Content-Type and adapt status if there is no content.
            content_length = None
            content_type = None

            # Inspect content-length
            if self.headers.has_key('Content-Length'):
                content_length = self.headers['Content-Length']
            else:
                if (isinstance(self.body, basestring) or
                    IStreamIterator.providedBy(self.body)):
                    body_length = len(self.body)
                    if body_length:
                        content_length = str(body_length)

            # Inspect content-type
            if self.headers.has_key('Content-Type'):
                content_type = self.headers['Content-Type']

            # Modify them
            if content_length is None:
                if content_type is None and self.status == 200:
                    # No content length and content-type switch to 204.
                    self.status = 204
                if self.status not in (100, 100, 101, 102, 204, 304):
                    content_length = '0'
            if content_length is not None:
                # If there is Content and no Content-Type, set HTML
                if content_type is None and content_length != '0':
                    content_type = 'text/html;charset={0}'.format(
                        self.default_charset)

            # Update content_length and content_type
            if content_length is not None:
                self.headers['Content-Length'] = content_length
            if content_type is not None:
                self.headers['Content-Type'] = content_type

        else:
            # Fire event before streaming
            notify(PublicationBeforeStreaming(self))

            # Fix default Content-Type
            if not self.headers.has_key('Content-Type'):
                self.headers['Content-Type'] = 'text/html;charset=%s' % (
                    self.default_charset,)

        formatted_status = "%d %s" % (
            self.status, status_reasons.get(self.status, 'OK'))
        formatted_headers = self.headers.items() + format_cookies(self.cookies)
        self.__write = self.__start_response(
            formatted_status, formatted_headers)
        return self.__write
示例#41
0
def Service__call__(self):
    self.request.response.setHeader("Content-Type", "application/json")
    result = self.render()
    if IStreamIterator.providedBy(result):
        return result
    return json.dumps(result, indent=2, sort_keys=True)
示例#42
0
    def __call__(self, client=None, REQUEST={}, RESPONSE=None, **kw):
        """Render using the given client object
        
        o If client is not passed, we are being called as a sub-template:
          don't do any error propagation.

        o If supplied, use the REQUEST mapping, Response, and key word
        arguments.
        """
        if not self._cache_namespace_keys:
            data = self.ZCacheable_get(default=_marker)
            if data is not _marker:
                if ( IStreamIterator.isImplementedBy(data) and
                     RESPONSE is not None ):
                    # This is a stream iterator and we need to set some
                    # headers now before giving it to medusa
                    if RESPONSE.headers.get('content-length', None) is None:
                        RESPONSE.setHeader('content-length', len(data))

                    if ( RESPONSE.headers.get('content-type', None) is None and
                         RESPONSE.headers.get('Content-type', None) is None ):
                        ct = ( self.__dict__.get('content_type') or
                               self.default_content_type )
                        RESPONSE.setHeader('content-type', ct)

                # Return cached results.
                return data

        __traceback_supplement__ = (PathTracebackSupplement, self)
        kw['document_id'] = self.getId()
        kw['document_title'] = self.title

        security = getSecurityManager()
        security.addContext(self)
        if self.__dict__.has_key('validate'):
            first_time_through = 0
        else:
            self.__dict__['validate'] = security.DTMLValidate
            first_time_through = 1
        try:

            if client is None:
                # Called as subtemplate, so don't need error propagation!
                r = apply(HTML.__call__, (self, client, REQUEST), kw)
                if RESPONSE is None:
                    result = r
                else:
                    result = decapitate(r, RESPONSE)
                if not self._cache_namespace_keys:
                    self.ZCacheable_set(result)
                return result

            r = apply(HTML.__call__, (self, client, REQUEST), kw)
            if type(r) is not str or RESPONSE is None:
                if not self._cache_namespace_keys:
                    self.ZCacheable_set(r)
                return r

        finally:
            security.removeContext(self)
            if first_time_through:
                del self.__dict__['validate']

        have_key = RESPONSE.headers.has_key
        if not (have_key('content-type') or have_key('Content-Type')):
            if self.__dict__.has_key('content_type'):
                c = self.content_type
            else:
                c, e = guess_content_type(self.getId(), r)
            RESPONSE.setHeader('Content-Type', c)
        result = decapitate(r, RESPONSE)
        if not self._cache_namespace_keys:
            self.ZCacheable_set(result)
        return result
示例#43
0
    setDefaultSkin(request)

    try:
        response = _publish(request, 'Zope2')
    except Unauthorized, v:
        response._unauthorized()
    except Redirect, v:
        response.redirect(v)

    # Start the WSGI server response
    status, headers = response.finalize()
    start_response(status, headers)

    body = response.body

    if isinstance(body, file) or IStreamIterator.providedBy(body):
        result = body
    else:
        # If somebody used response.write, that data will be in the
        # stdout StringIO, so we put that before the body.
        # XXX This still needs verification that it really works.
        result = (stdout.getvalue(), response.body)

    if 'repoze.tm.active' not in environ:
        request.close()  # this aborts the transation!

    stdout.close()

    for callable in response.after_list:
        callable()
示例#44
0
    def index_html(self, REQUEST, RESPONSE, path=None):
        """Publish the object to the external editor helper app"""

        security = getSecurityManager()
        if path is None:
            parent = self.aq_parent
            try:
                ob = parent[REQUEST['target']]  # Try getitem
            except KeyError:
                ob = getattr(parent, REQUEST['target'])  # Try getattr
            except AttributeError:
                # Handle objects that are methods in ZClasses
                ob = parent.propertysheets.methods[REQUEST['target']]
        else:
            ob = self.restrictedTraverse(path)

        r = []
        r.append('url:%s' % ob.absolute_url())
        r.append('meta_type:%s' % ob.meta_type)

        title = getattr(Acquisition.aq_base(ob), 'title', None)
        if title is not None:
            if callable(title):
                title = title()
            if isinstance(title, types.UnicodeType):
                title = unicode.encode(title, 'utf-8')
            r.append('title:%s' % title)

        if hasattr(Acquisition.aq_base(ob), 'content_type'):
            if callable(ob.content_type):
                r.append('content_type:%s' % ob.content_type())
            else:
                r.append('content_type:%s' % ob.content_type)

        if REQUEST._auth:
            if REQUEST._auth[-1] == '\n':
                auth = REQUEST._auth[:-1]
            else:
                auth = REQUEST._auth

            r.append('auth:%s' % auth)

        r.append('cookie:%s' % REQUEST.environ.get('HTTP_COOKIE', ''))

        if wl_isLocked(ob):
            # Object is locked, send down the lock token
            # owned by this user (if any)
            user_id = security.getUser().getId()
            for lock in ob.wl_lockValues():
                if not lock.isValid():
                    continue  # Skip invalid/expired locks
                creator = lock.getCreator()
                if creator and creator[1] == user_id:
                    # Found a lock for this user, so send it
                    r.append('lock-token:%s' % lock.getLockToken())
                    if REQUEST.get('borrow_lock'):
                        r.append('borrow_lock:1')
                    break

        r.append('')
        streamiterator = None

        # Using RESPONSE.setHeader('Pragma', 'no-cache') would be better, but
        # this chokes crappy most MSIE versions when downloads happen on SSL.
        # cf. http://support.microsoft.com/support/kb/articles/q316/4/31.asp
        RESPONSE.setHeader('Last-Modified', rfc1123_date())

        if hasattr(Acquisition.aq_base(ob), 'data') \
           and hasattr(ob.data, '__class__') \
           and ob.data.__class__ is Image.Pdata:
            # We have a File instance with chunked data, lets stream it
            metadata = join(r, '\n')
            RESPONSE.setHeader('Content-Type', 'application/x-zope-edit')
            RESPONSE.setHeader('Content-Length',
                               len(metadata) + ob.get_size() + 1)
            RESPONSE.write(metadata)
            RESPONSE.write('\n')
            data = ob.data
            while data is not None:
                RESPONSE.write(data.data)
                data = data.next
            return ''
        if hasattr(ob, 'manage_FTPget'):
            try:
                body = ob.manage_FTPget()
            except TypeError:  # some need the R/R pair!
                body = ob.manage_FTPget(REQUEST, RESPONSE)
        elif hasattr(ob, 'EditableBody'):
            body = ob.EditableBody()
        elif hasattr(ob, 'document_src'):
            body = ob.document_src(REQUEST, RESPONSE)
        elif hasattr(ob, 'read'):
            body = ob.read()
        else:
            # can't read it!
            raise 'BadRequest', 'Object does not support external editing'

        RESPONSE.setHeader('Content-Type', 'application/x-zope-edit')

        if (IStreamIterator is not None
                and IStreamIterator.isImplementedBy(body)):
            # We need to manage our content-length because we're streaming.
            # The content-length should have been set in the response by
            # the method that returns the iterator, but we need to fix it up
            # here because we insert metadata before the body.
            clen = RESPONSE.headers.get('content-length', None)
            assert clen is not None
            metadata = join(r, '\n')
            RESPONSE.setHeader('Content-Length', len(metadata) + int(clen) + 1)
            RESPONSE.write(metadata)
            RESPONSE.write('\n')
            for data in body:
                RESPONSE.write(data)
        else:
            r.append(body)
            return join(r, '\n')
    def getResourceContent(self, item, context, original=False, theme=None):
        """Fetch resource content for delivery."""

        if theme is None:
            theme = self.getCurrentSkinName()

        ids = self.concatenatedResourcesByTheme.get(theme, {}).get(item, None)
        resources = self.getResourcesDict()
        if ids is not None:
            ids = ids[:]
        output = u""
        if len(ids) > 1:
            output = output + self.merged_output_prefix

        portal = getToolByName(context, 'portal_url').getPortalObject()

        if context == self and portal is not None:
            context = portal

        default_charset = 'utf-8'

        for id in ids:
            try:
                if portal is not None:
                    obj = context.restrictedTraverse(id)
                else:
                    #Can't do anything other than attempt a getattr
                    obj = getattr(context, id)
            except (AttributeError, KeyError):
                output += u"\n/* XXX ERROR -- could not find '%s'*/\n" % id
                content = u''
                obj = None
            except Unauthorized:
                #If we're just returning a single resource, raise an Unauthorized,
                #otherwise we're merging resources in which case just log an error
                if len(ids) > 1:
                    #Object probably isn't published yet
                    output += u"\n/* XXX ERROR -- access to '%s' not authorized */\n" % id
                    content = u''
                    obj = None
                else:
                    raise

            if obj is not None:
                if isinstance(obj, z3_Resource):
                    # z3 resources
                    # XXX this is a temporary solution, we wrap the five resources
                    # into our mechanism, where it should be the other way around.
                    #
                    # First thing we must be aware of: resources give a complete
                    # response so first we must save the headers.
                    # Especially, we must delete the If-Modified-Since, because
                    # otherwise we might get a 30x response status in some cases.
                    original_headers, if_modified = self._removeCachingHeaders(
                    )
                    # Now, get the content.
                    try:
                        method = obj.__browser_default__(self.REQUEST)[1][0]
                    except AttributeError:  # zope.app.publisher.browser.fileresource
                        try:
                            method = obj.browserDefault(self.REQUEST)[1][0]
                        except (AttributeError, IndexError):
                            try:
                                method = obj.browserDefault(
                                    self.REQUEST)[0].__name__
                            except AttributeError:
                                # The above can all fail if request.method is
                                # POST.  We can still at least try to use the
                                # GET method, as we prefer that anyway.
                                method = getattr(obj, 'GET').__name__
                    method = method in ('HEAD', 'POST') and 'GET' or method
                    content = getattr(obj, method)()
                    if not isinstance(content, unicode):
                        contenttype = self.REQUEST.RESPONSE.headers.get(
                            'content-type', '')
                        contenttype = getCharsetFromContentType(
                            contenttype, default_charset)
                        content = unicode(content, contenttype)
                    self._restoreCachingHeaders(original_headers, if_modified)
                elif hasattr(aq_base(obj), 'meta_type') and obj.meta_type in [
                        'DTML Method', 'Filesystem DTML Method'
                ]:
                    content = obj(client=self.aq_parent,
                                  REQUEST=self.REQUEST,
                                  RESPONSE=self.REQUEST.RESPONSE)
                    contenttype = self.REQUEST.RESPONSE.headers.get(
                        'content-type', '')
                    contenttype = getCharsetFromContentType(
                        contenttype, default_charset)
                    content = unicode(content, contenttype)
                elif hasattr(
                        aq_base(obj),
                        'meta_type') and obj.meta_type == 'Filesystem File':
                    obj._updateFromFS()
                    content = obj._readFile(0)
                    contenttype = getCharsetFromContentType(
                        obj.content_type, default_charset)
                    content = unicode(content, contenttype)
                elif hasattr(
                        aq_base(obj),
                        'meta_type') and obj.meta_type in ('ATFile', 'ATBlob'):
                    f = obj.getFile()
                    contenttype = getCharsetFromContentType(
                        f.getContentType(), default_charset)
                    content = unicode(str(f), contenttype)
                # We should add more explicit type-matching checks
                elif hasattr(aq_base(obj), 'index_html') and callable(
                        obj.index_html):
                    original_headers, if_modified = self._removeCachingHeaders(
                    )
                    # "index_html" may use "RESPONSE.write" (e.g. for OFS.Image.Pdata)
                    tmp = StringIO()
                    response_write = self.REQUEST.RESPONSE.write
                    self.REQUEST.RESPONSE.write = tmp.write
                    try:
                        content = obj.index_html(self.REQUEST,
                                                 self.REQUEST.RESPONSE)
                    finally:
                        self.REQUEST.RESPONSE.write = response_write
                    content = tmp.getvalue() or content
                    if not isinstance(content, unicode):
                        content = unicode(content, default_charset)
                    self._restoreCachingHeaders(original_headers, if_modified)
                elif callable(obj):
                    try:
                        content = obj(self.REQUEST, self.REQUEST.RESPONSE)
                    except TypeError:
                        # Could be a view or browser resource
                        content = obj()

                    if IStreamIterator.providedBy(content):
                        content = content.read()

                    if not isinstance(content, unicode):
                        content = unicode(content, default_charset)
                else:
                    content = str(obj)
                    content = unicode(content, default_charset)

            # Add start/end notes to the resource for better
            # understanding and debugging
            if content:
                output += u'\n/* - %s - */\n' % (id, )
                if original:
                    output += content
                else:
                    output += self.finalizeContent(resources[id], content)
                output += u'\n'
        return output
示例#46
0
    def index_html(self, REQUEST, RESPONSE, path=None):
        """Publish the object to the external editor helper app"""
        
        security = getSecurityManager()
        if path is None:
            parent = self.aq_parent
            try:
                ob = parent[REQUEST['target']] # Try getitem
            except KeyError:
                ob = getattr(parent, REQUEST['target']) # Try getattr
            except AttributeError:
                # Handle objects that are methods in ZClasses
                ob = parent.propertysheets.methods[REQUEST['target']]
        else:
            ob = self.restrictedTraverse( path )
        
        r = []
        r.append('url:%s' % ob.absolute_url())
        r.append('meta_type:%s' % ob.meta_type)
        
        if hasattr(Acquisition.aq_base(ob), 'content_type'):
            if callable(ob.content_type):
                r.append('content_type:%s' % ob.content_type())
            else:
                r.append('content_type:%s' % ob.content_type)
                
        if REQUEST._auth:
            if REQUEST._auth[-1] == '\n':
                auth = REQUEST._auth[:-1]
            else:
                auth = REQUEST._auth
                
            r.append('auth:%s' % auth)
            
        r.append('cookie:%s' % REQUEST.environ.get('HTTP_COOKIE',''))
        
        if wl_isLocked(ob):
            # Object is locked, send down the lock token 
            # owned by this user (if any)
            user_id = security.getUser().getId()
            for lock in ob.wl_lockValues():
                if not lock.isValid():
                    continue # Skip invalid/expired locks
                creator = lock.getCreator()
                if creator and creator[1] == user_id:
                    # Found a lock for this user, so send it
                    r.append('lock-token:%s' % lock.getLockToken())
                    if REQUEST.get('borrow_lock'):
                        r.append('borrow_lock:1')
                    break       
              
        r.append('')
        streamiterator = None
        
        # Using RESPONSE.setHeader('Pragma', 'no-cache') would be better, but
        # this chokes crappy most MSIE versions when downloads happen on SSL.
        # cf. http://support.microsoft.com/support/kb/articles/q316/4/31.asp
        RESPONSE.setHeader('Last-Modified', rfc1123_date())
        
        if hasattr(Acquisition.aq_base(ob), 'data') \
           and hasattr(ob.data, '__class__') \
           and ob.data.__class__ is Image.Pdata:
            # We have a File instance with chunked data, lets stream it
            metadata = join(r, '\n')
            RESPONSE.setHeader('Content-Type', 'application/x-zope-edit')
            RESPONSE.setHeader('Content-Length', 
                               len(metadata) + ob.get_size() + 1)
            RESPONSE.write(metadata)
            RESPONSE.write('\n')
            data = ob.data
            while data is not None:
                RESPONSE.write(data.data)
                data = data.next         
            return ''
        if hasattr(ob, 'manage_FTPget'):
            try:
                body = ob.manage_FTPget()
            except TypeError: # some need the R/R pair!
                body = ob.manage_FTPget(REQUEST, RESPONSE)
        elif hasattr(ob, 'EditableBody'):
            body = ob.EditableBody()
        elif hasattr(ob, 'document_src'):
            body = ob.document_src(REQUEST, RESPONSE)
        elif hasattr(ob, 'read'):
            body = ob.read()
        else:
            # can't read it!
            raise 'BadRequest', 'Object does not support external editing'
        
        RESPONSE.setHeader('Content-Type', 'application/x-zope-edit')

        if (IStreamIterator is not None and
            IStreamIterator.isImplementedBy(body)):
            # We need to manage our content-length because we're streaming.
            # The content-length should have been set in the response by
            # the method that returns the iterator, but we need to fix it up
            # here because we insert metadata before the body.
            clen = RESPONSE.headers.get('content-length', None)
            assert clen is not None
            metadata = join(r, '\n')
            RESPONSE.setHeader('Content-Length', len(metadata) + int(clen) + 1)
            RESPONSE.write(metadata)
            RESPONSE.write('\n')
            for data in body:
                RESPONSE.write(data)
        else:
            r.append(body)
            return join(r, '\n')
 def testDownloadReturnsIterator(self):
     result=self.view()
     self.failUnless(IStreamIterator.providedBy(result))
    def index_html(self, REQUEST, RESPONSE, path=None):
        """Publish the object to the external editor helper app"""

        security = getSecurityManager()
        if path is None:
            parent = self.aq_parent
            try:
                ob = parent[REQUEST['target']]  # Try getitem
            except KeyError:
                ob = getattr(parent, REQUEST['target'])  # Try getattr
            except AttributeError:
                # Handle objects that are methods in ZClasses
                ob = parent.propertysheets.methods[REQUEST['target']]
        else:
            ob = self.restrictedTraverse(path)

        r = []
        r.append('url:%s' % ob.absolute_url())
        r.append('meta_type:%s' % ob.meta_type)

        title = getattr(aq_base(ob), 'title', None)
        if title is not None:
            if callable(title):
                title = title()
            if isinstance(title, types.UnicodeType):
                title = unicode.encode(title, 'utf-8')
            r.append('title:%s' % title)

        if hasattr(aq_base(ob), 'content_type'):
            if callable(ob.content_type):
                r.append('content_type:%s' % ob.content_type())
            else:
                r.append('content_type:%s' % ob.content_type)

        if REQUEST._auth:
            if REQUEST._auth[-1] == '\n':
                auth = REQUEST._auth[:-1]
            else:
                auth = REQUEST._auth

            r.append('auth:%s' % auth)

        r.append('cookie:%s' % REQUEST.environ.get('HTTP_COOKIE', ''))

        if wl_isLocked(ob):
            # Object is locked, send down the lock token
            # owned by this user (if any)
            user_id = security.getUser().getId()
            for lock in ob.wl_lockValues():
                if not lock.isValid():
                    continue  # Skip invalid/expired locks
                creator = lock.getCreator()
                if creator and creator[1] == user_id:
                    # Found a lock for this user, so send it
                    r.append('lock-token:%s' % lock.getLockToken())
                    if REQUEST.get('borrow_lock'):
                        r.append('borrow_lock:1')
                    break

        # Apply any extra callbacks that might have been registered.
        applyCallbacks(ob, r, REQUEST, RESPONSE)

        # Finish metadata with an empty line.
        r.append('')
        metadata = join(r, '\n')
        metadata_len = len(metadata)

        # Check if we should send the file's data down the response.
        if REQUEST.get('skip_data'):
            # We've been requested to send only the metadata. The
            # client will presumably fetch the data itself.
            self._write_metadata(RESPONSE, metadata, metadata_len)
            return ''

        ob_data = getattr(aq_base(ob), 'data', None)
        if (ob_data is not None and isinstance(ob_data, Image.Pdata)):
            # We have a File instance with chunked data, lets stream it.
            #
            # Note we are setting the content-length header here. This
            # is a simplification. Read comment below.
            #
            # We assume that ob.get_size() will return the exact size
            # of the PData chain. If that assumption is broken we
            # might have problems. This is mainly an optimization. If
            # we read the whole PData chain just to compute the
            # correct size that could cause the whole file to be read
            # into memory.
            RESPONSE.setHeader('Content-Length', ob.get_size())
            # It is safe to use this PDataStreamIterator here because
            # it is consumed right below. This is only used to
            # simplify the code below so it only has to deal with
            # stream iterators or plain strings.
            body = PDataStreamIterator(ob.data)
        elif hasattr(ob, 'manage_FTPget'):
            # Calling manage_FTPget *might* have side-effects. For
            # example, in Archetypes it does set the 'content-type'
            # response header, which would end up overriding our own
            # content-type header because we've set it 'too
            # early'. We've moved setting the content-type header to
            # the '_write_metadata' method since, and any manipulation
            # of response headers should happen there, if possible.
            try:
                body = ob.manage_FTPget()
            except TypeError:  # some need the R/R pair!
                body = ob.manage_FTPget(REQUEST, RESPONSE)
        elif hasattr(ob, 'EditableBody'):
            body = ob.EditableBody()
        elif hasattr(ob, 'document_src'):
            body = ob.document_src(REQUEST, RESPONSE)
        elif hasattr(ob, 'read'):
            body = ob.read()
        else:
            # can't read it!
            raise 'BadRequest', 'Object does not support external editing'

        if (HAVE_Z3_IFACE and IStreamIterator.providedBy(body) or
                (not HAVE_Z3_IFACE) and IStreamIterator.isImplementedBy(body)):
            # We need to manage our content-length because we're streaming.
            # The content-length should have been set in the response by
            # the method that returns the iterator, but we need to fix it up
            # here because we insert metadata before the body.
            clen = RESPONSE.headers.get('content-length', None)
            assert clen is not None
            self._write_metadata(RESPONSE, metadata, metadata_len + int(clen))
            for data in body:
                RESPONSE.write(data)
            return ''

        # If we reached this point, body *must* be a string. We *must*
        # set the headers ourselves since _write_metadata won't get
        # called.
        self._set_headers(RESPONSE)
        return join((metadata, body), '\n')
示例#49
0
    def __call__(self, client=None, REQUEST={}, RESPONSE=None, **kw):
        """Render using the given client object

        o If client is not passed, we are being called as a sub-template:
          don't do any error propagation.

        o If supplied, use the REQUEST mapping, Response, and key word
        arguments.
        """
        if not self._cache_namespace_keys:
            data = self.ZCacheable_get(default=_marker)
            if data is not _marker:
                if IStreamIterator.isImplementedBy(data) and \
                   RESPONSE is not None:
                    # This is a stream iterator and we need to set some
                    # headers now before giving it to medusa
                    headers_get = RESPONSE.headers.get

                    if headers_get('content-length', None) is None:
                        RESPONSE.setHeader('content-length', len(data))

                    if headers_get('content-type', None) is None and \
                       headers_get('Content-type', None) is None:
                        ct = (self.__dict__.get('content_type')
                              or self.default_content_type)
                        RESPONSE.setHeader('content-type', ct)

                # Return cached results.
                return data

        __traceback_supplement__ = (PathTracebackSupplement, self)
        kw['document_id'] = self.getId()
        kw['document_title'] = self.title

        security = getSecurityManager()
        security.addContext(self)
        if 'validate' in self.__dict__:
            first_time_through = 0
        else:
            self.__dict__['validate'] = security.DTMLValidate
            first_time_through = 1
        try:

            if client is None:
                # Called as subtemplate, so don't need error propagation!
                r = HTML.__call__(self, client, REQUEST, **kw)
                if RESPONSE is None:
                    result = r
                else:
                    result = decapitate(r, RESPONSE)
                if not self._cache_namespace_keys:
                    self.ZCacheable_set(result)
                return result

            r = HTML.__call__(self, client, REQUEST, **kw)

            if RESPONSE is None or not isinstance(r, str):
                if not self._cache_namespace_keys:
                    self.ZCacheable_set(r)
                return r

        finally:
            security.removeContext(self)
            if first_time_through:
                del self.__dict__['validate']

        have_key = RESPONSE.headers.__contains__
        if not (have_key('content-type') or have_key('Content-Type')):
            if 'content_type' in self.__dict__:
                c = self.content_type
            else:
                encoding = getattr(self, 'encoding', default_encoding)
                c, e = guess_content_type(self.getId(), r.encode(encoding))
            RESPONSE.setHeader('Content-Type', c)
        result = decapitate(r, RESPONSE)
        if not self._cache_namespace_keys:
            self.ZCacheable_set(result)
        return result
示例#50
0
    def __call__(self, client=None, REQUEST={}, RESPONSE=None, **kw):
        """Render the document given a client object, REQUEST mapping,
        Response, and key word arguments."""

        if not self._cache_namespace_keys:
            data = self.ZCacheable_get(default=_marker)
            if data is not _marker:
                if (IStreamIterator.isImplementedBy(data)
                        and RESPONSE is not None):
                    # This is a stream iterator and we need to set some
                    # headers now before giving it to medusa
                    if RESPONSE.headers.get('content-length', None) is None:
                        RESPONSE.setHeader('content-length', len(data))

                    if (RESPONSE.headers.get('content-type', None) is None
                            and RESPONSE.headers.get('Content-type',
                                                     None) is None):
                        ct = (self.__dict__.get('content_type')
                              or self.default_content_type)
                        RESPONSE.setHeader('content-type', ct)

                # Return cached results.
                return data

        __traceback_supplement__ = (PathTracebackSupplement, self)
        kw['document_id'] = self.getId()
        kw['document_title'] = self.title

        security = getSecurityManager()
        security.addContext(self)
        if self.__dict__.has_key('validate'):
            first_time_through = 0
        else:
            self.__dict__['validate'] = security.DTMLValidate
            first_time_through = 1
        try:

            if client is None:
                # Called as subtemplate, so don't need error propagation!
                r = apply(HTML.__call__, (self, client, REQUEST), kw)
                if RESPONSE is None: result = r
                else: result = decapitate(r, RESPONSE)
                if not self._cache_namespace_keys:
                    self.ZCacheable_set(result)
                return result

            r = apply(HTML.__call__, (self, client, REQUEST), kw)
            if type(r) is not type('') or RESPONSE is None:
                if not self._cache_namespace_keys:
                    self.ZCacheable_set(r)
                return r

        finally:
            security.removeContext(self)
            if first_time_through:
                del self.__dict__['validate']

        have_key = RESPONSE.headers.has_key
        if not (have_key('content-type') or have_key('Content-Type')):
            if self.__dict__.has_key('content_type'):
                c = self.content_type
            else:
                c, e = guess_content_type(self.getId(), r)
            RESPONSE.setHeader('Content-Type', c)
        result = decapitate(r, RESPONSE)
        if not self._cache_namespace_keys:
            self.ZCacheable_set(result)
        return result