summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreltrac <hi@eltr.ac>2026-05-06 11:56:09 +0800
committereltrac <hi@eltr.ac>2026-05-06 11:56:09 +0800
commit90f2c68c6e718f60f7b84f4ea8c840801245ddc8 (patch)
treeb0ce4119d58107861d3259888b1edcb69bf806e2
parent94051f0d73bb8c32be303e045239968892bc9e3d (diff)
refactor(processor): separate verification from processor logic
-rw-r--r--src/weepinbell/processor.clj28
-rw-r--r--src/weepinbell/utils.clj6
-rw-r--r--src/weepinbell/verifier.clj39
3 files changed, 45 insertions, 28 deletions
diff --git a/src/weepinbell/processor.clj b/src/weepinbell/processor.clj
index fe2d600..4466745 100644
--- a/src/weepinbell/processor.clj
+++ b/src/weepinbell/processor.clj
@@ -1,29 +1,13 @@
(ns weepinbell.processor
+ "Process in-coming webmentions.
+ If no such webmention exists and request is verified, create.
+ If exists and verification fails, delete it.
+ If exists and verification passes, update it."
(:require [clojure.core.async :refer [go-loop <!]]
- [clojure.string :refer [includes?]]
- [clj-http.client :as client]
- [weepinbell.utils :refer [validate-content-types]]
[weepinbell.wrapper :as wrapper]
+ [weepinbell.verifier :refer [verify-mention verify-content-types]]
[taoensso.timbre :as timbre]))
-(defn verify-mention
- "Get source and follow redirects to check if target link is present."
- [source target]
- (try
- (timbre/info (str "Verifying mention from: " source))
- ;; get first 1MB of source URL and verify
- (let [{:keys [status body]} (client/get source {:throw false
- :headers {"Range" "bytes=0-1048575"}})]
- (if (and (>= status 200) (< status 300))
- ;; TODO needs to be more robust
- (if (includes? (str body) target)
- true
- (do (timbre/error "Target link not found in source body.") false))
- (do (timbre/error "Source returned status:" status) false)))
- (catch Exception e
- (timbre/error "Error verifying mention:" (.getMessage e))
- false)))
-
(defn process-new-webmention
"Store new webmention if verifed. Do nothing otherwise."
[source target callbacks storage]
@@ -62,7 +46,7 @@
(let [{:keys [s t]} wm]
;; first check Content-Types of both urls
;; only proceed when it's HTML or plain text
- (if (validate-content-types s t)
+ (if (verify-content-types s t)
;; second check if such webmention exists
;; if so, update it or delete it
;; if not, write to data
diff --git a/src/weepinbell/utils.clj b/src/weepinbell/utils.clj
index 9afcc49..4611225 100644
--- a/src/weepinbell/utils.clj
+++ b/src/weepinbell/utils.clj
@@ -43,12 +43,6 @@
(string/includes? content-type "text/plain") :text
:else false))
-(defn validate-content-types [source target]
- (let [validate #(-> % get-content-type plain-or-html? boolean)
- source-valid (validate source)
- target-valid (validate target)]
- (and source-valid target-valid)))
-
(defn javamap->map [map]
(->> (seq map) (into {}) walk/keywordize-keys))
diff --git a/src/weepinbell/verifier.clj b/src/weepinbell/verifier.clj
new file mode 100644
index 0000000..0928fb5
--- /dev/null
+++ b/src/weepinbell/verifier.clj
@@ -0,0 +1,39 @@
+(ns weepinbell.verifier
+ "Verifies in-coming webmentions after receiver checks URL.
+ This makes sure:
+ 1) source contains target URL.
+ 2) source respond with 2** status code.
+ 3) source's Content-Type is either HTML or plain text."
+ (:require [weepinbell.utils :refer [get-content-type plain-or-html?]]
+ [clojure.string :refer [includes?]]
+ [clj-http.client :as client]
+ [taoensso.timbre :as timbre]))
+
+(defn verify-content-types [source target]
+ (let [validate #(-> % get-content-type plain-or-html? boolean)]
+ (and (validate source) (validate target))))
+
+(defn verify-mention
+ "Get source and follow redirects to check if target link is present."
+ [source target]
+ (try
+ (timbre/info (str "Verifying mention from: " source))
+ ;; get first 1MB of source URL and verify
+ (let [{:keys [status body]} (client/get source {:throw false
+ :headers {"Range" "bytes=0-1048575"}})]
+ ;; Verify status code
+ (if (and (>= status 200) (< status 300))
+ ;; Verify inclusion of target URL
+ ;; TODO needs to be more robust
+ (if (includes? (str body) target)
+ true
+ (do
+ (timbre/error "Target link not found in source body.")
+ false))
+ (do
+ (timbre/error "Source returned status:" status)
+ false)))
+ (catch Exception e
+ (timbre/error "Error verifying mention:" (.getMessage e))
+ false)))
+