diff options
| author | eltrac <hi@eltr.ac> | 2026-09-14 18:12:39 +0800 |
|---|---|---|
| committer | eltrac <hi@eltr.ac> | 2026-09-15 11:30:50 +0800 |
| commit | 9d30e52d4fd7c921683fd8a55c818ff7fd3ef7fe (patch) | |
| tree | 18a35d736635271c40e17288d7babce65a32d04d /src | |
| parent | 2ddf4e3fe155b1e4ff5dde8a587758d37d665ed4 (diff) | |
httpclient, webhook, verifier: add weepinbell.http.client to wrap org.httpkit.client
comment
Diffstat (limited to 'src')
| -rw-r--r-- | src/weepinbell/http/client.clj | 69 | ||||
| -rw-r--r-- | src/weepinbell/utils.clj | 7 | ||||
| -rw-r--r-- | src/weepinbell/verifier.clj | 6 | ||||
| -rw-r--r-- | src/weepinbell/webhook.clj | 8 |
4 files changed, 79 insertions, 11 deletions
diff --git a/src/weepinbell/http/client.clj b/src/weepinbell/http/client.clj new file mode 100644 index 0000000..34cd458 --- /dev/null +++ b/src/weepinbell/http/client.clj @@ -0,0 +1,69 @@ +(ns weepinbell.http.client
+ "HTTP client adapter. Only this adapter depends directly on external HTTP client library.
+ The rest of the codebase uses this adapter to make HTTP requests.
+ All HTTP client related changeability and complexity is containend within here,
+ for instance, all Exceptions are caught inside and returned as normal value."
+ (:refer-clojure :exclude [get])
+ (:require [org.httpkit.client :as hk]))
+
+(def default-options
+ {:user-agent "WebmentionBot"
+ :timeout 15000})
+
+(defn- wrap-response [response]
+ (assoc response :content-length (or (get-in response [:headers "Content-Length"])
+ (get-in response [:headers "content-length"]))))
+
+(defn- wrap-promise [promised-response]
+ (future (wrap-response @promised-response)))
+
+(defn post
+ "Sends POST request asynchronously. Returns a promise/future."
+ ([url]
+ (post url nil))
+ ([url options]
+ (post url options nil))
+ ([url options callbacks]
+ (-> url
+ (hk/post (merge default-options options) callbacks)
+ wrap-promise)))
+
+(defn get
+ "Sends GET request asynchronously. Returns a promise/future."
+ ([url]
+ (get url nil))
+ ([url options]
+ (get url options nil))
+ ([url options callbacks]
+ (-> url
+ (hk/get (merge default-options options) callbacks)
+ wrap-promise)))
+
+(defn get!
+ "Sends GET request synchronously. Returns response."
+ ([url]
+ @(get url nil))
+ ([url options]
+ @(get url options nil))
+ ([url options callbacks]
+ @(get url options callbacks)))
+
+(defn head
+ "Sends HEAD request asynchronously. Returns a promise/future."
+ ([url]
+ (head url nil))
+ ([url options]
+ (head url options nil))
+ ([url options callbacks]
+ (-> url
+ (hk/head (merge default-options options) callbacks)
+ wrap-promise)))
+
+(defn head!
+ "Sends HEAD request synchronously. Returns a response."
+ ([url]
+ @(head url nil))
+ ([url options]
+ @(head url options nil))
+ ([url options callbacks]
+ @(head url options callbacks)))
diff --git a/src/weepinbell/utils.clj b/src/weepinbell/utils.clj index 9c279b7..a2e0cd9 100644 --- a/src/weepinbell/utils.clj +++ b/src/weepinbell/utils.clj @@ -1,5 +1,5 @@ (ns weepinbell.utils - (:require [org.httpkit.client :as hk] + (:require [weepinbell.http.client :as client] [clojure.string :as string] [clojure.walk :as walk] [clojure.java.io :as io] @@ -16,9 +16,8 @@ parent-dir (.getParentFile file)] (when (and parent-dir (not (.exists parent-dir))) (.mkdirs parent-dir)) - (let [response (hk/get url {:as :stream - :timeout 30000}) - content-length (get-in @response [:headers "content-length"])] + (let [response (client/get! url {:as :stream}) + content-length (get-in response [:headers "content-length"])] (timbre/info "Downloading [" url "] -> [" dest-path "]") (when content-length (timbre/info "File size:" content-length "bytes")) diff --git a/src/weepinbell/verifier.clj b/src/weepinbell/verifier.clj index 2b28e3f..c79c539 100644 --- a/src/weepinbell/verifier.clj +++ b/src/weepinbell/verifier.clj @@ -5,7 +5,7 @@ 2) source respond with 2** status code. 3) source's Content-Type is either HTML or plain text." (:require [clojure.string :refer [includes? trim lower-case split]] - [org.httpkit.client :as hk] + [weepinbell.http.client :as client] [weepinbell.utils.digest :refer [digest-short]] [taoensso.timbre :as timbre])) @@ -23,8 +23,8 @@ [source target] (try ;; get first 1MB of source URL and verify - (let [{:keys [status body headers]} @(hk/get source {:headers {"Range" "bytes=0-1048575"}}) - target-headers (:headers @(hk/head target)) + (let [{:keys [status body headers]} (client/get! source {:headers {"Range" "bytes=0-1048575"}}) + target-headers (:headers (client/head! target)) id (digest-short (str source target))] (timbre/info "verifying webmention" id (str "(" "source: " source ", target: " target ")")) diff --git a/src/weepinbell/webhook.clj b/src/weepinbell/webhook.clj index e1283d1..c084f47 100644 --- a/src/weepinbell/webhook.clj +++ b/src/weepinbell/webhook.clj @@ -1,10 +1,10 @@ (ns weepinbell.webhook - (:require [org.httpkit.client :as hk] - [taoensso.timbre :as timbre] - [weepinbell.utils.url :refer [valid-http-url?]])) + (:require [taoensso.timbre :as timbre] + [weepinbell.utils.url :refer [valid-http-url?]] + [weepinbell.http.client :as client])) (defn- send-webhook [url] - (hk/post url + (client/post url {:timeout 15000} (fn async-callback [{:keys [status _ _ error]}] (cond |
