def response_http(self, status): headers = [( "Content-Length", 0, )] if status[0:3] == "101": headers += [( "Connection", "Upgrade", ), ( "Upgrade", "websocket", )] headers += [("Sec-WebSocket-Accept", wslib.gen_handshake_key(self.__http_ws_key))] headers += [("Sec-WebSocket-Protocol", "chat")] headers += [ ("X-Auth-Id", hashlib.sha256(self.__http_auth_id.encode()).hexdigest()) ] s = httputils.build_http1x_resp_header(status, headers) self.add_evt_write(self.fileno) self.writer.write(s.encode("iso-8859-1"))
def recv_handshake(self): size = self.reader.size() data = self.reader.read() p = data.find(b"\r\n\r\n") if p < 10 and size > 2048: logging.print_general("wrong_http_response_header", self.__server_address) self.delete_handler(self.fileno) return if p < 0: self.reader._putvalue(data) return p += 4 self.reader._putvalue(data[p:]) s = data[0:p].decode("iso-8859-1") try: resp, kv_pairs = httputils.parse_http1x_response_header(s) except httputils.Http1xHeaderErr: logging.print_general("wrong_http_reponse_header", self.__server_address) self.delete_handler(self.fileno) return version, status = resp if status.find("101") != 0: logging.print_general("https_handshake_error:%s" % status, self.__server_address) self.delete_handler(self.fileno) return accept_key = self.get_http_kv_pairs("sec-websocket-accept", kv_pairs) if wslib.gen_handshake_key(self.__http_handshake_key) != accept_key: logging.print_general("https_handshake_error:wrong websocket response key", self.__server_address) self.delete_handler(self.fileno) return auth_id = self.get_http_kv_pairs("x-auth-id", kv_pairs) if hashlib.sha256(self.__http_auth_id.encode()).hexdigest() != auth_id: logging.print_general("wrong_auth_id", self.__server_address) self.delete_handler(self.fileno) return self.__http_handshake_ok = True logging.print_general("http_handshake_ok", self.__server_address) # 发送还没有连接的时候堆积的数据包 if self.__tmp_buf: self.add_evt_write(self.fileno) while 1: try: self.writer.write(self.__tmp_buf.pop(0)) except IndexError: break '''''' ''''''
def __do_handshake(self, byte_data): try: sts = byte_data.decode("iso-8859-1") except UnicodeDecodeError: self.response_error() return False try: rs = httputils.parse_htt1x_request_header(sts) except: self.response_error() return False req, headers = rs dic = {} for k, v in headers: k = k.lower() dic[k] = v if "sec-websocket-key" not in dic: return False ws_version = dic.get("sec-websocket-version", 0) is_err = False try: ws_version = int(ws_version) if ws_version != 13: is_err = True except ValueError: is_err = True if is_err: self.response_error() return False if not self.on_handshake(req, headers): self.response_error() return False sec_ws_key = dic["sec-websocket-key"] resp_sec_key = websocket.gen_handshake_key(sec_ws_key) resp_headers = [("Upgrade", "websocket"), ("Connection", "Upgrade"), ("Sec-WebSocket-Accept", resp_sec_key)] resp_headers += self.__ext_handshake_resp_headers resp_sts = httputils.build_http1x_resp_header( "101 Switching Protocols", resp_headers, version="1.1") self.writer.write(resp_sts.encode("iso-8859-1")) self.add_evt_write(self.fileno) return True
def __do_handshake(self, byte_data): try: sts = byte_data.decode("iso-8859-1") except UnicodeDecodeError: self.response_error() return False try: rs = httputils.parse_htt1x_request_header(sts) except: self.response_error() return False req, headers = rs dic = {} for k, v in headers: k = k.lower() dic[k] = v if "sec-websocket-key" not in dic: return False ws_version = dic.get("sec-websocket-version", 0) is_err = False try: ws_version = int(ws_version) if ws_version != 13: is_err = True except ValueError: is_err = True if is_err: self.response_error() return False if not self.on_handshake(req, headers): self.response_error() return False sec_ws_key = dic["sec-websocket-key"] resp_sec_key = websocket.gen_handshake_key(sec_ws_key) resp_headers = [("Upgrade", "websocket"), ("Connection", "Upgrade"), ("Sec-WebSocket-Accept", resp_sec_key)] resp_headers += self.__ext_handshake_resp_headers resp_sts = httputils.build_http1x_resp_header("101 Switching Protocols", resp_headers, version="1.1") self.writer.write(resp_sts.encode("iso-8859-1")) self.add_evt_write(self.fileno) return True
def do_handshake(self): size = self.reader.size() rdata = self.reader.read() p = rdata.find(b"\r\n\r\n") if p < 5 and size > 2048: self.delete_handler(self.fileno) return s = rdata.decode("iso-8859-1") try: rq, kv = httputils.parse_htt1x_request_header(s) except httputils.Http1xHeaderErr: self.delete_handler(self.fileno) return m, uri, ver = rq if ver.lower() != "http/1.1": self.delete_handler(self.fileno) return if m != "GET": self.delete_handler(self.fileno) return upgrade = self.get_kv_value(kv, "upgrade") if not upgrade: self.send_403_response() return if upgrade.lower() != "websocket": self.send_403_response() return connection = self.get_kv_value(kv, "connection") if not connection: self.send_403_response() return if connection.lower() != "upgrade": self.send_403_response() return sec_ws_key = self.get_kv_value(kv, "sec-websocket-key") if not sec_ws_key: self.send_403_response() return origin = self.get_kv_value(kv, "origin") if not origin: self.send_403_response() return ws_ver = self.get_kv_value(kv, "sec-websocket-version") try: v = int(ws_ver) except ValueError: self.send_403_response() return if v != 13: self.send_403_response() return sec_ws_proto = self.get_kv_value(kv, "sec-websocket-protocol") if not sec_ws_proto: self.send_403_response() return auth_id = self.get_kv_value(kv, "x-auth-id") if not auth_id: self.send_403_response() return role = self.get_kv_value(kv, "x-role") if not role: self.send_403_response() return self.__role = role.lower() if self.__role not in ("cs", "ms",): self.send_403_response() return if self.__role == "ms": session_id = self.get_kv_value(kv, "x-session-id") if not session_id: self.send_403_response() return resp_headers = [ ("Content-Length", "0"), ] resp_headers += [("Connection", "Upgrade",), ("Upgrade", "websocket",)] resp_headers += [("Sec-WebSocket-Accept", ws.gen_handshake_key(sec_ws_key))] resp_headers += [("Sec-WebSocket-Protocol", "socks2https")] logging.print_general("handshake_ok", self.__caddr) self.__handshake_ok = True self.send_response("101 Switching Protocols", resp_headers)
def do_handshake(self): size = self.reader.size() rdata = self.reader.read() p = rdata.find(b"\r\n\r\n") if p < 5 and size > 2048: self.delete_handler(self.fileno) return s = rdata.decode("iso-8859-1") try: rq, kv = httputils.parse_htt1x_request_header(s) except httputils.Http1xHeaderErr: self.delete_handler(self.fileno) return m, uri, ver = rq if ver.lower() != "http/1.1": self.delete_handler(self.fileno) return if m != "GET": self.delete_handler(self.fileno) return upgrade = self.get_kv_value(kv, "upgrade") if not upgrade: if self.dispatcher.debug: sys.stderr.write("no upgrade field\r\n") self.send_403_response() return if upgrade.lower() != "websocket": if self.dispatcher.debug: sys.stderr.write("it is not websocket field\r\n") self.send_403_response() return connection = self.get_kv_value(kv, "connection") if not connection: if self.dispatcher.debug: sys.stderr.write("no connection field\r\n") self.send_403_response() return if connection.lower() != "upgrade": if self.dispatcher.debug: sys.stderr.write("connection is not upgrade\r\n") self.send_403_response() return sec_ws_key = self.get_kv_value(kv, "sec-websocket-key") if not sec_ws_key: if self.dispatcher.debug: sys.stderr.write("no websocket key\r\n") self.send_403_response() return origin = self.get_kv_value(kv, "origin") if not origin: if self.dispatcher.debug: sys.stderr.write("no origin key\r\n") self.send_403_response() return ws_ver = self.get_kv_value(kv, "sec-websocket-version") try: v = int(ws_ver) except ValueError: self.send_403_response() return if v != 13: if self.dispatcher.debug: sys.stderr.write("wrong websocket version\r\n") self.send_403_response() return sec_ws_proto = self.get_kv_value(kv, "sec-websocket-protocol") if not sec_ws_proto: if self.dispatcher.debug: sys.stderr.write("no sec-websocket-protocol\r\n") self.send_403_response() return auth_id = self.get_kv_value(kv, "x-auth-id") if not auth_id: if self.dispatcher.debug: sys.stderr.write("no auth-id field\r\n") self.send_403_response() return is_msg_tunnel = self.get_kv_value(kv, "x-msg-tunnel") if not is_msg_tunnel: sys.stderr.write("not found X-Msg-Tunnel value\r\n") self.send_403_response() return if not self.dispatcher.auth_id_exists(auth_id): if self.dispatcher.debug: sys.stderr.write("not found %s service\r\n" % auth_id) self.send_403_response() return if self.dispatcher.auth_id_exists(auth_id) and not is_msg_tunnel: self.send_403_response() return try: v = bool(int(is_msg_tunnel)) except ValueError: sys.stderr.write("wrong X-Msg-Tunnel value type\r\n") self.send_403_response() return self.__is_msg_tunnel = v if v: s = self.get_kv_value(kv, "x-session-id") self.__session_id = base64.b64decode(s.encode()) if not self.dispatcher.session_get(self.__session_id): sys.stderr.write("session id not exists\r\n") self.send_403_response() return else: self.dispatcher.reg_fwd_conn(auth_id, self.fileno) resp_headers = [ ("Content-Length", "0"), ] resp_headers += [( "Connection", "Upgrade", ), ( "Upgrade", "websocket", )] resp_headers += [("Sec-WebSocket-Accept", ws.gen_handshake_key(sec_ws_key))] resp_headers += [("Sec-WebSocket-Protocol", "intranet_pass")] logging.print_general("handshake_ok", self.__caddr) self.__handshake_ok = True self.__auth_id = auth_id self.send_response("101 Switching Protocols", resp_headers) self.tcp_loop_read_num = 10 if not v: return # 注意这里如果是消息隧道一定要等待握手协议发送完毕再告知连接成功,连接成功会发送堆积在服务器上的数据 self.dispatcher.tell_listener_conn_ok(self.__session_id, self.fileno)