Ejemplo n.º 1
0
def http_response_with_file(request, response, data_file, content_type,
                            file_size, file_mtime):
    # HTTP If-Modified-Since header handling.
    header=request.get_header('If-Modified-Since', None)
    if header is not None:
        header=string.split(header, ';')[0]
        # Some proxies seem to send invalid date strings for this
        # header. If the date string is not valid, we ignore it
        # rather than raise an error to be generally consistent
        # with common servers such as Apache (which can usually
        # understand the screwy date string as a lucky side effect
        # of the way they parse it).
        # This happens to be what RFC2616 tells us to do in the face of an
        # invalid date.
        try:    mod_since=long(DateTime(header).timeTime())
        except: mod_since=None
        if mod_since is not None:
            last_mod = long(file_mtime)
            if last_mod > 0 and last_mod <= mod_since:
                # Set header values since apache caching will return Content-Length
                # of 0 in response if size is not set here
                response.setHeader('Last-Modified', rfc1123_date(file_mtime))
                response.setHeader('Content-Type', content_type)
                response.setHeader('Content-Length', file_size)
                response.setStatus(304)
                return

    response.setHeader('Last-Modified', rfc1123_date(file_mtime))
    response.setHeader('Content-Type', content_type)
    response.setHeader('Content-Length', file_size)

    for chunk in iter_file_data(data_file):
        response.write(chunk)
Ejemplo n.º 2
0
 def test_handle_if_modified_since_requests(self):
     self.layer['request'].environ.update({
         'HTTP_IF_MODIFIED_SINCE': rfc1123_date(self.context._p_mtime+1)
     })
     self.index_html()
     response = self.layer['request'].RESPONSE
     self.assertEqual(304, response.getStatus())
Ejemplo n.º 3
0
    def render_attachment_preview(self, attachment):
        sm = getSecurityManager()
        if not sm.checkPermission(permissions.View, self.context):
            raise Unauthorized

        r = self.request.response
        settings = Settings(attachment)

        if self.preview_type not in ("large", "normal", "small"):
            self.preview_type = "small"
        if self.page is None:
            self.page = 1
        filepath = u"%s/dump_%s.%s" % (self.preview_type, self.page, settings.pdf_image_format)
        blob = settings.blob_files[filepath]
        blobfi = openBlob(blob)
        length = os.fstat(blobfi.fileno()).st_size
        blobfi.close()
        ext = os.path.splitext(os.path.normcase(filepath))[1][1:]
        if ext == "txt":
            ct = "text/plain"
        else:
            ct = "image/%s" % ext

        r.setHeader("Content-Type", ct)
        r.setHeader("Last-Modified", rfc1123_date(self.context._p_mtime))
        r.setHeader("Accept-Ranges", "bytes")
        r.setHeader("Content-Length", length)
        request_range = handleRequestRange(self.context, length, self.request, self.request.response)
        return BlobStreamIterator(blob, **request_range)
Ejemplo n.º 4
0
    def HEAD(self, REQUEST, RESPONSE):
        """Retrieve resource information without a response body."""
        self.dav__init(REQUEST, RESPONSE)

        content_type=None
        if hasattr(self, 'content_type'):
            content_type=absattr(self.content_type)
        if content_type is None:
            url=urlfix(REQUEST['URL'], 'HEAD')
            name=unquote(filter(None, url.split( '/')[-1]))
            content_type, encoding=mimetypes.guess_type(name)
        if content_type is None:
            if hasattr(self, 'default_content_type'):
                content_type=absattr(self.default_content_type)
        if content_type is None:
            content_type = 'application/octet-stream'
        RESPONSE.setHeader('Content-Type', content_type.lower())

        if hasattr(aq_base(self), 'get_size'):
            RESPONSE.setHeader('Content-Length', absattr(self.get_size))
        if hasattr(self, '_p_mtime'):
            mtime=rfc1123_date(self._p_mtime)
            RESPONSE.setHeader('Last-Modified', mtime)
        if hasattr(aq_base(self), 'http__etag'):
            etag = self.http__etag(readonly=1)
            if etag:
                RESPONSE.setHeader('Etag', etag)
        RESPONSE.setStatus(200)
        return RESPONSE
Ejemplo n.º 5
0
    def test_index_html( self ):

        path, ref = self._extractFile()

        import os
        from webdav.common import rfc1123_date

        mod_time = os.stat( path )[ 8 ]

        file = self._makeOne( 'test_file', 'test_file.swf' )
        file = file.__of__( self.root )

        data = file.index_html( self.REQUEST, self.RESPONSE )

        self.assertEqual( len( data ), len( ref ) )
        self.assertEqual( data, ref )
        # ICK!  'HTTPResponse.getHeader' doesn't case-flatten the key!
        # for Zope versions before 2.6.1: Content-Length has to be stringified
        self.assertEqual( str( self.RESPONSE.getHeader(
                                  'Content-Length'.lower() ) )
                        , str(len(ref)) )
        self.assertEqual( self.RESPONSE.getHeader( 'Content-Type'.lower() )
                        , 'application/octet-stream' )
        self.assertEqual( self.RESPONSE.getHeader( 'Last-Modified'.lower() )
                        , rfc1123_date( mod_time ) )
Ejemplo n.º 6
0
    def index_html(self, REQUEST=None, RESPONSE=None, charset='utf-8', disposition='inline'):
        """ make it directly viewable when entering the objects URL """

        if REQUEST is None:
            REQUEST = self.REQUEST

        if RESPONSE is None:
            RESPONSE = REQUEST.RESPONSE

        RESPONSE.setHeader('Last-Modified', rfc1123_date(self._p_mtime))
        RESPONSE.setHeader('Content-Type', self.getContentType())
        RESPONSE.setHeader('Accept-Ranges', 'bytes')

        if handleIfModifiedSince(self, REQUEST, RESPONSE):
            return ''

        length = self.get_size()
        RESPONSE.setHeader('Content-Length', length)

        filename = self.getFilename()
        if filename is not None:
            if not isinstance(filename, unicode):
                filename = unicode(filename, charset)
            filename = IUserPreferredFileNameNormalizer(REQUEST).normalize(
                filename)
            header_value = contentDispositionHeader(
                disposition=disposition,
                filename=filename)
            RESPONSE.setHeader("Content-disposition", header_value)

        request_range = handleRequestRange(self, length, REQUEST, RESPONSE)
        return self.getIterator(**request_range)
Ejemplo n.º 7
0
    def get_logo(self, disposition='inline', headers=True):
        portal = getToolByName(self.context, 'portal_url').getPortalObject()
        customstyles_util = CustomStylesUtility(portal)
        customstyles = customstyles_util.annotations.get(
            'customstyles', OOBTree(DEFAULT_STYLES))

        REQUEST = self.request
        RESPONSE = REQUEST.RESPONSE
        blob = LOGO_KEY in customstyles and customstyles[LOGO_RIGHT_KEY] or None
        if not blob:
            return ''
        length = blob.get_size()
        if headers:
            RESPONSE.setHeader('Last-Modified',
                               rfc1123_date(self.context._p_mtime))
            RESPONSE.setHeader('Content-Type', blob.getContentType())
            RESPONSE.setHeader('Accept-Ranges', 'bytes')

            if handleIfModifiedSince(self.context, REQUEST, RESPONSE):
                return ''
            RESPONSE.setHeader('Content-Length', length)
            filename = blob.getFilename()
            if filename is not None:
                filename = IUserPreferredFileNameNormalizer(REQUEST).normalize(
                    unicode(filename, self.context.getCharset()))
                header_value = contentDispositionHeader(
                    disposition=disposition,
                    filename=filename)
                RESPONSE.setHeader("Content-disposition", header_value)

        range = handleRequestRange(self.context, length, REQUEST, RESPONSE)

        return blob.getIterator(**range)
Ejemplo n.º 8
0
def index_html(self, instance, REQUEST=None, RESPONSE=None, disposition='inline'):
    """ make it directly viewable when entering the objects URL """
    if REQUEST is None:
        REQUEST = instance.REQUEST
    if RESPONSE is None:
        RESPONSE = REQUEST.RESPONSE
    blob = self.getUnwrapped(instance, raw=True)    # TODO: why 'raw'?
    RESPONSE.setHeader('Last-Modified', rfc1123_date(instance._p_mtime))
    RESPONSE.setHeader('Content-Type', self.getContentType(instance))
    # The only change is to comment out this header:
    #RESPONSE.setHeader('Accept-Ranges', 'bytes')
    if handleIfModifiedSince(instance, REQUEST, RESPONSE):
        return ''
    length = blob.get_size()
    RESPONSE.setHeader('Content-Length', length)
    filename = self.getFilename(instance)
    if filename is not None:
        filename = IUserPreferredFileNameNormalizer(REQUEST).normalize(
            unicode(filename, instance.getCharset()))
        header_value = contentDispositionHeader(
            disposition=disposition,
            filename=filename)
        RESPONSE.setHeader("Content-disposition", header_value)
    range = handleRequestRange(instance, length, REQUEST, RESPONSE)
    return blob.getIterator(**range)
