Nokia123543 commited on
Commit
e4e1f36
·
verified ·
1 Parent(s): db66f3a

PLUS: проверка API понимает заглушку провайдера, переоткрытий не больше 5

Browse files
Files changed (1) hide show
  1. plus/serve_muscriptor.py +32 -7
plus/serve_muscriptor.py CHANGED
@@ -22,6 +22,7 @@ import subprocess
22
  import sys
23
  import threading
24
  import time
 
25
  import urllib.request
26
 
27
  LINKS_FILE = "muscriptor_links.txt"
@@ -280,15 +281,31 @@ BROWSER_UA = ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
280
  "(KHTML, like Gecko) Chrome/128.0 Safari/537.36")
281
 
282
 
 
 
 
 
 
283
  def probe_api(url: str, timeout: float = 10.0) -> tuple[bool, str]:
284
- """API через туннель: должен вернуть JSON со списком инструментов."""
 
285
  try:
286
- with urllib.request.urlopen(url + "/instruments", timeout=timeout) as answer:
287
- if answer.status != 200:
288
- return False, "API код %d" % answer.status
289
- data = json.loads(answer.read().decode("utf-8", "ignore"))
 
290
  except Exception as problem:
291
  return False, "API не ответил (%s)" % type(problem).__name__
 
 
 
 
 
 
 
 
 
292
  names = data.get("instruments") if isinstance(data, dict) else None
293
  if not names:
294
  return False, "API отдал пустой список инструментов"
@@ -612,6 +629,8 @@ def main(argv: list[str] | None = None) -> int:
612
  if tunnel.url and SUBDOMAIN and SUBDOMAIN not in tunnel.url:
613
  say(" провайдер выдал другой адрес (свой поддомен занят): %s" % tunnel.url)
614
  if tunnel.url:
 
 
615
  ttfb, total, size = speed_probe(tunnel.url)
616
  if ttfb >= 0:
617
  say(" скорость ссылки: первый байт %.1f с, страница %.1f с"
@@ -624,6 +643,7 @@ def main(argv: list[str] | None = None) -> int:
624
 
625
  started, beat = time.time(), time.time()
626
  public_fails, checked = 0, time.time()
 
627
  try:
628
  while True:
629
  time.sleep(10)
@@ -655,14 +675,19 @@ def main(argv: list[str] | None = None) -> int:
655
  else:
656
  public_fails += 1
657
  say(" ссылка снаружи: %s (%d подряд)" % (note, public_fails))
658
- if public_fails >= 2:
659
- say(" переоткрываю туннель: снаружи не отвечает")
 
 
660
  tunnel.kill()
661
  tunnel = open_tunnel(proxy_port, order)
662
  write_link(tunnel.url or "", args.port, proxy_port)
663
  if tunnel.url:
664
  say(">>> OPEN THIS LINK: " + tunnel.url)
665
  public_fails = 0
 
 
 
666
  if tunnel is not None and not tunnel.alive():
667
  say("туннель умер, открываю новый")
668
  tunnel.kill()
 
22
  import sys
23
  import threading
24
  import time
25
+ import urllib.error
26
  import urllib.request
27
 
28
  LINKS_FILE = "muscriptor_links.txt"
 
281
  "(KHTML, like Gecko) Chrome/128.0 Safari/537.36")
282
 
283
 
284
+ BYPASS_HEADERS = {"serveo-skip-browser-warning": "true"}
285
+ PAGE_MARKS = ("continue to", "continue to site", "proceed", "phishing",
286
+ "browser warning", "serveo")
287
+
288
+
289
  def probe_api(url: str, timeout: float = 10.0) -> tuple[bool, str]:
290
+ """API через туннель: JSON со списком инструментов, заглушка — не поломка."""
291
+ request = urllib.request.Request(url + "/instruments", headers=BYPASS_HEADERS)
292
  try:
293
+ with urllib.request.urlopen(request, timeout=timeout) as answer:
294
+ status = answer.status
295
+ body = answer.read().decode("utf-8", "ignore")
296
+ except urllib.error.HTTPError as problem:
297
+ return False, "API код %d" % problem.code
298
  except Exception as problem:
299
  return False, "API не ответил (%s)" % type(problem).__name__
300
+ if status != 200:
301
+ return False, "API код %d" % status
302
+ try:
303
+ data = json.loads(body)
304
+ except Exception:
305
+ low = body.lower()
306
+ if any(mark in low for mark in PAGE_MARKS):
307
+ return True, "API за страницей-предупреждением провайдера"
308
+ return False, "API отдал не JSON"
309
  names = data.get("instruments") if isinstance(data, dict) else None
310
  if not names:
311
  return False, "API отдал пустой список инструментов"
 
629
  if tunnel.url and SUBDOMAIN and SUBDOMAIN not in tunnel.url:
630
  say(" провайдер выдал другой адрес (свой поддомен занят): %s" % tunnel.url)
631
  if tunnel.url:
632
+ api_ok, api_note = probe_api(tunnel.url)
633
+ say(" API снаружи: %s" % api_note)
634
  ttfb, total, size = speed_probe(tunnel.url)
635
  if ttfb >= 0:
636
  say(" скорость ссылки: первый байт %.1f с, страница %.1f с"
 
643
 
644
  started, beat = time.time(), time.time()
645
  public_fails, checked = 0, time.time()
646
+ reopens = 0
647
  try:
648
  while True:
649
  time.sleep(10)
 
675
  else:
676
  public_fails += 1
677
  say(" ссылка снаружи: %s (%d подряд)" % (note, public_fails))
678
+ if public_fails >= 3 and reopens < 5:
679
+ reopens += 1
680
+ say(" переоткрываю туннель: снаружи не отвечает"
681
+ " (раз %d из 5)" % reopens)
682
  tunnel.kill()
683
  tunnel = open_tunnel(proxy_port, order)
684
  write_link(tunnel.url or "", args.port, proxy_port)
685
  if tunnel.url:
686
  say(">>> OPEN THIS LINK: " + tunnel.url)
687
  public_fails = 0
688
+ elif public_fails >= 3:
689
+ say(" переоткрытий уже 5, оставляю этот туннель:"
690
+ " проблема не в нём")
691
  if tunnel is not None and not tunnel.alive():
692
  say("туннель умер, открываю новый")
693
  tunnel.kill()