Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "Make :headers-map's string keys lower-case (#36)" #37

Merged
merged 1 commit into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
## 0.10.0 (unreleased)

**BREAKING**: Header names are now lowercase to comply with Ring Spec (1.5)
- Changed "Location" header to "location" in redirect and creation responses

## 0.9.4 (29.6.2024)

- add teapot functionality [#33](https://github.com/metosin/ring-http-response/pull/33)
Expand Down
16 changes: 8 additions & 8 deletions src/ring/util/http_response.clj
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
([url] (created url nil))
([url body]
{:status 201
:headers {"location" url}
:headers {"Location" url}
:body body}))

(defn accepted
Expand Down Expand Up @@ -128,31 +128,31 @@
There are multiple options for the resource that the client may follow."
([url]
{:status 300
:headers {"location" url}
:headers {"Location" url}
:body ""}))

(defn moved-permanently
"301 Moved Permanently (Redirection)
This and all future requests should be directed to the given URI."
([url]
{:status 301
:headers {"location" url}
:headers {"Location" url}
:body ""}))

(defn found
"302 Found (Redirection)
The resource was found but at a different URI."
([url]
{:status 302
:headers {"location" url}
:headers {"Location" url}
:body ""}))

(defn see-other
"303 See Other (Redirection)
The response to the request can be found under another URI using a GET method."
([url]
{:status 303
:headers {"location" url}
:headers {"Location" url}
:body ""}))

(defn not-modified
Expand All @@ -168,23 +168,23 @@
This single request is to be repeated via the proxy given by the Location field."
([url]
{:status 305
:headers {"location" url}
:headers {"Location" url}
:body ""}))

(defn temporary-redirect
"307 Temporary Redirect (Redirection)
The request should be repeated with another URI but future requests can still use the original URI."
([url]
{:status 307
:headers {"location" url}
:headers {"Location" url}
:body ""}))

(defn permanent-redirect
"308 Permanent Redirect (Redirection)
The request and all future requests should be repeated using another URI."
([url]
{:status 308
:headers {"location" url}
:headers {"Location" url}
:body ""}))

(defn bad-request
Expand Down
120 changes: 10 additions & 110 deletions test/ring/util/http_response_test.clj
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
(ns ring.util.http-response-test
(:require [clojure.test :refer :all]
[ring.util.http-response :refer :all]
[clojure.string :as str]
[clojure.repl :refer [demunge]]))
[ring.util.http-response :refer :all]))

(deftest http-responses-test

Expand All @@ -13,8 +11,8 @@

(testing "Success"
(is (= {:status 200 :headers {} :body "body"} (ok "body")))
(is (= {:status 201 :headers {"location" "/url"} :body nil} (created "/url")))
(is (= {:status 201 :headers {"location" "/url"} :body "body"} (created "/url" "body")))
(is (= {:status 201 :headers {"Location" "/url"} :body nil} (created "/url")))
(is (= {:status 201 :headers {"Location" "/url"} :body "body"} (created "/url" "body")))
(is (= {:status 202 :headers {} :body "body"} (accepted "body")))
(is (= {:status 203 :headers {} :body "body"} (non-authoritative-information "body")))
(is (= {:status 204 :headers {} :body ""} (no-content)))
Expand All @@ -25,14 +23,14 @@
(is (= {:status 226 :headers {} :body "body"} (im-used "body"))))

(testing "Redirection"
(is (= {:status 300 :headers {"location" "/url"} :body ""} (multiple-choices "/url")))
(is (= {:status 301 :headers {"location" "/url"} :body ""} (moved-permanently "/url")))
(is (= {:status 302 :headers {"location" "/url"} :body ""} (found "/url")))
(is (= {:status 303 :headers {"location" "/url"} :body ""} (see-other "/url")))
(is (= {:status 300 :headers {"Location" "/url"} :body ""} (multiple-choices "/url")))
(is (= {:status 301 :headers {"Location" "/url"} :body ""} (moved-permanently "/url")))
(is (= {:status 302 :headers {"Location" "/url"} :body ""} (found "/url")))
(is (= {:status 303 :headers {"Location" "/url"} :body ""} (see-other "/url")))
(is (= {:status 304 :headers {} :body ""} (not-modified)))
(is (= {:status 305 :headers {"location" "/url"} :body ""} (use-proxy "/url")))
(is (= {:status 307 :headers {"location" "/url"} :body ""} (temporary-redirect "/url")))
(is (= {:status 308 :headers {"location" "/url"} :body ""} (permanent-redirect "/url"))))
(is (= {:status 305 :headers {"Location" "/url"} :body ""} (use-proxy "/url")))
(is (= {:status 307 :headers {"Location" "/url"} :body ""} (temporary-redirect "/url")))
(is (= {:status 308 :headers {"Location" "/url"} :body ""} (permanent-redirect "/url"))))

(testing "ClientError"
(is (= {:status 400 :headers {} :body "body"} (bad-request "body")))
Expand Down Expand Up @@ -83,104 +81,6 @@
(is (= {:status 598 :headers {} :body "body"} (network-read-timeout "body")))
(is (= {:status 599 :headers {} :body "body"} (network-connect-timeout "body")))))


;; Functions that can be called with 1 argument
(def one-args-response-fns
[multiple-choices
moved-permanently
found
see-other
use-proxy
temporary-redirect
permanent-redirect])

;; Functions that can be called with 0 arguments
(def zero-arg-response-fns
[continue
switching-protocols
processing
ok
created
accepted
non-authoritative-information
no-content
reset-content
partial-content
multi-status
already-reported
im-used
not-modified
bad-request
unauthorized
payment-required
forbidden
not-found
method-not-allowed
not-acceptable
proxy-authentication-required
request-timeout
conflict
gone
length-required
precondition-failed
request-entity-too-large
request-uri-too-long
unsupported-media-type
requested-range-not-satisfiable
expectation-failed
im-a-teapot
enhance-your-calm
unprocessable-entity
locked
failed-dependency
unordered-collection
upgrade-required
precondition-required
too-many-requests
request-header-fields-too-large
retry-with
blocked-by-windows-parental-controls
unavailable-for-legal-reasons
internal-server-error
not-implemented
bad-gateway
service-unavailable
gateway-timeout
http-version-not-supported
variant-also-negotiates
insufficient-storage
loop-detected
bandwidth-limit-exceeded
not-extended
network-authentication-required
network-read-timeout
network-connect-timeout])

(defn- pretty-demunge [f]
(-> (str f) demunge (str/split #"@") first))

;; https://github.com/ring-clojure/ring/blob/master/SPEC.md
(deftest ring-spec-test
(testing "`:headers` is a clojure map of lowercased header name strings to corresponding header value strings"
;; for functions that have a one-arity definition
(doseq [f one-args-response-fns
:let [request-map (f "foo")
headers (:headers request-map)]]
(testing (pretty-demunge f)
(is (map? headers))
(is (every? (fn [header-name]
(= (str/lower-case header-name) header-name))
(keys headers)))))
;; for functions that have a zero-arity definition
(doseq [f zero-arg-response-fns
:let [request-map (f)
headers (:headers request-map)]]
(testing (pretty-demunge f)
(is (map? headers))
(is (every? (fn [header-name]
(= (str/lower-case header-name) header-name))
(keys headers)))))))

(declare slingshots?)
(defmethod assert-expr 'slingshots? [msg form]
(let [expected (second form)
Expand Down
Loading