示例#1
0
 def __init__(self, stream, boundary):
     self.stream = BufferedStream(stream)
     self.boundary = "--" + boundary
     self.first = True
示例#2
0
class MultipartMimeStream(object):
    implements(IStream)
    def __init__(self, stream, boundary):
        self.stream = BufferedStream(stream)
        self.boundary = "--" + boundary
        self.first = True
        
    def read(self):
        """
        Return a deferred which will fire with a tuple of:
        (fieldname, filename, ctype, dataStream)
        or None when all done.
        
        Format errors will be sent to the errback.
        
        Returns None when all done.

        IMPORTANT: you *must* exhaust dataStream returned by this call
        before calling .read() again!
        """
        if self.first:
            self.first = False
            d = self._readFirstBoundary()
        else:
            d = self._readBoundaryLine()
        d.addCallback(self._doReadHeaders)
        d.addCallback(self._gotHeaders)
        return d

    def _readFirstBoundary(self):
        #print "_readFirstBoundary"
        line = self.stream.readline(size=1024)
        if isinstance(line, defer.Deferred):
            line = defer.waitForDeferred(line)
            yield line
            line = line.getResult()
        if line != self.boundary + '\r\n':
            raise MimeFormatError("Extra data before first boundary: %r looking for: %r" % (line, self.boundary + '\r\n'))
        
        self.boundary = "\r\n" + self.boundary
        yield True
        return
    _readFirstBoundary = defer.deferredGenerator(_readFirstBoundary)

    def _readBoundaryLine(self):
        #print "_readBoundaryLine"
        line = self.stream.readline(size=1024)
        if isinstance(line, defer.Deferred):
            line = defer.waitForDeferred(line)
            yield line
            line = line.getResult()
        
        if line == "--\r\n":
            # THE END!
            yield False
            return
        elif line != "\r\n":
            raise MimeFormatError("Unexpected data on same line as boundary: %r" % (line,))
        yield True
        return
    _readBoundaryLine = defer.deferredGenerator(_readBoundaryLine)

    def _doReadHeaders(self, morefields):
        #print "_doReadHeaders", morefields
        if not morefields:
            return None
        return _readHeaders(self.stream)
    
    def _gotHeaders(self, headers):
        if headers is None:
            return None
        bws = _BoundaryWatchingStream(self.stream, self.boundary)
        self.deferred = bws.deferred
        ret = list(headers)
        ret.append(bws)
        return tuple(ret)