Skip to content

Commit

Permalink
Merge pull request #37 from metosin/revert-change-headers-key-case
Browse files Browse the repository at this point in the history
Revert "Make `:headers`-map's string keys lower-case (#36)"
  • Loading branch information
opqdonut authored Nov 18, 2024
2 parents f279bb1 + ffc9e02 commit 70944e9
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 123 deletions.
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

0 comments on commit 70944e9

Please sign in to comment.