Ejemplo n.º 9
0
    def test_index_html( self ):

        path, ref = self._extractFile()

        import os
        from webdav.common import rfc1123_date

        mod_time = os.stat( path )[ 8 ]

        image = self._makeOne( 'test_image', 'test_image.gif' )
        image = image.__of__( self.root )

        data = image.index_html( self.REQUEST, self.RESPONSE )

        self.assertEqual( len( data ), len( ref ) )
        self.assertEqual( data, ref )
        #
        #   ICK!  'HTTPResponse.getHeader' doesn't case-flatten the key!
        #
        self.assertEqual( self.RESPONSE.getHeader( 'Content-Length'.lower() )
                        , str( len( ref ) ) )
        self.assertEqual( self.RESPONSE.getHeader( 'Content-Type'.lower() )
                        , 'image/gif' )
        self.assertEqual( self.RESPONSE.getHeader( 'Last-Modified'.lower() )
                        , rfc1123_date( mod_time ) )
Ejemplo n.º 10
0
 def test304ResponseSetsCache(self):
     response = self.publish(self.file_path,
                             env={'HTTP_IF_MODIFIED_SINCE': rfc1123_date(DateTime()+7)},
                             basic=user_auth)
     self.assertEqual(response.getStatus(), 304)
     self.assertEqual(self.cache.data, None)
     self.assertEqual(self.cache.called, ['set'])
Ejemplo n.º 11
0
    def test_index_html_200_with_cpm( self ):
        # should behave the same as without cpm installed
        from Products.CMFCore.tests.base.dummy import DummyCachingManager
        self.root.caching_policy_manager = DummyCachingManager()
        path, ref = self._extractFile('test_file.swf')

        import os
        from webdav.common import rfc1123_date
        
        file = self._makeOne( 'test_file', 'test_file.swf' )
        file = file.__of__( self.root )

        mod_time = os.stat( path )[ 8 ]

        data = file.index_html( self.REQUEST, self.RESPONSE )

        self.assertEqual( len( data ), len( ref ) )
        self.assertEqual( data, ref )
        # ICK!  'HTTPResponse.getHeader' doesn't case-flatten the key!
        self.assertEqual( self.RESPONSE.getHeader( 'Content-Length'.lower() )
                        , str(len(ref)) )
        self.assertEqual( self.RESPONSE.getHeader( 'Content-Type'.lower() )
                        , 'application/octet-stream' )
        self.assertEqual( self.RESPONSE.getHeader( 'Last-Modified'.lower() )
                        , rfc1123_date( mod_time ) )
Ejemplo n.º 12
0
    def test_index_html_with_304_and_caching( self ):

        # See collector #355
        self._setupCachingPolicyManager(DummyCachingManager())
        original_len = len(self.RESPONSE.headers)
        path, ref = self._extractFile()

        from webdav.common import rfc1123_date

        self.root.image = self._makeOne( 'test_image', 'test_image.gif' )
        image = self.root.image
        transaction.savepoint(optimistic=True)

        mod_time = image.modified()

        self.REQUEST.environ[ 'IF_MODIFIED_SINCE'
                            ] = '%s;' % rfc1123_date( mod_time+1 )

        data = image.index_html( self.REQUEST, self.RESPONSE )

        self.assertEqual( data, '' )
        self.assertEqual( self.RESPONSE.getStatus(), 304 )

        headers = self.RESPONSE.headers
        self.failUnless(len(headers) >= original_len + 3)
        self.failUnless('foo' in headers.keys())
        self.failUnless('bar' in headers.keys())
        self.assertEqual(headers['test_path'], '/test_image')
Ejemplo n.º 13
0
    def index_html(self, REQUEST, RESPONSE):
        """
        The default view of the contents of a File or Image.

        Returns the contents of the file or image.  Also, sets the
        Content-Type HTTP header to the objects content type.
        """
        # HTTP If-Modified-Since header handling.
        data = self._readFile()
        header=REQUEST.get_header('If-Modified-Since', None)
        if header is not None:
            header=string.split(header, ';')[0]
            # Some proxies seem to send invalid date strings for this
            # header. If the date string is not valid, we ignore it
            # rather than raise an error to be generally consistent
            # with common servers such as Apache (which can usually
            # understand the screwy date string as a lucky side effect
            # of the way they parse it).
            try:    mod_since=long(DateTime(header).timeTime())
            except: mod_since=None
            if mod_since is not None:
                last_mod = self.file_mod_time
                if last_mod > 0 and last_mod <= mod_since:
                    RESPONSE.setStatus(304)
                    return ''

        RESPONSE.setHeader('Last-Modified', rfc1123_date(self.file_mod_time))
        RESPONSE.setHeader('Content-Type', self.content_type)
        RESPONSE.setHeader('Content-Length', len(data))

        return data
Ejemplo n.º 14
0
 def _if_modified_since_request_handler(self, REQUEST):
     """ HTTP If-Modified-Since header handling: return True if
         we can handle this request by returning a 304 response.
     """
     header = REQUEST.get_header("If-Modified-Since", None)
     if header is not None:
         header = string.split(header, ";")[0]
         try:
             mod_since = long(DateTime(header).timeTime())
         except:
             mod_since = None
         if mod_since is not None:
             if self._p_mtime:
                 last_mod = long(self._p_mtime)
             else:
                 last_mod = long(0)
             if last_mod > 0 and last_mod < mod_since:
                 # Set headers for Apache caching
                 last_mod = rfc1123_date(self._p_mtime)
                 REQUEST.RESPONSE.setHeader("Last-Modified", last_mod)
                 REQUEST.RESPONSE.setHeader("Content-Type", self.content_type)
                 # RFC violation. See http://collector.zope.org/Zope/544
                 # REQUEST.RESPONSE.setHeader('Content-Length', self.get_size())
                 REQUEST.RESPONSE.setStatus(304)
                 return 1
Ejemplo n.º 15
0
def _FSCacheHeaders(obj):

    REQUEST = getattr(obj, 'REQUEST', None)
    if REQUEST is None:
        return False

    RESPONSE = REQUEST.RESPONSE
    header = REQUEST.get_header('If-Modified-Since', None)
    last_mod = obj._file_mod_time

    if header is not None:
        header = header.split(';')[0]
        # Some proxies seem to send invalid date strings for this
        # header. If the date string is not valid, we ignore it
        # rather than raise an error to be generally consistent
        # with common servers such as Apache (which can usually
        # understand the screwy date string as a lucky side effect
        # of the way they parse it).
        try:
            mod_since=DateTime(header)
            mod_since=long(mod_since.timeTime())
        except TypeError:
            mod_since=None
               
        if mod_since is not None:
            if last_mod > 0 and last_mod <= mod_since:
                RESPONSE.setStatus(304)
                return True

    #Last-Modified will get stomped on by a cache policy if there is
    #one set....
    RESPONSE.setHeader('Last-Modified', rfc1123_date(last_mod))
Ejemplo n.º 16
0
 def _if_modified_since_request_handler(self, REQUEST, RESPONSE):
     # HTTP If-Modified-Since header handling: return True if
     # we can handle this request by returning a 304 response
     header = REQUEST.get_header("If-Modified-Since", None)
     if header is not None:
         header = header.split(";")[0]
         # Some proxies seem to send invalid date strings for this
         # header. If the date string is not valid, we ignore it
         # rather than raise an error to be generally consistent
         # with common servers such as Apache (which can usually
         # understand the screwy date string as a lucky side effect
         # of the way they parse it).
         # This happens to be what RFC2616 tells us to do in the face of an
         # invalid date.
         try:
             mod_since = long(DateTime(header).timeTime())
         except:
             mod_since = None
         if mod_since is not None:
             if self._p_mtime:
                 last_mod = long(self._p_mtime)
             else:
                 last_mod = long(0)
             if last_mod > 0 and last_mod <= mod_since:
                 RESPONSE.setHeader("Last-Modified", rfc1123_date(self._p_mtime))
                 RESPONSE.setHeader("Content-Type", self.content_type)
                 RESPONSE.setHeader("Accept-Ranges", "bytes")
                 RESPONSE.setStatus(304)
                 return True
