Пример #1
0
class HttpLengthBody():
    u""" http 实体类(Length 类型、同时支持关闭连接类型)

头部空行结束后就是实体,实体直接按长度结束,结束时并没有多余的换行。
    """

    def __init__(self, sock=None, length=None):
        u"""初始化"""
        if sock:
            self.sock = sock
        else:
            self.sock = BytesIO()
        self.length = length
        self.readed_length = 0

    def _recv(self, size):
        if hasattr(self.sock, "recv"):
            return self.sock.recv(size)
        else:
            return self.sock.read(size)

    def recv(self, size):
        u"""读取

正常结束时返回空,非正常结束(连接断开)时引发异常。
        """
        if self.length is None:
            return self._recv(size)
        else:
            assert self.readed_length <= self.length

            if self.readed_length == self.length:
                return b""
            else:
                remain_length = self.length - self.readed_length

                if size > remain_length:
                    size = remain_length

                data = self.recv(size)
                self.readed_length += len(data)

                if not data and size != 0:
                    raise Exception(u'连接异常关闭,数据未全部传输完成!')

                return data
Пример #2
0
class HttpLengthBody():
    u""" http 实体类(Length 类型、同时支持关闭连接类型)

头部空行结束后就是实体,实体直接按长度结束,结束时并没有多余的换行。
    """
    def __init__(self, sock=None, length=None):
        u"""初始化"""
        if sock:
            self.sock = sock
        else:
            self.sock = BytesIO()
        self.length = length
        self.readed_length = 0

    def _recv(self, size):
        if hasattr(self.sock, "recv"):
            return self.sock.recv(size)
        else:
            return self.sock.read(size)

    def recv(self, size):
        u"""读取

正常结束时返回空,非正常结束(连接断开)时引发异常。
        """
        if self.length is None:
            return self._recv(size)
        else:
            assert self.readed_length <= self.length

            if self.readed_length == self.length:
                return b""
            else:
                remain_length = self.length - self.readed_length

                if size > remain_length:
                    size = remain_length

                data = self.recv(size)
                self.readed_length += len(data)

                if not data and size != 0:
                    raise Exception(u'连接异常关闭,数据未全部传输完成!')

                return data
Пример #3
0
class HttpChunkedBody():
    u"""chunked 格式 body

提供带 chunked head 及不带 head 两种输出。
但是不提供gzip等解压操作。
"""

    def __init__(self, sock=None, chunked_head=False):
        u"""初始化

sock        mysocket 实例或 BytesIO 实例,需要包含 readline 方法
chunked_head        是否输出 chunked head

        """
        if sock:
            self.sock = sock
        else:
            self.sock = BytesIO()

        self.chunked_head = chunked_head

        self.chunked_length = None
        self.readed_length = 0

    def _recv(self, size):
        if hasattr(self.sock, "recv"):
            return self.sock.recv(size)
        else:
            return self.sock.read(size)

    def recv_chunked_head(self):
        str_length = self.sock.readline()
        if not str_length:
            raise Exception(u'连接非正常结束!')
        self.chunked_length = int(str_length, 16)
        self.readed_length = 0
        return str_length

    def recv(self, size):
        u"""读取

正常结束时返回空,非正常结束(连接断开)时引发异常。
        """
        res = BytesIO()

        if self.chunked_length == 0:
            # 读到结束块结束
            # 尾头域另行读取
            return res.getvalue()

        if self.chunked_length is None or \
                        self.chunked_length == self.readed_length:
            # 第一次读取 或 当前块读取结束
            if self.chunked_head:
                res.write(self.recv_chunked_head())

        data = self._recv(self.chunked_length - self.readed_length)
        if self.chunked_length != 0 and (not data):
            raise Exception(u'连接非正常结束!')

        self.readed_length += len(data)

        assert self.readed_length <= self.chunked_length

        res.write(data)

        if self.chunked_length == self.readed_length:
            # 每个块结束都有 \r\n,并且不包含在块长度里面。
            end_line = (self.sock.readline(2))
            if end_line[-1] != '\n':
                raise Exception(u'非正常的块结束标记. endline:%s' % end_line)
            if self.chunked_head:
                res.write(end_line)

        return res.getvalue()
Пример #4
0
class HttpChunkedBody():
    u"""chunked 格式 body

提供带 chunked head 及不带 head 两种输出。
但是不提供gzip等解压操作。
"""
    def __init__(self, sock=None, chunked_head=False):
        u"""初始化

sock        mysocket 实例或 BytesIO 实例,需要包含 readline 方法
chunked_head        是否输出 chunked head

        """
        if sock:
            self.sock = sock
        else:
            self.sock = BytesIO()

        self.chunked_head = chunked_head

        self.chunked_length = None
        self.readed_length = 0

    def _recv(self, size):
        if hasattr(self.sock, "recv"):
            return self.sock.recv(size)
        else:
            return self.sock.read(size)

    def recv_chunked_head(self):
        str_length = self.sock.readline()
        if not str_length:
            raise Exception(u'连接非正常结束!')
        self.chunked_length = int(str_length, 16)
        self.readed_length = 0
        return str_length

    def recv(self, size):
        u"""读取

正常结束时返回空,非正常结束(连接断开)时引发异常。
        """
        res = BytesIO()

        if self.chunked_length == 0:
            # 读到结束块结束
            # 尾头域另行读取
            return res.getvalue()

        if self.chunked_length is None or \
                        self.chunked_length == self.readed_length:
            # 第一次读取 或 当前块读取结束
            if self.chunked_head:
                res.write(self.recv_chunked_head())

        data = self._recv(self.chunked_length - self.readed_length)
        if self.chunked_length != 0 and (not data):
            raise Exception(u'连接非正常结束!')

        self.readed_length += len(data)

        assert self.readed_length <= self.chunked_length

        res.write(data)

        if self.chunked_length == self.readed_length:
            # 每个块结束都有 \r\n,并且不包含在块长度里面。
            end_line = (self.sock.readline(2))
            if end_line[-1] != '\n':
                raise Exception(u'非正常的块结束标记. endline:%s' % end_line)
            if self.chunked_head:
                res.write(end_line)

        return res.getvalue()