mirror of
https://github.com/9001/copyparty.git
synced 2025-09-28 12:42:26 -06:00
url-param "dl" downloads file
This commit is contained in:
parent
68503444c7
commit
48d6224ec8
|
@ -12,7 +12,6 @@ import random
|
|||
import re
|
||||
import socket
|
||||
import stat
|
||||
import string
|
||||
import sys
|
||||
import threading # typechk
|
||||
import time
|
||||
|
@ -31,7 +30,7 @@ try:
|
|||
except:
|
||||
pass
|
||||
|
||||
from .__init__ import ANYWIN, PY2, RES, TYPE_CHECKING, EnvParams, unicode
|
||||
from .__init__ import ANYWIN, RES, TYPE_CHECKING, EnvParams, unicode
|
||||
from .__version__ import S_VERSION
|
||||
from .authsrv import LEELOO_DALLAS, VFS # typechk
|
||||
from .bos import bos
|
||||
|
@ -66,6 +65,7 @@ from .util import (
|
|||
exclude_dotfiles,
|
||||
formatdate,
|
||||
fsenc,
|
||||
gen_content_disposition,
|
||||
gen_filekey,
|
||||
gen_filekey_dbg,
|
||||
gencookie,
|
||||
|
@ -4013,6 +4013,13 @@ class HttpCli(object):
|
|||
if not editions:
|
||||
return self.tx_404()
|
||||
|
||||
#
|
||||
# force download
|
||||
|
||||
if "dl" in self.ouparam:
|
||||
cdis = gen_content_disposition(os.path.basename(req_path))
|
||||
self.out_headers["Content-Disposition"] = cdis
|
||||
|
||||
#
|
||||
# if-modified
|
||||
|
||||
|
@ -4181,6 +4188,13 @@ class HttpCli(object):
|
|||
if not editions:
|
||||
return self.tx_404()
|
||||
|
||||
#
|
||||
# force download
|
||||
|
||||
if "dl" in self.ouparam:
|
||||
cdis = gen_content_disposition(os.path.basename(req_path))
|
||||
self.out_headers["Content-Disposition"] = cdis
|
||||
|
||||
#
|
||||
# if-modified
|
||||
|
||||
|
@ -4729,24 +4743,7 @@ class HttpCli(object):
|
|||
if maxn < nf:
|
||||
raise Pebkac(400, t)
|
||||
|
||||
safe = (string.ascii_letters + string.digits).replace("%", "")
|
||||
afn = "".join([x if x in safe.replace('"', "") else "_" for x in fn])
|
||||
bascii = unicode(safe).encode("utf-8")
|
||||
zb = fn.encode("utf-8", "xmlcharrefreplace")
|
||||
if not PY2:
|
||||
zbl = [
|
||||
chr(x).encode("utf-8")
|
||||
if x in bascii
|
||||
else "%{:02x}".format(x).encode("ascii")
|
||||
for x in zb
|
||||
]
|
||||
else:
|
||||
zbl = [unicode(x) if x in bascii else "%{:02x}".format(ord(x)) for x in zb]
|
||||
|
||||
ufn = b"".join(zbl).decode("ascii")
|
||||
|
||||
cdis = "attachment; filename=\"{}.{}\"; filename*=UTF-8''{}.{}"
|
||||
cdis = cdis.format(afn, ext, ufn, ext)
|
||||
cdis = gen_content_disposition("%s.%s" % (fn, ext))
|
||||
self.log(repr(cdis))
|
||||
self.send_headers(None, mime=mime, headers={"Content-Disposition": cdis})
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ from .__init__ import (
|
|||
VT100,
|
||||
WINDOWS,
|
||||
EnvParams,
|
||||
unicode,
|
||||
)
|
||||
from .__version__ import S_BUILD_DT, S_VERSION
|
||||
from .stolen import surrogateescape
|
||||
|
@ -115,6 +116,10 @@ IP6ALL = "0:0:0:0:0:0:0:0"
|
|||
IP6_LL = ("fe8", "fe9", "fea", "feb")
|
||||
IP64_LL = ("fe8", "fe9", "fea", "feb", "169.254")
|
||||
|
||||
UC_CDISP = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789._"
|
||||
BC_CDISP = UC_CDISP.encode("ascii")
|
||||
UC_CDISP_SET = set(UC_CDISP)
|
||||
BC_CDISP_SET = set(BC_CDISP)
|
||||
|
||||
try:
|
||||
import fcntl
|
||||
|
@ -2073,6 +2078,29 @@ def gencookie(
|
|||
)
|
||||
|
||||
|
||||
def gen_content_disposition(fn: str) -> str:
|
||||
safe = UC_CDISP_SET
|
||||
bsafe = BC_CDISP_SET
|
||||
fn = fn.replace("/", "_").replace("\\", "_")
|
||||
zb = fn.encode("utf-8", "xmlcharrefreplace")
|
||||
if not PY2:
|
||||
zbl = [
|
||||
chr(x).encode("utf-8")
|
||||
if x in bsafe
|
||||
else "%{:02X}".format(x).encode("ascii")
|
||||
for x in zb
|
||||
]
|
||||
else:
|
||||
zbl = [unicode(x) if x in bsafe else "%{:02X}".format(ord(x)) for x in zb]
|
||||
|
||||
ufn = b"".join(zbl).decode("ascii")
|
||||
afn = "".join([x if x in safe else "_" for x in fn]).lstrip(".")
|
||||
while ".." in afn:
|
||||
afn = afn.replace("..", ".")
|
||||
|
||||
return "attachment; filename=\"%s\"; filename*=UTF-8''%s" % (afn, ufn)
|
||||
|
||||
|
||||
def humansize(sz: float, terse: bool = False) -> str:
|
||||
for unit in HUMANSIZE_UNITS:
|
||||
if sz < 1024:
|
||||
|
|
|
@ -160,6 +160,7 @@ authenticate using header `Cookie: cppwd=foo` or url param `&pw=foo`
|
|||
|
||||
| method | params | result |
|
||||
|--|--|--|
|
||||
| GET | `?dl` | download file (don't show in-browser) |
|
||||
| GET | `?ls` | list files/folders at URL as JSON |
|
||||
| GET | `?ls&dots` | list files/folders at URL as JSON, including dotfiles |
|
||||
| GET | `?ls=t` | list files/folders at URL as plaintext |
|
||||
|
|
Loading…
Reference in a new issue