Ejemplo n.º 17
0
    def test_index_html_with_304_and_caching( self ):

        # See collector #355
        self.root.caching_policy_manager = DummyCachingManager()
        original_len = len(self.RESPONSE.headers)
        path, ref = self._extractFile()

        import os
        from webdav.common import rfc1123_date

        mod_time = os.stat( path )[ 8 ]

        image = self._makeOne( 'test_image', 'test_image.gif' )
        image = image.__of__( self.root )

        self.REQUEST.environ[ 'IF_MODIFIED_SINCE'
                            ] = '%s;' % rfc1123_date( mod_time+3600 )

        data = image.index_html( self.REQUEST, self.RESPONSE )

        self.assertEqual( data, '' )
        self.assertEqual( self.RESPONSE.getStatus(), 304 )

        headers = self.RESPONSE.headers
        self.failUnless(len(headers) >= original_len + 3)
        self.failUnless('foo' in headers.keys())
        self.failUnless('bar' in headers.keys())
        self.assertEqual(headers['test_path'], '/test_image')
    def __call__(self):
        sm = getSecurityManager()
        if not sm.checkPermission(permissions.View, self.context.context):
            raise Unauthorized

        settings = self.context.settings
        filepath = self.context.filepath
        blob = settings.blob_files[filepath]
        blobfi = openBlob(blob)
        length = os.fstat(blobfi.fileno()).st_size
        blobfi.close()
        ext = os.path.splitext(os.path.normcase(filepath))[1][1:]
        if ext == 'txt':
            ct = 'text/plain'
        else:
            ct = 'image/%s' % ext

        self.request.response.setHeader('Last-Modified',
                                        rfc1123_date(self.context._p_mtime))
        self.request.response.setHeader('Accept-Ranges', 'bytes')
        self.request.response.setHeader("Content-Length", length)
        self.request.response.setHeader('Content-Type', ct)
        request_range = handleRequestRange(
            self.context, length, self.request, self.request.response)
        return BlobStreamIterator(blob, **request_range)
Ejemplo n.º 19
0
    def index_html (self, icon=0, preview=0, width=None, height=None,
                    REQUEST=None):
        """ Return the file with it's corresponding MIME-type """

        if REQUEST is not None:
            if self._if_modified_since_request_handler(REQUEST):
                self.ZCacheable_set(None)
                return ''

            if self._redirect_default_view_request_handler(icon, preview, REQUEST):
                return ''

        filename, content_type, icon, preview = self._get_file_to_serve(icon, preview)
        filename = self._get_fsname(filename)

        if _debug > 1: logger.info('serving %s, %s, %s, %s' %(filename, content_type, icon, preview))

        if filename:
            size = os.stat(filename)[6]
        else:
            filename = self._get_icon_file(broken=True)
            size = os.stat(filename)[6]
            content_type = 'image/gif'
            icon = 1

        if icon==0 and width is not None and height is not None:
            data = TemporaryFile() # hold resized image
            try:
                from PIL import Image
                im = Image.open(filename)
                if im.mode!='RGB':
                    im = im.convert('RGB')
                filter = Image.BICUBIC
                if hasattr(Image, 'ANTIALIAS'): # PIL 1.1.3
                    filter = Image.ANTIALIAS
                im = im.resize((int(width),int(height)), filter)
                im.save(data, 'JPEG', quality=85)
            except:
                data = open(filename, 'rb')
            else:
                data.seek(0,2)
                size = data.tell()
                data.seek(0)
                content_type = 'image/jpeg'
        else:
            data = open(filename, 'rb')

        if REQUEST is not None:
            last_mod = rfc1123_date(self._p_mtime)
            REQUEST.RESPONSE.setHeader('Last-Modified', last_mod)
            REQUEST.RESPONSE.setHeader('Content-Type', content_type)
            REQUEST.RESPONSE.setHeader('Content-Length', size)
            self.ZCacheable_set(None)
            return stream_iterator(data)

        try:
            return data.read()
        finally:
            data.close()
Ejemplo n.º 20
0
 def testRedirectDefaultViewReturns304(self):
     self.file.manage_file_upload(gifImage)
     self.file.redirect_default_view = 1
     response = self.publish(self.file_path,
                             env={'HTTP_IF_MODIFIED_SINCE': rfc1123_date(DateTime()+7)},
                             basic=user_auth)
     self.assertEqual(response.getStatus(), 304)
     self.assertEqual(response.getHeader('Location'), None)
Ejemplo n.º 21
0
    def index_html(self, REQUEST, RESPONSE):
        """
        The default view of the contents of a File or Image.

        Returns the contents of the file or image.  Also, sets the
        Content-Type HTTP header to the objects content type.
        """

        if self._if_modified_since_request_handler(REQUEST, RESPONSE):
            # we were able to handle this by returning a 304
            # unfortunately, because the HTTP cache manager uses the cache
            # API, and because 304 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 self.precondition and hasattr(self, str(self.precondition)):
            # Grab whatever precondition was defined and then
            # execute it.  The precondition will raise an exception
            # if something violates its terms.
            c = getattr(self, str(self.precondition))
            if hasattr(c, "isDocTemp") and c.isDocTemp:
                c(REQUEST["PARENTS"][1], REQUEST)
            else:
                c()

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

        RESPONSE.setHeader("Last-Modified", rfc1123_date(self._p_mtime))
        RESPONSE.setHeader("Content-Type", self.content_type)
        RESPONSE.setHeader("Content-Length", self.size)
        RESPONSE.setHeader("Accept-Ranges", "bytes")

        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)

        data = self.data
        if isinstance(data, str):
            RESPONSE.setBase(None)
            return data

        while data is not None:
            RESPONSE.write(data.data)
            data = data.next

        return ""
Ejemplo n.º 22
0
    def view_image(self, REQUEST, RESPONSE):
        """ The default view of the contents of an Image.

            Returns the contents of the file or image.  Also, sets the
            Content-Type HTTP header to the objects content type.
        """
        # HTTP If-Modified-Since header handling.
        header=REQUEST.get_header('If-Modified-Since', None)
        if header is not None:
            header=string.split(header, ';')[0]
            # Some proxies seem to send invalid date strings for this
            # header. If the date string is not valid, we ignore it
            # rather than raise an error to be generally consistent
            # with common servers such as Apache (which can usually
            # understand the screwy date string as a lucky side effect
            # of the way they parse it).
            try:    mod_since=long(DateTime(header).timeTime())
            except: mod_since=None
            last_mod = long(0)
            if mod_since is not None:
                if self._p_mtime:
                    last_mod = long(self._p_mtime)
                else:
                    last_mod = long(0)
            if last_mod > 0 and last_mod <= mod_since:
                # Set header values since apache caching will return Content-Length
                # of 0 in response if size is not set here
                RESPONSE.setHeader('Last-Modified', rfc1123_date(self._p_mtime))
                RESPONSE.setHeader('Content-Type', self._v_image['content_type'])
                RESPONSE.setHeader('Content-Length', self._v_image['size'])
                RESPONSE.setStatus(304)
                return ''

        RESPONSE.setHeader('Last-Modified', rfc1123_date(self._p_mtime))
        RESPONSE.setHeader('Content-Type', self._v_image['content_type'])
        RESPONSE.setHeader('Content-Length', self._v_image['size'])

        data=self._v_image['data']
        if type(data) is type(''): return data

        while data is not None:
            RESPONSE.write(data.data)
            data=data.next

        return ''
Ejemplo n.º 23
0
 def other_headers(self, headers):
     if self._include_last_modified and 'Last-Modified' not in headers:
         # If missing, add a last-modified header with the modification time.
         modification = self.context.get_modification_datetime()
         if modification is not None:
             self.response.setHeader(
                 'Last-Modified',
                 rfc1123_date(modification))
     super(HTTPResponseHeaders, self).other_headers(headers)
Ejemplo n.º 24
0
    def index_html(self, REQUEST, RESPONSE):
        """
        The default view of the contents of a File or Image.

        Returns the contents of the file or image.  Also, sets the
        Content-Type HTTP header to the objects content type.
        """
        self._updateFromFS()
        data = self._data
        # HTTP If-Modified-Since header handling.
        header=REQUEST.get_header('If-Modified-Since', None)
        if header is not None:
            header = header.split(';')[0]
            # Some proxies seem to send invalid date strings for this
            # header. If the date string is not valid, we ignore it
            # rather than raise an error to be generally consistent
            # with common servers such as Apache (which can usually
            # understand the screwy date string as a lucky side effect
            # of the way they parse it).
            try:    mod_since=long(DateTime(header).timeTime())
            except: mod_since=None
            if mod_since is not None:
                last_mod = self._file_mod_time
                if last_mod > 0 and last_mod <= mod_since:
                    # Set header values since apache caching will return
                    # Content-Length of 0 in response if size is not set here
                    RESPONSE.setHeader('Last-Modified', rfc1123_date(last_mod))
                    RESPONSE.setHeader('Content-Type', self.content_type)
                    RESPONSE.setHeader('Content-Length', len(data))
                    RESPONSE.setStatus(304)
                    return ''

        #Last-Modified will get stomped on by a cache policy it there is one set....
        RESPONSE.setHeader('Last-Modified', rfc1123_date(self._file_mod_time))
        RESPONSE.setHeader('Content-Type', self.content_type)
        RESPONSE.setHeader('Content-Length', len(data))

        #There are 2 Cache Managers which can be in play....need to decide which to use
        #to determine where the cache headers are decided on.
        if self.ZCacheable_getManager() is not None:
            self.ZCacheable_set(None)
        else:
            _setCacheHeaders(self, extra_context={})
        return data
