Ejemplo n.º 1
0
 def __init__(self, sock, addr, enable_tls, debug, is_client = False):
     self.setSocket(sock, enable_tls)
     self.addr = addr
     self.table = Table()
     self.streams = {}
     self.enablePush = SETTINGS.INIT_VALUE["enable_push"]
     self.maxConcurrentStreams = SETTINGS.INIT_VALUE["concurrent_streams"]
     self.maxFrameSize = SETTINGS.INIT_VALUE["frame_size"]
     self.maxHeaderListSize = SETTINGS.INIT_VALUE["header_list_size"]
     self.initialWindowSize = SETTINGS.INIT_VALUE["window_size"]
     self.peerSettingACK = False
     self.nextStreamID = 0
     self.addStream(0)
     self.preface = is_client
     self.is_goaway = False
     # temporaly using
     self.debug = debug
Ejemplo n.º 2
0
class Connection(object):
    def __init__(self, sock, addr, enable_tls, debug, is_client = False):
        self.setSocket(sock, enable_tls)
        self.addr = addr
        self.table = Table()
        self.streams = {}
        self.enablePush = SETTINGS.INIT_VALUE["enable_push"]
        self.maxConcurrentStreams = SETTINGS.INIT_VALUE["concurrent_streams"]
        self.maxFrameSize = SETTINGS.INIT_VALUE["frame_size"]
        self.maxHeaderListSize = SETTINGS.INIT_VALUE["header_list_size"]
        self.initialWindowSize = SETTINGS.INIT_VALUE["window_size"]
        self.peerSettingACK = False
        self.nextStreamID = 0
        self.addStream(0)
        self.preface = is_client
        self.is_goaway = False
        # temporaly using
        self.debug = debug

    def setSocket(self, sock, enable_tls):
        self.sock = sock
        if enable_tls:
            self._send = sock.write
            self._recv = sock.read
        else:
            self._send = sock.send
            self._recv = sock.recv

    def _send(self):
        pass

    def _recv(self):
        pass

    def PING(self, data):
        self.sendFrame(Ping(data))

    def pushContent(self, ID, link):
        headers = self.getStream(ID).headers
        headers[":path"] = link
        self.addStream(self.nextStreamID, STATE.RESERVED_L)
        self.sendFrame(Push_Promise(ID, self.nextStreamID, flags=FLAG.END_HEADERS))
        self.sendFrame(Headers(self.nextStreamID, flags=FLAG.END_HEADERS))
        self.setHeaders(self.nextStreamID, headers)
        self.sendFrame(Data("", self.nextStreamID, flags=FLAG.END_STREAM))
        self.nextStreamID += 2

    def sendFrame(self, frame):
        frame.sendEval(self) #TODO: makeWire and send if this returns true
        stream = self.getStream(frame.streamID)
        stream.sendEval(frame.flags)
        frame.makeWire()
        print "%s\n\t%s\n\t%s" % (sendC.apply("SEND"), stream.string(), frame.string())
        self._send(frame.getWire())

    def setStreamState(self, ID, state):
        self.streams[ID].setState(state)

    def setHeaders(self, ID, headers):
        self.streams[ID].setHeaders(headers)

    def getStream(self, ID):
        stream = self.streams.get(ID, None)
        return stream

    def getStreamState(self, ID):
        return self.streams[ID].getState()

    def initFlagment(self, ID):
        self.streams[ID].initFlagment()

    def appendFlagment(self, ID, flagment):
        self.streams[ID].appendFlagment(flagment)

    def validateData(self):
        if self.preface:
            headerOctet = self._recv(9)
            if len(headerOctet) == 0:
                # when connection closed from client
                self.preface = False
                return False
            info = Http2Header.getHeaderInfo(headerOctet)
            if not self.is_goaway or self.is_goaway and (info.type == TYPE.HEADERS or
                                                         info.type == TYPE.PRIORITY or
                                                         info.type == TYPE.CONTINUATION):
                stream = self.getStream(info.streamID)
                if not stream:
                    self.addStream(info.streamID)
                    stream = self.getStream(info.streamID)

                frameFunc = getFrameFunc(info.type)
                frame = frameFunc(info, self._recv(info.length))
                if info.flags&FLAG.END_HEADERS == FLAG.END_HEADERS:
                    stream.setHeaders(list2dict(HPACK.decode(stream.headerFlagment+frame.headerFlagment, self.table)))
                print "%s\n\t%s\n\t%s" % (recvC.apply("RECV"), stream.string(), frame.string())

                if stream.continuing and info.type != TYPE.CONTINUATION:
                    self.sendFrame(Goaway(self.lastStreamID, err=ERR_CODE.PROTOCOL_ERROR))
                if (stream.getState() == STATE.CLOSED and
                    info.type != TYPE.PRIORITY and
                    info.type != TYPE.RST_STREAM):
                    self.sendFrame(Rst_Stream(info.streamID, err=ERR_CODE.STREAM_CLOSED))
                frame.recvEval(self)
            else:
                self._recv(info.length)
        else:
            data = self._recv(24)
            if data == CONNECTION_PREFACE:
                self.preface = True
        return True

    def addStream(self, ID, state = STATE.IDLE):
        self.streams[ID] = Stream(ID, self.initialWindowSize, state)

    def setHeaderTableSize(self, size):
        self.table.setMaxHeaderTableSize(size)

    def useWindow(self, ID, size):
        self.streams[0].useWindow(size)
        self.streams[ID].useWindow(size)

    def recoverWindow(self, ID, size):
        self.streams[ID].recoverWindow(size)

    def setInitialWindowSize(self, size):
        for ID in self.streams:
            if self.stream[ID].state != STATE.IDLE:
                self.stream[ID].setInitialWindowSize(size)