Skip to content

Commit 3c082e2

Browse files
committed
Add resume option to http downloader
1 parent 6f127df commit 3c082e2

File tree

3 files changed

+21
-12
lines changed

3 files changed

+21
-12
lines changed

dev-resources/test.png.download

7.9 KB
Binary file not shown.

src/cavia/downloader.clj

+12-9
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@
1515
(defn- download!
1616
"Downloads from the InputStream to the OutputStream. To print progress, it
1717
requires the content length."
18-
[^InputStream is ^OutputStream os content-len]
18+
[^InputStream is ^OutputStream os content-len resume]
1919
(let [data (byte-array *download-buffer-size*)
20-
with-print (and *verbose* (pos? content-len))]
20+
with-print (and *verbose* (pos? content-len))
21+
resume (or resume 0)]
2122
(loop [len (.read is data)
22-
sum len
23+
sum (+ resume len)
2324
bar (pr/progress-bar 100)]
2425
(when (Thread/interrupted) (throw (InterruptedException.)))
2526
(if (= len -1)
@@ -32,16 +33,18 @@
3233

3334
(defn http-download!
3435
"Downloads from the url via HTTP/HTTPS and saves it to local as f."
35-
[url f & {:keys [auth]}]
36+
[url f & {:keys [auth resume]}]
3637
(let [option (merge {:as :stream}
3738
(if-let [{:keys [type user password]} auth]
38-
{(keyword (str (name type) "-auth")) [user password]}))
39+
{(keyword (str (name type) "-auth")) [user password]})
40+
(when resume
41+
{:headers {:range (str "bytes=" resume "-")}}))
3942
response (client/get url option)
4043
content-len (if-let [content-len (get-in response [:headers "content-length"])]
4144
(str->int content-len) -1)
4245
is (:body response)]
43-
(with-open [os (io/output-stream f)]
44-
(download! is os content-len))))
46+
(with-open [os (io/output-stream f :append (boolean resume))]
47+
(download! is os content-len resume))))
4548

4649
(defn- ftp-content-len
4750
[^FTPClient ftp-client path]
@@ -69,7 +72,7 @@
6972
content-len (ftp-content-len client* (:path u))]
7073
(with-open [is ^InputStream (.retrieveFileStream client* (:path u))
7174
os (io/output-stream f)]
72-
(download! is os content-len)))
75+
(download! is os content-len 0)))
7376
(try
7477
(complete-pending-command client*)
7578
(catch java.net.SocketTimeoutException e
@@ -88,4 +91,4 @@
8891
content-len (.. entry getAttrs getSize)]
8992
(with-open [is (.get channel (:path u))
9093
os (io/output-stream f)]
91-
(download! is os content-len)))))
94+
(download! is os content-len 0)))))

test/cavia/downloader_test.clj

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
(ns cavia.downloader-test
22
(:require [clojure.test :refer :all]
3-
[clojure.java.io :refer [file]]
3+
[clojure.java.io :as io]
44
[digest]
55
[cavia.test-util :refer :all]
66
[cavia.downloader :as dl]))
@@ -32,7 +32,7 @@
3232

3333
(defn- sha1-file
3434
[f]
35-
(digest/sha1 (file f)))
35+
(digest/sha1 (io/file f)))
3636

3737
;;;
3838
;;; Tests
@@ -42,7 +42,13 @@
4242
(testing "returns nil when finishing successfully "
4343
(is (nil? (dl/http-download! http-test-url http-test-local))))
4444
(testing "check the resource's hash"
45-
(is (= (sha1-file http-test-local) http-test-hash))))
45+
(is (= (sha1-file http-test-local) http-test-hash)))
46+
(testing "resume"
47+
(let [http-test-fragment (str temp-dir "/http-test-resource-fragment")]
48+
(io/copy (io/file (io/resource "test.png.download")) (io/file http-test-fragment))
49+
(is (nil? (dl/http-download! http-test-url http-test-fragment
50+
:resume (.length (io/file http-test-fragment)))))
51+
(is (= (sha1-file http-test-fragment) http-test-hash)))))
4652

4753
(deftest ftp-download!-test
4854
(testing "returns nil when finishing successfully "

0 commit comments

Comments
 (0)