mirror of
https://github.com/9001/copyparty.git
synced 2025-08-17 00:52:16 -06:00
support location-based rproxy
This commit is contained in:
parent
02ad4bfab2
commit
db194ab519
|
@ -673,6 +673,7 @@ def run_argparse(
|
|||
ap2.add_argument("-p", metavar="PORT", type=u, default="3923", help="ports to bind (comma/range)")
|
||||
ap2.add_argument("--ll", action="store_true", help="include link-local IPv4/IPv6 even if the NIC has routable IPs (breaks some mdns clients)")
|
||||
ap2.add_argument("--rproxy", metavar="DEPTH", type=int, default=1, help="which ip to keep; [\033[32m0\033[0m]=tcp, [\033[32m1\033[0m]=origin (first x-fwd), [\033[32m2\033[0m]=cloudflare, [\033[32m3\033[0m]=nginx, [\033[32m-1\033[0m]=closest proxy")
|
||||
ap2.add_argument("--webroot", metavar="PATH", type=u, default="", help="if reverse-proxying on a location instead of a dedicated subdomain, provide the location here")
|
||||
if ANYWIN:
|
||||
ap2.add_argument("--reuseaddr", action="store_true", help="set reuseaddr on listening sockets on windows; allows rapid restart of copyparty at the expense of being able to accidentally start multiple instances")
|
||||
ap2.add_argument("--s-wr-sz", metavar="B", type=int, default=256*1024, help="socket write size in bytes")
|
||||
|
|
|
@ -119,6 +119,8 @@ class HttpCli(object):
|
|||
# placeholders; assigned by run()
|
||||
self.keepalive = False
|
||||
self.is_https = False
|
||||
self.is_proxied = False
|
||||
self.is_vproxied = False
|
||||
self.in_hdr_recv = True
|
||||
self.headers: dict[str, str] = {}
|
||||
self.mode = " "
|
||||
|
@ -191,6 +193,7 @@ class HttpCli(object):
|
|||
|
||||
def j2s(self, name: str, **ka: Any) -> str:
|
||||
tpl = self.conn.hsrv.j2[name]
|
||||
ka["r"] = self.args.SR if self.is_vproxied else ""
|
||||
ka["ts"] = self.conn.hsrv.cachebuster()
|
||||
ka["lang"] = self.args.lang
|
||||
ka["favico"] = self.args.favico
|
||||
|
@ -276,6 +279,8 @@ class HttpCli(object):
|
|||
self.log(t.format(self.args.rproxy, zso), c=3)
|
||||
|
||||
self.log_src = self.conn.set_rproxy(self.ip)
|
||||
self.is_vproxied = bool(self.args.R)
|
||||
self.is_proxied = True
|
||||
|
||||
if self.is_banned():
|
||||
return False
|
||||
|
@ -320,6 +325,13 @@ class HttpCli(object):
|
|||
else:
|
||||
uparam[k.lower()] = ""
|
||||
|
||||
if self.is_vproxied:
|
||||
if vpath.startswith(self.args.R):
|
||||
vpath = vpath[len(self.args.R) + 1 :]
|
||||
else:
|
||||
t = "incorrect --webroot or webserver config; expected vpath starting with [{}] but got [{}]"
|
||||
self.log(t.format(self.args.R, vpath), 1)
|
||||
|
||||
self.ouparam = {k: zs for k, zs in uparam.items()}
|
||||
|
||||
if self.args.rsp_slp:
|
||||
|
@ -604,10 +616,11 @@ class HttpCli(object):
|
|||
status: int = 200,
|
||||
use302: bool = False,
|
||||
) -> bool:
|
||||
vp = self.args.RS + vpath
|
||||
html = self.j2s(
|
||||
"msg",
|
||||
h2='<a href="/{}">{} /{}</a>'.format(
|
||||
quotep(vpath) + suf, flavor, html_escape(vpath, crlf=True) + suf
|
||||
quotep(vp) + suf, flavor, html_escape(vp, crlf=True) + suf
|
||||
),
|
||||
pre=msg,
|
||||
click=click,
|
||||
|
@ -1375,7 +1388,7 @@ class HttpCli(object):
|
|||
url = "{}://{}/{}".format(
|
||||
"https" if self.is_https else "http",
|
||||
self.headers.get("host") or "{}:{}".format(*list(self.s.getsockname()[:2])),
|
||||
vpath + vsuf,
|
||||
self.args.RS + vpath + vsuf,
|
||||
)
|
||||
|
||||
return post_sz, sha_hex, sha_b64, remains, path, url
|
||||
|
@ -1576,6 +1589,10 @@ class HttpCli(object):
|
|||
|
||||
x = self.conn.hsrv.broker.ask("up2k.handle_json", body)
|
||||
ret = x.get()
|
||||
if self.is_vproxied:
|
||||
if "purl" in ret:
|
||||
ret["purl"] = self.args.SR + ret["purl"]
|
||||
|
||||
ret = json.dumps(ret)
|
||||
self.log(ret)
|
||||
self.reply(ret.encode("utf-8"), mime="application/json")
|
||||
|
@ -1634,6 +1651,10 @@ class HttpCli(object):
|
|||
if t not in order:
|
||||
order.append(t)
|
||||
|
||||
if self.is_vproxied:
|
||||
for hit in hits:
|
||||
hit["rp"] = self.args.RS + hit["rp"]
|
||||
|
||||
r = json.dumps({"hits": hits, "tag_order": order}).encode("utf-8")
|
||||
self.reply(r, mime="application/json")
|
||||
return True
|
||||
|
@ -2032,7 +2053,7 @@ class HttpCli(object):
|
|||
)[: vfs.flags["fk"]]
|
||||
|
||||
vpath = "{}/{}".format(upload_vpath, lfn).strip("/")
|
||||
rel_url = quotep(vpath) + vsuf
|
||||
rel_url = quotep(self.args.RS + vpath) + vsuf
|
||||
msg += 'sha512: {} // {} // {} bytes // <a href="/{}">{}</a> {}\n'.format(
|
||||
sha_hex[:56],
|
||||
sha_b64,
|
||||
|
@ -2537,6 +2558,7 @@ class HttpCli(object):
|
|||
|
||||
boundary = "\roll\tide"
|
||||
targs = {
|
||||
"r": self.args.SR if self.is_vproxied else "",
|
||||
"ts": self.conn.hsrv.cachebuster(),
|
||||
"svcname": self.args.doctitle,
|
||||
"html_head": self.html_head,
|
||||
|
@ -2765,6 +2787,11 @@ class HttpCli(object):
|
|||
dst = dst[len(top) + 1 :]
|
||||
|
||||
ret = self.gen_tree(top, dst)
|
||||
if self.is_vproxied:
|
||||
parents = self.args.R.split("/")
|
||||
for parent in parents[::-1]:
|
||||
ret = {"k{}".format(parent): ret, "a": []}
|
||||
|
||||
zs = json.dumps(ret)
|
||||
self.reply(zs.encode("utf-8"), mime="application/json")
|
||||
return True
|
||||
|
@ -2875,6 +2902,11 @@ class HttpCli(object):
|
|||
break
|
||||
|
||||
ret = ret[:2000]
|
||||
|
||||
if self.is_vproxied:
|
||||
for v in ret:
|
||||
v["vp"] = self.args.SR + v["vp"]
|
||||
|
||||
jtxt = json.dumps(ret, indent=2, sort_keys=True).encode("utf-8", "replace")
|
||||
self.log("{} #{} {:.2f}sec".format(lm, len(ret), time.time() - t0))
|
||||
self.reply(jtxt, mime="application/json")
|
||||
|
@ -2889,6 +2921,8 @@ class HttpCli(object):
|
|||
|
||||
if not req:
|
||||
req = [self.vpath]
|
||||
elif self.is_vproxied:
|
||||
req = [x[len(self.args.SR) :] for x in req]
|
||||
|
||||
nlim = int(self.uparam.get("lim") or 0)
|
||||
lim = [nlim, nlim] if nlim else []
|
||||
|
@ -2900,6 +2934,10 @@ class HttpCli(object):
|
|||
def handle_mv(self) -> bool:
|
||||
# full path of new loc (incl filename)
|
||||
dst = self.uparam.get("move")
|
||||
|
||||
if self.is_vproxied and dst and dst.startswith(self.args.SR):
|
||||
dst = dst[len(self.args.RS) :]
|
||||
|
||||
if not dst:
|
||||
raise Pebkac(400, "need dst vpath")
|
||||
|
||||
|
|
|
@ -178,11 +178,6 @@ class HttpSrv(object):
|
|||
def listen(self, sck: socket.socket, nlisteners: int) -> None:
|
||||
if self.args.j != 1:
|
||||
# lost in the pickle; redefine
|
||||
try:
|
||||
sck.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
|
||||
except:
|
||||
pass
|
||||
|
||||
if not ANYWIN or self.args.reuseaddr:
|
||||
sck.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# coding: utf-8
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
import stat
|
||||
import tarfile
|
||||
|
||||
from queue import Queue
|
||||
|
@ -79,6 +80,9 @@ class StreamTar(StreamArc):
|
|||
src = f["ap"]
|
||||
fsi = f["st"]
|
||||
|
||||
if stat.S_ISDIR(fsi.st_mode):
|
||||
return
|
||||
|
||||
inf = tarfile.TarInfo(name=name)
|
||||
inf.mode = fsi.st_mode
|
||||
inf.size = fsi.st_size
|
||||
|
|
|
@ -301,6 +301,17 @@ class SvcHub(object):
|
|||
vs = [x for x in vs if x]
|
||||
setattr(al, n, vs)
|
||||
|
||||
R = al.webroot
|
||||
if "//" in R or ":" in R:
|
||||
t = "found URL in --webroot; it should be just the location, for example /foo/bar"
|
||||
raise Exception(t)
|
||||
|
||||
R = R.strip("/")
|
||||
if R:
|
||||
al.R = R
|
||||
al.SR = "/" + R
|
||||
al.RS = R + "/"
|
||||
|
||||
return True
|
||||
|
||||
def _setlimits(self) -> None:
|
||||
|
|
|
@ -3,6 +3,7 @@ from __future__ import print_function, unicode_literals
|
|||
|
||||
import calendar
|
||||
import time
|
||||
import stat
|
||||
import zlib
|
||||
|
||||
from .bos import bos
|
||||
|
@ -238,6 +239,9 @@ class StreamZip(StreamArc):
|
|||
src = f["ap"]
|
||||
st = f["st"]
|
||||
|
||||
if stat.S_ISDIR(st.st_mode):
|
||||
return
|
||||
|
||||
sz = st.st_size
|
||||
ts = st.st_mtime
|
||||
|
||||
|
|
|
@ -209,10 +209,6 @@ class TcpSrv(object):
|
|||
def _listen(self, ip: str, port: int) -> None:
|
||||
ipv = socket.AF_INET6 if ":" in ip else socket.AF_INET
|
||||
srv = socket.socket(ipv, socket.SOCK_STREAM)
|
||||
try:
|
||||
srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
|
||||
except:
|
||||
pass
|
||||
|
||||
if not ANYWIN or self.args.reuseaddr:
|
||||
srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
|
|
|
@ -1075,18 +1075,18 @@ html.y #widget.open {
|
|||
top: -.12em;
|
||||
}
|
||||
#wtico {
|
||||
cursor: url(/.cpr/dd/4.png), pointer;
|
||||
cursor: url(dd/4.png), pointer;
|
||||
animation: cursor 500ms;
|
||||
}
|
||||
#wtico:hover {
|
||||
animation: cursor 500ms infinite;
|
||||
}
|
||||
@keyframes cursor {
|
||||
0% {cursor: url(/.cpr/dd/2.png), pointer}
|
||||
30% {cursor: url(/.cpr/dd/3.png), pointer}
|
||||
50% {cursor: url(/.cpr/dd/4.png), pointer}
|
||||
75% {cursor: url(/.cpr/dd/5.png), pointer}
|
||||
85% {cursor: url(/.cpr/dd/4.png), pointer}
|
||||
0% {cursor: url(dd/2.png), pointer}
|
||||
30% {cursor: url(dd/3.png), pointer}
|
||||
50% {cursor: url(dd/4.png), pointer}
|
||||
75% {cursor: url(dd/5.png), pointer}
|
||||
85% {cursor: url(dd/4.png), pointer}
|
||||
}
|
||||
@keyframes spin {
|
||||
100% {transform: rotate(360deg)}
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=0.8, minimum-scale=0.6">
|
||||
<meta name="theme-color" content="#333">
|
||||
{{ html_head }}
|
||||
<link rel="stylesheet" media="screen" href="/.cpr/ui.css?_={{ ts }}">
|
||||
<link rel="stylesheet" media="screen" href="/.cpr/browser.css?_={{ ts }}">
|
||||
<link rel="stylesheet" media="screen" href="{{ r }}/.cpr/ui.css?_={{ ts }}">
|
||||
<link rel="stylesheet" media="screen" href="{{ r }}/.cpr/browser.css?_={{ ts }}">
|
||||
{%- if css %}
|
||||
<link rel="stylesheet" media="screen" href="{{ css }}?_={{ ts }}">
|
||||
{%- endif %}
|
||||
|
@ -71,7 +71,7 @@
|
|||
<h1 id="path">
|
||||
<a href="#" id="entree">🌲</a>
|
||||
{%- for n in vpnodes %}
|
||||
<a href="/{{ n[0] }}">{{ n[1] }}</a>
|
||||
<a href="{{ r }}/{{ n[0] }}">{{ n[1] }}</a>
|
||||
{%- endfor %}
|
||||
</h1>
|
||||
|
||||
|
@ -121,7 +121,7 @@
|
|||
|
||||
<div id="epi" class="logue">{{ logues[1] }}</div>
|
||||
|
||||
<h2><a href="/?h" id="goh">control-panel</a></h2>
|
||||
<h2><a href="{{ r }}/?h" id="goh">control-panel</a></h2>
|
||||
|
||||
<a href="#" id="repl">π</a>
|
||||
|
||||
|
@ -134,7 +134,8 @@
|
|||
<div id="widget"></div>
|
||||
|
||||
<script>
|
||||
var acct = "{{ acct }}",
|
||||
var SR = {{ r|tojson }},
|
||||
acct = "{{ acct }}",
|
||||
perms = {{ perms }},
|
||||
themes = {{ themes }},
|
||||
dtheme = "{{ dtheme }}",
|
||||
|
@ -160,10 +161,10 @@
|
|||
|
||||
document.documentElement.className = localStorage.theme || dtheme;
|
||||
</script>
|
||||
<script src="/.cpr/util.js?_={{ ts }}"></script>
|
||||
<script src="/.cpr/baguettebox.js?_={{ ts }}"></script>
|
||||
<script src="/.cpr/browser.js?_={{ ts }}"></script>
|
||||
<script src="/.cpr/up2k.js?_={{ ts }}"></script>
|
||||
<script src="{{ r }}/.cpr/util.js?_={{ ts }}"></script>
|
||||
<script src="{{ r }}/.cpr/baguettebox.js?_={{ ts }}"></script>
|
||||
<script src="{{ r }}/.cpr/browser.js?_={{ ts }}"></script>
|
||||
<script src="{{ r }}/.cpr/up2k.js?_={{ ts }}"></script>
|
||||
{%- if js %}
|
||||
<script src="{{ js }}?_={{ ts }}"></script>
|
||||
{%- endif %}
|
||||
|
|
|
@ -3647,7 +3647,7 @@ var showfile = (function () {
|
|||
qsr('#prism_css');
|
||||
var el = mknod('link', 'prism_css');
|
||||
el.rel = 'stylesheet';
|
||||
el.href = '/.cpr/deps/prism' + (light ? '' : 'd') + '.css';
|
||||
el.href = SR + '/.cpr/deps/prism' + (light ? '' : 'd') + '.css';
|
||||
document.head.appendChild(el);
|
||||
};
|
||||
|
||||
|
@ -3775,7 +3775,7 @@ var showfile = (function () {
|
|||
if (!defer)
|
||||
fun(el.firstChild);
|
||||
else
|
||||
import_js('/.cpr/deps/prism.js', function () { fun(); });
|
||||
import_js(SR + '/.cpr/deps/prism.js', function () { fun(); });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4181,10 +4181,10 @@ var thegrid = (function () {
|
|||
if (r.thumbs) {
|
||||
ihref += '?th=' + (have_webp ? 'w' : 'j');
|
||||
if (href == "#")
|
||||
ihref = '/.cpr/ico/⏏️';
|
||||
ihref = SR + '/.cpr/ico/⏏️';
|
||||
}
|
||||
else if (isdir) {
|
||||
ihref = '/.cpr/ico/folder';
|
||||
ihref = SR + '/.cpr/ico/folder';
|
||||
}
|
||||
else {
|
||||
var ar = href.split('.');
|
||||
|
@ -4209,7 +4209,7 @@ var thegrid = (function () {
|
|||
else
|
||||
ext = "unk";
|
||||
}
|
||||
ihref = '/.cpr/ico/' + ext;
|
||||
ihref = SR + '/.cpr/ico/' + ext;
|
||||
}
|
||||
ihref += (ihref.indexOf('?') > 0 ? '&' : '?') + 'cache=i';
|
||||
|
||||
|
@ -4784,7 +4784,7 @@ document.onkeydown = function (e) {
|
|||
clearTimeout(search_timeout);
|
||||
|
||||
var xhr = new XHR();
|
||||
xhr.open('POST', '/?srch', true);
|
||||
xhr.open('POST', SR + '/?srch', true);
|
||||
xhr.setRequestHeader('Content-Type', 'text/plain');
|
||||
xhr.onload = xhr.onerror = xhr_search_results;
|
||||
xhr.ts = Date.now();
|
||||
|
@ -5323,7 +5323,12 @@ var treectl = (function () {
|
|||
treegrow.call(this.previousSibling, e);
|
||||
return;
|
||||
}
|
||||
r.reqls(this.getAttribute('href'), true);
|
||||
var href = this.getAttribute('href');
|
||||
if (R && !href.startsWith(SR)) {
|
||||
window.location = href;
|
||||
return;
|
||||
}
|
||||
r.reqls(href, true);
|
||||
r.dir_cb = tree_scrollto;
|
||||
thegrid.setvis(true);
|
||||
}
|
||||
|
@ -5547,7 +5552,7 @@ var treectl = (function () {
|
|||
qsr('#bbsw');
|
||||
if (ls0 === null) {
|
||||
var xhr = new XHR();
|
||||
xhr.open('GET', '/?am_js', true);
|
||||
xhr.open('GET', SR + '/?am_js', true);
|
||||
xhr.send();
|
||||
|
||||
r.ls_cb = showfile.addlinks;
|
||||
|
@ -6552,7 +6557,7 @@ function show_md(md, name, div, url, depth) {
|
|||
if (depth)
|
||||
return toast.warn(10, errmsg + 'failed to load marked.js')
|
||||
|
||||
return import_js('/.cpr/deps/marked.js', function () {
|
||||
return import_js(SR + '/.cpr/deps/marked.js', function () {
|
||||
show_md(md, name, div, url, 1);
|
||||
});
|
||||
}
|
||||
|
@ -6705,7 +6710,7 @@ var unpost = (function () {
|
|||
r.me = me;
|
||||
}
|
||||
|
||||
var q = '/?ups';
|
||||
var q = SR + '/?ups';
|
||||
if (filt.value)
|
||||
q += '&filter=' + uricom_enc(filt.value, true);
|
||||
|
||||
|
@ -6771,7 +6776,7 @@ var unpost = (function () {
|
|||
var xhr = new XHR();
|
||||
xhr.n = n;
|
||||
xhr.n2 = n2;
|
||||
xhr.open('POST', '/?delete&lim=' + req.length, true);
|
||||
xhr.open('POST', SR + '/?delete&lim=' + req.length, true);
|
||||
xhr.onload = xhr.onerror = unpost_delete_cb;
|
||||
xhr.send(JSON.stringify(req));
|
||||
};
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
<div>{{ logues[1] }}</div><br />
|
||||
{%- endif %}
|
||||
|
||||
<h2><a href="/{{ url_suf }}{{ url_suf and '&' or '?' }}h">control-panel</a></h2>
|
||||
<h2><a href="{{ r }}/{{ url_suf }}{{ url_suf and '&' or '?' }}h">control-panel</a></h2>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=0.7">
|
||||
<meta name="theme-color" content="#333">
|
||||
{{ html_head }}
|
||||
<link rel="stylesheet" href="/.cpr/ui.css?_={{ ts }}">
|
||||
<link rel="stylesheet" href="/.cpr/md.css?_={{ ts }}">
|
||||
<link rel="stylesheet" href="{{ r }}/.cpr/ui.css?_={{ ts }}">
|
||||
<link rel="stylesheet" href="{{ r }}/.cpr/md.css?_={{ ts }}">
|
||||
{%- if edit %}
|
||||
<link rel="stylesheet" href="/.cpr/md2.css?_={{ ts }}">
|
||||
<link rel="stylesheet" href="{{ r }}/.cpr/md2.css?_={{ ts }}">
|
||||
{%- endif %}
|
||||
</head>
|
||||
<body>
|
||||
|
@ -128,7 +128,8 @@ write markdown (most html is 🙆 too)
|
|||
|
||||
<script>
|
||||
|
||||
var last_modified = {{ lastmod }},
|
||||
var SR = {{ r|tojson }},
|
||||
last_modified = {{ lastmod }},
|
||||
have_emp = {{ have_emp|tojson }},
|
||||
dfavico = "{{ favico }}";
|
||||
|
||||
|
@ -153,10 +154,10 @@ l.light = drk? 0:1;
|
|||
})();
|
||||
|
||||
</script>
|
||||
<script src="/.cpr/util.js?_={{ ts }}"></script>
|
||||
<script src="/.cpr/deps/marked.js?_={{ ts }}"></script>
|
||||
<script src="/.cpr/md.js?_={{ ts }}"></script>
|
||||
<script src="{{ r }}/.cpr/util.js?_={{ ts }}"></script>
|
||||
<script src="{{ r }}/.cpr/deps/marked.js?_={{ ts }}"></script>
|
||||
<script src="{{ r }}/.cpr/md.js?_={{ ts }}"></script>
|
||||
{%- if edit %}
|
||||
<script src="/.cpr/md2.js?_={{ ts }}"></script>
|
||||
<script src="{{ r }}/.cpr/md2.js?_={{ ts }}"></script>
|
||||
{%- endif %}
|
||||
</body></html>
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=0.7">
|
||||
<meta name="theme-color" content="#333">
|
||||
{{ html_head }}
|
||||
<link rel="stylesheet" href="/.cpr/ui.css?_={{ ts }}">
|
||||
<link rel="stylesheet" href="/.cpr/mde.css?_={{ ts }}">
|
||||
<link rel="stylesheet" href="/.cpr/deps/mini-fa.css?_={{ ts }}">
|
||||
<link rel="stylesheet" href="/.cpr/deps/easymde.css?_={{ ts }}">
|
||||
<link rel="stylesheet" href="{{ r }}/.cpr/ui.css?_={{ ts }}">
|
||||
<link rel="stylesheet" href="{{ r }}/.cpr/mde.css?_={{ ts }}">
|
||||
<link rel="stylesheet" href="{{ r }}/.cpr/deps/mini-fa.css?_={{ ts }}">
|
||||
<link rel="stylesheet" href="{{ r }}/.cpr/deps/easymde.css?_={{ ts }}">
|
||||
</head>
|
||||
<body>
|
||||
<div id="mw">
|
||||
|
@ -26,7 +26,8 @@
|
|||
<a href="#" id="repl">π</a>
|
||||
<script>
|
||||
|
||||
var last_modified = {{ lastmod }},
|
||||
var SR = {{ r|tojson }},
|
||||
last_modified = {{ lastmod }},
|
||||
have_emp = {{ have_emp|tojson }},
|
||||
dfavico = "{{ favico }}";
|
||||
|
||||
|
@ -48,8 +49,8 @@ l.light = drk? 0:1;
|
|||
})();
|
||||
|
||||
</script>
|
||||
<script src="/.cpr/util.js?_={{ ts }}"></script>
|
||||
<script src="/.cpr/deps/marked.js?_={{ ts }}"></script>
|
||||
<script src="/.cpr/deps/easymde.js?_={{ ts }}"></script>
|
||||
<script src="/.cpr/mde.js?_={{ ts }}"></script>
|
||||
<script src="{{ r }}/.cpr/util.js?_={{ ts }}"></script>
|
||||
<script src="{{ r }}/.cpr/deps/marked.js?_={{ ts }}"></script>
|
||||
<script src="{{ r }}/.cpr/deps/easymde.js?_={{ ts }}"></script>
|
||||
<script src="{{ r }}/.cpr/mde.js?_={{ ts }}"></script>
|
||||
</body></html>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=0.8">
|
||||
<meta name="theme-color" content="#333">
|
||||
{{ html_head }}
|
||||
<link rel="stylesheet" media="screen" href="/.cpr/msg.css?_={{ ts }}">
|
||||
<link rel="stylesheet" media="screen" href="{{ r }}/.cpr/msg.css?_={{ ts }}">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
|
|
@ -8,19 +8,19 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=0.8">
|
||||
<meta name="theme-color" content="#333">
|
||||
{{ html_head }}
|
||||
<link rel="stylesheet" media="screen" href="/.cpr/splash.css?_={{ ts }}">
|
||||
<link rel="stylesheet" media="screen" href="/.cpr/ui.css?_={{ ts }}">
|
||||
<link rel="stylesheet" media="screen" href="{{ r }}/.cpr/splash.css?_={{ ts }}">
|
||||
<link rel="stylesheet" media="screen" href="{{ r }}/.cpr/ui.css?_={{ ts }}">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="wrap">
|
||||
<a id="a" href="/?h" class="af">refresh</a>
|
||||
<a id="v" href="/?hc" class="af">connect</a>
|
||||
<a id="a" href="{{ r }}/?h" class="af">refresh</a>
|
||||
<a id="v" href="{{ r }}/?hc" class="af">connect</a>
|
||||
|
||||
{%- if this.uname == '*' %}
|
||||
<p id="b">howdy stranger <small>(you're not logged in)</small></p>
|
||||
{%- else %}
|
||||
<a id="c" href="/?pw=x" class="logout">logout</a>
|
||||
<a id="c" href="{{ r }}/?pw=x" class="logout">logout</a>
|
||||
<p><span id="m">welcome back,</span> <strong>{{ this.uname }}</strong></p>
|
||||
{%- endif %}
|
||||
|
||||
|
@ -53,8 +53,8 @@
|
|||
</table>
|
||||
</td></tr></table>
|
||||
<div class="btns">
|
||||
<a id="d" href="/?stack">dump stack</a>
|
||||
<a id="e" href="/?reload=cfg">reload cfg</a>
|
||||
<a id="d" href="{{ r }}/?stack">dump stack</a>
|
||||
<a id="e" href="{{ r }}/?reload=cfg">reload cfg</a>
|
||||
</div>
|
||||
{%- endif %}
|
||||
|
||||
|
@ -79,18 +79,18 @@
|
|||
<h1 id="cc">client config:</h1>
|
||||
<ul>
|
||||
{% if k304 %}
|
||||
<li><a id="h" href="/?k304=n">disable k304</a> (currently enabled)
|
||||
<li><a id="h" href="{{ r }}/?k304=n">disable k304</a> (currently enabled)
|
||||
{%- else %}
|
||||
<li><a id="i" href="/?k304=y" class="r">enable k304</a> (currently disabled)
|
||||
<li><a id="i" href="{{ r }}/?k304=y" class="r">enable k304</a> (currently disabled)
|
||||
{% endif %}
|
||||
<blockquote id="j">enabling this will disconnect your client on every HTTP 304, which can prevent some buggy proxies from getting stuck (suddenly not loading pages), <em>but</em> it will also make things slower in general</blockquote></li>
|
||||
|
||||
<li><a id="k" href="/?reset" class="r" onclick="localStorage.clear();return true">reset client settings</a></li>
|
||||
<li><a id="k" href="{{ r }}/?reset" class="r" onclick="localStorage.clear();return true">reset client settings</a></li>
|
||||
</ul>
|
||||
|
||||
<h1 id="l">login for more:</h1>
|
||||
<ul>
|
||||
<form method="post" enctype="multipart/form-data" action="/{{ qvpath }}">
|
||||
<form method="post" enctype="multipart/form-data" action="{{ r }}/{{ qvpath }}">
|
||||
<input type="hidden" name="act" value="login" />
|
||||
<input type="password" name="cppwd" />
|
||||
<input type="submit" value="Login" />
|
||||
|
@ -100,13 +100,14 @@
|
|||
<a href="#" id="repl">π</a>
|
||||
<script>
|
||||
|
||||
var lang="{{ lang }}",
|
||||
var SR = {{ r|tojson }},
|
||||
lang="{{ lang }}",
|
||||
dfavico="{{ favico }}";
|
||||
|
||||
document.documentElement.className=localStorage.theme||"{{ this.args.theme }}";
|
||||
|
||||
</script>
|
||||
<script src="/.cpr/util.js?_={{ ts }}"></script>
|
||||
<script src="/.cpr/splash.js?_={{ ts }}"></script>
|
||||
<script src="{{ r }}/.cpr/util.js?_={{ ts }}"></script>
|
||||
<script src="{{ r }}/.cpr/splash.js?_={{ ts }}"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -8,14 +8,14 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=0.8">
|
||||
<meta name="theme-color" content="#333">
|
||||
{{ html_head }}
|
||||
<link rel="stylesheet" media="screen" href="/.cpr/splash.css?_={{ ts }}">
|
||||
<link rel="stylesheet" media="screen" href="/.cpr/ui.css?_={{ ts }}">
|
||||
<link rel="stylesheet" media="screen" href="{{ r }}/.cpr/splash.css?_={{ ts }}">
|
||||
<link rel="stylesheet" media="screen" href="{{ r }}/.cpr/ui.css?_={{ ts }}">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="wrap" class="w">
|
||||
<div class="cn">
|
||||
<p class="btns"><a href="/{{ vp }}">browse files</a> // <a href="/?h">control panel</a></p>
|
||||
<p class="btns"><a href="{{ r }}/{{ vp }}">browse files</a> // <a href="{{ r }}/?h">control panel</a></p>
|
||||
<p>or choose your OS for cooler alternatives:</p>
|
||||
<div class="ossel">
|
||||
<a id="swin" href="#">Windows</a>
|
||||
|
@ -53,7 +53,7 @@
|
|||
<p><em>note: if you are on LAN (or just dont have valid certificates), add <code>--no-check-certificate</code> to the mount command</em><br />---</p>
|
||||
{% endif %}
|
||||
|
||||
<p>if you want to use the native WebDAV client in windows instead (slow and buggy), first run <a href="/.cpr/a/webdav-cfg.bat">webdav-cfg.bat</a> to remove the 47 MiB filesize limit (also fixes latency and password login), then connect:</p>
|
||||
<p>if you want to use the native WebDAV client in windows instead (slow and buggy), first run <a href="{{ r }}/.cpr/a/webdav-cfg.bat">webdav-cfg.bat</a> to remove the 47 MiB filesize limit (also fixes latency and password login), then connect:</p>
|
||||
<pre>
|
||||
net use <b>w:</b> http{{ s }}://{{ ep }}/{{ vp }}{% if accs %} k /user:<b>{{ pw }}</b>{% endif %}
|
||||
</pre>
|
||||
|
@ -144,7 +144,7 @@
|
|||
|
||||
<h1>partyfuse</h1>
|
||||
<p>
|
||||
<a href="/.cpr/a/partyfuse.py">partyfuse.py</a> -- fast, read-only,
|
||||
<a href="{{ r }}/.cpr/a/partyfuse.py">partyfuse.py</a> -- fast, read-only,
|
||||
<span class="os win">needs <a href="https://winfsp.dev/rel/">winfsp</a></span>
|
||||
<span class="os lin">doesn't need root</span>
|
||||
</p>
|
||||
|
@ -155,7 +155,7 @@
|
|||
<p><em>note: if you are on LAN (or just dont have valid certificates), add <code>-td</code></em></p>
|
||||
{% endif %}
|
||||
<p>
|
||||
you can use <a href="/.cpr/a/up2k.py">up2k.py</a> to upload (sometimes faster than web-browsers)
|
||||
you can use <a href="{{ r }}/.cpr/a/up2k.py">up2k.py</a> to upload (sometimes faster than web-browsers)
|
||||
</p>
|
||||
|
||||
|
||||
|
@ -188,13 +188,14 @@
|
|||
<a href="#" id="repl">π</a>
|
||||
<script>
|
||||
|
||||
var lang="{{ lang }}",
|
||||
var SR = {{ r|tojson }},
|
||||
lang="{{ lang }}",
|
||||
dfavico="{{ favico }}";
|
||||
|
||||
document.documentElement.className=localStorage.theme||"{{ args.theme }}";
|
||||
|
||||
</script>
|
||||
<script src="/.cpr/util.js?_={{ ts }}"></script>
|
||||
<script src="/.cpr/svcs.js?_={{ ts }}"></script>
|
||||
<script src="{{ r }}/.cpr/util.js?_={{ ts }}"></script>
|
||||
<script src="{{ r }}/.cpr/svcs.js?_={{ ts }}"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
@font-face {
|
||||
font-family: 'scp';
|
||||
font-display: swap;
|
||||
src: local('Source Code Pro Regular'), local('SourceCodePro-Regular'), url(/.cpr/deps/scp.woff2) format('woff2');
|
||||
src: local('Source Code Pro Regular'), local('SourceCodePro-Regular'), url(deps/scp.woff2) format('woff2');
|
||||
}
|
||||
html {
|
||||
touch-action: manipulation;
|
||||
|
|
|
@ -779,7 +779,7 @@ function up2k_init(subtle) {
|
|||
|
||||
setTimeout(function () {
|
||||
if (window.WebAssembly && !hws.length)
|
||||
fetch('/.cpr/w.hash.js' + CB);
|
||||
fetch(SR + '/.cpr/w.hash.js' + CB);
|
||||
}, 1000);
|
||||
|
||||
function showmodal(msg) {
|
||||
|
@ -809,7 +809,7 @@ function up2k_init(subtle) {
|
|||
m = L.u_https1 + ' <a href="' + (window.location + '').replace(':', 's:') + '">' + L.u_https2 + '</a> ' + L.u_https3;
|
||||
|
||||
showmodal('<h1>loading ' + fn + '</h1>');
|
||||
import_js('/.cpr/deps/' + fn, unmodal);
|
||||
import_js(SR + '/.cpr/deps/' + fn, unmodal);
|
||||
|
||||
if (HTTPS) {
|
||||
// chrome<37 firefox<34 edge<12 opera<24 safari<7
|
||||
|
@ -1312,7 +1312,7 @@ function up2k_init(subtle) {
|
|||
|
||||
if (window.WebAssembly && !hws.length) {
|
||||
for (var a = 0; a < Math.min(navigator.hardwareConcurrency || 4, 16); a++)
|
||||
hws.push(new Worker('/.cpr/w.hash.js' + CB));
|
||||
hws.push(new Worker(SR + '/.cpr/w.hash.js' + CB));
|
||||
|
||||
console.log(hws.length + " hashers");
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ if (!window.console || !console.log)
|
|||
var wah = '',
|
||||
L, tt, treectl, thegrid, up2k, asmCrypto, hashwasm, vbar, marked,
|
||||
CB = '?_=' + Date.now(),
|
||||
R = SR.slice(1),
|
||||
RS = R ? "/" + R : "",
|
||||
HALFMAX = 8192 * 8192 * 8192 * 8192,
|
||||
HTTPS = (window.location + '').indexOf('https:') === 0,
|
||||
TOUCH = 'ontouchstart' in window,
|
||||
|
|
|
@ -19,7 +19,7 @@ catch (ex) {
|
|||
}
|
||||
function load_fb() {
|
||||
subtle = null;
|
||||
importScripts('/.cpr/deps/sha512.hw.js');
|
||||
importScripts('deps/sha512.hw.js');
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ font-family: 'fa';
|
|||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: block;
|
||||
src: url("/.cpr/deps/mini-fa.woff") format("woff");
|
||||
src: url("mini-fa.woff") format("woff");
|
||||
}
|
||||
|
||||
.fa,
|
||||
|
|
Loading…
Reference in a new issue