Beispiel #1
0
 def retrieveFileStreamIterator(self, filename, REQUEST=None):
     threshold = 2 << 16  # 128 kb
     local_filename = self.targetFile(filename)
     try:
         fsize = os.path.getsize(local_filename)
     except:
         fsize = 0
         raise NotFound
     if fsize < threshold or REQUEST.RESPONSE is None:
         try:
             f = open(local_filename, 'rb')
             data = f.read()
         finally:
             f.close()
     else:
         data = filestream_iterator(local_filename, 'rb')
     try:
         mt, enc = standard.guess_content_type(local_filename, data)
     except:
         mt, enc = 'content/unknown', ''
     # Remove timestamp from filename.
     filename = filename[:filename.rfind('_')] + filename[filename.rfind('.'
                                                                         ):]
     standard.set_response_headers(filename, mt, fsize, REQUEST)
     return data
Beispiel #2
0
    def __call__(self, REQUEST=None, **kw):
        """"""
        if REQUEST is not None and 'path_to_handle' in REQUEST:
            REQUEST['path_to_handle'] = []
            RESPONSE = REQUEST.RESPONSE
            parent = self.aq_parent

            access = parent.hasAccess(REQUEST) or parent.getConfProperty(
                'ZMS.blobfields.grant_public_access', 0) == 1
            # Hook for custom access rules: return True/False, return 404 (Forbidden) if you want to perform redirect
            if access:
                # @deprecated
                # @TODO log deprecation warning
                try:
                    name = 'hasCustomAccess'
                    if hasattr(parent, name):
                        v = zopeutil.callObject(getattr(parent, name), parent)
                        if type(v) is bool:
                            access = access and v
                        elif type(v) is int and v == 404:
                            return ''
                except:
                    standard.writeError(parent, '[__call__]: can\'t %s' % name)
            # Raise unauthorized error.
            else:
                RESPONSE.setHeader('Expires', '-1')
                RESPONSE.setHeader('Cache-Control', 'no-cache')
                RESPONSE.setHeader('Pragma', 'no-cache')
                raise zExceptions.Unauthorized

            # Set custom response-headers:
            # - explicit Last-Modified
            # - explicit Content-Disposition and Content-Type
            # - addtional Content-Disposition via ZMS_ADDITIONAL_CONTENT_DISPOSITION
            try:
                name = 'getCustomBlobResponseHeaders'
                if hasattr(parent, name):
                    zopeutil.callObject(getattr(parent, name), parent)
            except:
                standard.writeError(parent, '[__call__]: can\'t %s' % name)

            if not RESPONSE.getHeader(
                    'Last-Modified'
            ) and self._if_modified_since_request_handler(REQUEST, RESPONSE):
                # we were able to handle this by returning a 304 (not modified)
                # unfortunately, because the HTTP cache manager uses the cache
                # API, and because 304 (not modified) responses are required to carry the Expires
                # header for HTTP/1.1, we need to call ZCacheable_set here.
                # This is nonsensical for caches other than the HTTP cache manager
                # unfortunately.
                self.ZCacheable_set(None)
                return ''

            if isinstance(self, MyImage) and self._range_request_handler(
                    REQUEST, RESPONSE):
                # we served a chunk of content in response to a range request.
                return ''

            # If blob-object came from call of py-attribute by path-handler check content-disposition and content-type.
            if not (RESPONSE.getHeader('Content-Disposition')
                    and RESPONSE.getHeader('Content-Type')):
                standard.set_response_headers(self.getFilename(),
                                              self.getContentType(),
                                              self.get_size(), REQUEST)
            if not (RESPONSE.getHeader('Last-Modified')):
                RESPONSE.setHeader('Last-Modified',
                                   rfc1123_date(parent._p_mtime))

            # Cacheable.
            cacheable = not REQUEST.get('preview') == 'preview'
            if cacheable:
                cacheable = parent.hasPublicAccess()
            if not cacheable:
                RESPONSE.setHeader('Expires', '-1')
                RESPONSE.setHeader('Cache-Control', 'no-cache')
                # IE6 SSL Download bug:
                # http://support.microsoft.com/kb/812935/en-us
                # http://support.microsoft.com/kb/323308/en-us
                if not REQUEST.get('URL', '').startswith('https://'):
                    RESPONSE.setHeader('Pragma', 'no-cache')

            if self.ZCacheable_isCachingEnabled():
                result = self.ZCacheable_get(default=None)
                if result is not None:
                    # We will always get None from RAMCacheManager and HTTP
                    # Accelerated Cache Manager but we will get
                    # something implementing the IStreamIterator interface
                    # from a "FileCacheManager"
                    return result

            self.ZCacheable_set(None)

            mediadb = parent.getMediaDb()
            if mediadb is not None:
                mediadbfile = self.getMediadbfile()
                if mediadbfile is not None:
                    return mediadb.retrieveFileStreamIterator(
                        mediadbfile, REQUEST)

            RESPONSE.setBase(None)
            return self.getData()

        return self