-
Notifications
You must be signed in to change notification settings - Fork 1
/
ftp.clj
33 lines (32 loc) · 1.43 KB
/
ftp.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
(ns cavia.ftp
(:require [lambdaisland.uri :as uri]
[cavia.internal :refer [str->int url-decode parse-auth]])
(:import [org.apache.commons.net.ftp FTP FTPClient FTPSClient FTPReply]))
(defn ^FTPClient client
[url & [{:keys [auth file-type local-mode]
:or {file-type :binary, local-mode :passive}}]]
(let [u (uri/uri url)
^FTPClient client (case (:scheme u)
"ftp" (FTPClient.)
"ftps" (FTPSClient.)
(throw (ex-info "Unexpected scheme" {:scheme (:scheme u)})))
auth (or (parse-auth u auth) {:user "anonymous" :password nil})
port (int (or (str->int (:port u)) 21))]
(.connect client ^String (:host u) port)
(let [reply (.getReplyCode client)]
(when-not (FTPReply/isPositiveCompletion reply)
(throw (ex-info "Connection refused" {:reply-code reply
:reply-string (.getReplyString client)}))))
(doto client
(.login (:user auth) (:password auth))
(.setFileType (case file-type
:binary FTP/BINARY_FILE_TYPE
:ascii FTP/ASCII_FILE_TYPE))
(.setControlKeepAliveTimeout 300)
(.setControlKeepAliveReplyTimeout 1000)
(.setSoTimeout 30000)
(.setDataTimeout 30000))
(case local-mode
:active (.enterLocalActiveMode client)
:passive (.enterLocalPassiveMode client))
client))