diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py index 7ded17ee..79355774 100644 --- a/copyparty/httpcli.py +++ b/copyparty/httpcli.py @@ -545,6 +545,10 @@ class HttpCli(object): static_path = os.path.join(E.mod, "web/", self.vpath[5:]) return self.tx_file(static_path) + if "cf_challenge" in self.uparam: + self.reply(self.j2s("cf").encode("utf-8", "replace")) + return True + if not self.can_read and not self.can_write and not self.can_get: if self.vpath: self.log("inaccessible: [{}]".format(self.vpath)) @@ -911,6 +915,9 @@ class HttpCli(object): except: raise Pebkac(422, "you POSTed invalid json") + # self.reply(b" DDoS Protection ", 503) + # return True + if "srch" in self.uparam or "srch" in body: return self.handle_search(body) diff --git a/copyparty/httpsrv.py b/copyparty/httpsrv.py index fd449b5f..3f40b5e9 100644 --- a/copyparty/httpsrv.py +++ b/copyparty/httpsrv.py @@ -81,7 +81,7 @@ class HttpSrv(object): env.loader = jinja2.FileSystemLoader(os.path.join(E.mod, "web")) self.j2 = { x: env.get_template(x + ".html") - for x in ["splash", "browser", "browser2", "msg", "md", "mde"] + for x in ["splash", "browser", "browser2", "msg", "md", "mde", "cf"] } self.prism = os.path.exists(os.path.join(E.mod, "web", "deps", "prism.js.gz")) diff --git a/copyparty/util.py b/copyparty/util.py index 844f4add..d7c4a782 100644 --- a/copyparty/util.py +++ b/copyparty/util.py @@ -127,6 +127,7 @@ HTTPCODE = { 429: "Too Many Requests", 500: "Internal Server Error", 501: "Not Implemented", + 503: "Service Unavailable", } diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index a4513516..9767ed98 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -248,6 +248,7 @@ var Ls = { "md_eshow": "cannot show ", "xhr403": "403: Access denied\n\ntry pressing F5, maybe you got logged out", + "cf_ok": "sorry about that -- DDoS protection kicked in\n\nthings should resume in about 30 sec\n\nif nothing happens, hit F5 to reload the page", "tl_xe1": "could not list subfolders:\n\nerror ", "tl_xe2": "404: Folder not found", "fl_xe1": "could not list files in folder:\n\nerror ", @@ -572,6 +573,7 @@ var Ls = { "md_eshow": "kan ikke vise ", "xhr403": "403: Tilgang nektet\n\nkanskje du ble logget ut? prøv å trykk F5", + "cf_ok": "beklager -- liten tilfeldig kontroll, alt OK\n\nting skal fortsette om ca. 30 sekunder\n\nhvis ikkeno skjer, trykk F5 for å laste siden på nytt", "tl_xe1": "kunne ikke hente undermapper:\n\nfeil ", "tl_xe2": "404: Mappen finnes ikke", "fl_xe1": "kunne ikke hente filer i mappen:\n\nfeil ", diff --git a/copyparty/web/cf.html b/copyparty/web/cf.html new file mode 100644 index 00000000..05c5a7e9 --- /dev/null +++ b/copyparty/web/cf.html @@ -0,0 +1,27 @@ + + + + + + {{ svcname }} + + + + + +
+

please press F5 to reload the page

+

sorry for the inconvenience

+
+ + + + + diff --git a/copyparty/web/ui.css b/copyparty/web/ui.css index 4381de5f..ce12fc83 100644 --- a/copyparty/web/ui.css +++ b/copyparty/web/ui.css @@ -190,6 +190,18 @@ html.y #tth { color: #000; background: #fff; } +#cf_frame { + position: fixed; + z-index: 573; + top: 3em; + left: 50%; + width: 40em; + height: 30em; + margin-left: -20.2em; + border-radius: .4em; + border: .4em solid var(--fg); + box-shadow: 0 2em 4em 1em var(--bg-max); +} #modal { position: fixed; overflow: auto; diff --git a/copyparty/web/util.js b/copyparty/web/util.js index cfd41da5..67135f8a 100644 --- a/copyparty/web/util.js +++ b/copyparty/web/util.js @@ -1455,6 +1455,7 @@ var favico = (function () { })(); +var cf_ddos_t = 0; function xhrchk(xhr, prefix, e404) { if (xhr.status < 400 && xhr.status >= 200) return true; @@ -1465,6 +1466,24 @@ function xhrchk(xhr, prefix, e404) { if (xhr.status == 404) return toast.err(0, prefix + e404); - return toast.err(0, prefix + xhr.status + ": " + ( - (xhr.response && xhr.response.err) || xhr.responseText)); + var errtxt = (xhr.response && xhr.response.err) || xhr.responseText, + fun = toast.err; + + if (xhr.status == 503 && /\bDDoS [Pp]rotection|>Just a moment|#cf-bubbles|Checking your browser/.test(errtxt)) { + var now = Date.now(), td = now - cf_ddos_t; + if (td < 15000) + return; + + cf_ddos_t = now; + errtxt = 'Cloudflare DDoS protection kicked in\n\ntrying to fix it...'; + fun = toast.warn; + + qsr('#cf_frame'); + var fr = mknod('iframe'); + fr.src = '/?cf_challenge'; + fr.setAttribute('id', 'cf_frame'); + document.body.appendChild(fr); + } + + return fun(0, prefix + xhr.status + ": " + errtxt); } diff --git a/scripts/sfx.ls b/scripts/sfx.ls index d08d1843..a7bc05e2 100644 --- a/scripts/sfx.ls +++ b/scripts/sfx.ls @@ -43,6 +43,7 @@ copyparty/web/browser.html, copyparty/web/browser.js, copyparty/web/browser2.html, copyparty/web/copyparty.gif, +copyparty/web/cf.html, copyparty/web/dd, copyparty/web/dd/2.png, copyparty/web/dd/3.png,