Ejemplo n.º 25
0
    def index_html(self, REQUEST, RESPONSE=None):
        """Default view for VirtualBinary file"""
        ranges = None
        if RESPONSE is None:
            RESPONSE = REQUEST.RESPONSE

        if self.__content_class__ is None:
            # Build your own headers
            RESPONSE.setHeader('Content-Type', self.content_type)
            RESPONSE.setHeader('Content-Length', self.size)

        else:
            # Call index_html method of content class with a fake
            # self.data attribute which will return empty value
            # Use this artifice to make sure content class is not loading
            # all data in memory since it is better to return a stream iterator
            # There is an exception with multiple range
            if REQUEST.environ.has_key('HTTP_RANGE'):
                ranges = parseRange(REQUEST.environ.get('HTTP_RANGE'))
             ## in case of mutiple range we don't know do with an iterator
            if ranges is not None and len(ranges) > 1:
                ## call normally OFS.image with data
                return self.__content_class__.index_html(self, REQUEST, RESPONSE)
            else:
                ### now we deal correctly with 304 header
                if self._if_modified_since_request_handler(REQUEST, RESPONSE):
                    self.ZCacheable_set(None)
                    return ''
                ### set correctly header
                RESPONSE.setHeader('Last-Modified', rfc1123_date(self._p_mtime))
                RESPONSE.setHeader('Content-Type', self.content_type)
                RESPONSE.setHeader('Content-Length', self.size)
                RESPONSE.setHeader('Accept-Ranges', 'bytes')
                self.ZCacheable_set(None)

            # This is a default header that can be bypassed by other products
            # such as attachment field.
            if RESPONSE.getHeader('content-disposition') is None:
                # headers are in lower case in HTTPResponse
                RESPONSE.setHeader(
                    'Content-Disposition',
                    'inline; filename="%s"' % self.filename
                    )
        if ranges and len(ranges) == 1:
            ## is an range request with one range ,
            ## return an iterator with this range
            [(start,end)] = ranges

            if end is None:
                end = self.size

            iterator = range_filestream_iterator(self.path, start, end, mode='rb')
            return iterator
        else:
            return filestream_iterator(self.path, mode='rb')
Ejemplo n.º 26
0
 def dav__init(self, request, response):
     # We are allowed to accept a url w/o a trailing slash
     # for a collection, but are supposed to provide a
     # hint to the client that it should be using one.
     # [WebDAV, 5.2]
     pathinfo=request.get('PATH_INFO','')
     if pathinfo and pathinfo[-1] != '/':
         location='%s/' % request['URL1']
         response.setHeader('Content-Location', location)
     response.setHeader('Connection', 'close', 1)
     response.setHeader('Date', rfc1123_date(), 1)
Ejemplo n.º 27
0
    def index_html(self, REQUEST, RESPONSE):
        """
        The default view of the contents of a File or Image.

        Returns the contents of the file or image.  Also, sets the
        Content-Type HTTP header to the objects content type.
        """
        self._updateFromFS()
        data = self._readFile(0)
        data_len = len(data)
        last_mod = self._file_mod_time
        status = 200
        # HTTP If-Modified-Since header handling.
        header = REQUEST.get_header('If-Modified-Since', None)
        if header is not None:
            header = header.split(';')[0]
            # Some proxies seem to send invalid date strings for this
            # header. If the date string is not valid, we ignore it
            # rather than raise an error to be generally consistent
            # with common servers such as Apache (which can usually
            # understand the screwy date string as a lucky side effect
            # of the way they parse it).
            try:
                mod_since = long(DateTime(header).timeTime())
            except:
                mod_since = None

            if mod_since is not None:
                if last_mod > 0 and last_mod <= mod_since:
                    status = 304
                    data = ''

        #Last-Modified will get stomped on by a cache policy it there is
        #one set....
        RESPONSE.setStatus(status)
        RESPONSE.setHeader('Last-Modified', rfc1123_date(last_mod))
        RESPONSE.setHeader('Content-Type', self.content_type)

        if status != 304:
            # Avoid setting content-length for a 304. See RFC 2616.
            # Zope might still, for better or for worse, set a
            # content-length header with value "0".
            RESPONSE.setHeader('Content-Length', data_len)

        #There are 2 Cache Managers which can be in play....
        #need to decide which to use to determine where the cache headers
        #are decided on.
        if self.ZCacheable_getManager() is not None:
            self.ZCacheable_set(None)
        else:
            _setCacheHeaders(_ViewEmulator().__of__(self), extra_context={})
        return data
Ejemplo n.º 28
0
    def index_html(self, instance, REQUEST=None, RESPONSE=None,
                   charset='utf-8', disposition='inline'):
        """Kicks download.
        Writes data including file name and content type to RESPONSE
        """

        if REQUEST is None:
            REQUEST = instance.REQUEST

        if RESPONSE is None:
            RESPONSE = REQUEST.RESPONSE

        RESPONSE.setHeader('Last-Modified', rfc1123_date(instance._p_mtime))
        RESPONSE.setHeader('Content-Type', self.getContentType(instance))
        RESPONSE.setHeader('Accept-Ranges', 'bytes')

        if handleIfModifiedSince(instance, REQUEST, RESPONSE):
            return ''

        length = self.get_size(instance)
        RESPONSE.setHeader('Content-Length', length)

        filename = self.getFilename(instance)
        if filename is not None:
            if isinstance(filename, unicode):
                filename = filename.encode(charset, errors="ignore")

            # Create a user agent specific disposition header
            # IE needs an url quoted filename
            # Other browsers need an unquoted filename
            user_agent = REQUEST.get('HTTP_USER_AGENT', '')
            if 'MSIE' in user_agent:
                header_value = '%s; filename=%s' % (disposition,
                                                    quote(filename))
            else:
                header_value = '%s; filename="%s"' % (disposition, filename)
            RESPONSE.setHeader("Content-disposition", header_value)

        request_range = handleRequestRange(instance, length, REQUEST, RESPONSE)

        # Notify file downloads, but do not notify range requests
        if not ('start' in request_range and request_range['start'] > 0):
            portal_state = getMultiAdapter((instance, instance.REQUEST),
                                           name='plone_portal_state')
            if not portal_state.anonymous():
                registry = getUtility(IRegistry)
                user_ids = registry['ftw.file.filesettings.user_ids']
                if portal_state.member().id \
                        and not portal_state.member().id in user_ids:
                    notify(FileDownloadedEvent(instance, filename))

        return self.get(instance).getIterator(**request_range)
Ejemplo n.º 29
0
    def index_html(self, REQUEST, RESPONSE):
        """
        The default view of the contents of a File or Image.

        Returns the contents of the file or image.  Also, sets the
        Content-Type HTTP header to the objects content type.
        """
        self._updateFromFS()
        data = self._readFile(0)
        data_len = len(data)
        last_mod = self._file_mod_time
        status = 200
        # HTTP If-Modified-Since header handling.
        header=REQUEST.get_header('If-Modified-Since', None)
        if header is not None:
            header = header.split(';')[0]
            # Some proxies seem to send invalid date strings for this
            # header. If the date string is not valid, we ignore it
            # rather than raise an error to be generally consistent
            # with common servers such as Apache (which can usually
            # understand the screwy date string as a lucky side effect
            # of the way they parse it).
            try:
                mod_since=long(DateTime(header).timeTime())
            except:
                mod_since=None
                
            if mod_since is not None:
                if last_mod > 0 and last_mod <= mod_since:
                    status = 304
                    data = ''

        #Last-Modified will get stomped on by a cache policy it there is
        #one set....
        RESPONSE.setStatus(status)
        RESPONSE.setHeader('Last-Modified', rfc1123_date(last_mod))
        RESPONSE.setHeader('Content-Type', self.content_type)

        if status != 304:
            # Avoid setting content-length for a 304. See RFC 2616.
            # Zope might still, for better or for worse, set a 
            # content-length header with value "0".
            RESPONSE.setHeader('Content-Length', data_len)

        #There are 2 Cache Managers which can be in play....
        #need to decide which to use to determine where the cache headers
        #are decided on.
        if self.ZCacheable_getManager() is not None:
            self.ZCacheable_set(None)
        else:
            _setCacheHeaders(_ViewEmulator().__of__(self), extra_context={})
        return data
