diff --git a/code/default/launcher/config.py b/code/default/launcher/config.py index 4d4472f64d..0031c976cf 100644 --- a/code/default/launcher/config.py +++ b/code/default/launcher/config.py @@ -24,6 +24,7 @@ config.set_var("control_ip", "127.0.0.1") config.set_var("control_port", 8085) +config.set_var("allowed_refers", [""]) # System config config.set_var("language", "") # en_US, diff --git a/code/default/launcher/web_control.py b/code/default/launcher/web_control.py index bed1ee7bff..169f33d1f4 100644 --- a/code/default/launcher/web_control.py +++ b/code/default/launcher/web_control.py @@ -67,6 +67,15 @@ def handle_one_request(self): self.close_connection = 0 +CORS_header = { + "Allow": "GET,POST,OPTIONS", + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Methods": "GET,POST,OPTIONS", + "Access-Control-Allow-Headers": "Authorization,Content-Type", + "Connection": "close", + "Content-Type": "text/html", +} + class Http_Handler(simple_http_server.HttpServerHandler): deploy_proc = None @@ -95,17 +104,24 @@ def load_module_menus(self): def do_OPTIONS(self): try: - origin = utils.to_str(self.headers.get(b'Origin')) + # origin = utils.to_str(self.headers.get(b'Origin')) # if origin not in self.config.allow_web_origins: # return - header = { - "Allow": "GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS", - "Access-Control-Allow-Origin": origin, - "Access-Control-Allow-Methods": "GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS", - "Access-Control-Allow-Headers": "Authorization,Content-Type", - } - return self.send_response(headers=header) + self.headers = utils.to_str(self.headers) + self.path = utils.to_str(self.path) + + refer = self.headers.get('Referer') + if refer: + refer_loc = urlparse(refer).netloc + host = self.headers.get('Host') + if refer_loc != host and refer_loc not in config.allowed_refers: + xlog.warn("web control ref:%s host:%s", refer_loc, host) + return + + self.set_CORS(CORS_header) + + return self.send_response() except Exception as e: xlog.exception("options fail:%r", e) return self.send_not_found() @@ -118,10 +134,12 @@ def do_POST(self): if refer: refer_loc = urlparse(refer).netloc host = self.headers.get('Host') - if refer_loc != host: + if refer_loc != host and refer_loc not in config.allowed_refers: xlog.warn("web control ref:%s host:%s", refer_loc, host) return + self.set_CORS(CORS_header) + try: content_type = self.headers.get('Content-Type', "") ctype, pdict = cgi.parse_header(content_type) diff --git a/code/default/lib/noarch/simple_http_server.py b/code/default/lib/noarch/simple_http_server.py index fbd2769849..b01deb3e96 100644 --- a/code/default/lib/noarch/simple_http_server.py +++ b/code/default/lib/noarch/simple_http_server.py @@ -49,6 +49,8 @@ class HttpServerHandler(): rbufsize = 32 * 1024 wbufsize = 32 * 1024 + res_headers = {} + def __init__(self, sock, client, args, logger=None): self.connection = sock sock.setblocking(1) @@ -65,6 +67,9 @@ def __init__(self, sock, client, args, logger=None): self.setup() + def set_CORS(self, headers): + self.res_headers = headers + def setup(self): pass @@ -364,7 +369,10 @@ def send_response(self, mimetype=b"", content=b"", headers=b"", status=200): content = utils.to_bytes(content) + for key in self.res_headers: + data.append(b"%s: %s\r\n" % (utils.to_bytes(key), utils.to_bytes(self.res_headers[key]))) data.append(b'Content-Length: %d\r\n' % len(content)) + if len(headers): if isinstance(headers, dict): headers = utils.to_bytes(headers)