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