Ejemplo n.º 30
0
    def index_html(self, REQUEST, RESPONSE):
        """
        The default view of the contents of a File or Image.

        Returns the contents of the file or image.  Also, sets the
        Content-Type HTTP header to the objects content type.
        """
        self._updateFromFS()
        data = self._data
        # HTTP If-Modified-Since header handling.
        header = REQUEST.get_header('If-Modified-Since', None)
        if header is not None:
            header = string.split(header, ';')[0]
            # Some proxies seem to send invalid date strings for this
            # header. If the date string is not valid, we ignore it
            # rather than raise an error to be generally consistent
            # with common servers such as Apache (which can usually
            # understand the screwy date string as a lucky side effect
            # of the way they parse it).
            try:
                mod_since = long(DateTime(header).timeTime())
            except:
                mod_since = None
            if mod_since is not None:
                last_mod = self._file_mod_time
                if last_mod > 0 and last_mod <= mod_since:
                    # Set header values since apache caching will return
                    # Content-Length of 0 in response if size is not set here
                    RESPONSE.setHeader('Last-Modified', rfc1123_date(last_mod))
                    RESPONSE.setHeader('Content-Type', self.content_type)
                    RESPONSE.setHeader('Content-Length', len(data))
                    RESPONSE.setStatus(304)
                    return ''

        RESPONSE.setHeader('Last-Modified', rfc1123_date(self._file_mod_time))
        RESPONSE.setHeader('Content-Type', self.content_type)
        RESPONSE.setHeader('Content-Length', len(data))

        return data
Ejemplo n.º 31
0
    def wrapper(self, REQUEST, RESPONSE, **kwargs):
        """ Look in cache:
            - if item exists in cache:
                if If-Modified-Sience in REQUEST headers:
                  set status 304, Not Modified
                  return ''
                return cached value
            - else
                compute result, cache and return it.
        """
        RESPONSE.setHeader('Cache-Control', 'public,max-age=3600')
        kwargs.update(REQUEST.form)
        
        # Get page from cache if exists
        keyset = None
        if self.ZCacheable_isCachingEnabled():
            # Prepare a cache key.
            keyset = kwargs.copy()
            keyset['*'] = ()
            result = self.ZCacheable_get(keywords=keyset, default=_marker)
            if result is not _marker:
                last_mod_req = REQUEST.get_header('If-Modified-Since', None)
                if not last_mod_req:
                    # Return from server cache
                    REQUEST.RESPONSE.setHeader('Last-Modified', rfc1123_date())
                    return result
                # Return from client cache
                RESPONSE.setStatus(304)
                return ''
        
        # Compute result
        result = method(self, REQUEST=REQUEST, RESPONSE=RESPONSE, **kwargs)

        # Update cache
        if keyset is not None:
            self.ZCacheable_set(result, keywords=keyset)
        REQUEST.RESPONSE.setHeader('Last-Modified', rfc1123_date())
        return result
Ejemplo n.º 32
0
    def wrapper(self, REQUEST, RESPONSE, **kwargs):
        """ Look in cache:
            - if item exists in cache:
                if If-Modified-Sience in REQUEST headers:
                  set status 304, Not Modified
                  return ''
                return cached value
            - else
                compute result, cache and return it.
        """
        RESPONSE.setHeader('Cache-Control', 'public,max-age=3600')
        kwargs.update(REQUEST.form)

        # Get page from cache if exists
        keyset = None
        if self.ZCacheable_isCachingEnabled():
            # Prepare a cache key.
            keyset = kwargs.copy()
            keyset['*'] = ()
            result = self.ZCacheable_get(keywords=keyset, default=_marker)
            if result is not _marker:
                last_mod_req = REQUEST.get_header('If-Modified-Since', None)
                if not last_mod_req:
                    # Return from server cache
                    REQUEST.RESPONSE.setHeader('Last-Modified', rfc1123_date())
                    return result
                # Return from client cache
                RESPONSE.setStatus(304)
                return ''

        # Compute result
        result = method(self, REQUEST=REQUEST, RESPONSE=RESPONSE, **kwargs)

        # Update cache
        if keyset is not None:
            self.ZCacheable_set(result, keywords=keyset)
        REQUEST.RESPONSE.setHeader('Last-Modified', rfc1123_date())
        return result
Ejemplo n.º 33
0
def dav__init(self, request, response):
    # We are allowed to accept a url w/o a trailing slash
    # for a collection, but are supposed to provide a
    # hint to the client that it should be using one.
    # [WebDAV, 5.2]
    pathinfo = request.get('PATH_INFO', '')
    if pathinfo and pathinfo[-1] != '/':
        location = '%s/' % request['URL1']
        response.setHeader('Content-Location', location)
    # We sniff for a ZServer response object, because we don't
    # want to write duplicate headers (since ZS writes Date
    # and Connection itself).
    if not hasattr(response, '_server_version'):
        response.setHeader('Connection', 'close', 1)
        response.setHeader('Date', rfc1123_date(), 1)
Ejemplo n.º 34
0
    def dav__init(self, request, response):
        # Init expected HTTP 1.1 / WebDAV headers which are not
        # currently set by the base response object automagically.
        #
        # We sniff for a ZServer response object, because we don't
        # want to write duplicate headers (since ZS writes Date
        # and Connection itself).
        if not hasattr(response, '_server_version'):
            response.setHeader('Connection', 'close')
            response.setHeader('Date', rfc1123_date(), 1)

        # HTTP Range support
        if HTTPRangeInterface.providedBy(self):
            response.setHeader('Accept-Ranges', 'bytes')
        else:
            response.setHeader('Accept-Ranges', 'none')
Ejemplo n.º 35
0
def index_html(self,
               REQUEST=None,
               RESPONSE=None,
               charset='utf-8',
               disposition='inline'):
    """ make it directly viewable when entering the objects URL """

    if REQUEST is None:
        REQUEST = self.REQUEST

    if RESPONSE is None:
        RESPONSE = REQUEST.RESPONSE

    RESPONSE.setHeader('Last-Modified', rfc1123_date(self._p_mtime))
    RESPONSE.setHeader('Content-Type', self.getContentType())
    RESPONSE.setHeader('Accept-Ranges', 'bytes')

    if handleIfModifiedSince(self, REQUEST, RESPONSE):
        return ''

    length = self.get_size()
    RESPONSE.setHeader('Content-Length', length)

    filename = self.getFilename()
    if filename is not None:
        if REQUEST.HTTP_USER_AGENT.find('MSIE') != -1:
            if isinstance(filename, unicode):
                filename = filename.encode('gb18030')
            else:
                filename = unicode(filename, charset, errors="ignore")
                filename = filename.encode('gb18030')
            header_value = contentDispositionHeader(disposition,
                                                    'gb18030',
                                                    filename=filename)
        else:
            if not isinstance(filename, unicode):
                filename = unicode(filename, charset, errors="ignore")

#            filename = IUserPreferredFileNameNormalizer(REQUEST).normalize(
#                filename)
            header_value = contentDispositionHeader(disposition=disposition,
                                                    filename=filename)
        RESPONSE.setHeader("Content-disposition", header_value)

    request_range = handleRequestRange(self, length, REQUEST, RESPONSE)
    return self.getIterator(**request_range)
Ejemplo n.º 36
0
    def test_304_response_from_cpm(self):
        # test that we get a 304 response from the cpm via this template
        from DateTime import DateTime
        from webdav.common import rfc1123_date
        from Products.CMFCore.tests.base.dummy \
            import DummyCachingManagerWithPolicy

        mod_time = DateTime()
        self.root.caching_policy_manager = DummyCachingManagerWithPolicy()
        script = self._makeOne('testReST', 'testReST.rst')
        script = script.__of__(self.root)
        self.REQUEST.environ['IF_MODIFIED_SINCE'] = '%s;' % rfc1123_date(
            mod_time + 3600)
        data = script(self.REQUEST, self.RESPONSE)

        self.assertEqual(data, '')
        self.assertEqual(self.RESPONSE.getStatus(), 304)
Ejemplo n.º 37
0
 def other_headers(self, headers):
     if self._include_last_modified:
         self.response.setHeader(
             'Last-Modified',
             rfc1123_date(self.context.get_modification_datetime()))
     self.response.setHeader(
         'Content-Disposition',
         'inline;filename=%s' % (self.context.get_filename()))
     self.response.setHeader('Content-Type',
                             self.context.get_content_type())
     if self.context.get_content_encoding():
         self.response.setHeader('Content-Encoding',
                                 self.context.get_content_encoding())
     if not self.response.getHeader('Content-Length'):
         self.response.setHeader('Content-Length',
                                 self.context.get_file_size())
     if not self.response.getHeader('Accept-Ranges'):
         self.response.setHeader('Accept-Ranges', 'none')
