📄 gost-save-server.py 📝 编辑 ⬇ 下载 ← 返回列表
#!/usr/bin/env python3
"""极简HTTP服务: POST /save 接收规则JSON写回gost.yaml"""
 json, subprocess
 http.server  BaseHTTPRequestHandler, HTTPServer

 H(BaseHTTPRequestHandler):
    USER="admin"; PASS="oyh159159oiw.@"
     _check_auth(self):
         base64
        a=self.headers.get("Authorization","")
         a.startswith("Basic "):
            :
                u,p=base64.b64decode(a[:]).decode().split(":",)
                 u==self.USER  p==self.PASS
             Exception:  
         
     _cors(self):
        self.send_header("Access-Control-Allow-Origin","*")
        self.send_header("Access-Control-Allow-Headers","*")
        self.send_header("Access-Control-Allow-Methods","POST, OPTIONS")
     do_OPTIONS(self):
        self.send_response(); self._cors(); self.end_headers()
     do_GET(self):
          self._check_auth():
            self.send_response(); self._cors()
            self.send_header("WWW-Authenticate","Basic realm=gost"); self.end_headers(); 
         self.path   ("/yaml","/rawyaml"):
            self.send_response(); self._cors(); self.end_headers(); 
         self.path=="/rawyaml":
             open("/etc/gost/gost.yaml","rb")  f: raw=f.read()
            self.send_response()
            self._cors(); self.send_header("Content-Type","text/plain; charset=utf-")
            self.end_headers(); self.wfile.write(raw)
            
            self.send_response(); self._cors(); self.end_headers(); 
        :
             open("/etc/gost/gost.yaml")  f: txt=f.read()
             yaml  Y
            data=Y.safe_load(txt)  {}
             json  J
            out=J.dumps({"services":data.get("services",[])}).encode()
            self.send_response()
         Exception  e:
            out=str(e).encode(); self.send_response()
        self._cors(); self.send_header("Content-Type","application/json")
        self.end_headers(); self.wfile.write(out)
     do_POST(self):
          self._check_auth():
            self.send_response(); self._cors()
            self.send_header("WWW-Authenticate","Basic realm=gost"); self.end_headers(); 
         self.path != "/save":
            self.send_response(); self._cors(); self.end_headers(); 
        n = int(self.headers.get("Content-Length",""))
        body = self.rfile.read(n)
        :
            r = subprocess.run(["python3","/usr/local/bin/gost-save.py"],
                input=body, capture_output=, timeout=)
            out = r.stdout.decode()  r.stderr.decode()
            code =   r.returncode==  
         Exception  e:
            out = str(e); code = 
        self.send_response(code)
        self._cors(); self.send_header("Content-Type","text/plain")
        self.end_headers()
        self.wfile.write(out.encode())
     log_message(self,*a): 

 auto_sync():
     time, urllib.request, base64, yaml  Y, shutil, datetime
    CONF="/etc/gost/gost.yaml"
    auth="Basic "+base64.b64encode(b"admin:oyh159159oiw.@").decode()
     :
        time.sleep()
        :
            req=urllib.request.Request("http://.:/gostapi/config")
            req.add_header("Authorization",auth)
             urllib.request.urlopen(req,timeout=)  r:
                rt=json.load(r)
            names_rt=sorted(s["name"]  s  (rt.get("services")  []))
             open(CONF)  f: cfg=Y.safe_load(f)  {}
            names_yaml=sorted(s["name"]  s  (cfg.get("services")  []))
            # 提取运行时规则的纯净结构(去掉status等动态字段)
            clean=[]
             s  (rt.get("services")  []):
                d={k:v  k,v  s.items()  k  ("name","addr","handler","listener","forwarder","metadata","ignoreClientVersion")}
                clean.append(d)
             names_rt!=names_yaml:
                bak=CONF+".bak-"+datetime.datetime.now().strftime("%Y%m%d%H%M%S")
                shutil.copy(CONF,bak)
                cfg["services"]=clean
                 open(CONF,"w")  f: Y.safe_dump(cfg,f,sort_keys=,allow_unicode=)
                ("auto-synced yaml:",names_rt,flush=)
         Exception  e:
            ("auto-sync err:",e,flush=)
 threading
threading.Thread(target=auto_sync,daemon=).start()
HTTPServer((".",),H).serve_forever()