# HG changeset patch # User Arne Babenhauserheide # Date 1597185617 -7200 # Wed Aug 12 00:40:17 2020 +0200 # Node ID f057370a56e84283ef875b39cd4d83f3c5309977 # Parent 3b83665c33859c1105a22a52c66614cd66389fab heuristic: anyone asking for a language can accept a range response diff --git a/run-wispserve.w b/run-wispserve.w --- a/run-wispserve.w +++ b/run-wispserve.w @@ -15,11 +15,10 @@ tests test-assert : string-contains (help-message '("./program")) "./program" test-equal #\U : string-ref (help-message '("./program")) 0 - format #f "Usage: ~a [options] + format #f "Usage: ~a [DOWNLOAD_URL | --serve FOLDER] [options] Options: [link [link ...]] download file(s) - --serve serve the files in FOLDER --ip set server IP (default: [::]) --port set server port (default: 8083) --lazy hash served when they are requested instead of at startup (default: #f) @@ -42,14 +41,14 @@ cond : or (null? arguments) (member "--help" arguments) (member "-h" arguments) help args - : and {(length arguments) > 1} : equal? "--serve" : car arguments + : and {(length arguments) > 1} : equal? "--serve" : first arguments let : ip-opt : or (opt-member arguments "--ip") '("--ip" "::") port-opt : or (opt-member arguments "--port") '("--port" "8083") lazy : member "--lazy" arguments serve (second arguments) (second ip-opt) (string->number (second port-opt)) (not lazy) else - let* + let* : download-data : download-file : car arguments output-opt : opt-member arguments "--output" output-file diff --git a/wispserve/serve.w b/wispserve/serve.w --- a/wispserve/serve.w +++ b/wispserve/serve.w @@ -430,17 +430,17 @@ set! served-paths : vhash-cons (served-serverpath new-served) new-served : vhash-delete (served-serverpath served-cdr) served-paths cons (car served-file) new-served -define : server-serve-file range-requested begin-end served-file +define : server-serve-file range-requested disallow-range begin-end served-file define range-begin : car begin-end define filesize or : and=> (and=> (and=> (and=> served-file cdr) served-accesspath) stat) stat:size . 32KiB define range-end - if : not range-requested + if : or disallow-range : and (< filesize 2MiB) : not range-requested . #f or cdr begin-end - ;; if no size is requested, optimize for streaming video + ;; if no size is requested, optimize for streaming video, since that’s tho only thing that really needs optimizing min : - filesize 1 + range-begin cond @@ -467,6 +467,7 @@ cons `(content-range . ,(format #f "bytes ~d-~d/~d" range-begin range-end file-size)) . base-headers . base-headers + ;; pretty-print : ` resp-headers ,headers values build-response . #:headers headers @@ -580,11 +581,88 @@ . pieces +;; Headers for Tizen Smart-TV +;; ((req-headers +;; ((host "192.168.2.105" . 8083) +;; (connection keep-alive) +;; (user-agent +;; . +;; "Mozilla/5.0 (SMART-TV; Linux; Tizen 5.0) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/2.2 Chrome/63.0.3239.84 TV Safari/537.36") +;; (accept +;; (image/webp) +;; (image/apng) +;; (image/*) +;; (*/* (q . 800))) +;; (referer +;; . +;; #< scheme: http userinfo: #f host: "192.168.2.105" port: 8083 path: "/" query: #f fragment: #f>) +;; (accept-encoding +;; (1000 . "gzip") +;; (1000 . "deflate")) +;; (accept-language (1000 . "de-DE")))) + + +;; Headers for IceCat: +;; ((req-headers +;; ((host "192.168.2.105" . 8083) +;; (user-agent +;; . +;; "Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0") +;; (accept +;; (video/webm) +;; (video/ogg) +;; (video/* (q . 900)) +;; (application/ogg (q . 700)) +;; (audio/* (q . 600)) +;; (*/* (q . 500))) +;; (accept-language (1000 . "en-US") (500 . "en")) +;; (referer +;; . +;; #< scheme: http userinfo: #f host: "192.168.2.105" port: 8083 path: "/drachenzaehmen-leicht-gemacht-1.mp4" query: #f fragment: #f>) +;; (range bytes (10518541 . #f)) +;; (dnt . "1") +;; (connection keep-alive))) + +;; Headers for Chromium: +;; ((req-headers +;; ((host "192.168.2.105" . 8083) +;; (connection keep-alive) +;; (dnt . "1") +;; (accept-encoding (1000 . "identity") (0 . "*")) +;; (user-agent +;; . +;; "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36") +;; (accept (*/*)) +;; (referer +;; . +;; #< scheme: http userinfo: #f host: "192.168.2.105" port: 8083 path: "/drachenzaehmen-leicht-gemacht-1.mp4" query: #f fragment: #f>) +;; (accept-language +;; (1000 . "de-DE") +;; (900 . "de") +;; (800 . "en-US") +;; (700 . "en")) +;; (range bytes (6324235 . #f)))) + +;; Wget +;; ((req-headers +;; ((user-agent . "Wget/1.20.3 (linux-gnu)") +;; (accept (*/*)) +;; (accept-encoding (1000 . "identity")) +;; (host "192.168.2.105" . 8083) +;; (connection keep-alive))) + +;; Curl +;; ((req-headers +;; ((host "192.168.2.105" . 8083) +;; (user-agent . "curl/7.71.0") +;; (accept (*/*)))) + define : server-file-download-handler folder-path request body define headers : request-headers request let* : range-requested : assoc-item headers 'range + disallow-range : not : or range-requested : assoc-item headers 'accept-language ;; accept-language is typically interactive, so if it is not present, we fall back to providing the whole file in one go. This is just a heuristic, though. There is no good way to detect "will accept Range response, even though it did not request it". begin-end if : or (not range-requested) {(length range-requested) < 3} . '(0 . #f) @@ -599,6 +677,9 @@ ;; ipv4 : inet-ntop AF_INET ip ipv6 : inet-ntop AF_INET6 ip ;; pretty-print : list 'xalt xalt 'ipv6 ipv6 'peer peer + ;; pretty-print + ;; ` : req-headers ,headers + ;; disallow-range ,disallow-range cond : null? path-elements server-list-files @@ -613,7 +694,7 @@ alist-cons sha256 delete-duplicates : cons ipv6 : or (assoc-ref xalt sha256) : list . xalt - server-serve-file range-requested begin-end + server-serve-file range-requested disallow-range begin-end hash-and-mime-if-unknown! served-file define : sha256sum path