Ejemplo n.º 38
0
    def test_304_response_from_cpm(self):
        # test that we get a 304 response from the cpm via this template

        from webdav.common import rfc1123_date

        mod_time = DateTime()
        self._setupCachingPolicyManager(DummyCachingManagerWithPolicy())
        content = DummyContent(id='content')
        content.modified_date = mod_time
        content = content.__of__(self.root)
        script = self._makeOne('testDTML', 'testDTML.dtml')
        script = script.__of__(content)
        self.REQUEST.environ['IF_MODIFIED_SINCE'] = '%s;' % rfc1123_date(
            mod_time + 3600)
        data = script(content, self.REQUEST, self.RESPONSE)

        self.assertEqual(data, '')
        self.assertEqual(self.RESPONSE.getStatus(), 304)
Ejemplo n.º 39
0
    def test_index_html_without_304(self):

        path, ref = self._extractFile()

        import os
        from webdav.common import rfc1123_date

        mod_time = os.stat(path)[8]

        image = self._makeOne('test_image', 'test_image.gif')
        image = image.__of__(self.root)

        self.REQUEST.environ['IF_MODIFIED_SINCE'] = '%s;' % rfc1123_date(
            mod_time - 3600)

        data = image.index_html(self.REQUEST, self.RESPONSE)

        self.failUnless(data, '')
        self.assertEqual(self.RESPONSE.getStatus(), 200)
Ejemplo n.º 40
0
    def test_index_html_with_304(self):

        path, ref = self._extractFile()

        import os
        from webdav.common import rfc1123_date

        mod_time = os.stat(path)[8]

        file = self._makeOne('test_file', 'test_file.swf')
        file = file.__of__(self.root)

        self.REQUEST.environ['IF_MODIFIED_SINCE'] = '%s;' % rfc1123_date(
            mod_time + 3600)

        data = file.index_html(self.REQUEST, self.RESPONSE)

        self.assertEqual(data, '')
        self.assertEqual(self.RESPONSE.getStatus(), 304)
Ejemplo n.º 41
0
    def test_index_html_with_304_from_cpm(self):
        self._setupCachingPolicyManager(DummyCachingManagerWithPolicy())
        path, ref = self._extractFile()

        from webdav.common import rfc1123_date
        from Products.CMFCore.tests.base.dummy import FAKE_ETAG

        self.root.file = self._makeOne('test_file', 'test_image.jpg', file=ref)
        file = self.root.file

        mod_time = file.modified()

        self.REQUEST.environ['IF_MODIFIED_SINCE'] = '%s;' % rfc1123_date(
            mod_time)
        self.REQUEST.environ['IF_NONE_MATCH'] = '%s;' % FAKE_ETAG

        data = file.index_html(self.REQUEST, self.RESPONSE)
        self.assertEqual(len(data), 0)
        self.assertEqual(self.RESPONSE.getStatus(), 304)
Ejemplo n.º 42
0
    def render_attachment_preview(self, attachment):
        sm = getSecurityManager()
        if not sm.checkPermission(permissions.View, self.context):
            raise Unauthorized

        r = self.request.response

        # avoid long dreaded CSRF error
        annotations = IAnnotations(attachment)
        if not annotations.get('collective.documentviewer', None):
            safeWrite(attachment)
        settings = Settings(attachment)  # possibly creates annotation

        if self.preview_type not in ('large', 'normal', 'small'):
            self.preview_type = 'small'
        if self.page is None:
            self.page = 1
        filepath = u'%s/dump_%s.%s' % (self.preview_type, self.page,
                                       settings.pdf_image_format)
        try:
            blob = settings.blob_files[filepath]
        except TypeError:
            # 'NoneType' object has no attribute '__getitem__'
            # happens e.g. when missing preview for stream attachment
            return

        blobfi = openBlob(blob)
        length = os.fstat(blobfi.fileno()).st_size
        blobfi.close()
        ext = os.path.splitext(os.path.normcase(filepath))[1][1:]
        if ext == 'txt':
            ct = 'text/plain'
        else:
            ct = 'image/%s' % ext

        r.setHeader('Content-Type', ct)
        r.setHeader('Last-Modified', rfc1123_date(self.context._p_mtime))
        r.setHeader('Accept-Ranges', 'bytes')
        r.setHeader("Content-Length", length)
        request_range = handleRequestRange(self.context, length, self.request,
                                           self.request.response)
        return BlobStreamIterator(blob, **request_range)
Ejemplo n.º 43
0
    def test_index_html_with_304_from_cpm(self):
        self.root.caching_policy_manager = DummyCachingManagerWithPolicy()
        path, ref = self._extractFile()

        import os
        from webdav.common import rfc1123_date
        from base.dummy import FAKE_ETAG

        file = self._makeOne('test_file', 'test_image.gif')
        file = file.__of__(self.root)

        mod_time = os.stat(path)[8]

        self.REQUEST.environ['IF_MODIFIED_SINCE'] = '%s;' % rfc1123_date(
            mod_time)
        self.REQUEST.environ['IF_NONE_MATCH'] = '%s;' % FAKE_ETAG

        data = file.index_html(self.REQUEST, self.RESPONSE)
        self.assertEqual(len(data), 0)
        self.assertEqual(self.RESPONSE.getStatus(), 304)
Ejemplo n.º 44
0
    def render_blob_version(self):
        # done much like it is done in plone.app.blob's index_html
        header_value = contentDispositionHeader(
            disposition='inline',
            filename=self.context.getFilename().replace('.pdf', '.swf'))

        blob = self.settings.data
        blobfi = openBlob(blob)
        length = fstat(blobfi.fileno()).st_size
        blobfi.close()

        self.request.response.setHeader('Last-Modified',
                                        rfc1123_date(self.context._p_mtime))
        self.request.response.setHeader('Accept-Ranges', 'bytes')
        self.request.response.setHeader('Content-Disposition', header_value)
        self.request.response.setHeader("Content-Length", length)
        self.request.response.setHeader('Content-Type',
                                        'application/x-shockwave-flash')
        range = handleRequestRange(self.context, length, self.request,
                                   self.request.response)
        return BlobStreamIterator(blob, **range)
Ejemplo n.º 45
0
def stream_avatar_data(profile, size, request):
    """Generate avatar at the specified size and stream it

    This is a utility method used by the browser views below.
    """
    response = request.response

    if not profile:
        return default_avatar(response)
    imaging = plone_api.content.get_view(
        request=request,
        context=profile,
        name='images')

    if size not in AVATAR_SIZES:
        return default_avatar(response)

    width = height = AVATAR_SIZES.get(size)

    try:
        scale = imaging.scale(
            fieldname='portrait',
            width=width,
            height=height,
            direction='down',
        )
    except TypeError:
        # No image found
        return default_avatar(response)

    if scale is not None:
        data = scale.data
        mtime = rfc1123_date(profile._p_mtime)
        response.setHeader('Last-Modified', mtime)
        from plone.namedfile.utils import set_headers, stream_data
        set_headers(data, response)
        return stream_data(data)
    else:
        return default_avatar(response)
Ejemplo n.º 46
0
    def __call__(self):
        sm = getSecurityManager()
        if not sm.checkPermission(permissions.View, self.context.context):
            raise Unauthorized

        settings = self.context.settings
        filepath = self.context.filepath
        blob = settings.blob_files[filepath]
        filename = blob._p_blob_uncommitted or blob.committed()

        length = os.path.getsize(filename)
        ext = os.path.splitext(os.path.normcase(filepath))[1][1:]
        if ext == 'txt':
            ct = 'text/plain'
        else:
            ct = 'image/%s' % ext

        self.request.response.setHeader('Last-Modified',
                                        rfc1123_date(self.context._p_mtime))
        self.request.response.setHeader("Content-Length", length)
        self.request.response.setHeader('Content-Type', ct)
        return filestream_iterator(filename, 'rb')
Ejemplo n.º 47
0
    def test_index_html_with_304(self):

        path, ref = self._extractFile()

        import os
        from webdav.common import rfc1123_date

        mod_time = os.stat(path)[8]

        image = self._makeOne('test_image', 'test_image.gif')
        image = image.__of__(self.root)

        self.REQUEST.environ['IF_MODIFIED_SINCE'] = '%s;' % rfc1123_date(
            mod_time + 3600)

        data = image.index_html(self.REQUEST, self.RESPONSE)

        self.assertEqual(data, '')
        # test that we properly hack around apache bug noted in code
        self.assertEqual(self.RESPONSE.getHeader('Content-Length'.lower()),
                         str(len(ref)))
        self.assertEqual(self.RESPONSE.getStatus(), 304)
