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()
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)
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 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, 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 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 __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!")
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!")
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 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 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()
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 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 __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
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')
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')
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
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