safemime.py :  » Web-Server » CherryPy » CherryPy-3.1.2 » cherrypy » lib » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Web Server » CherryPy 
CherryPy » CherryPy 3.1.2 » cherrypy » lib » safemime.py
import cherrypy


class MultipartWrapper(object):
    """Wraps a file-like object, returning '' when Content-Length is reached.
    
    The cgi module's logic for reading multipart MIME messages doesn't
    allow the parts to know when the Content-Length for the entire message
    has been reached, and doesn't allow for multipart-MIME messages that
    omit the trailing CRLF (Flash 8's FileReference.upload(url), for example,
    does this). The read_lines_to_outerboundary function gets stuck in a loop
    until the socket times out.
    
    This rfile wrapper simply monitors the incoming stream. When a read is
    attempted past the Content-Length, it returns an empty string rather
    than timing out (of course, if the last read *overlaps* the C-L, you'll
    get the last bit of data up to C-L, and then the next read will return
    an empty string).
    """
    
    def __init__(self, rfile, clen):
        self.rfile = rfile
        self.clen = clen
        self.bytes_read = 0
    
    def read(self, size = None):
        if self.clen:
            # Return '' if we've read all the data.
            if self.bytes_read >= self.clen:
                return ''
            
            # Reduce 'size' if it's over our limit.
            new_bytes_read = self.bytes_read + size
            if new_bytes_read > self.clen:
                size = self.clen - self.bytes_read
        
        data = self.rfile.read(size)
        self.bytes_read += len(data)
        return data
    
    def readline(self, size = None):
        if size is not None:
            if self.clen:
                # Return '' if we've read all the data.
                if self.bytes_read >= self.clen:
                    return ''
                
                # Reduce 'size' if it's over our limit.
                new_bytes_read = self.bytes_read + size
                if new_bytes_read > self.clen:
                    size = self.clen - self.bytes_read
            
            data = self.rfile.readline(size)
            self.bytes_read += len(data)
            return data
        
        # User didn't specify a size ...
        # We read the line in chunks to make sure it's not a 100MB line !
        res = []
        size = 256
        while True:
            if self.clen:
                # Return if we've read all the data.
                if self.bytes_read >= self.clen:
                    return ''.join(res)
                
                # Reduce 'size' if it's over our limit.
                new_bytes_read = self.bytes_read + size
                if new_bytes_read > self.clen:
                    size = self.clen - self.bytes_read
            
            data = self.rfile.readline(size)
            self.bytes_read += len(data)
            res.append(data)
            # See http://www.cherrypy.org/ticket/421
            if len(data) < size or data[-1:] == "\n":
                return ''.join(res)
    
    def readlines(self, sizehint = 0):
        # Shamelessly stolen from StringIO
        total = 0
        lines = []
        line = self.readline()
        while line:
            lines.append(line)
            total += len(line)
            if 0 < sizehint <= total:
                break
            line = self.readline()
        return lines
    
    def close(self):
        self.rfile.close()
    
    def __iter__(self):
        return self.rfile
    
    def next(self):
        if self.clen:
            # Return '' if we've read all the data.
            if self.bytes_read >= self.clen:
                return ''
        
        data = self.rfile.next()
        self.bytes_read += len(data)
        return data


def safe_multipart(flash_only=False):
    """Wrap request.rfile in a reader that won't crash on no trailing CRLF."""
    h = cherrypy.request.headers
    if not h.get('Content-Type','').startswith('multipart/'):
        return
    if flash_only and not 'Shockwave Flash' in h.get('User-Agent', ''):
        return
    
    clen = h.get('Content-Length', '0')
    try:
        clen = int(clen)
    except ValueError:
        return
    cherrypy.request.rfile = MultipartWrapper(cherrypy.request.rfile, clen)

def init():
    """Create a Tool for safe_multipart and add it to cherrypy.tools."""
    cherrypy.tools.safe_multipart = cherrypy.Tool('before_request_body',
                                                   safe_multipart)

www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.