Ejemplo n.º 48
0
    def test_index_html_with_304( self ):

        path, ref = self._extractFile('test_file.swf')

        import os
        from webdav.common import rfc1123_date

        mod_time = os.stat( path )[ 8 ]

        file = self._makeOne( 'test_file', 'test_file.swf' )
        file = file.__of__( self.root )

        self.REQUEST.environ[ 'IF_MODIFIED_SINCE'
                            ] = '%s;' % rfc1123_date( mod_time+3600 )

        data = file.index_html( self.REQUEST, self.RESPONSE )

        self.assertEqual( data, '' )
        # test that we don't supply a content-length
        self.assertEqual( self.RESPONSE.getHeader('Content-Length'.lower()),
                                               None )
        self.assertEqual( self.RESPONSE.getStatus(), 304 )
Ejemplo n.º 49
0
    def index_html(self, REQUEST=None, RESPONSE=None, charset='utf-8',
                   disposition='inline'):
        """ make it directly viewable when entering the objects URL """

        if REQUEST is None:
            REQUEST = self.REQUEST

        if RESPONSE is None:
            RESPONSE = REQUEST.RESPONSE

        RESPONSE.setHeader('Last-Modified', rfc1123_date(self._p_mtime))
        RESPONSE.setHeader('Content-Type', self.getContentType())
        RESPONSE.setHeader('Accept-Ranges', 'bytes')

        if handleIfModifiedSince(self, REQUEST, RESPONSE):
            return ''

        length = self.get_size()
        RESPONSE.setHeader('Content-Length', length)

        filename = self.getFilename()
        if filename is not None:
            if not isinstance(filename, six.text_type):
                filename = six.text_type(filename, charset, errors='ignore')
            filename = IUserPreferredFileNameNormalizer(
                REQUEST,
            ).normalize(
                filename,
            )
            header_value = contentDispositionHeader(
                disposition=disposition,
                filename=filename,
            )
            # Add original filename in utf-8, ref to rfc2231
            RESPONSE.setHeader('Content-disposition', header_value)

        request_range = handleRequestRange(self, length, REQUEST, RESPONSE)
        return self.getIterator(**request_range)
Ejemplo n.º 50
0
    def test_index_html(self):

        path, ref = self._extractFile()

        import os
        from webdav.common import rfc1123_date

        mod_time = os.stat(path)[8]

        image = self._makeOne('test_image', 'test_image.gif')
        image = image.__of__(self.root)

        data = image.index_html(self.REQUEST, self.RESPONSE)

        self.assertEqual(len(data), len(ref))
        self.assertEqual(data, ref)
        # ICK!  'HTTPResponse.getHeader' doesn't case-flatten the key!
        self.assertEqual(self.RESPONSE.getHeader('Content-Length'.lower()),
                         str(len(ref)))
        self.assertEqual(self.RESPONSE.getHeader('Content-Type'.lower()),
                         'image/gif')
        self.assertEqual(self.RESPONSE.getHeader('Last-Modified'.lower()),
                         rfc1123_date(mod_time))
Ejemplo n.º 51
0
 def __call__(self):
     sm = getSecurityManager()
     if not sm.checkPermission(permissions.View, self.context.context):
         raise Unauthorized
     settings = self.context.settings
     filepath = self.context.filepath
     blob = settings.blob_files[filepath]
     blobfi = openBlob(blob)
     length = os.fstat(blobfi.fileno()).st_size
     blobfi.close()
     ext = os.path.splitext(os.path.normcase(filepath))[1][1:]
     if ext == 'txt':
         ct = 'text/plain'
     else:
         ct = 'image/%s' % ext
     self.request.response.setHeader('Last-Modified',
                                     rfc1123_date(self.context._p_mtime))
     self.request.response.setHeader('Accept-Ranges', 'bytes')
     self.request.response.setHeader("Content-Length", length)
     self.request.response.setHeader('Content-Type', ct)
     range = handleRequestRange(self.context, length, self.request,
                                self.request.response)
     return BlobStreamIterator(blob, **range)
Ejemplo n.º 52
0
    def test_index_html_200_with_cpm(self):
        # should behave the same as without cpm installed
        self.root.caching_policy_manager = DummyCachingManager()
        path, ref = self._extractFile()

        from webdav.common import rfc1123_date

        file = self._makeOne('test_file', 'test_file.swf', file=ref)
        file = file.__of__(self.root)

        mod_time = file.modified().timeTime()

        data = file.index_html(self.REQUEST, self.RESPONSE)

        self.assertEqual(len(data), len(ref))
        self.assertEqual(data, ref)
        # ICK!  'HTTPResponse.getHeader' doesn't case-flatten the key!
        self.assertEqual(self.RESPONSE.getHeader('Content-Length'.lower()),
                         str(len(ref)))
        self.assertEqual(self.RESPONSE.getHeader('Content-Type'.lower()),
                         'application/octet-stream')
        self.assertEqual(self.RESPONSE.getHeader('Last-Modified'.lower()),
                         rfc1123_date(mod_time))
Ejemplo n.º 53
0
    def test_forced_content_type( self ):

        path, ref = self._extractFile('test_file_two.swf')

        import os
        from webdav.common import rfc1123_date

        mod_time = os.stat( path )[ 8 ]

        file = self._makeOne( 'test_file', 'test_file_two.swf' )
        file = file.__of__( self.root )

        data = file.index_html( self.REQUEST, self.RESPONSE )

        self.assertEqual( len( data ), len( ref ) )
        self.assertEqual( data, ref )
        # ICK!  'HTTPResponse.getHeader' doesn't case-flatten the key!
        self.assertEqual( self.RESPONSE.getHeader( 'Content-Length'.lower() )
                        , str(len(ref)) )
        self.assertEqual( self.RESPONSE.getHeader( 'Content-Type'.lower() )
                        , 'application/x-shockwave-flash' )
        self.assertEqual( self.RESPONSE.getHeader( 'Last-Modified'.lower() )
                        , rfc1123_date( mod_time ) )
Ejemplo n.º 54
0
    def test_index_html_200_with_cpm(self):
        self._setupCachingPolicyManager(DummyCachingManagerWithPolicy())
        path, ref = self._extractFile()

        from webdav.common import rfc1123_date

        file = self._makeOne('test_file', 'test_image.jpg', file=ref)
        file = file.__of__(self.root)

        mod_time = file.modified()

        data = file.index_html(self.REQUEST, self.RESPONSE)

        # should behave the same as without cpm
        self.assertEqual(len(data), len(ref))
        self.assertEqual(data, ref)
        # ICK!  'HTTPResponse.getHeader' doesn't case-flatten the key!
        self.assertEqual(self.RESPONSE.getHeader('Content-Length'.lower()),
                         str(len(ref)))
        self.assertEqual(self.RESPONSE.getHeader('Content-Type'.lower()),
                         'image/jpeg')
        self.assertEqual(self.RESPONSE.getHeader('Last-Modified'.lower()),
                         rfc1123_date(mod_time))
Ejemplo n.º 55
0
    def __call__(self):
        try:
            data = self.get_data()
        except IOError:
            # can be from zeo client blob file weirdness with PIL
            # ocassionally
            logger.info('Could not get blob data', exc_info=True)
            raise NotFound

        if data:
            is_blob = False
            if isinstance(data, basestring):
                length = len(data)
            else:
                is_blob = True
                blobfi = openBlob(data)
                length = fstat(blobfi.fileno()).st_size
                blobfi.close()

            self.request.response.setHeader(
                'Last-Modified', rfc1123_date(self.context._p_mtime))
            resp = self.request.response
            resp.setHeader(
                'Content-Disposition', 'inline; filename=%s.%s' %
                (self.context.getId(), self.file_ext))
            resp.setHeader("Content-Length", length)
            resp.setHeader('Content-Type', self.content_type)

            if is_blob:
                resp.setHeader('Accept-Ranges', 'bytes')
                range = handleRequestRange(self.context, length, self.request,
                                           self.request.response)
                return BlobStreamIterator(data, **range)
            else:
                return data
        else:
            raise NotFound
Ejemplo n.º 56
0
    def index_html(self, REQUEST, RESPONSE):
        """
        The default view of the contents of a File or Image.

        Returns the contents of the file or image.  Also, sets the
        Content-Type HTTP header to the objects content type.
        """

        if self.precondition and hasattr(self, str(self.precondition)):
            # Grab whatever precondition was defined and then
            # execute it.  The precondition will raise an exception
            # if something violates its terms.
            c = getattr(self, str(self.precondition))
            if hasattr(c, 'isDocTemp') and c.isDocTemp:
                # DTML thingy
                c(REQUEST['PARENTS'][1], REQUEST)
            else:
                c()

        RESPONSE.setHeader('Last-Modified', rfc1123_date(self._p_mtime))
        RESPONSE.setHeader('Content-Type', self.content_type)
        RESPONSE.setHeader('Content-Length', self.size)

        return self.getIterator()
