|
44 | 44 | (doseq [l *loggers*] |
45 | 45 | (l category values))) |
46 | 46 |
|
47 | | -(declare if-none-match-exists?) |
48 | | - |
49 | 47 | (defn map-values [f m] |
50 | 48 | (persistent! (reduce-kv (fn [out-m k v] (assoc! out-m k (f v))) (transient {}) m))) |
51 | 49 |
|
|
192 | 190 | `(defn ~name [context#] |
193 | 191 | (run-handler '~name ~status ~message context#))) |
194 | 192 |
|
195 | | -(defn header-exists? [header context] |
196 | | - (get-in context [:request :headers header])) |
197 | | - |
198 | | -(defn if-match-star [context] |
199 | | - (= "*" (get-in context [:request :headers "if-match"]))) |
200 | | - |
201 | 193 | (defn =method [method context] |
202 | 194 | (= (get-in context [:request :request-method]) method)) |
203 | 195 |
|
|
283 | 275 | (defhandler handle-precondition-failed 412 "Precondition failed.") |
284 | 276 |
|
285 | 277 | (defdecision if-match-star-exists-for-missing? |
286 | | - if-match-star |
| 278 | + (fn [context] (= "*" (get-in context [:request :headers "if-match"]))) |
287 | 279 | handle-precondition-failed |
288 | 280 | method-put?) |
289 | 281 |
|
|
314 | 306 | method-patch?) |
315 | 307 |
|
316 | 308 | (defdecision modified-since? |
317 | | - (fn [context] |
318 | | - (let [last-modified (gen-last-modified context)] |
319 | | - [(and last-modified (.after last-modified (::if-modified-since-date context))) |
320 | | - {::last-modified last-modified}])) |
| 309 | + (fn [{:keys [request] :as context}] |
| 310 | + (let [modified-since (parse-http-date (get-in request [:headers "if-modified-since"]))] |
| 311 | + (or (nil? modified-since) |
| 312 | + (let [last-modified (gen-last-modified context)] |
| 313 | + [(and last-modified (.after last-modified modified-since)) |
| 314 | + {::last-modified last-modified}])))) |
321 | 315 | method-delete? |
322 | 316 | handle-not-modified) |
323 | 317 |
|
324 | | -(defdecision if-modified-since-valid-date? |
325 | | - (fn [context] |
326 | | - (if-let [date (parse-http-date (get-in context [:request :headers "if-modified-since"]))] |
327 | | - {::if-modified-since-date date})) |
328 | | - modified-since? |
329 | | - method-delete?) |
330 | | - |
331 | | -(defdecision if-modified-since-exists? |
332 | | - (partial header-exists? "if-modified-since") |
333 | | - if-modified-since-valid-date? |
334 | | - method-delete?) |
335 | | - |
336 | 318 | (defdecision etag-matches-for-if-none? |
337 | | - (fn [context] |
338 | | - (let [etag (gen-etag context)] |
339 | | - [(= (get-in context [:request :headers "if-none-match"]) etag) |
340 | | - {::etag etag}])) |
341 | | - if-none-match? |
342 | | - if-modified-since-exists?) |
343 | | - |
344 | | -(defdecision if-none-match-star? |
345 | | - #(= "*" (get-in % [:request :headers "if-none-match"])) |
| 319 | + (fn [{:keys [request] :as context}] |
| 320 | + (if-let [if-none-match (get-in context [:request :headers "if-none-match"])] |
| 321 | + (let [etag (gen-etag context)] |
| 322 | + [(#{"*" etag} if-none-match) |
| 323 | + {::etag etag}]))) |
346 | 324 | if-none-match? |
347 | | - etag-matches-for-if-none?) |
348 | | - |
349 | | -(defdecision if-none-match-exists? (partial header-exists? "if-none-match") |
350 | | - if-none-match-star? if-modified-since-exists?) |
| 325 | + modified-since?) |
351 | 326 |
|
352 | 327 | (defdecision unmodified-since? |
353 | | - (fn [context] |
354 | | - (let [last-modified (gen-last-modified context)] |
355 | | - [(and last-modified |
356 | | - (.after last-modified |
357 | | - (::if-unmodified-since-date context))) |
358 | | - {::last-modified last-modified}])) |
| 328 | + (fn [{:keys [request] :as context}] |
| 329 | + (when-let [unmodified-since (parse-http-date (get-in request [:headers "if-unmodified-since"]))] |
| 330 | + (let [last-modified (gen-last-modified context)] |
| 331 | + [(and last-modified (.after last-modified unmodified-since)) |
| 332 | + {::last-modified last-modified}]))) |
359 | 333 | handle-precondition-failed |
360 | | - if-none-match-exists?) |
361 | | - |
362 | | -(defdecision if-unmodified-since-valid-date? |
363 | | - (fn [context] |
364 | | - (when-let [date (parse-http-date (get-in context [:request :headers "if-unmodified-since"]))] |
365 | | - {::if-unmodified-since-date date})) |
366 | | - unmodified-since? |
367 | | - if-none-match-exists?) |
| 334 | + etag-matches-for-if-none?) |
368 | 335 |
|
369 | | -(defdecision if-unmodified-since-exists? (partial header-exists? "if-unmodified-since") |
370 | | - if-unmodified-since-valid-date? if-none-match-exists?) |
| 336 | +(defn- match-etag-for-existing [{:keys [request resource] :as context}] |
| 337 | + (let [if-match (get-in request [:headers "if-match"])] |
| 338 | + (or (empty? if-match) |
| 339 | + (= "*" if-match) |
| 340 | + (let [etag (gen-etag context)] |
| 341 | + [(= etag if-match) |
| 342 | + {::etag etag}])))) |
371 | 343 |
|
372 | 344 | (defdecision etag-matches-for-if-match? |
373 | | - (fn [context] |
374 | | - (let [etag (gen-etag context)] |
375 | | - [(= etag (get-in context [:request :headers "if-match"])) |
376 | | - {::etag etag}])) |
377 | | - if-unmodified-since-exists? |
| 345 | + match-etag-for-existing |
| 346 | + unmodified-since? |
378 | 347 | handle-precondition-failed) |
379 | 348 |
|
380 | | -(defdecision if-match-star? |
381 | | - if-match-star if-unmodified-since-exists? etag-matches-for-if-match?) |
382 | | - |
383 | | -(defdecision if-match-exists? (partial header-exists? "if-match") |
384 | | - if-match-star? if-unmodified-since-exists?) |
385 | | - |
386 | | -(defdecision exists? if-match-exists? if-match-star-exists-for-missing?) |
| 349 | +(defdecision exists? etag-matches-for-if-match? if-match-star-exists-for-missing?) |
387 | 350 |
|
388 | 351 | (defhandler handle-unprocessable-entity 422 "Unprocessable entity.") |
| 352 | + |
389 | 353 | (defdecision processable? exists? handle-unprocessable-entity) |
390 | 354 |
|
391 | 355 | (defhandler handle-not-acceptable 406 "No acceptable resource available.") |
|
0 commit comments