def init(self): """docstring for init""" self.log.write(self.message["enter"]) self.session = Qsession(self.log) self.timeout = self.config["timeout"] self.max_buf_size = self.config["bufsize"] # ASTMPHandler 的默认状态是一直接收数据, 当ibuffer中数据大于限定值时, # 由collect_incomming_data() 负责调用found_terminator() self.set_terminator("\r\n")
def __init__(self, conn, addr, log, message, json_config): self.conn = conn self.addr = addr self.log = log self.message = message self.config = json_config self.session = Qsession(log) self.timeout = self.config["timeout"] self.bufsize = self.config["bufsize"]
class TSTMPMachine: """docstring for STMPMachine""" def __init__(self, conn, addr, logger, message, json_config): self.conn = conn self.addr = addr self.logger = logger self.message = message self.config = json_config self.session = Qsession(logger) self.timeout = self.config["timeout"] self.bufsize = self.config["bufsize"] def write(self, msg): self.conn.send(msg) def read(self): try: # we only need to monitor the timeout for # reading data from client socket self.conn.settimeout(self.timeout) data = self.conn.recv(self.bufsize) self.conn.settimeout(None) except socket.timeout: self.logger.write(self.message["timeout"]) data = None return data def close(self): self.conn.close() ## # @brief # # @return def run(self): try: self.logger.write(self.message["enter"]) is_continue = True while is_continue: data = self.read() if data is None: break response, is_continue = self.session.feed(data) if response is not None: self.write(response) self.logger.write(self.message["exit"]) self.close() except: self.logger.write("Unexpected error: {0}".format(sys.exc_info())[0])
class STMPMachine: """docstring for STMPMachine""" def __init__(self, conn, addr, log, message, json_config): self.conn = conn self.addr = addr self.log = log self.message = message self.config = json_config self.session = Qsession(log) self.timeout = self.config["timeout"] self.bufsize = self.config["bufsize"] def write(self, msg): self.send(msg) def read(self): # timeout 只有在接收用户数据时候需要考虑 self.conn.settimeout(self.timeout) try: data = self.conn.recv(bufsize) except socket.timeout: # 直接设置为None, data中应该没有数据?? self.log.write(self.message["timeout"]) data = None self.conn.settimeout(None) return data def close(self): self.conn.close() def run(self): self.log.write(self.message["enter"]) is_continue = True while is_continue: data = self.read() # read None 意味着超时 if data is None: break response, is_continue = self.session.feed(data) if response is not None: self.write(response) self.log.write(self.message["exit"]) self.close()
def __init__(self, sock, addr, message, json_config, logger): # calling the super class __init__ asynchat.async_chat.__init__(self, sock=sock) self.addr = addr self.ibuffer = [] self.config = json_config self.message = message self.logger = logger # as a handler in stmp server, we expected the message # sending from server will be small. self.ac_out_buffer_size = 512 self.timeout = self.config["timeout"] self.max_buf_size = self.config["bufsize"] # usually, we won't use "\r\n" as the terminator in # stmp protocol, but, for simplicity. self.set_terminator("\r\n") # log a user enter self.session = Qsession(self.logger) self.logger.write(self.message["enter"])
class ASTMPHandler(asynchat.async_chat): """docstring for STMPHandler""" def __init__(self, sock, addr, message, json_config, logger): # calling the super class __init__ asynchat.async_chat.__init__(self, sock=sock) self.addr = addr self.ibuffer = [] self.config = json_config self.message = message self.logger = logger # as a handler in stmp server, we expected the message # sending from server will be small. self.ac_out_buffer_size = 512 self.timeout = self.config["timeout"] self.max_buf_size = self.config["bufsize"] # usually, we won't use "\r\n" as the terminator in # stmp protocol, but, for simplicity. self.set_terminator("\r\n") # log a user enter self.session = Qsession(self.logger) self.logger.write(self.message["enter"]) ## # @brief # # @param data the receiving data # # @return None def collect_incoming_data(self, data): self.ibuffer.append(data) if len(self.ibuffer) >= self.max_buf_size: self.found_terminator() ## # @brief # There are only two available situation this function # will be called. # 1. async_chat meet the terminator; # 2. the self.ibuffer contain too many data. # @return None def found_terminator(self): data = "".join(self.ibuffer) # we say the self.ibuffer have been consumed. self.ibuffer = [] # The session (Qsession) will give response based on # the given data. # 1. response will send back to client; # 2. is_continue tell handler that is this connection should # be closed ? response, is_continue = self.session.feed(data) if response is not None: self.push(response) if not is_continue: self.close_when_done() def handle_close(self): self.logger.write(self.message["exit"]) asynchat.async_chat.handle_close(self) def handle_read(self): try: self.settimeout(self.timeout) ret = asynchat.async_chat.handle_read(self) # we only need timeout work when read the data from client self.settimeout(None) except socket.timeout: self.logger.write(self.message["timeout"]) self.close_when_done() return ret
def setUp(self): """docstring for setup""" log = open("./test.log", "w") self.session = Qsession(log)
class QsessionTest(unittest.TestCase): """docstring for QsessionTest""" def setUp(self): """docstring for setup""" log = open("./test.log", "w") self.session = Qsession(log) def test_writeFile(self): """docstring for test_writeFile""" self.session.filename = "session_test" msg = "QSESSION TEST" self.session.mail_content = msg self.session.writeFile() with open(self.session.filename) as stream: for line in stream.readlines(): self.assertEqual(line, msg, \ "file msg {0} should be equal with {1}".format(line, msg)) def test_is_addr_valid(self): """docstring for is_addr_valid""" filename = "invalid_mail_address" with open(filename, "r") as stream: for address in stream.readlines(): self.assertEqual(False, self.session.is_addr_valid(address)) filename = "valid_mail_address" with open(filename, "r") as stream: for address in stream.readlines(): self.assertEqual(True, self.session.is_addr_valid(address)) def test_checkFormal(self): """docstring for test_checkFormal""" filename = "valid_check_formal" # format: cmd session_value data expected_ret with open(filename, "r") as stream: for line in stream.readlines(): items = line.split(",") items = map(lambda x: x.strip(), items) cmd = items[0] if cmd == "0": self.session.mail_from = items[1] ret = self.session.checkFormal(items[2], int(cmd)) self.assertEqual(ret, bool(items[3])) elif cmd == "1": self.session.mail_to = items[1] ret = self.session.checkFormal(items[2], int(cmd)) self.assertEqual(ret, bool(items[3])) elif cmd == "2": ret = self.session.checkFormal(items[1], int(cmd)) self.assertEqual(ret, bool(items[2])) elif cmd == "3": ret = self.session.checkFormal(items[1], int(cmd)) self.assertEqual(ret, bool(items[2])) def test_feed(self): """docstring for test_feed""" infile = "test_feed_request" outfile = "test_feed_response" with open(infile, "r") as instream: with open(outfile, "r") as outstream: request = map(lambda x: x+"\r\n", instream.read().split("\r\n")) response = outstream.read().split("\n") for i in range(len(request)): ret = self.session.feed(request[i]) self.assertEqual(ret[0], response[i])
class ASTMPHandler(asynchat.async_chat): """docstring for STMPHandler""" def __init__(self, sock, addr, message, json_config): asynchat.async_chat.__init__(self, sock=sock) # 创建STMP 日志对象 self.addr = addr self.ibuffer = [] self.config = json_config self.message = message self.log = STMPLog(logging.getLogger(self.config["server_name"]), self.addr) # 服务器回应数据很小 self.ac_out_buffer_size = 512 self.init() # 初始终止条件 # self.set_terminator("\r\n") def init(self): """docstring for init""" self.log.write(self.message["enter"]) self.session = Qsession(self.log) self.timeout = self.config["timeout"] self.max_buf_size = self.config["bufsize"] # ASTMPHandler 的默认状态是一直接收数据, 当ibuffer中数据大于限定值时, # 由collect_incomming_data() 负责调用found_terminator() self.set_terminator("\r\n") ## # @brief # # @param data # # @return def collect_incoming_data(self, data): """docstring for collect_incoming_data""" self.ibuffer.append(data) if len(self.ibuffer) >= self.max_buf_size: self.found_terminator() ## # @brief # # @return def found_terminator(self): # 形成字串, 清空ibuffer data = "".join(self.ibuffer) self.ibuffer = [] # Qsession 负责STMP协议的逻辑部分 response, is_continue = self.session.feed(data) # response 为None时表示本次无需响应, 可能是由于当前待 # 接收数据不完整 if response is not None: self.push(response) if not is_continue: # 执行关闭, 效果是待发送数据发送完毕, 则关闭对应链接 self.close_when_done() def handle_close(self): self.log.write(self.message["exit"]) super(ASTMPHandler, self).handle_close() def handle_read(self): # timeout 只有在接收用户数据时候需要考虑 self.settimeout(self.timeout) try: ret = super(ASTMPHandler, self).handle_read() except socket.timeout: self.log.write("timeout") self.close_when_done() self.settimeout(None) return ret