Ejemplo n.º 57
0
 def createLastModifiedDate(self, offset=0):
     return rfc1123_date(self.file._p_mtime + offset)
Ejemplo n.º 58
0
    def getHTTPCachingHeaders( self, content, view_name, keywords, time=None ):

         # if the object has a modified method, add it as last-modified
         if hasattr(content, 'modified'):
             headers = ( ('Last-modified', rfc1123_date(content.modified()) ), )
         return headers
Ejemplo n.º 59
0
    def _range_request_handler(self, REQUEST, RESPONSE):
        # HTTP Range header handling: return True if we've served a range
        # chunk out of our data.
        range = REQUEST.get_header('Range', None)
        request_range = REQUEST.get_header('Request-Range', None)
        if request_range is not None:
            # Netscape 2 through 4 and MSIE 3 implement a draft version
            # Later on, we need to serve a different mime-type as well.
            range = request_range
        if_range = REQUEST.get_header('If-Range', None)
        if range is not None:
            ranges = HTTPRangeSupport.parseRange(range)

            if if_range is not None:
                # Only send ranges if the data isn't modified, otherwise send
                # the whole object. Support both ETags and Last-Modified dates!
                if len(if_range) > 1 and if_range[:2] == 'ts':
                    # ETag:
                    if if_range != self.http__etag():
                        # Modified, so send a normal response. We delete
                        # the ranges, which causes us to skip to the 200
                        # response.
                        ranges = None
                else:
                    # Date
                    date = if_range.split(';')[0]
                    try:
                        mod_since = long(DateTime(date).timeTime())
                    except:
                        mod_since = None
                    if mod_since is not None:
                        if self._p_mtime:
                            last_mod = long(self._p_mtime)
                        else:
                            last_mod = long(0)
                        if last_mod > mod_since:
                            # Modified, so send a normal response. We delete
                            # the ranges, which causes us to skip to the 200
                            # response.
                            ranges = None

            if ranges:
                # Search for satisfiable ranges.
                satisfiable = 0
                for start, end in ranges:
                    if start < self.size:
                        satisfiable = 1
                        break

                if not satisfiable:
                    RESPONSE.setHeader('Content-Range',
                                       'bytes */%d' % self.size)
                    RESPONSE.setHeader('Accept-Ranges', 'bytes')
                    RESPONSE.setHeader('Last-Modified',
                                       rfc1123_date(self._p_mtime))
                    RESPONSE.setHeader('Content-Type', self.content_type)
                    RESPONSE.setHeader('Content-Length', self.size)
                    RESPONSE.setStatus(416)
                    return True

                ranges = HTTPRangeSupport.expandRanges(ranges, self.size)

                if len(ranges) == 1:
                    # Easy case, set extra header and return partial set.
                    start, end = ranges[0]
                    size = end - start

                    RESPONSE.setHeader('Last-Modified',
                                       rfc1123_date(self._p_mtime))
                    RESPONSE.setHeader('Content-Type', self.content_type)
                    RESPONSE.setHeader('Content-Length', size)
                    RESPONSE.setHeader('Accept-Ranges', 'bytes')
                    RESPONSE.setHeader(
                        'Content-Range',
                        'bytes %d-%d/%d' % (start, end - 1, self.size))
                    RESPONSE.setStatus(206)  # Partial content

                    data = self.data
                    if isinstance(data, str):
                        RESPONSE.write(data[start:end])
                        return True

                    # Linked Pdata objects. Urgh.
                    pos = 0
                    while data is not None:
                        l = len(data.data)
                        pos = pos + l
                        if pos > start:
                            # We are within the range
                            lstart = l - (pos - start)

                            if lstart < 0: lstart = 0

                            # find the endpoint
                            if end <= pos:
                                lend = l - (pos - end)

                                # Send and end transmission
                                RESPONSE.write(data[lstart:lend])
                                break

                            # Not yet at the end, transmit what we have.
                            RESPONSE.write(data[lstart:])

                        data = data.next

                    return True

                else:
                    boundary = choose_boundary()

                    # Calculate the content length
                    size = (
                        8 + len(boundary) +  # End marker length
                        len(ranges) * (  # Constant lenght per set
                            49 + len(boundary) + len(self.content_type) +
                            len('%d' % self.size)))
                    for start, end in ranges:
                        # Variable length per set
                        size = (size + len('%d%d' % (start, end - 1)) + end -
                                start)

                    # Some clients implement an earlier draft of the spec, they
                    # will only accept x-byteranges.
                    draftprefix = (request_range is not None) and 'x-' or ''

                    RESPONSE.setHeader('Content-Length', size)
                    RESPONSE.setHeader('Accept-Ranges', 'bytes')
                    RESPONSE.setHeader('Last-Modified',
                                       rfc1123_date(self._p_mtime))
                    RESPONSE.setHeader(
                        'Content-Type', 'multipart/%sbyteranges; boundary=%s' %
                        (draftprefix, boundary))
                    RESPONSE.setStatus(206)  # Partial content

                    data = self.data
                    # The Pdata map allows us to jump into the Pdata chain
                    # arbitrarily during out-of-order range searching.
                    pdata_map = {}
                    pdata_map[0] = data

                    for start, end in ranges:
                        RESPONSE.write('\r\n--%s\r\n' % boundary)
                        RESPONSE.write('Content-Type: %s\r\n' %
                                       self.content_type)
                        RESPONSE.write(
                            'Content-Range: bytes %d-%d/%d\r\n\r\n' %
                            (start, end - 1, self.size))

                        if isinstance(data, str):
                            RESPONSE.write(data[start:end])

                        else:
                            # Yippee. Linked Pdata objects. The following
                            # calculations allow us to fast-forward through the
                            # Pdata chain without a lot of dereferencing if we
                            # did the work already.
                            first_size = len(pdata_map[0].data)
                            if start < first_size:
                                closest_pos = 0
                            else:
                                closest_pos = ((
                                    (start - first_size) >> 16 << 16) +
                                               first_size)
                            pos = min(closest_pos, max(pdata_map.keys()))
                            data = pdata_map[pos]

                            while data is not None:
                                l = len(data.data)
                                pos = pos + l
                                if pos > start:
                                    # We are within the range
                                    lstart = l - (pos - start)

                                    if lstart < 0: lstart = 0

                                    # find the endpoint
                                    if end <= pos:
                                        lend = l - (pos - end)

                                        # Send and loop to next range
                                        RESPONSE.write(data[lstart:lend])
                                        break

                                    # Not yet at the end, transmit what we have.
                                    RESPONSE.write(data[lstart:])

                                data = data.next
                                # Store a reference to a Pdata chain link so we
                                # don't have to deref during this request again.
                                pdata_map[pos] = data

                    # Do not keep the link references around.
                    del pdata_map

                    RESPONSE.write('\r\n--%s--\r\n' % boundary)
                    return True
Ejemplo n.º 60
0
    def index_html(self,
                   icon=0,
                   preview=0,
                   width=None,
                   height=None,
                   REQUEST=None):
        """ Return the file with it's corresponding MIME-type """

        if REQUEST is not None:
            if self._if_modified_since_request_handler(REQUEST):
                self.ZCacheable_set(None)
                return ''

            if self._redirect_default_view_request_handler(
                    icon, preview, REQUEST):
                return ''

        filename, content_type, icon, preview = self._get_file_to_serve(
            icon, preview)
        filename = self._get_fsname(filename)

        if _debug > 1:
            logger.info('serving %s, %s, %s, %s' %
                        (filename, content_type, icon, preview))

        if filename:
            size = os.stat(filename)[6]
        else:
            filename = self._get_icon_file(broken=True)
            size = os.stat(filename)[6]
            content_type = 'image/gif'
            icon = 1

        if icon == 0 and width is not None and height is not None:
            data = TemporaryFile()  # hold resized image
            try:
                from PIL import Image
                im = Image.open(filename)
                if im.mode != 'RGB':
                    im = im.convert('RGB')
                filter = Image.BICUBIC
                if hasattr(Image, 'ANTIALIAS'):  # PIL 1.1.3
                    filter = Image.ANTIALIAS
                im = im.resize((int(width), int(height)), filter)
                im.save(data, 'JPEG', quality=85)
            except:
                data = open(filename, 'rb')
            else:
                data.seek(0, 2)
                size = data.tell()
                data.seek(0)
                content_type = 'image/jpeg'
        else:
            data = open(filename, 'rb')

        if REQUEST is not None:
            last_mod = rfc1123_date(self._p_mtime)
            REQUEST.RESPONSE.setHeader('Last-Modified', last_mod)
            REQUEST.RESPONSE.setHeader('Content-Type', content_type)
            REQUEST.RESPONSE.setHeader('Content-Length', size)
            self.ZCacheable_set(None)
            return stream_iterator(data)

        try:
            return data.read()
        finally:
            data.close()