├── .github └── workflows │ ├── clojure.yml │ └── release.yml ├── .gitignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── deps.edn ├── dev └── user.clj ├── project.clj ├── src └── ring │ ├── middleware │ └── http_response.clj │ └── util │ ├── http_predicates.clj │ ├── http_predicates.cljs │ ├── http_response.clj │ ├── http_status.clj │ └── http_status.cljs ├── templates ├── http-predicates.mustache ├── http-response.mustache └── http-status.mustache └── test └── ring ├── middleware └── http_response_test.clj └── util ├── http_predicates_test.clj ├── http_response_test.clj └── http_status_test.clj /.github/workflows/clojure.yml: -------------------------------------------------------------------------------- 1 | name: Run tests 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | 11 | jobs: 12 | build-clj: 13 | strategy: 14 | matrix: 15 | # LTS and latest 16 | jdk: [8, 11, 17, 21] 17 | name: "Clojure (Java ${{ matrix.jdk }})" 18 | runs-on: ubuntu-latest 19 | steps: 20 | - uses: actions/checkout@v2 21 | - name: "Setup Java ${{ matrix.jdk }}" 22 | uses: actions/setup-java@v1.4.3 23 | with: 24 | java-version: ${{ matrix.jdk }} 25 | - name: Setup Clojure 26 | uses: DeLaGuardo/setup-clojure@master 27 | with: 28 | lein: latest 29 | - name: Run tests 30 | run: lein all 31 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | release: 5 | types: 6 | - published # reacts to releases and prereleases, but not their drafts 7 | 8 | jobs: 9 | build-and-release: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v2 13 | - name: "Setup Java 8" 14 | uses: actions/setup-java@v1.4.3 15 | with: 16 | java-version: 8 17 | - name: Setup Clojure 18 | uses: DeLaGuardo/setup-clojure@master 19 | with: 20 | lein: latest 21 | - name: Run tests 22 | run: lein test 23 | - name: Build jar 24 | run: lein jar 25 | - name: Deploy to Clojars 26 | run: lein deploy 27 | env: 28 | CLOJARS_USER: metosinci 29 | CLOJARS_DEPLOY_TOKEN: "${{ secrets.CLOJARS_DEPLOY_TOKEN }}" 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | pom.xml 5 | pom.xml.asc 6 | *.jar 7 | *.class 8 | /.lein-* 9 | /.nrepl-port 10 | .project 11 | .ccw* 12 | ccw* 13 | /.idea 14 | /*.iml 15 | ;; Clojure tooling 16 | .cache 17 | .lsp 18 | .calva 19 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.9.5 (1.1.2025) 2 | 3 | - Fix pre-expr syntax [#34](https://github.com/metosin/ring-http-response/pull/34) 4 | - updated dependencies: 5 | 6 | ```clojure 7 | [ring/ring-core "1.13.0"] is available but we use "1.12.2" 8 | ``` 9 | 10 | ## 0.9.4 (29.6.2024) 11 | 12 | - add teapot functionality [#33](https://github.com/metosin/ring-http-response/pull/33) 13 | - updated dependencies: 14 | 15 | ```clojure 16 | [ring/ring-core "1.12.2"] is available but we use "1.10.0" 17 | [potemkin "0.4.7"] is available but we use "0.4.5" 18 | ``` 19 | 20 | ## 0.9.3 (25.8.2021) 21 | 22 | - updated dependencies: 23 | 24 | ``` 25 | [ring/ring-core "1.9.4"] 26 | ``` 27 | 28 | ## 0.9.2 (4.2.2021) 29 | 30 | - updated dependencies: 31 | 32 | ``` 33 | [ring/ring-core "1.9.0"] is available but we use "1.7.1" 34 | ``` 35 | 36 | ## 0.9.1 (10.11.2018) 37 | 38 | - updated dependencies: 39 | 40 | ``` 41 | [ring/ring-core "1.7.1"] is available but we use "1.6.0" 42 | [potemkin "0.4.5"] is available but we use "0.4.3" 43 | ``` 44 | 45 | ## 0.9.0 (10.5.2017) 46 | 47 | - require `[ring/ring-core "1.6.0"]` 48 | - `get-charset` added to `ring.util.http-response` 49 | - run tests with Clojure `1.9.0-alpha16` 50 | - updated dependencies: 51 | 52 | ``` 53 | [ring/ring-core "1.6.0"] is available but we use "1.5.1" 54 | ``` 55 | 56 | ## 0.8.2 (8.2.2017) 57 | 58 | - Add ring-async support to `ring.middleware.http-response/wrap-http-response` 59 | - Use `ex-info` & `ex-data` instead of slingshot in exceptions 60 | 61 | - removed dependencies: 62 | 63 | ```clj 64 | [slingshot "0.12.2"] 65 | ``` 66 | 67 | ## 0.8.1 (11.1.2017) 68 | 69 | - Update Ring to [avoid a path traversal vulnerability](https://groups.google.com/forum/#!topic/clojure/YDrKBV26rnA). 70 | 71 | ```clj 72 | [ring/ring-core "1.5.1"] is available but we use "1.5.0" 73 | ``` 74 | 75 | ## 0.8.0 (28.6.2016) 76 | 77 | - **BREAKING**: first argument for `created` is `url`, not `body`. Has 2-arity version which takes both `url` & `body` in align to the [spec](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) & [ring](https://github.com/ring-clojure/ring/blob/master/ring-core/src/ring/util/response.clj#L37) 78 | - fixes [#12](https://github.com/metosin/ring-http-response/issues/12). 79 | 80 | ## 0.7.0 (13.6.2016) 81 | 82 | - Test with Clojure 1.7.0 & 1.8.0 83 | - Better imports of `ring.util.response` -> `ring.util.http-response` (fail with informative message if old version of Ring is used) 84 | - update dependencies 85 | 86 | ```clj 87 | [ring/ring-core "1.5.0"] is available but we use "1.4.0" 88 | [potemkin "0.4.3"] is available but we use "0.4.1" 89 | ``` 90 | 91 | ## 0.6.5 (1.9.2016) 92 | 93 | - import only extra ring vars if they exist, so that the ns compiles with non-latest ring. 94 | 95 | ## 0.6.4 (21.8.2016) 96 | 97 | - import new functions from ring 1.4.0: `find-header`, `get-header`, `resource-data` 98 | - update dependencies: 99 | 100 | ```clojure 101 | [ring/ring-core "1.4.0"] is available but we use "1.3.2" 102 | [potemkin "0.4.1"] is available but we use "0.3.13" 103 | [stencil "0.5.0"] is available but we use "0.3.5" 104 | [midje "1.7.0"] is available but we use "1.6.3" 105 | ``` 106 | 107 | ## 0.6.3 (8.7.2015) 108 | 109 | - Added predicates for HTTP status types (classes) such as `success?`, `client-error?` and `server-error?` 110 | 111 | ## 0.6.2 (20.5.2015) 112 | 113 | - added `get-name` and `get-description` to status-ns. 114 | - update dependencies 115 | 116 | ```clojure 117 | [potemkin "0.3.13"] is available but we use "0.3.11" 118 | ``` 119 | 120 | ## 0.6.1 (11.3.2015) 121 | 122 | - generate also `ring.util.http-predicates` for ClojureScript. 123 | 124 | ## 0.6.0 (1.3.2015) 125 | 126 | - move from macro-based compile-time code-generation into mustache-based pre-compile code generation 127 | (big thanks to [@frankiesardo](https://github.com/frankiesardo)!) 128 | - FIXES 129 | - [#2](https://github.com/metosin/ring-http-response/issues/2) new namespace `ring.util.http-status` 130 | - [#3](https://github.com/metosin/ring-http-response/issues/3) `(user/generate!)` 131 | - [#5](https://github.com/metosin/ring-http-response/issues/5) `ring.util.http-predicates` 132 | - **Breaking changes:**: 133 | - `reset-content` takes no body 134 | - `blocked-by-parental-control` => `blocked-by-windows-parental-controls` 135 | - `ring.middleware.http-response/catch-response` => `ring.middleware.http-response/wrap-http-response` 136 | - removed dependencies: 137 | ```clojure 138 | [org.tobereplaced/lettercase "1.0.0"] 139 | ``` 140 | - updated dependencies: 141 | ```clojure 142 | [ring/ring-core "1.3.2"] is available but we use "1.3.1" 143 | [slingshot "0.12.2"] is available but we use "0.11.0" 144 | [potemkin "0.3.11"] is available but we use "0.3.9" 145 | ``` 146 | 147 | ## 0.5.2 (11.11.2014) 148 | 149 | - use `[org.tobereplaced/lettercase "1.0.0"]` for camel-casing 150 | 151 | ## 0.5.1 (14.10.2014) 152 | 153 | - Remove body from redirect responses (#4), thanks to [Joe Littlejohn](https://github.com/joelittlejohn). 154 | - updated dependencies: 155 | 156 | ```clojure 157 | [slingshot "0.11.0"] is available but we use "0.10.3" 158 | [potemkin "0.3.9"] is available but we use "0.3.8" 159 | ``` 160 | 161 | ## 0.5.0 (4.9.2014) 162 | 163 | - updated dependencies: 164 | 165 | ```clojure 166 | [ring/ring-core "1.3.1"] 167 | [potemkin "0.3.8"] 168 | [camel-snake-kebab "0.2.4"] 169 | ``` 170 | - Camel\_SNAKE-kebab 0.2.0 renamed the ns camel-snake-kebab to camel-snake-kebab.core 171 | 172 | ## 0.4.1 (15.7.2014) 173 | 174 | - updated dependencies: 175 | 176 | ```clojure 177 | [org.clojure/clojure "1.6.0"] 178 | [ring/ring-core "1.3.0"] 179 | [camel-snake-kebab "0.1.5"] 180 | [midje "1.6.3"] 181 | ``` 182 | 183 | ## 0.4.0 (15.3.2014) 184 | 185 | - Added `throw!` to throw any http-response 186 | - Fixed documentation bug 187 | - New Docs 188 | 189 | ## 0.3.0 (13.2.2014) 190 | 191 | - Initial public version 192 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | 3 | Contributions are welcome. 4 | 5 | Please file bug reports and feature requests to https://github.com/metosin/ring-http-response/issues. 6 | 7 | ## Making changes 8 | 9 | * Fork the repository on Github 10 | * Create a topic branch from where you want to base your work (usually the master branch) 11 | * Check the formatting rules from existing code (no trailing whitespace, mostly default indentation) 12 | * Ensure any new code is well-tested, and if possible, any issue fixed is covered by one or more new tests 13 | * Verify that all tests pass using ```lein all``` 14 | * Push your code to your fork of the repository 15 | * Make a Pull Request 16 | 17 | ## Commit messages 18 | 19 | 1. Separate subject from body with a blank line 20 | 2. Limit the subject line to 50 characters 21 | 3. Capitalize the subject line 22 | 4. Do not end the subject line with a period 23 | 5. Use the imperative mood in the subject line 24 | - "Add x", "Fix y", "Support z", "Remove x" 25 | 6. Wrap the body at 72 characters 26 | 7. Use the body to explain what and why vs. how 27 | 28 | For comprehensive explanation read this [post by Chris Beams](http://chris.beams.io/posts/git-commit/#seven-rules). 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Eclipse Public License - v 1.0 2 | 3 | THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC 4 | LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM 5 | CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 6 | 7 | 1. DEFINITIONS 8 | 9 | "Contribution" means: 10 | 11 | a) in the case of the initial Contributor, the initial code and documentation 12 | distributed under this Agreement, and 13 | b) in the case of each subsequent Contributor: 14 | i) changes to the Program, and 15 | ii) additions to the Program; 16 | 17 | where such changes and/or additions to the Program originate from and are 18 | distributed by that particular Contributor. A Contribution 'originates' 19 | from a Contributor if it was added to the Program by such Contributor 20 | itself or anyone acting on such Contributor's behalf. Contributions do not 21 | include additions to the Program which: (i) are separate modules of 22 | software distributed in conjunction with the Program under their own 23 | license agreement, and (ii) are not derivative works of the Program. 24 | 25 | "Contributor" means any person or entity that distributes the Program. 26 | 27 | "Licensed Patents" mean patent claims licensable by a Contributor which are 28 | necessarily infringed by the use or sale of its Contribution alone or when 29 | combined with the Program. 30 | 31 | "Program" means the Contributions distributed in accordance with this 32 | Agreement. 33 | 34 | "Recipient" means anyone who receives the Program under this Agreement, 35 | including all Contributors. 36 | 37 | 2. GRANT OF RIGHTS 38 | a) Subject to the terms of this Agreement, each Contributor hereby grants 39 | Recipient a non-exclusive, worldwide, royalty-free copyright license to 40 | reproduce, prepare derivative works of, publicly display, publicly 41 | perform, distribute and sublicense the Contribution of such Contributor, 42 | if any, and such derivative works, in source code and object code form. 43 | b) Subject to the terms of this Agreement, each Contributor hereby grants 44 | Recipient a non-exclusive, worldwide, royalty-free patent license under 45 | Licensed Patents to make, use, sell, offer to sell, import and otherwise 46 | transfer the Contribution of such Contributor, if any, in source code and 47 | object code form. This patent license shall apply to the combination of 48 | the Contribution and the Program if, at the time the Contribution is 49 | added by the Contributor, such addition of the Contribution causes such 50 | combination to be covered by the Licensed Patents. The patent license 51 | shall not apply to any other combinations which include the Contribution. 52 | No hardware per se is licensed hereunder. 53 | c) Recipient understands that although each Contributor grants the licenses 54 | to its Contributions set forth herein, no assurances are provided by any 55 | Contributor that the Program does not infringe the patent or other 56 | intellectual property rights of any other entity. Each Contributor 57 | disclaims any liability to Recipient for claims brought by any other 58 | entity based on infringement of intellectual property rights or 59 | otherwise. As a condition to exercising the rights and licenses granted 60 | hereunder, each Recipient hereby assumes sole responsibility to secure 61 | any other intellectual property rights needed, if any. For example, if a 62 | third party patent license is required to allow Recipient to distribute 63 | the Program, it is Recipient's responsibility to acquire that license 64 | before distributing the Program. 65 | d) Each Contributor represents that to its knowledge it has sufficient 66 | copyright rights in its Contribution, if any, to grant the copyright 67 | license set forth in this Agreement. 68 | 69 | 3. REQUIREMENTS 70 | 71 | A Contributor may choose to distribute the Program in object code form under 72 | its own license agreement, provided that: 73 | 74 | a) it complies with the terms and conditions of this Agreement; and 75 | b) its license agreement: 76 | i) effectively disclaims on behalf of all Contributors all warranties 77 | and conditions, express and implied, including warranties or 78 | conditions of title and non-infringement, and implied warranties or 79 | conditions of merchantability and fitness for a particular purpose; 80 | ii) effectively excludes on behalf of all Contributors all liability for 81 | damages, including direct, indirect, special, incidental and 82 | consequential damages, such as lost profits; 83 | iii) states that any provisions which differ from this Agreement are 84 | offered by that Contributor alone and not by any other party; and 85 | iv) states that source code for the Program is available from such 86 | Contributor, and informs licensees how to obtain it in a reasonable 87 | manner on or through a medium customarily used for software exchange. 88 | 89 | When the Program is made available in source code form: 90 | 91 | a) it must be made available under this Agreement; and 92 | b) a copy of this Agreement must be included with each copy of the Program. 93 | Contributors may not remove or alter any copyright notices contained 94 | within the Program. 95 | 96 | Each Contributor must identify itself as the originator of its Contribution, 97 | if 98 | any, in a manner that reasonably allows subsequent Recipients to identify the 99 | originator of the Contribution. 100 | 101 | 4. COMMERCIAL DISTRIBUTION 102 | 103 | Commercial distributors of software may accept certain responsibilities with 104 | respect to end users, business partners and the like. While this license is 105 | intended to facilitate the commercial use of the Program, the Contributor who 106 | includes the Program in a commercial product offering should do so in a manner 107 | which does not create potential liability for other Contributors. Therefore, 108 | if a Contributor includes the Program in a commercial product offering, such 109 | Contributor ("Commercial Contributor") hereby agrees to defend and indemnify 110 | every other Contributor ("Indemnified Contributor") against any losses, 111 | damages and costs (collectively "Losses") arising from claims, lawsuits and 112 | other legal actions brought by a third party against the Indemnified 113 | Contributor to the extent caused by the acts or omissions of such Commercial 114 | Contributor in connection with its distribution of the Program in a commercial 115 | product offering. The obligations in this section do not apply to any claims 116 | or Losses relating to any actual or alleged intellectual property 117 | infringement. In order to qualify, an Indemnified Contributor must: 118 | a) promptly notify the Commercial Contributor in writing of such claim, and 119 | b) allow the Commercial Contributor to control, and cooperate with the 120 | Commercial Contributor in, the defense and any related settlement 121 | negotiations. The Indemnified Contributor may participate in any such claim at 122 | its own expense. 123 | 124 | For example, a Contributor might include the Program in a commercial product 125 | offering, Product X. That Contributor is then a Commercial Contributor. If 126 | that Commercial Contributor then makes performance claims, or offers 127 | warranties related to Product X, those performance claims and warranties are 128 | such Commercial Contributor's responsibility alone. Under this section, the 129 | Commercial Contributor would have to defend claims against the other 130 | Contributors related to those performance claims and warranties, and if a 131 | court requires any other Contributor to pay any damages as a result, the 132 | Commercial Contributor must pay those damages. 133 | 134 | 5. NO WARRANTY 135 | 136 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN 137 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR 138 | IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, 139 | NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each 140 | Recipient is solely responsible for determining the appropriateness of using 141 | and distributing the Program and assumes all risks associated with its 142 | exercise of rights under this Agreement , including but not limited to the 143 | risks and costs of program errors, compliance with applicable laws, damage to 144 | or loss of data, programs or equipment, and unavailability or interruption of 145 | operations. 146 | 147 | 6. DISCLAIMER OF LIABILITY 148 | 149 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY 150 | CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, 151 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION 152 | LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 153 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 154 | ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE 155 | EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY 156 | OF SUCH DAMAGES. 157 | 158 | 7. GENERAL 159 | 160 | If any provision of this Agreement is invalid or unenforceable under 161 | applicable law, it shall not affect the validity or enforceability of the 162 | remainder of the terms of this Agreement, and without further action by the 163 | parties hereto, such provision shall be reformed to the minimum extent 164 | necessary to make such provision valid and enforceable. 165 | 166 | If Recipient institutes patent litigation against any entity (including a 167 | cross-claim or counterclaim in a lawsuit) alleging that the Program itself 168 | (excluding combinations of the Program with other software or hardware) 169 | infringes such Recipient's patent(s), then such Recipient's rights granted 170 | under Section 2(b) shall terminate as of the date such litigation is filed. 171 | 172 | All Recipient's rights under this Agreement shall terminate if it fails to 173 | comply with any of the material terms or conditions of this Agreement and does 174 | not cure such failure in a reasonable period of time after becoming aware of 175 | such noncompliance. If all Recipient's rights under this Agreement terminate, 176 | Recipient agrees to cease use and distribution of the Program as soon as 177 | reasonably practicable. However, Recipient's obligations under this Agreement 178 | and any licenses granted by Recipient relating to the Program shall continue 179 | and survive. 180 | 181 | Everyone is permitted to copy and distribute copies of this Agreement, but in 182 | order to avoid inconsistency the Agreement is copyrighted and may only be 183 | modified in the following manner. The Agreement Steward reserves the right to 184 | publish new versions (including revisions) of this Agreement from time to 185 | time. No one other than the Agreement Steward has the right to modify this 186 | Agreement. The Eclipse Foundation is the initial Agreement Steward. The 187 | Eclipse Foundation may assign the responsibility to serve as the Agreement 188 | Steward to a suitable separate entity. Each new version of the Agreement will 189 | be given a distinguishing version number. The Program (including 190 | Contributions) may always be distributed subject to the version of the 191 | Agreement under which it was received. In addition, after a new version of the 192 | Agreement is published, Contributor may elect to distribute the Program 193 | (including its Contributions) under the new version. Except as expressly 194 | stated in Sections 2(a) and 2(b) above, Recipient receives no rights or 195 | licenses to the intellectual property of any Contributor under this Agreement, 196 | whether expressly, by implication, estoppel or otherwise. All rights in the 197 | Program not expressly granted under this Agreement are reserved. 198 | 199 | This Agreement is governed by the laws of the State of New York and the 200 | intellectual property laws of the United States of America. No party to this 201 | Agreement will bring a legal action under this Agreement more than one year 202 | after the cause of action arose. Each party waives its rights to a jury trial in 203 | any resulting litigation. 204 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ring-http-response ![Build Status](https://github.com/metosin/ring-http-response/actions/workflows/clojure.yml/badge.svg) [![cljdoc badge](https://cljdoc.xyz/badge/metosin/ring-http-response)](https://cljdoc.xyz/d/metosin/ring-http-response/CURRENT) 2 | 3 | Handling HTTP Statuses with Clojure(Script), originally ported from the awesome [Spray](http://spray.io/). 4 | Mostly a drop-in-place replacement for `ring.util.response`. 5 | 6 | ## Latest version 7 | 8 | [![Clojars Project](http://clojars.org/metosin/ring-http-response/latest-version.svg)](http://clojars.org/metosin/ring-http-response) 9 | 10 | ## Usage 11 | 12 | ### Generating HTTP responses 13 | 14 | Functions take either a `body`, `url`, both or nothing as parameters in align to the [spec](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html). 15 | 16 | ```clojure 17 | (require '[ring.util.http-response :refer :all]) 18 | 19 | (continue) 20 | ; {:status 100, :headers {}, :body ""} 21 | 22 | (ok "body") 23 | ; {:status 200, :headers {}, :body "body"} 24 | 25 | (created "url" "body") 26 | ; {:status 201, :headers {"Location" "url"}, :body "body"} 27 | 28 | (found "url") 29 | ; {:status 302, :headers {"Location" "url"}, :body ""} 30 | ``` 31 | 32 | ### Asserting HTTP responses 33 | 34 | Available for both Clojure & ClojureScript. 35 | 36 | ```clojure 37 | (require '[ring.util.http-predicates :as predicates]) 38 | 39 | (predicates/ok? {:status 200}) 40 | ; true 41 | 42 | (predicates/not-found? {:status 404}) 43 | ; true 44 | ``` 45 | 46 | ### Status codes & documentation 47 | 48 | For referring HTTP codes by name & for api docs like [Swagger](https://github.com/metosin/ring-swagger). 49 | 50 | ```clojure 51 | (require '[ring.util.http-status :as status]) 52 | 53 | status/ok 54 | ; 200 55 | 56 | status/not-found 57 | ; 404 58 | 59 | (status/get-name 404) 60 | ; "Not Found" 61 | 62 | (status/get-description 404) 63 | ; "The requested resource could not be found but may be available again in the future." 64 | 65 | (status/status 404) 66 | ; {:name "Not Found" 67 | ; :description "The requested resource could not be found but may be available again in the future."} 68 | ``` 69 | 70 | ### Throwing error responses 71 | 72 | All response functions for HTTP error response have a exception throwing sibling with a bang in the name 73 | (`bad-request` & `bad-request!`). These functions throw the 74 | response wrapped in an `ExceptionInfo`. 75 | 76 | ```clojure 77 | (require '[ring.util.http-response :as response]) 78 | 79 | (response/bad-request "fail") 80 | ; {:status 400, :headers {}, :body "fail"} 81 | 82 | (response/bad-request! "fail") 83 | ; clojure.lang.ExceptionInfo: throw: {:type :ring.util.http-response/response, :response {:status 400, :headers {}, :body "fail"}} 84 | ``` 85 | 86 | There is also a `throw!` function to throw any kind response in an exception. 87 | 88 | ```clojure 89 | (require '[ring.util.http-response :as response]) 90 | 91 | (response/throw! (response/header (response/bad-request "body") "header" "value")) 92 | ; clojure.lang.ExceptionInfo: throw: {:type :ring.util.http-response/response, :response {:status 400, :headers {"header" "value"}, :body "body"}} 93 | ``` 94 | 95 | ### Catching thrown HTTP responses 96 | 97 | Middleware `ring.middleware.http-response/wrap-http-response` catches thrown HTTP-responses and returns the responses within. 98 | See the [facts](https://github.com/metosin/ring-http-response/blob/master/test/ring/middleware/http_response_test.clj) for examples. 99 | 100 | ## Migrating from ring.util.response 101 | 1. add the dependency 102 | 2. change your imports from `ring.util.response` to `ring.util.http-response` 103 | 3. convert your responses to use the correct HTTP-terms: 104 | - 200: `response` => `ok` 105 | - 302: `redirect` => `found` 106 | - 303: `redirect-after-post` => `see-other` 107 | 4. enjoy 108 | 109 | `created` and `not-found` are same in both packages. Also rest of the public vars in `ring.util.response` are available via `ring.util.http-response`. 110 | These include: `status`, `header`, `file-response`, `content-type`, `find-header`, `get-header`, `update-header`, `charset`, `set-cookie`, `response?` 111 | `resource-data`, `url-response` and `resource-response`. 112 | 113 | ## Adding new HTTP status codes 114 | 115 | All code is generated using [Mustache](https://mustache.github.io/) templates, see [user.clj](https://github.com/metosin/ring-http-response/blob/master/dev/user.clj). 116 | 117 | ``` 118 | lein repl 119 | user=> (generate!) 120 | ``` 121 | 122 | ## Making a release 123 | 124 | - Update `CHANGELOG.md` and increment the version number in `project.clj` 125 | - Commit and push to Github 126 | - Create a Github release [here](https://github.com/metosin/ring-http-response/releases) 127 | - Use the version number of the release for the tag name 128 | - The [Github Actions release workflow](.github/workflows/release.yml) should fire and deploy a release to clojars 129 | 130 | ## License 131 | Original [code](https://github.com/spray/spray/blob/master/spray-http/src/main/scala/spray/http/StatusCode.scala): Copyright © 2011-2013 the spray project . 132 | 133 | Copyright © 2014-2024 [Metosin Oy](http://www.metosin.fi) 134 | 135 | Distributed under the Eclipse Public License, the same as Clojure. 136 | -------------------------------------------------------------------------------- /deps.edn: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /dev/user.clj: -------------------------------------------------------------------------------- 1 | (ns user 2 | (:require [org.tobereplaced.lettercase :as lc] 3 | [clojure.string :as str] 4 | [stencil.core :as mustache])) 5 | 6 | (def responses 7 | "Format: [status name description & [options]]" 8 | [[100 "Continue" "The server has received the request headers and the client should proceed to send the request body."] 9 | [101 "Switching Protocols" "The server is switching protocols because the client requested the switch."] 10 | [102 "Processing" "The server is processing the request but no response is available yet."] 11 | [200 "OK" "OK"] 12 | [201 "Created" "The request has been fulfilled and resulted in a new resource being created." {:location? true, :entity? true}] 13 | [202 "Accepted" "The request has been accepted for processing but the processing has not been completed."] 14 | [203 "Non-Authoritative Information" "The server successfully processed the request but is returning information that may be from another source."] 15 | [204 "No Content" "The server successfully processed the request, but is not returning any content. Usually used as a response to a successful delete request." {:entity? false}] 16 | [205 "Reset Content" "The server successfully processed the request but is not returning any content. Unlike a 204 response, this response requires that the requester reset the document view." {:entity? false}] 17 | [206 "Partial Content" "The server is delivering only part of the resource due to a range header sent by the client."] 18 | [207 "Multi-Status" "The message body that follows is an XML message and can contain a number of separate response codes depending on how many sub-requests were made."] 19 | [208 "Already Reported" "The members of a DAV binding have already been enumerated in a previous reply to this request and are not being included again."] 20 | [226 "IM Used" "The server has fulfilled a GET request for the resource and the response is a representation of the result of one or more instance-manipulations applied to the current instance."] 21 | [300 "Multiple Choices" "There are multiple options for the resource that the client may follow."] 22 | [301 "Moved Permanently" "This and all future requests should be directed to the given URI."] 23 | [302 "Found" "The resource was found but at a different URI."] 24 | [303 "See Other" "The response to the request can be found under another URI using a GET method."] 25 | [304 "Not Modified" "The resource has not been modified since last requested." {:location? false}] 26 | [305 "Use Proxy" "This single request is to be repeated via the proxy given by the Location field."] 27 | [307 "Temporary Redirect" "The request should be repeated with another URI but future requests can still use the original URI."] 28 | [308 "Permanent Redirect" "The request and all future requests should be repeated using another URI."] 29 | [400 "Bad Request" "The request contains bad syntax or cannot be fulfilled."] 30 | [401 "Unauthorized" "Authentication is possible but has failed or not yet been provided."] 31 | [402 "Payment Required" "Reserved for future use."] 32 | [403 "Forbidden" "The request was a legal request but the server is refusing to respond to it."] 33 | [404 "Not Found" "The requested resource could not be found but may be available again in the future."] 34 | [405 "Method Not Allowed" "A request was made of a resource using a request method not supported by that resource;"] 35 | [406 "Not Acceptable" "The requested resource is only capable of generating content not acceptable according to the Accept headers sent in the request."] 36 | [407 "Proxy Authentication Required" "Proxy authentication is required to access the requested resource."] 37 | [408 "Request Timeout" "The server timed out waiting for the request."] 38 | [409 "Conflict" "The request could not be processed because of conflict in the request such as an edit conflict."] 39 | [410 "Gone" "The resource requested is no longer available and will not be available again."] 40 | [411 "Length Required" "The request did not specify the length of its content which is required by the requested resource."] 41 | [412 "Precondition Failed" "The server does not meet one of the preconditions that the requester put on the request."] 42 | [413 "Request Entity Too Large" "The request is larger than the server is willing or able to process."] 43 | [414 "Request-URI Too Long" "The URI provided was too long for the server to process."] 44 | [415 "Unsupported Media Type" "The request entity has a media type which the server or resource does not support."] 45 | [416 "Requested Range Not Satisfiable" "The client has asked for a portion of the file but the server cannot supply that portion."] 46 | [417 "Expectation Failed" "The server cannot meet the requirements of the Expect request-header field."] 47 | [418 "I'm a teapot" "Any attempt to brew coffee with a teapot should result in the error code \"418 I'm a teapot\". The resulting entity body MAY be short and stout."] 48 | [420 "Enhance Your Calm" "You are being rate-limited."] 49 | [422 "Unprocessable Entity" "The request was well-formed but was unable to be followed due to semantic errors."] 50 | [423 "Locked" "The resource that is being accessed is locked."] 51 | [424 "Failed Dependency" "The request failed due to failure of a previous request."] 52 | [425 "Unordered Collection" "The collection is unordered."] 53 | [426 "Upgrade Required" "The client should switch to a different protocol."] 54 | [428 "Precondition Required" "The server requires the request to be conditional."] 55 | [429 "Too Many Requests" "The user has sent too many requests in a given amount of time."] 56 | [431 "Request Header Fields Too Large" "The server is unwilling to process the request because either an individual header field or all the header fields collectively are too large."] 57 | [449 "Retry With" "The request should be retried after doing the appropriate action."] 58 | [450 "Blocked by Windows Parental Controls" "Windows Parental Controls are turned on and are blocking access to the given webpage."] 59 | [451 "Unavailable For Legal Reasons" "Resource access is denied for legal reasons."] 60 | [500 "Internal Server Error" "There was an internal server error."] 61 | [501 "Not Implemented" "The server either does not recognize the request method or it lacks the ability to fulfill the request."] 62 | [502 "Bad Gateway" "The server was acting as a gateway or proxy and received an invalid response from the upstream server."] 63 | [503 "Service Unavailable" "The server is currently unavailable (because it is overloaded or down for maintenance)."] 64 | [504 "Gateway Timeout" "The server was acting as a gateway or proxy and did not receive a timely request from the upstream server."] 65 | [505 "HTTP Version Not Supported" "The server does not support the HTTP protocol version used in the request."] 66 | [506 "Variant Also Negotiates" "Transparent content negotiation for the request results in a circular reference."] 67 | [507 "Insufficient Storage" "Insufficient storage to complete the request."] 68 | [508 "Loop Detected" "The server detected an infinite loop while processing the request."] 69 | [509 "Bandwidth Limit Exceeded" "Bandwidth limit has been exceeded."] 70 | [510 "Not Extended" "Further extensions to the request are required for the server to fulfill it."] 71 | [511 "Network Authentication Required" "The client needs to authenticate to gain network access."] 72 | [598 "Network read timeout" ""] 73 | [599 "Network connect timeout" ""]]) 74 | 75 | (def types 76 | [{:type "Informational", :entity? false, :location? false, :success? true, :start 100, :end 199} 77 | {:type "Success", :entity? true, :location? false, :success? true, :start 200, :end 299} 78 | {:type "Redirection", :entity? false, :location? true, :success? true, :start 300, :end 399} 79 | {:type "ClientError", :entity? true, :location? false, :success? false, :start 400, :end 499} 80 | {:type "ServerError", :entity? true, :location? false, :success? false, :start 500, :end 599}]) 81 | 82 | (def types-by-code (into {} (for [type types] 83 | [(:start type) type]))) 84 | 85 | (defn get-type [status] 86 | (get types-by-code (- status (mod status 100)))) 87 | 88 | (def template 89 | (for [[status name description options] responses] 90 | (merge 91 | {:fn-name (str/replace (lc/lower-hyphen-name name) #"'" "") 92 | :status status 93 | :name name 94 | :description description 95 | :location-entity? (and (:location? options) (:entity? options))} 96 | (get-type status) 97 | options))) 98 | 99 | (def type-template 100 | (map (fn [{:keys [type] :as m}] 101 | (assoc m :fn-name (lc/lower-hyphen-name type))) 102 | types)) 103 | 104 | (def imports 105 | ["status" "header" "file-response" "content-type" "find-header" "get-header" 106 | "update-header" "charset" "set-cookie" "response?" "resource-data" 107 | "url-response" "resource-response" "get-charset"]) 108 | 109 | (stencil.loader/set-cache (clojure.core.cache/ttl-cache-factory {} :ttl 0)) 110 | 111 | (defn generate! [] 112 | (spit "src/ring/util/http_response.clj" 113 | (mustache/render-file "http-response.mustache" 114 | {:template template 115 | :imports imports})) 116 | (doseq [ext ["clj" "cljs"]] 117 | (spit (str "src/ring/util/http_status." ext) 118 | (mustache/render-file "http-status.mustache" 119 | {:template template})) 120 | 121 | (spit (str "src/ring/util/http_predicates." ext) 122 | (mustache/render-file "http-predicates.mustache" 123 | {:template template 124 | :types type-template})))) 125 | 126 | (comment 127 | (generate!)) 128 | -------------------------------------------------------------------------------- /project.clj: -------------------------------------------------------------------------------- 1 | (defproject metosin/ring-http-response "0.9.5" 2 | :description "Handling HTTP Statuses with Clojure(Script)" 3 | :url "https://github.com/metosin/ring-http-response" 4 | :license {:name "Eclipse Public License" 5 | :url "http://www.eclipse.org/legal/epl-v10.html" 6 | :distribution :repo 7 | :comments "same as Clojure"} 8 | :dependencies [[ring/ring-core "1.13.0"] 9 | [potemkin "0.4.7"]] 10 | :profiles {:dev {:plugins [[lein-clojars "0.9.1"]] 11 | :resource-paths ["templates"] 12 | :source-paths ["dev"] 13 | :dependencies [[org.clojure/clojure "1.12.0"] 14 | [org.tobereplaced/lettercase "1.0.0"] 15 | [stencil "0.5.0"]]} 16 | :1.10 {:dependencies [[org.clojure/clojure "1.10.0"]]}} 17 | :deploy-repositories [["releases" {:url "https://repo.clojars.org/" 18 | :sign-releases false 19 | :username :env/CLOJARS_USER 20 | :password :env/CLOJARS_DEPLOY_TOKEN}]] 21 | :aliases {"all" ["with-profile" "dev:dev,1.10" "test"]}) 22 | -------------------------------------------------------------------------------- /src/ring/middleware/http_response.clj: -------------------------------------------------------------------------------- 1 | (ns ring.middleware.http-response) 2 | 3 | (defn- handle-exception [e respond raise] 4 | (let [{:keys [type response]} (ex-data e)] 5 | (if (= type :ring.util.http-response/response) 6 | (respond response) 7 | (raise e)))) 8 | 9 | (defn wrap-http-response 10 | "Catches thrown http-exceptions and converts them into 11 | corresponding ring-responses. e.g. exception from 12 | (bad-request! \"bad\") is converted into (bad-request \"bad\"). 13 | Supports async-ring." 14 | [handler] 15 | (let [throw #(throw %)] 16 | (fn 17 | ([request] 18 | (try 19 | (handler request) 20 | (catch Exception e 21 | (handle-exception e identity throw)))) 22 | ([request respond raise] 23 | (try 24 | (handler request respond #(handle-exception % respond raise)) 25 | (catch Exception e 26 | (handle-exception e respond throw))))))) 27 | 28 | -------------------------------------------------------------------------------- /src/ring/util/http_predicates.clj: -------------------------------------------------------------------------------- 1 | (ns ring.util.http-predicates) 2 | 3 | (defn informational? 4 | "Check whether the response type is Informational (status code is between 5 | 100 and 199)." 6 | [response] 7 | {:pre [(map? response)]} 8 | (<= 100 (:status response) 199)) 9 | 10 | (defn success? 11 | "Check whether the response type is Success (status code is between 12 | 200 and 299)." 13 | [response] 14 | {:pre [(map? response)]} 15 | (<= 200 (:status response) 299)) 16 | 17 | (defn redirection? 18 | "Check whether the response type is Redirection (status code is between 19 | 300 and 399)." 20 | [response] 21 | {:pre [(map? response)]} 22 | (<= 300 (:status response) 399)) 23 | 24 | (defn client-error? 25 | "Check whether the response type is ClientError (status code is between 26 | 400 and 499)." 27 | [response] 28 | {:pre [(map? response)]} 29 | (<= 400 (:status response) 499)) 30 | 31 | (defn server-error? 32 | "Check whether the response type is ServerError (status code is between 33 | 500 and 599)." 34 | [response] 35 | {:pre [(map? response)]} 36 | (<= 500 (:status response) 599)) 37 | 38 | (defn continue? 39 | "Checks whether the response has status code 100" 40 | [response] 41 | {:pre [(map? response)]} 42 | (= (:status response) 100)) 43 | 44 | (defn switching-protocols? 45 | "Checks whether the response has status code 101" 46 | [response] 47 | {:pre [(map? response)]} 48 | (= (:status response) 101)) 49 | 50 | (defn processing? 51 | "Checks whether the response has status code 102" 52 | [response] 53 | {:pre [(map? response)]} 54 | (= (:status response) 102)) 55 | 56 | (defn ok? 57 | "Checks whether the response has status code 200" 58 | [response] 59 | {:pre [(map? response)]} 60 | (= (:status response) 200)) 61 | 62 | (defn created? 63 | "Checks whether the response has status code 201" 64 | [response] 65 | {:pre [(map? response)]} 66 | (= (:status response) 201)) 67 | 68 | (defn accepted? 69 | "Checks whether the response has status code 202" 70 | [response] 71 | {:pre [(map? response)]} 72 | (= (:status response) 202)) 73 | 74 | (defn non-authoritative-information? 75 | "Checks whether the response has status code 203" 76 | [response] 77 | {:pre [(map? response)]} 78 | (= (:status response) 203)) 79 | 80 | (defn no-content? 81 | "Checks whether the response has status code 204" 82 | [response] 83 | {:pre [(map? response)]} 84 | (= (:status response) 204)) 85 | 86 | (defn reset-content? 87 | "Checks whether the response has status code 205" 88 | [response] 89 | {:pre [(map? response)]} 90 | (= (:status response) 205)) 91 | 92 | (defn partial-content? 93 | "Checks whether the response has status code 206" 94 | [response] 95 | {:pre [(map? response)]} 96 | (= (:status response) 206)) 97 | 98 | (defn multi-status? 99 | "Checks whether the response has status code 207" 100 | [response] 101 | {:pre [(map? response)]} 102 | (= (:status response) 207)) 103 | 104 | (defn already-reported? 105 | "Checks whether the response has status code 208" 106 | [response] 107 | {:pre [(map? response)]} 108 | (= (:status response) 208)) 109 | 110 | (defn im-used? 111 | "Checks whether the response has status code 226" 112 | [response] 113 | {:pre [(map? response)]} 114 | (= (:status response) 226)) 115 | 116 | (defn multiple-choices? 117 | "Checks whether the response has status code 300" 118 | [response] 119 | {:pre [(map? response)]} 120 | (= (:status response) 300)) 121 | 122 | (defn moved-permanently? 123 | "Checks whether the response has status code 301" 124 | [response] 125 | {:pre [(map? response)]} 126 | (= (:status response) 301)) 127 | 128 | (defn found? 129 | "Checks whether the response has status code 302" 130 | [response] 131 | {:pre [(map? response)]} 132 | (= (:status response) 302)) 133 | 134 | (defn see-other? 135 | "Checks whether the response has status code 303" 136 | [response] 137 | {:pre [(map? response)]} 138 | (= (:status response) 303)) 139 | 140 | (defn not-modified? 141 | "Checks whether the response has status code 304" 142 | [response] 143 | {:pre [(map? response)]} 144 | (= (:status response) 304)) 145 | 146 | (defn use-proxy? 147 | "Checks whether the response has status code 305" 148 | [response] 149 | {:pre [(map? response)]} 150 | (= (:status response) 305)) 151 | 152 | (defn temporary-redirect? 153 | "Checks whether the response has status code 307" 154 | [response] 155 | {:pre [(map? response)]} 156 | (= (:status response) 307)) 157 | 158 | (defn permanent-redirect? 159 | "Checks whether the response has status code 308" 160 | [response] 161 | {:pre [(map? response)]} 162 | (= (:status response) 308)) 163 | 164 | (defn bad-request? 165 | "Checks whether the response has status code 400" 166 | [response] 167 | {:pre [(map? response)]} 168 | (= (:status response) 400)) 169 | 170 | (defn unauthorized? 171 | "Checks whether the response has status code 401" 172 | [response] 173 | {:pre [(map? response)]} 174 | (= (:status response) 401)) 175 | 176 | (defn payment-required? 177 | "Checks whether the response has status code 402" 178 | [response] 179 | {:pre [(map? response)]} 180 | (= (:status response) 402)) 181 | 182 | (defn forbidden? 183 | "Checks whether the response has status code 403" 184 | [response] 185 | {:pre [(map? response)]} 186 | (= (:status response) 403)) 187 | 188 | (defn not-found? 189 | "Checks whether the response has status code 404" 190 | [response] 191 | {:pre [(map? response)]} 192 | (= (:status response) 404)) 193 | 194 | (defn method-not-allowed? 195 | "Checks whether the response has status code 405" 196 | [response] 197 | {:pre [(map? response)]} 198 | (= (:status response) 405)) 199 | 200 | (defn not-acceptable? 201 | "Checks whether the response has status code 406" 202 | [response] 203 | {:pre [(map? response)]} 204 | (= (:status response) 406)) 205 | 206 | (defn proxy-authentication-required? 207 | "Checks whether the response has status code 407" 208 | [response] 209 | {:pre [(map? response)]} 210 | (= (:status response) 407)) 211 | 212 | (defn request-timeout? 213 | "Checks whether the response has status code 408" 214 | [response] 215 | {:pre [(map? response)]} 216 | (= (:status response) 408)) 217 | 218 | (defn conflict? 219 | "Checks whether the response has status code 409" 220 | [response] 221 | {:pre [(map? response)]} 222 | (= (:status response) 409)) 223 | 224 | (defn gone? 225 | "Checks whether the response has status code 410" 226 | [response] 227 | {:pre [(map? response)]} 228 | (= (:status response) 410)) 229 | 230 | (defn length-required? 231 | "Checks whether the response has status code 411" 232 | [response] 233 | {:pre [(map? response)]} 234 | (= (:status response) 411)) 235 | 236 | (defn precondition-failed? 237 | "Checks whether the response has status code 412" 238 | [response] 239 | {:pre [(map? response)]} 240 | (= (:status response) 412)) 241 | 242 | (defn request-entity-too-large? 243 | "Checks whether the response has status code 413" 244 | [response] 245 | {:pre [(map? response)]} 246 | (= (:status response) 413)) 247 | 248 | (defn request-uri-too-long? 249 | "Checks whether the response has status code 414" 250 | [response] 251 | {:pre [(map? response)]} 252 | (= (:status response) 414)) 253 | 254 | (defn unsupported-media-type? 255 | "Checks whether the response has status code 415" 256 | [response] 257 | {:pre [(map? response)]} 258 | (= (:status response) 415)) 259 | 260 | (defn requested-range-not-satisfiable? 261 | "Checks whether the response has status code 416" 262 | [response] 263 | {:pre [(map? response)]} 264 | (= (:status response) 416)) 265 | 266 | (defn expectation-failed? 267 | "Checks whether the response has status code 417" 268 | [response] 269 | {:pre [(map? response)]} 270 | (= (:status response) 417)) 271 | 272 | (defn im-a-teapot? 273 | "Checks whether the response has status code 418" 274 | [response] 275 | {:pre [(map? response)]} 276 | (= (:status response) 418)) 277 | 278 | (defn enhance-your-calm? 279 | "Checks whether the response has status code 420" 280 | [response] 281 | {:pre [(map? response)]} 282 | (= (:status response) 420)) 283 | 284 | (defn unprocessable-entity? 285 | "Checks whether the response has status code 422" 286 | [response] 287 | {:pre [(map? response)]} 288 | (= (:status response) 422)) 289 | 290 | (defn locked? 291 | "Checks whether the response has status code 423" 292 | [response] 293 | {:pre [(map? response)]} 294 | (= (:status response) 423)) 295 | 296 | (defn failed-dependency? 297 | "Checks whether the response has status code 424" 298 | [response] 299 | {:pre [(map? response)]} 300 | (= (:status response) 424)) 301 | 302 | (defn unordered-collection? 303 | "Checks whether the response has status code 425" 304 | [response] 305 | {:pre [(map? response)]} 306 | (= (:status response) 425)) 307 | 308 | (defn upgrade-required? 309 | "Checks whether the response has status code 426" 310 | [response] 311 | {:pre [(map? response)]} 312 | (= (:status response) 426)) 313 | 314 | (defn precondition-required? 315 | "Checks whether the response has status code 428" 316 | [response] 317 | {:pre [(map? response)]} 318 | (= (:status response) 428)) 319 | 320 | (defn too-many-requests? 321 | "Checks whether the response has status code 429" 322 | [response] 323 | {:pre [(map? response)]} 324 | (= (:status response) 429)) 325 | 326 | (defn request-header-fields-too-large? 327 | "Checks whether the response has status code 431" 328 | [response] 329 | {:pre [(map? response)]} 330 | (= (:status response) 431)) 331 | 332 | (defn retry-with? 333 | "Checks whether the response has status code 449" 334 | [response] 335 | {:pre [(map? response)]} 336 | (= (:status response) 449)) 337 | 338 | (defn blocked-by-windows-parental-controls? 339 | "Checks whether the response has status code 450" 340 | [response] 341 | {:pre [(map? response)]} 342 | (= (:status response) 450)) 343 | 344 | (defn unavailable-for-legal-reasons? 345 | "Checks whether the response has status code 451" 346 | [response] 347 | {:pre [(map? response)]} 348 | (= (:status response) 451)) 349 | 350 | (defn internal-server-error? 351 | "Checks whether the response has status code 500" 352 | [response] 353 | {:pre [(map? response)]} 354 | (= (:status response) 500)) 355 | 356 | (defn not-implemented? 357 | "Checks whether the response has status code 501" 358 | [response] 359 | {:pre [(map? response)]} 360 | (= (:status response) 501)) 361 | 362 | (defn bad-gateway? 363 | "Checks whether the response has status code 502" 364 | [response] 365 | {:pre [(map? response)]} 366 | (= (:status response) 502)) 367 | 368 | (defn service-unavailable? 369 | "Checks whether the response has status code 503" 370 | [response] 371 | {:pre [(map? response)]} 372 | (= (:status response) 503)) 373 | 374 | (defn gateway-timeout? 375 | "Checks whether the response has status code 504" 376 | [response] 377 | {:pre [(map? response)]} 378 | (= (:status response) 504)) 379 | 380 | (defn http-version-not-supported? 381 | "Checks whether the response has status code 505" 382 | [response] 383 | {:pre [(map? response)]} 384 | (= (:status response) 505)) 385 | 386 | (defn variant-also-negotiates? 387 | "Checks whether the response has status code 506" 388 | [response] 389 | {:pre [(map? response)]} 390 | (= (:status response) 506)) 391 | 392 | (defn insufficient-storage? 393 | "Checks whether the response has status code 507" 394 | [response] 395 | {:pre [(map? response)]} 396 | (= (:status response) 507)) 397 | 398 | (defn loop-detected? 399 | "Checks whether the response has status code 508" 400 | [response] 401 | {:pre [(map? response)]} 402 | (= (:status response) 508)) 403 | 404 | (defn bandwidth-limit-exceeded? 405 | "Checks whether the response has status code 509" 406 | [response] 407 | {:pre [(map? response)]} 408 | (= (:status response) 509)) 409 | 410 | (defn not-extended? 411 | "Checks whether the response has status code 510" 412 | [response] 413 | {:pre [(map? response)]} 414 | (= (:status response) 510)) 415 | 416 | (defn network-authentication-required? 417 | "Checks whether the response has status code 511" 418 | [response] 419 | {:pre [(map? response)]} 420 | (= (:status response) 511)) 421 | 422 | (defn network-read-timeout? 423 | "Checks whether the response has status code 598" 424 | [response] 425 | {:pre [(map? response)]} 426 | (= (:status response) 598)) 427 | 428 | (defn network-connect-timeout? 429 | "Checks whether the response has status code 599" 430 | [response] 431 | {:pre [(map? response)]} 432 | (= (:status response) 599)) 433 | -------------------------------------------------------------------------------- /src/ring/util/http_predicates.cljs: -------------------------------------------------------------------------------- 1 | (ns ring.util.http-predicates) 2 | 3 | (defn informational? 4 | "Check whether the response type is Informational (status code is between 5 | 100 and 199)." 6 | [response] 7 | {:pre [(map? response)]} 8 | (<= 100 (:status response) 199)) 9 | 10 | (defn success? 11 | "Check whether the response type is Success (status code is between 12 | 200 and 299)." 13 | [response] 14 | {:pre [(map? response)]} 15 | (<= 200 (:status response) 299)) 16 | 17 | (defn redirection? 18 | "Check whether the response type is Redirection (status code is between 19 | 300 and 399)." 20 | [response] 21 | {:pre [(map? response)]} 22 | (<= 300 (:status response) 399)) 23 | 24 | (defn client-error? 25 | "Check whether the response type is ClientError (status code is between 26 | 400 and 499)." 27 | [response] 28 | {:pre [(map? response)]} 29 | (<= 400 (:status response) 499)) 30 | 31 | (defn server-error? 32 | "Check whether the response type is ServerError (status code is between 33 | 500 and 599)." 34 | [response] 35 | {:pre [(map? response)]} 36 | (<= 500 (:status response) 599)) 37 | 38 | (defn continue? 39 | "Checks whether the response has status code 100" 40 | [response] 41 | {:pre [(map? response)]} 42 | (= (:status response) 100)) 43 | 44 | (defn switching-protocols? 45 | "Checks whether the response has status code 101" 46 | [response] 47 | {:pre [(map? response)]} 48 | (= (:status response) 101)) 49 | 50 | (defn processing? 51 | "Checks whether the response has status code 102" 52 | [response] 53 | {:pre [(map? response)]} 54 | (= (:status response) 102)) 55 | 56 | (defn ok? 57 | "Checks whether the response has status code 200" 58 | [response] 59 | {:pre [(map? response)]} 60 | (= (:status response) 200)) 61 | 62 | (defn created? 63 | "Checks whether the response has status code 201" 64 | [response] 65 | {:pre [(map? response)]} 66 | (= (:status response) 201)) 67 | 68 | (defn accepted? 69 | "Checks whether the response has status code 202" 70 | [response] 71 | {:pre [(map? response)]} 72 | (= (:status response) 202)) 73 | 74 | (defn non-authoritative-information? 75 | "Checks whether the response has status code 203" 76 | [response] 77 | {:pre [(map? response)]} 78 | (= (:status response) 203)) 79 | 80 | (defn no-content? 81 | "Checks whether the response has status code 204" 82 | [response] 83 | {:pre [(map? response)]} 84 | (= (:status response) 204)) 85 | 86 | (defn reset-content? 87 | "Checks whether the response has status code 205" 88 | [response] 89 | {:pre [(map? response)]} 90 | (= (:status response) 205)) 91 | 92 | (defn partial-content? 93 | "Checks whether the response has status code 206" 94 | [response] 95 | {:pre [(map? response)]} 96 | (= (:status response) 206)) 97 | 98 | (defn multi-status? 99 | "Checks whether the response has status code 207" 100 | [response] 101 | {:pre [(map? response)]} 102 | (= (:status response) 207)) 103 | 104 | (defn already-reported? 105 | "Checks whether the response has status code 208" 106 | [response] 107 | {:pre [(map? response)]} 108 | (= (:status response) 208)) 109 | 110 | (defn im-used? 111 | "Checks whether the response has status code 226" 112 | [response] 113 | {:pre [(map? response)]} 114 | (= (:status response) 226)) 115 | 116 | (defn multiple-choices? 117 | "Checks whether the response has status code 300" 118 | [response] 119 | {:pre [(map? response)]} 120 | (= (:status response) 300)) 121 | 122 | (defn moved-permanently? 123 | "Checks whether the response has status code 301" 124 | [response] 125 | {:pre [(map? response)]} 126 | (= (:status response) 301)) 127 | 128 | (defn found? 129 | "Checks whether the response has status code 302" 130 | [response] 131 | {:pre [(map? response)]} 132 | (= (:status response) 302)) 133 | 134 | (defn see-other? 135 | "Checks whether the response has status code 303" 136 | [response] 137 | {:pre [(map? response)]} 138 | (= (:status response) 303)) 139 | 140 | (defn not-modified? 141 | "Checks whether the response has status code 304" 142 | [response] 143 | {:pre [(map? response)]} 144 | (= (:status response) 304)) 145 | 146 | (defn use-proxy? 147 | "Checks whether the response has status code 305" 148 | [response] 149 | {:pre [(map? response)]} 150 | (= (:status response) 305)) 151 | 152 | (defn temporary-redirect? 153 | "Checks whether the response has status code 307" 154 | [response] 155 | {:pre [(map? response)]} 156 | (= (:status response) 307)) 157 | 158 | (defn permanent-redirect? 159 | "Checks whether the response has status code 308" 160 | [response] 161 | {:pre [(map? response)]} 162 | (= (:status response) 308)) 163 | 164 | (defn bad-request? 165 | "Checks whether the response has status code 400" 166 | [response] 167 | {:pre [(map? response)]} 168 | (= (:status response) 400)) 169 | 170 | (defn unauthorized? 171 | "Checks whether the response has status code 401" 172 | [response] 173 | {:pre [(map? response)]} 174 | (= (:status response) 401)) 175 | 176 | (defn payment-required? 177 | "Checks whether the response has status code 402" 178 | [response] 179 | {:pre [(map? response)]} 180 | (= (:status response) 402)) 181 | 182 | (defn forbidden? 183 | "Checks whether the response has status code 403" 184 | [response] 185 | {:pre [(map? response)]} 186 | (= (:status response) 403)) 187 | 188 | (defn not-found? 189 | "Checks whether the response has status code 404" 190 | [response] 191 | {:pre [(map? response)]} 192 | (= (:status response) 404)) 193 | 194 | (defn method-not-allowed? 195 | "Checks whether the response has status code 405" 196 | [response] 197 | {:pre [(map? response)]} 198 | (= (:status response) 405)) 199 | 200 | (defn not-acceptable? 201 | "Checks whether the response has status code 406" 202 | [response] 203 | {:pre [(map? response)]} 204 | (= (:status response) 406)) 205 | 206 | (defn proxy-authentication-required? 207 | "Checks whether the response has status code 407" 208 | [response] 209 | {:pre [(map? response)]} 210 | (= (:status response) 407)) 211 | 212 | (defn request-timeout? 213 | "Checks whether the response has status code 408" 214 | [response] 215 | {:pre [(map? response)]} 216 | (= (:status response) 408)) 217 | 218 | (defn conflict? 219 | "Checks whether the response has status code 409" 220 | [response] 221 | {:pre [(map? response)]} 222 | (= (:status response) 409)) 223 | 224 | (defn gone? 225 | "Checks whether the response has status code 410" 226 | [response] 227 | {:pre [(map? response)]} 228 | (= (:status response) 410)) 229 | 230 | (defn length-required? 231 | "Checks whether the response has status code 411" 232 | [response] 233 | {:pre [(map? response)]} 234 | (= (:status response) 411)) 235 | 236 | (defn precondition-failed? 237 | "Checks whether the response has status code 412" 238 | [response] 239 | {:pre [(map? response)]} 240 | (= (:status response) 412)) 241 | 242 | (defn request-entity-too-large? 243 | "Checks whether the response has status code 413" 244 | [response] 245 | {:pre [(map? response)]} 246 | (= (:status response) 413)) 247 | 248 | (defn request-uri-too-long? 249 | "Checks whether the response has status code 414" 250 | [response] 251 | {:pre [(map? response)]} 252 | (= (:status response) 414)) 253 | 254 | (defn unsupported-media-type? 255 | "Checks whether the response has status code 415" 256 | [response] 257 | {:pre [(map? response)]} 258 | (= (:status response) 415)) 259 | 260 | (defn requested-range-not-satisfiable? 261 | "Checks whether the response has status code 416" 262 | [response] 263 | {:pre [(map? response)]} 264 | (= (:status response) 416)) 265 | 266 | (defn expectation-failed? 267 | "Checks whether the response has status code 417" 268 | [response] 269 | {:pre [(map? response)]} 270 | (= (:status response) 417)) 271 | 272 | (defn im-a-teapot? 273 | "Checks whether the response has status code 418" 274 | [response] 275 | {:pre [(map? response)]} 276 | (= (:status response) 418)) 277 | 278 | (defn enhance-your-calm? 279 | "Checks whether the response has status code 420" 280 | [response] 281 | {:pre [(map? response)]} 282 | (= (:status response) 420)) 283 | 284 | (defn unprocessable-entity? 285 | "Checks whether the response has status code 422" 286 | [response] 287 | {:pre [(map? response)]} 288 | (= (:status response) 422)) 289 | 290 | (defn locked? 291 | "Checks whether the response has status code 423" 292 | [response] 293 | {:pre [(map? response)]} 294 | (= (:status response) 423)) 295 | 296 | (defn failed-dependency? 297 | "Checks whether the response has status code 424" 298 | [response] 299 | {:pre [(map? response)]} 300 | (= (:status response) 424)) 301 | 302 | (defn unordered-collection? 303 | "Checks whether the response has status code 425" 304 | [response] 305 | {:pre [(map? response)]} 306 | (= (:status response) 425)) 307 | 308 | (defn upgrade-required? 309 | "Checks whether the response has status code 426" 310 | [response] 311 | {:pre [(map? response)]} 312 | (= (:status response) 426)) 313 | 314 | (defn precondition-required? 315 | "Checks whether the response has status code 428" 316 | [response] 317 | {:pre [(map? response)]} 318 | (= (:status response) 428)) 319 | 320 | (defn too-many-requests? 321 | "Checks whether the response has status code 429" 322 | [response] 323 | {:pre [(map? response)]} 324 | (= (:status response) 429)) 325 | 326 | (defn request-header-fields-too-large? 327 | "Checks whether the response has status code 431" 328 | [response] 329 | {:pre [(map? response)]} 330 | (= (:status response) 431)) 331 | 332 | (defn retry-with? 333 | "Checks whether the response has status code 449" 334 | [response] 335 | {:pre [(map? response)]} 336 | (= (:status response) 449)) 337 | 338 | (defn blocked-by-windows-parental-controls? 339 | "Checks whether the response has status code 450" 340 | [response] 341 | {:pre [(map? response)]} 342 | (= (:status response) 450)) 343 | 344 | (defn unavailable-for-legal-reasons? 345 | "Checks whether the response has status code 451" 346 | [response] 347 | {:pre [(map? response)]} 348 | (= (:status response) 451)) 349 | 350 | (defn internal-server-error? 351 | "Checks whether the response has status code 500" 352 | [response] 353 | {:pre [(map? response)]} 354 | (= (:status response) 500)) 355 | 356 | (defn not-implemented? 357 | "Checks whether the response has status code 501" 358 | [response] 359 | {:pre [(map? response)]} 360 | (= (:status response) 501)) 361 | 362 | (defn bad-gateway? 363 | "Checks whether the response has status code 502" 364 | [response] 365 | {:pre [(map? response)]} 366 | (= (:status response) 502)) 367 | 368 | (defn service-unavailable? 369 | "Checks whether the response has status code 503" 370 | [response] 371 | {:pre [(map? response)]} 372 | (= (:status response) 503)) 373 | 374 | (defn gateway-timeout? 375 | "Checks whether the response has status code 504" 376 | [response] 377 | {:pre [(map? response)]} 378 | (= (:status response) 504)) 379 | 380 | (defn http-version-not-supported? 381 | "Checks whether the response has status code 505" 382 | [response] 383 | {:pre [(map? response)]} 384 | (= (:status response) 505)) 385 | 386 | (defn variant-also-negotiates? 387 | "Checks whether the response has status code 506" 388 | [response] 389 | {:pre [(map? response)]} 390 | (= (:status response) 506)) 391 | 392 | (defn insufficient-storage? 393 | "Checks whether the response has status code 507" 394 | [response] 395 | {:pre [(map? response)]} 396 | (= (:status response) 507)) 397 | 398 | (defn loop-detected? 399 | "Checks whether the response has status code 508" 400 | [response] 401 | {:pre [(map? response)]} 402 | (= (:status response) 508)) 403 | 404 | (defn bandwidth-limit-exceeded? 405 | "Checks whether the response has status code 509" 406 | [response] 407 | {:pre [(map? response)]} 408 | (= (:status response) 509)) 409 | 410 | (defn not-extended? 411 | "Checks whether the response has status code 510" 412 | [response] 413 | {:pre [(map? response)]} 414 | (= (:status response) 510)) 415 | 416 | (defn network-authentication-required? 417 | "Checks whether the response has status code 511" 418 | [response] 419 | {:pre [(map? response)]} 420 | (= (:status response) 511)) 421 | 422 | (defn network-read-timeout? 423 | "Checks whether the response has status code 598" 424 | [response] 425 | {:pre [(map? response)]} 426 | (= (:status response) 598)) 427 | 428 | (defn network-connect-timeout? 429 | "Checks whether the response has status code 599" 430 | [response] 431 | {:pre [(map? response)]} 432 | (= (:status response) 599)) 433 | -------------------------------------------------------------------------------- /src/ring/util/http_response.clj: -------------------------------------------------------------------------------- 1 | (ns ring.util.http-response 2 | (:require [potemkin.namespaces :as p] 3 | ring.util.response)) 4 | 5 | (defn throw! 6 | "Throwns an exception with ex-info: 7 | {:type :ring.util.http-response/response 8 | :response response}" 9 | [response] 10 | {:pre [(map? response)]} 11 | (throw (ex-info (str "HTTP "(:status response)) {:type ::response :response response}))) 12 | 13 | (defn continue 14 | "100 Continue (Informational) 15 | The server has received the request headers and the client should proceed to send the request body." 16 | ([] 17 | {:status 100 18 | :headers {} 19 | :body ""})) 20 | 21 | (defn switching-protocols 22 | "101 Switching Protocols (Informational) 23 | The server is switching protocols because the client requested the switch." 24 | ([] 25 | {:status 101 26 | :headers {} 27 | :body ""})) 28 | 29 | (defn processing 30 | "102 Processing (Informational) 31 | The server is processing the request but no response is available yet." 32 | ([] 33 | {:status 102 34 | :headers {} 35 | :body ""})) 36 | 37 | (defn ok 38 | "200 OK (Success) 39 | OK" 40 | ([] (ok nil)) 41 | ([body] 42 | {:status 200 43 | :headers {} 44 | :body body})) 45 | 46 | (defn created 47 | "201 Created (Success) 48 | The request has been fulfilled and resulted in a new resource being created." 49 | ([] (created nil)) 50 | ([url] (created url nil)) 51 | ([url body] 52 | {:status 201 53 | :headers {"Location" url} 54 | :body body})) 55 | 56 | (defn accepted 57 | "202 Accepted (Success) 58 | The request has been accepted for processing but the processing has not been completed." 59 | ([] (accepted nil)) 60 | ([body] 61 | {:status 202 62 | :headers {} 63 | :body body})) 64 | 65 | (defn non-authoritative-information 66 | "203 Non-Authoritative Information (Success) 67 | The server successfully processed the request but is returning information that may be from another source." 68 | ([] (non-authoritative-information nil)) 69 | ([body] 70 | {:status 203 71 | :headers {} 72 | :body body})) 73 | 74 | (defn no-content 75 | "204 No Content (Success) 76 | The server successfully processed the request, but is not returning any content. Usually used as a response to a successful delete request." 77 | ([] 78 | {:status 204 79 | :headers {} 80 | :body ""})) 81 | 82 | (defn reset-content 83 | "205 Reset Content (Success) 84 | The server successfully processed the request but is not returning any content. Unlike a 204 response, this response requires that the requester reset the document view." 85 | ([] 86 | {:status 205 87 | :headers {} 88 | :body ""})) 89 | 90 | (defn partial-content 91 | "206 Partial Content (Success) 92 | The server is delivering only part of the resource due to a range header sent by the client." 93 | ([] (partial-content nil)) 94 | ([body] 95 | {:status 206 96 | :headers {} 97 | :body body})) 98 | 99 | (defn multi-status 100 | "207 Multi-Status (Success) 101 | The message body that follows is an XML message and can contain a number of separate response codes depending on how many sub-requests were made." 102 | ([] (multi-status nil)) 103 | ([body] 104 | {:status 207 105 | :headers {} 106 | :body body})) 107 | 108 | (defn already-reported 109 | "208 Already Reported (Success) 110 | The members of a DAV binding have already been enumerated in a previous reply to this request and are not being included again." 111 | ([] (already-reported nil)) 112 | ([body] 113 | {:status 208 114 | :headers {} 115 | :body body})) 116 | 117 | (defn im-used 118 | "226 IM Used (Success) 119 | The server has fulfilled a GET request for the resource and the response is a representation of the result of one or more instance-manipulations applied to the current instance." 120 | ([] (im-used nil)) 121 | ([body] 122 | {:status 226 123 | :headers {} 124 | :body body})) 125 | 126 | (defn multiple-choices 127 | "300 Multiple Choices (Redirection) 128 | There are multiple options for the resource that the client may follow." 129 | ([url] 130 | {:status 300 131 | :headers {"Location" url} 132 | :body ""})) 133 | 134 | (defn moved-permanently 135 | "301 Moved Permanently (Redirection) 136 | This and all future requests should be directed to the given URI." 137 | ([url] 138 | {:status 301 139 | :headers {"Location" url} 140 | :body ""})) 141 | 142 | (defn found 143 | "302 Found (Redirection) 144 | The resource was found but at a different URI." 145 | ([url] 146 | {:status 302 147 | :headers {"Location" url} 148 | :body ""})) 149 | 150 | (defn see-other 151 | "303 See Other (Redirection) 152 | The response to the request can be found under another URI using a GET method." 153 | ([url] 154 | {:status 303 155 | :headers {"Location" url} 156 | :body ""})) 157 | 158 | (defn not-modified 159 | "304 Not Modified (Redirection) 160 | The resource has not been modified since last requested." 161 | ([] 162 | {:status 304 163 | :headers {} 164 | :body ""})) 165 | 166 | (defn use-proxy 167 | "305 Use Proxy (Redirection) 168 | This single request is to be repeated via the proxy given by the Location field." 169 | ([url] 170 | {:status 305 171 | :headers {"Location" url} 172 | :body ""})) 173 | 174 | (defn temporary-redirect 175 | "307 Temporary Redirect (Redirection) 176 | The request should be repeated with another URI but future requests can still use the original URI." 177 | ([url] 178 | {:status 307 179 | :headers {"Location" url} 180 | :body ""})) 181 | 182 | (defn permanent-redirect 183 | "308 Permanent Redirect (Redirection) 184 | The request and all future requests should be repeated using another URI." 185 | ([url] 186 | {:status 308 187 | :headers {"Location" url} 188 | :body ""})) 189 | 190 | (defn bad-request 191 | "400 Bad Request (ClientError) 192 | The request contains bad syntax or cannot be fulfilled." 193 | ([] (bad-request nil)) 194 | ([body] 195 | {:status 400 196 | :headers {} 197 | :body body})) 198 | 199 | (defn bad-request! 200 | "400 Bad Request (ClientError) 201 | The request contains bad syntax or cannot be fulfilled. 202 | Throws an exception with ex-info: 203 | {:type :ring.util.http-response/response 204 | :response response}" 205 | ([] (bad-request! nil)) 206 | ([body] 207 | (throw! 208 | {:status 400 209 | :headers {} 210 | :body body}))) 211 | 212 | (defn unauthorized 213 | "401 Unauthorized (ClientError) 214 | Authentication is possible but has failed or not yet been provided." 215 | ([] (unauthorized nil)) 216 | ([body] 217 | {:status 401 218 | :headers {} 219 | :body body})) 220 | 221 | (defn unauthorized! 222 | "401 Unauthorized (ClientError) 223 | Authentication is possible but has failed or not yet been provided. 224 | Throws an exception with ex-info: 225 | {:type :ring.util.http-response/response 226 | :response response}" 227 | ([] (unauthorized! nil)) 228 | ([body] 229 | (throw! 230 | {:status 401 231 | :headers {} 232 | :body body}))) 233 | 234 | (defn payment-required 235 | "402 Payment Required (ClientError) 236 | Reserved for future use." 237 | ([] (payment-required nil)) 238 | ([body] 239 | {:status 402 240 | :headers {} 241 | :body body})) 242 | 243 | (defn payment-required! 244 | "402 Payment Required (ClientError) 245 | Reserved for future use. 246 | Throws an exception with ex-info: 247 | {:type :ring.util.http-response/response 248 | :response response}" 249 | ([] (payment-required! nil)) 250 | ([body] 251 | (throw! 252 | {:status 402 253 | :headers {} 254 | :body body}))) 255 | 256 | (defn forbidden 257 | "403 Forbidden (ClientError) 258 | The request was a legal request but the server is refusing to respond to it." 259 | ([] (forbidden nil)) 260 | ([body] 261 | {:status 403 262 | :headers {} 263 | :body body})) 264 | 265 | (defn forbidden! 266 | "403 Forbidden (ClientError) 267 | The request was a legal request but the server is refusing to respond to it. 268 | Throws an exception with ex-info: 269 | {:type :ring.util.http-response/response 270 | :response response}" 271 | ([] (forbidden! nil)) 272 | ([body] 273 | (throw! 274 | {:status 403 275 | :headers {} 276 | :body body}))) 277 | 278 | (defn not-found 279 | "404 Not Found (ClientError) 280 | The requested resource could not be found but may be available again in the future." 281 | ([] (not-found nil)) 282 | ([body] 283 | {:status 404 284 | :headers {} 285 | :body body})) 286 | 287 | (defn not-found! 288 | "404 Not Found (ClientError) 289 | The requested resource could not be found but may be available again in the future. 290 | Throws an exception with ex-info: 291 | {:type :ring.util.http-response/response 292 | :response response}" 293 | ([] (not-found! nil)) 294 | ([body] 295 | (throw! 296 | {:status 404 297 | :headers {} 298 | :body body}))) 299 | 300 | (defn method-not-allowed 301 | "405 Method Not Allowed (ClientError) 302 | A request was made of a resource using a request method not supported by that resource;" 303 | ([] (method-not-allowed nil)) 304 | ([body] 305 | {:status 405 306 | :headers {} 307 | :body body})) 308 | 309 | (defn method-not-allowed! 310 | "405 Method Not Allowed (ClientError) 311 | A request was made of a resource using a request method not supported by that resource; 312 | Throws an exception with ex-info: 313 | {:type :ring.util.http-response/response 314 | :response response}" 315 | ([] (method-not-allowed! nil)) 316 | ([body] 317 | (throw! 318 | {:status 405 319 | :headers {} 320 | :body body}))) 321 | 322 | (defn not-acceptable 323 | "406 Not Acceptable (ClientError) 324 | The requested resource is only capable of generating content not acceptable according to the Accept headers sent in the request." 325 | ([] (not-acceptable nil)) 326 | ([body] 327 | {:status 406 328 | :headers {} 329 | :body body})) 330 | 331 | (defn not-acceptable! 332 | "406 Not Acceptable (ClientError) 333 | The requested resource is only capable of generating content not acceptable according to the Accept headers sent in the request. 334 | Throws an exception with ex-info: 335 | {:type :ring.util.http-response/response 336 | :response response}" 337 | ([] (not-acceptable! nil)) 338 | ([body] 339 | (throw! 340 | {:status 406 341 | :headers {} 342 | :body body}))) 343 | 344 | (defn proxy-authentication-required 345 | "407 Proxy Authentication Required (ClientError) 346 | Proxy authentication is required to access the requested resource." 347 | ([] (proxy-authentication-required nil)) 348 | ([body] 349 | {:status 407 350 | :headers {} 351 | :body body})) 352 | 353 | (defn proxy-authentication-required! 354 | "407 Proxy Authentication Required (ClientError) 355 | Proxy authentication is required to access the requested resource. 356 | Throws an exception with ex-info: 357 | {:type :ring.util.http-response/response 358 | :response response}" 359 | ([] (proxy-authentication-required! nil)) 360 | ([body] 361 | (throw! 362 | {:status 407 363 | :headers {} 364 | :body body}))) 365 | 366 | (defn request-timeout 367 | "408 Request Timeout (ClientError) 368 | The server timed out waiting for the request." 369 | ([] (request-timeout nil)) 370 | ([body] 371 | {:status 408 372 | :headers {} 373 | :body body})) 374 | 375 | (defn request-timeout! 376 | "408 Request Timeout (ClientError) 377 | The server timed out waiting for the request. 378 | Throws an exception with ex-info: 379 | {:type :ring.util.http-response/response 380 | :response response}" 381 | ([] (request-timeout! nil)) 382 | ([body] 383 | (throw! 384 | {:status 408 385 | :headers {} 386 | :body body}))) 387 | 388 | (defn conflict 389 | "409 Conflict (ClientError) 390 | The request could not be processed because of conflict in the request such as an edit conflict." 391 | ([] (conflict nil)) 392 | ([body] 393 | {:status 409 394 | :headers {} 395 | :body body})) 396 | 397 | (defn conflict! 398 | "409 Conflict (ClientError) 399 | The request could not be processed because of conflict in the request such as an edit conflict. 400 | Throws an exception with ex-info: 401 | {:type :ring.util.http-response/response 402 | :response response}" 403 | ([] (conflict! nil)) 404 | ([body] 405 | (throw! 406 | {:status 409 407 | :headers {} 408 | :body body}))) 409 | 410 | (defn gone 411 | "410 Gone (ClientError) 412 | The resource requested is no longer available and will not be available again." 413 | ([] (gone nil)) 414 | ([body] 415 | {:status 410 416 | :headers {} 417 | :body body})) 418 | 419 | (defn gone! 420 | "410 Gone (ClientError) 421 | The resource requested is no longer available and will not be available again. 422 | Throws an exception with ex-info: 423 | {:type :ring.util.http-response/response 424 | :response response}" 425 | ([] (gone! nil)) 426 | ([body] 427 | (throw! 428 | {:status 410 429 | :headers {} 430 | :body body}))) 431 | 432 | (defn length-required 433 | "411 Length Required (ClientError) 434 | The request did not specify the length of its content which is required by the requested resource." 435 | ([] (length-required nil)) 436 | ([body] 437 | {:status 411 438 | :headers {} 439 | :body body})) 440 | 441 | (defn length-required! 442 | "411 Length Required (ClientError) 443 | The request did not specify the length of its content which is required by the requested resource. 444 | Throws an exception with ex-info: 445 | {:type :ring.util.http-response/response 446 | :response response}" 447 | ([] (length-required! nil)) 448 | ([body] 449 | (throw! 450 | {:status 411 451 | :headers {} 452 | :body body}))) 453 | 454 | (defn precondition-failed 455 | "412 Precondition Failed (ClientError) 456 | The server does not meet one of the preconditions that the requester put on the request." 457 | ([] (precondition-failed nil)) 458 | ([body] 459 | {:status 412 460 | :headers {} 461 | :body body})) 462 | 463 | (defn precondition-failed! 464 | "412 Precondition Failed (ClientError) 465 | The server does not meet one of the preconditions that the requester put on the request. 466 | Throws an exception with ex-info: 467 | {:type :ring.util.http-response/response 468 | :response response}" 469 | ([] (precondition-failed! nil)) 470 | ([body] 471 | (throw! 472 | {:status 412 473 | :headers {} 474 | :body body}))) 475 | 476 | (defn request-entity-too-large 477 | "413 Request Entity Too Large (ClientError) 478 | The request is larger than the server is willing or able to process." 479 | ([] (request-entity-too-large nil)) 480 | ([body] 481 | {:status 413 482 | :headers {} 483 | :body body})) 484 | 485 | (defn request-entity-too-large! 486 | "413 Request Entity Too Large (ClientError) 487 | The request is larger than the server is willing or able to process. 488 | Throws an exception with ex-info: 489 | {:type :ring.util.http-response/response 490 | :response response}" 491 | ([] (request-entity-too-large! nil)) 492 | ([body] 493 | (throw! 494 | {:status 413 495 | :headers {} 496 | :body body}))) 497 | 498 | (defn request-uri-too-long 499 | "414 Request-URI Too Long (ClientError) 500 | The URI provided was too long for the server to process." 501 | ([] (request-uri-too-long nil)) 502 | ([body] 503 | {:status 414 504 | :headers {} 505 | :body body})) 506 | 507 | (defn request-uri-too-long! 508 | "414 Request-URI Too Long (ClientError) 509 | The URI provided was too long for the server to process. 510 | Throws an exception with ex-info: 511 | {:type :ring.util.http-response/response 512 | :response response}" 513 | ([] (request-uri-too-long! nil)) 514 | ([body] 515 | (throw! 516 | {:status 414 517 | :headers {} 518 | :body body}))) 519 | 520 | (defn unsupported-media-type 521 | "415 Unsupported Media Type (ClientError) 522 | The request entity has a media type which the server or resource does not support." 523 | ([] (unsupported-media-type nil)) 524 | ([body] 525 | {:status 415 526 | :headers {} 527 | :body body})) 528 | 529 | (defn unsupported-media-type! 530 | "415 Unsupported Media Type (ClientError) 531 | The request entity has a media type which the server or resource does not support. 532 | Throws an exception with ex-info: 533 | {:type :ring.util.http-response/response 534 | :response response}" 535 | ([] (unsupported-media-type! nil)) 536 | ([body] 537 | (throw! 538 | {:status 415 539 | :headers {} 540 | :body body}))) 541 | 542 | (defn requested-range-not-satisfiable 543 | "416 Requested Range Not Satisfiable (ClientError) 544 | The client has asked for a portion of the file but the server cannot supply that portion." 545 | ([] (requested-range-not-satisfiable nil)) 546 | ([body] 547 | {:status 416 548 | :headers {} 549 | :body body})) 550 | 551 | (defn requested-range-not-satisfiable! 552 | "416 Requested Range Not Satisfiable (ClientError) 553 | The client has asked for a portion of the file but the server cannot supply that portion. 554 | Throws an exception with ex-info: 555 | {:type :ring.util.http-response/response 556 | :response response}" 557 | ([] (requested-range-not-satisfiable! nil)) 558 | ([body] 559 | (throw! 560 | {:status 416 561 | :headers {} 562 | :body body}))) 563 | 564 | (defn expectation-failed 565 | "417 Expectation Failed (ClientError) 566 | The server cannot meet the requirements of the Expect request-header field." 567 | ([] (expectation-failed nil)) 568 | ([body] 569 | {:status 417 570 | :headers {} 571 | :body body})) 572 | 573 | (defn expectation-failed! 574 | "417 Expectation Failed (ClientError) 575 | The server cannot meet the requirements of the Expect request-header field. 576 | Throws an exception with ex-info: 577 | {:type :ring.util.http-response/response 578 | :response response}" 579 | ([] (expectation-failed! nil)) 580 | ([body] 581 | (throw! 582 | {:status 417 583 | :headers {} 584 | :body body}))) 585 | 586 | (defn im-a-teapot 587 | "418 I'm a teapot (ClientError) 588 | Any attempt to brew coffee with a teapot should result in the error code "418 I'm a teapot". The resulting entity body MAY be short and stout." 589 | ([] (im-a-teapot nil)) 590 | ([body] 591 | {:status 418 592 | :headers {} 593 | :body body})) 594 | 595 | (defn im-a-teapot! 596 | "418 I'm a teapot (ClientError) 597 | Any attempt to brew coffee with a teapot should result in the error code "418 I'm a teapot". The resulting entity body MAY be short and stout. 598 | Throws an exception with ex-info: 599 | {:type :ring.util.http-response/response 600 | :response response}" 601 | ([] (im-a-teapot! nil)) 602 | ([body] 603 | (throw! 604 | {:status 418 605 | :headers {} 606 | :body body}))) 607 | 608 | (defn enhance-your-calm 609 | "420 Enhance Your Calm (ClientError) 610 | You are being rate-limited." 611 | ([] (enhance-your-calm nil)) 612 | ([body] 613 | {:status 420 614 | :headers {} 615 | :body body})) 616 | 617 | (defn enhance-your-calm! 618 | "420 Enhance Your Calm (ClientError) 619 | You are being rate-limited. 620 | Throws an exception with ex-info: 621 | {:type :ring.util.http-response/response 622 | :response response}" 623 | ([] (enhance-your-calm! nil)) 624 | ([body] 625 | (throw! 626 | {:status 420 627 | :headers {} 628 | :body body}))) 629 | 630 | (defn unprocessable-entity 631 | "422 Unprocessable Entity (ClientError) 632 | The request was well-formed but was unable to be followed due to semantic errors." 633 | ([] (unprocessable-entity nil)) 634 | ([body] 635 | {:status 422 636 | :headers {} 637 | :body body})) 638 | 639 | (defn unprocessable-entity! 640 | "422 Unprocessable Entity (ClientError) 641 | The request was well-formed but was unable to be followed due to semantic errors. 642 | Throws an exception with ex-info: 643 | {:type :ring.util.http-response/response 644 | :response response}" 645 | ([] (unprocessable-entity! nil)) 646 | ([body] 647 | (throw! 648 | {:status 422 649 | :headers {} 650 | :body body}))) 651 | 652 | (defn locked 653 | "423 Locked (ClientError) 654 | The resource that is being accessed is locked." 655 | ([] (locked nil)) 656 | ([body] 657 | {:status 423 658 | :headers {} 659 | :body body})) 660 | 661 | (defn locked! 662 | "423 Locked (ClientError) 663 | The resource that is being accessed is locked. 664 | Throws an exception with ex-info: 665 | {:type :ring.util.http-response/response 666 | :response response}" 667 | ([] (locked! nil)) 668 | ([body] 669 | (throw! 670 | {:status 423 671 | :headers {} 672 | :body body}))) 673 | 674 | (defn failed-dependency 675 | "424 Failed Dependency (ClientError) 676 | The request failed due to failure of a previous request." 677 | ([] (failed-dependency nil)) 678 | ([body] 679 | {:status 424 680 | :headers {} 681 | :body body})) 682 | 683 | (defn failed-dependency! 684 | "424 Failed Dependency (ClientError) 685 | The request failed due to failure of a previous request. 686 | Throws an exception with ex-info: 687 | {:type :ring.util.http-response/response 688 | :response response}" 689 | ([] (failed-dependency! nil)) 690 | ([body] 691 | (throw! 692 | {:status 424 693 | :headers {} 694 | :body body}))) 695 | 696 | (defn unordered-collection 697 | "425 Unordered Collection (ClientError) 698 | The collection is unordered." 699 | ([] (unordered-collection nil)) 700 | ([body] 701 | {:status 425 702 | :headers {} 703 | :body body})) 704 | 705 | (defn unordered-collection! 706 | "425 Unordered Collection (ClientError) 707 | The collection is unordered. 708 | Throws an exception with ex-info: 709 | {:type :ring.util.http-response/response 710 | :response response}" 711 | ([] (unordered-collection! nil)) 712 | ([body] 713 | (throw! 714 | {:status 425 715 | :headers {} 716 | :body body}))) 717 | 718 | (defn upgrade-required 719 | "426 Upgrade Required (ClientError) 720 | The client should switch to a different protocol." 721 | ([] (upgrade-required nil)) 722 | ([body] 723 | {:status 426 724 | :headers {} 725 | :body body})) 726 | 727 | (defn upgrade-required! 728 | "426 Upgrade Required (ClientError) 729 | The client should switch to a different protocol. 730 | Throws an exception with ex-info: 731 | {:type :ring.util.http-response/response 732 | :response response}" 733 | ([] (upgrade-required! nil)) 734 | ([body] 735 | (throw! 736 | {:status 426 737 | :headers {} 738 | :body body}))) 739 | 740 | (defn precondition-required 741 | "428 Precondition Required (ClientError) 742 | The server requires the request to be conditional." 743 | ([] (precondition-required nil)) 744 | ([body] 745 | {:status 428 746 | :headers {} 747 | :body body})) 748 | 749 | (defn precondition-required! 750 | "428 Precondition Required (ClientError) 751 | The server requires the request to be conditional. 752 | Throws an exception with ex-info: 753 | {:type :ring.util.http-response/response 754 | :response response}" 755 | ([] (precondition-required! nil)) 756 | ([body] 757 | (throw! 758 | {:status 428 759 | :headers {} 760 | :body body}))) 761 | 762 | (defn too-many-requests 763 | "429 Too Many Requests (ClientError) 764 | The user has sent too many requests in a given amount of time." 765 | ([] (too-many-requests nil)) 766 | ([body] 767 | {:status 429 768 | :headers {} 769 | :body body})) 770 | 771 | (defn too-many-requests! 772 | "429 Too Many Requests (ClientError) 773 | The user has sent too many requests in a given amount of time. 774 | Throws an exception with ex-info: 775 | {:type :ring.util.http-response/response 776 | :response response}" 777 | ([] (too-many-requests! nil)) 778 | ([body] 779 | (throw! 780 | {:status 429 781 | :headers {} 782 | :body body}))) 783 | 784 | (defn request-header-fields-too-large 785 | "431 Request Header Fields Too Large (ClientError) 786 | The server is unwilling to process the request because either an individual header field or all the header fields collectively are too large." 787 | ([] (request-header-fields-too-large nil)) 788 | ([body] 789 | {:status 431 790 | :headers {} 791 | :body body})) 792 | 793 | (defn request-header-fields-too-large! 794 | "431 Request Header Fields Too Large (ClientError) 795 | The server is unwilling to process the request because either an individual header field or all the header fields collectively are too large. 796 | Throws an exception with ex-info: 797 | {:type :ring.util.http-response/response 798 | :response response}" 799 | ([] (request-header-fields-too-large! nil)) 800 | ([body] 801 | (throw! 802 | {:status 431 803 | :headers {} 804 | :body body}))) 805 | 806 | (defn retry-with 807 | "449 Retry With (ClientError) 808 | The request should be retried after doing the appropriate action." 809 | ([] (retry-with nil)) 810 | ([body] 811 | {:status 449 812 | :headers {} 813 | :body body})) 814 | 815 | (defn retry-with! 816 | "449 Retry With (ClientError) 817 | The request should be retried after doing the appropriate action. 818 | Throws an exception with ex-info: 819 | {:type :ring.util.http-response/response 820 | :response response}" 821 | ([] (retry-with! nil)) 822 | ([body] 823 | (throw! 824 | {:status 449 825 | :headers {} 826 | :body body}))) 827 | 828 | (defn blocked-by-windows-parental-controls 829 | "450 Blocked by Windows Parental Controls (ClientError) 830 | Windows Parental Controls are turned on and are blocking access to the given webpage." 831 | ([] (blocked-by-windows-parental-controls nil)) 832 | ([body] 833 | {:status 450 834 | :headers {} 835 | :body body})) 836 | 837 | (defn blocked-by-windows-parental-controls! 838 | "450 Blocked by Windows Parental Controls (ClientError) 839 | Windows Parental Controls are turned on and are blocking access to the given webpage. 840 | Throws an exception with ex-info: 841 | {:type :ring.util.http-response/response 842 | :response response}" 843 | ([] (blocked-by-windows-parental-controls! nil)) 844 | ([body] 845 | (throw! 846 | {:status 450 847 | :headers {} 848 | :body body}))) 849 | 850 | (defn unavailable-for-legal-reasons 851 | "451 Unavailable For Legal Reasons (ClientError) 852 | Resource access is denied for legal reasons." 853 | ([] (unavailable-for-legal-reasons nil)) 854 | ([body] 855 | {:status 451 856 | :headers {} 857 | :body body})) 858 | 859 | (defn unavailable-for-legal-reasons! 860 | "451 Unavailable For Legal Reasons (ClientError) 861 | Resource access is denied for legal reasons. 862 | Throws an exception with ex-info: 863 | {:type :ring.util.http-response/response 864 | :response response}" 865 | ([] (unavailable-for-legal-reasons! nil)) 866 | ([body] 867 | (throw! 868 | {:status 451 869 | :headers {} 870 | :body body}))) 871 | 872 | (defn internal-server-error 873 | "500 Internal Server Error (ServerError) 874 | There was an internal server error." 875 | ([] (internal-server-error nil)) 876 | ([body] 877 | {:status 500 878 | :headers {} 879 | :body body})) 880 | 881 | (defn internal-server-error! 882 | "500 Internal Server Error (ServerError) 883 | There was an internal server error. 884 | Throws an exception with ex-info: 885 | {:type :ring.util.http-response/response 886 | :response response}" 887 | ([] (internal-server-error! nil)) 888 | ([body] 889 | (throw! 890 | {:status 500 891 | :headers {} 892 | :body body}))) 893 | 894 | (defn not-implemented 895 | "501 Not Implemented (ServerError) 896 | The server either does not recognize the request method or it lacks the ability to fulfill the request." 897 | ([] (not-implemented nil)) 898 | ([body] 899 | {:status 501 900 | :headers {} 901 | :body body})) 902 | 903 | (defn not-implemented! 904 | "501 Not Implemented (ServerError) 905 | The server either does not recognize the request method or it lacks the ability to fulfill the request. 906 | Throws an exception with ex-info: 907 | {:type :ring.util.http-response/response 908 | :response response}" 909 | ([] (not-implemented! nil)) 910 | ([body] 911 | (throw! 912 | {:status 501 913 | :headers {} 914 | :body body}))) 915 | 916 | (defn bad-gateway 917 | "502 Bad Gateway (ServerError) 918 | The server was acting as a gateway or proxy and received an invalid response from the upstream server." 919 | ([] (bad-gateway nil)) 920 | ([body] 921 | {:status 502 922 | :headers {} 923 | :body body})) 924 | 925 | (defn bad-gateway! 926 | "502 Bad Gateway (ServerError) 927 | The server was acting as a gateway or proxy and received an invalid response from the upstream server. 928 | Throws an exception with ex-info: 929 | {:type :ring.util.http-response/response 930 | :response response}" 931 | ([] (bad-gateway! nil)) 932 | ([body] 933 | (throw! 934 | {:status 502 935 | :headers {} 936 | :body body}))) 937 | 938 | (defn service-unavailable 939 | "503 Service Unavailable (ServerError) 940 | The server is currently unavailable (because it is overloaded or down for maintenance)." 941 | ([] (service-unavailable nil)) 942 | ([body] 943 | {:status 503 944 | :headers {} 945 | :body body})) 946 | 947 | (defn service-unavailable! 948 | "503 Service Unavailable (ServerError) 949 | The server is currently unavailable (because it is overloaded or down for maintenance). 950 | Throws an exception with ex-info: 951 | {:type :ring.util.http-response/response 952 | :response response}" 953 | ([] (service-unavailable! nil)) 954 | ([body] 955 | (throw! 956 | {:status 503 957 | :headers {} 958 | :body body}))) 959 | 960 | (defn gateway-timeout 961 | "504 Gateway Timeout (ServerError) 962 | The server was acting as a gateway or proxy and did not receive a timely request from the upstream server." 963 | ([] (gateway-timeout nil)) 964 | ([body] 965 | {:status 504 966 | :headers {} 967 | :body body})) 968 | 969 | (defn gateway-timeout! 970 | "504 Gateway Timeout (ServerError) 971 | The server was acting as a gateway or proxy and did not receive a timely request from the upstream server. 972 | Throws an exception with ex-info: 973 | {:type :ring.util.http-response/response 974 | :response response}" 975 | ([] (gateway-timeout! nil)) 976 | ([body] 977 | (throw! 978 | {:status 504 979 | :headers {} 980 | :body body}))) 981 | 982 | (defn http-version-not-supported 983 | "505 HTTP Version Not Supported (ServerError) 984 | The server does not support the HTTP protocol version used in the request." 985 | ([] (http-version-not-supported nil)) 986 | ([body] 987 | {:status 505 988 | :headers {} 989 | :body body})) 990 | 991 | (defn http-version-not-supported! 992 | "505 HTTP Version Not Supported (ServerError) 993 | The server does not support the HTTP protocol version used in the request. 994 | Throws an exception with ex-info: 995 | {:type :ring.util.http-response/response 996 | :response response}" 997 | ([] (http-version-not-supported! nil)) 998 | ([body] 999 | (throw! 1000 | {:status 505 1001 | :headers {} 1002 | :body body}))) 1003 | 1004 | (defn variant-also-negotiates 1005 | "506 Variant Also Negotiates (ServerError) 1006 | Transparent content negotiation for the request results in a circular reference." 1007 | ([] (variant-also-negotiates nil)) 1008 | ([body] 1009 | {:status 506 1010 | :headers {} 1011 | :body body})) 1012 | 1013 | (defn variant-also-negotiates! 1014 | "506 Variant Also Negotiates (ServerError) 1015 | Transparent content negotiation for the request results in a circular reference. 1016 | Throws an exception with ex-info: 1017 | {:type :ring.util.http-response/response 1018 | :response response}" 1019 | ([] (variant-also-negotiates! nil)) 1020 | ([body] 1021 | (throw! 1022 | {:status 506 1023 | :headers {} 1024 | :body body}))) 1025 | 1026 | (defn insufficient-storage 1027 | "507 Insufficient Storage (ServerError) 1028 | Insufficient storage to complete the request." 1029 | ([] (insufficient-storage nil)) 1030 | ([body] 1031 | {:status 507 1032 | :headers {} 1033 | :body body})) 1034 | 1035 | (defn insufficient-storage! 1036 | "507 Insufficient Storage (ServerError) 1037 | Insufficient storage to complete the request. 1038 | Throws an exception with ex-info: 1039 | {:type :ring.util.http-response/response 1040 | :response response}" 1041 | ([] (insufficient-storage! nil)) 1042 | ([body] 1043 | (throw! 1044 | {:status 507 1045 | :headers {} 1046 | :body body}))) 1047 | 1048 | (defn loop-detected 1049 | "508 Loop Detected (ServerError) 1050 | The server detected an infinite loop while processing the request." 1051 | ([] (loop-detected nil)) 1052 | ([body] 1053 | {:status 508 1054 | :headers {} 1055 | :body body})) 1056 | 1057 | (defn loop-detected! 1058 | "508 Loop Detected (ServerError) 1059 | The server detected an infinite loop while processing the request. 1060 | Throws an exception with ex-info: 1061 | {:type :ring.util.http-response/response 1062 | :response response}" 1063 | ([] (loop-detected! nil)) 1064 | ([body] 1065 | (throw! 1066 | {:status 508 1067 | :headers {} 1068 | :body body}))) 1069 | 1070 | (defn bandwidth-limit-exceeded 1071 | "509 Bandwidth Limit Exceeded (ServerError) 1072 | Bandwidth limit has been exceeded." 1073 | ([] (bandwidth-limit-exceeded nil)) 1074 | ([body] 1075 | {:status 509 1076 | :headers {} 1077 | :body body})) 1078 | 1079 | (defn bandwidth-limit-exceeded! 1080 | "509 Bandwidth Limit Exceeded (ServerError) 1081 | Bandwidth limit has been exceeded. 1082 | Throws an exception with ex-info: 1083 | {:type :ring.util.http-response/response 1084 | :response response}" 1085 | ([] (bandwidth-limit-exceeded! nil)) 1086 | ([body] 1087 | (throw! 1088 | {:status 509 1089 | :headers {} 1090 | :body body}))) 1091 | 1092 | (defn not-extended 1093 | "510 Not Extended (ServerError) 1094 | Further extensions to the request are required for the server to fulfill it." 1095 | ([] (not-extended nil)) 1096 | ([body] 1097 | {:status 510 1098 | :headers {} 1099 | :body body})) 1100 | 1101 | (defn not-extended! 1102 | "510 Not Extended (ServerError) 1103 | Further extensions to the request are required for the server to fulfill it. 1104 | Throws an exception with ex-info: 1105 | {:type :ring.util.http-response/response 1106 | :response response}" 1107 | ([] (not-extended! nil)) 1108 | ([body] 1109 | (throw! 1110 | {:status 510 1111 | :headers {} 1112 | :body body}))) 1113 | 1114 | (defn network-authentication-required 1115 | "511 Network Authentication Required (ServerError) 1116 | The client needs to authenticate to gain network access." 1117 | ([] (network-authentication-required nil)) 1118 | ([body] 1119 | {:status 511 1120 | :headers {} 1121 | :body body})) 1122 | 1123 | (defn network-authentication-required! 1124 | "511 Network Authentication Required (ServerError) 1125 | The client needs to authenticate to gain network access. 1126 | Throws an exception with ex-info: 1127 | {:type :ring.util.http-response/response 1128 | :response response}" 1129 | ([] (network-authentication-required! nil)) 1130 | ([body] 1131 | (throw! 1132 | {:status 511 1133 | :headers {} 1134 | :body body}))) 1135 | 1136 | (defn network-read-timeout 1137 | "598 Network read timeout (ServerError) 1138 | " 1139 | ([] (network-read-timeout nil)) 1140 | ([body] 1141 | {:status 598 1142 | :headers {} 1143 | :body body})) 1144 | 1145 | (defn network-read-timeout! 1146 | "598 Network read timeout (ServerError) 1147 | 1148 | Throws an exception with ex-info: 1149 | {:type :ring.util.http-response/response 1150 | :response response}" 1151 | ([] (network-read-timeout! nil)) 1152 | ([body] 1153 | (throw! 1154 | {:status 598 1155 | :headers {} 1156 | :body body}))) 1157 | 1158 | (defn network-connect-timeout 1159 | "599 Network connect timeout (ServerError) 1160 | " 1161 | ([] (network-connect-timeout nil)) 1162 | ([body] 1163 | {:status 599 1164 | :headers {} 1165 | :body body})) 1166 | 1167 | (defn network-connect-timeout! 1168 | "599 Network connect timeout (ServerError) 1169 | 1170 | Throws an exception with ex-info: 1171 | {:type :ring.util.http-response/response 1172 | :response response}" 1173 | ([] (network-connect-timeout! nil)) 1174 | ([body] 1175 | (throw! 1176 | {:status 599 1177 | :headers {} 1178 | :body body}))) 1179 | 1180 | ;; 1181 | ;; Imported vars from ring.util.response 1182 | ;; 1183 | 1184 | ;; status 1185 | (if-not (ns-resolve 'ring.util.response 'status) 1186 | (println "Can't import ring.util.response/status, try updating to Ring 1.6.0+")) 1187 | (p/import-vars [ring.util.response status]) 1188 | 1189 | ;; header 1190 | (if-not (ns-resolve 'ring.util.response 'header) 1191 | (println "Can't import ring.util.response/header, try updating to Ring 1.6.0+")) 1192 | (p/import-vars [ring.util.response header]) 1193 | 1194 | ;; file-response 1195 | (if-not (ns-resolve 'ring.util.response 'file-response) 1196 | (println "Can't import ring.util.response/file-response, try updating to Ring 1.6.0+")) 1197 | (p/import-vars [ring.util.response file-response]) 1198 | 1199 | ;; content-type 1200 | (if-not (ns-resolve 'ring.util.response 'content-type) 1201 | (println "Can't import ring.util.response/content-type, try updating to Ring 1.6.0+")) 1202 | (p/import-vars [ring.util.response content-type]) 1203 | 1204 | ;; find-header 1205 | (if-not (ns-resolve 'ring.util.response 'find-header) 1206 | (println "Can't import ring.util.response/find-header, try updating to Ring 1.6.0+")) 1207 | (p/import-vars [ring.util.response find-header]) 1208 | 1209 | ;; get-header 1210 | (if-not (ns-resolve 'ring.util.response 'get-header) 1211 | (println "Can't import ring.util.response/get-header, try updating to Ring 1.6.0+")) 1212 | (p/import-vars [ring.util.response get-header]) 1213 | 1214 | ;; update-header 1215 | (if-not (ns-resolve 'ring.util.response 'update-header) 1216 | (println "Can't import ring.util.response/update-header, try updating to Ring 1.6.0+")) 1217 | (p/import-vars [ring.util.response update-header]) 1218 | 1219 | ;; charset 1220 | (if-not (ns-resolve 'ring.util.response 'charset) 1221 | (println "Can't import ring.util.response/charset, try updating to Ring 1.6.0+")) 1222 | (p/import-vars [ring.util.response charset]) 1223 | 1224 | ;; set-cookie 1225 | (if-not (ns-resolve 'ring.util.response 'set-cookie) 1226 | (println "Can't import ring.util.response/set-cookie, try updating to Ring 1.6.0+")) 1227 | (p/import-vars [ring.util.response set-cookie]) 1228 | 1229 | ;; response? 1230 | (if-not (ns-resolve 'ring.util.response 'response?) 1231 | (println "Can't import ring.util.response/response?, try updating to Ring 1.6.0+")) 1232 | (p/import-vars [ring.util.response response?]) 1233 | 1234 | ;; resource-data 1235 | (if-not (ns-resolve 'ring.util.response 'resource-data) 1236 | (println "Can't import ring.util.response/resource-data, try updating to Ring 1.6.0+")) 1237 | (p/import-vars [ring.util.response resource-data]) 1238 | 1239 | ;; url-response 1240 | (if-not (ns-resolve 'ring.util.response 'url-response) 1241 | (println "Can't import ring.util.response/url-response, try updating to Ring 1.6.0+")) 1242 | (p/import-vars [ring.util.response url-response]) 1243 | 1244 | ;; resource-response 1245 | (if-not (ns-resolve 'ring.util.response 'resource-response) 1246 | (println "Can't import ring.util.response/resource-response, try updating to Ring 1.6.0+")) 1247 | (p/import-vars [ring.util.response resource-response]) 1248 | 1249 | ;; get-charset 1250 | (if-not (ns-resolve 'ring.util.response 'get-charset) 1251 | (println "Can't import ring.util.response/get-charset, try updating to Ring 1.6.0+")) 1252 | (p/import-vars [ring.util.response get-charset]) 1253 | 1254 | -------------------------------------------------------------------------------- /src/ring/util/http_status.clj: -------------------------------------------------------------------------------- 1 | (ns ring.util.http-status) 2 | 3 | (def continue 100) 4 | (def switching-protocols 101) 5 | (def processing 102) 6 | (def ok 200) 7 | (def created 201) 8 | (def accepted 202) 9 | (def non-authoritative-information 203) 10 | (def no-content 204) 11 | (def reset-content 205) 12 | (def partial-content 206) 13 | (def multi-status 207) 14 | (def already-reported 208) 15 | (def im-used 226) 16 | (def multiple-choices 300) 17 | (def moved-permanently 301) 18 | (def found 302) 19 | (def see-other 303) 20 | (def not-modified 304) 21 | (def use-proxy 305) 22 | (def temporary-redirect 307) 23 | (def permanent-redirect 308) 24 | (def bad-request 400) 25 | (def unauthorized 401) 26 | (def payment-required 402) 27 | (def forbidden 403) 28 | (def not-found 404) 29 | (def method-not-allowed 405) 30 | (def not-acceptable 406) 31 | (def proxy-authentication-required 407) 32 | (def request-timeout 408) 33 | (def conflict 409) 34 | (def gone 410) 35 | (def length-required 411) 36 | (def precondition-failed 412) 37 | (def request-entity-too-large 413) 38 | (def request-uri-too-long 414) 39 | (def unsupported-media-type 415) 40 | (def requested-range-not-satisfiable 416) 41 | (def expectation-failed 417) 42 | (def im-a-teapot 418) 43 | (def enhance-your-calm 420) 44 | (def unprocessable-entity 422) 45 | (def locked 423) 46 | (def failed-dependency 424) 47 | (def unordered-collection 425) 48 | (def upgrade-required 426) 49 | (def precondition-required 428) 50 | (def too-many-requests 429) 51 | (def request-header-fields-too-large 431) 52 | (def retry-with 449) 53 | (def blocked-by-windows-parental-controls 450) 54 | (def unavailable-for-legal-reasons 451) 55 | (def internal-server-error 500) 56 | (def not-implemented 501) 57 | (def bad-gateway 502) 58 | (def service-unavailable 503) 59 | (def gateway-timeout 504) 60 | (def http-version-not-supported 505) 61 | (def variant-also-negotiates 506) 62 | (def insufficient-storage 507) 63 | (def loop-detected 508) 64 | (def bandwidth-limit-exceeded 509) 65 | (def not-extended 510) 66 | (def network-authentication-required 511) 67 | (def network-read-timeout 598) 68 | (def network-connect-timeout 599) 69 | 70 | (def status 71 | "Maps status to name and description" 72 | { 73 | 100 {:name "Continue" 74 | :description "The server has received the request headers and the client should proceed to send the request body."} 75 | 101 {:name "Switching Protocols" 76 | :description "The server is switching protocols because the client requested the switch."} 77 | 102 {:name "Processing" 78 | :description "The server is processing the request but no response is available yet."} 79 | 200 {:name "OK" 80 | :description "OK"} 81 | 201 {:name "Created" 82 | :description "The request has been fulfilled and resulted in a new resource being created."} 83 | 202 {:name "Accepted" 84 | :description "The request has been accepted for processing but the processing has not been completed."} 85 | 203 {:name "Non-Authoritative Information" 86 | :description "The server successfully processed the request but is returning information that may be from another source."} 87 | 204 {:name "No Content" 88 | :description "The server successfully processed the request, but is not returning any content. Usually used as a response to a successful delete request."} 89 | 205 {:name "Reset Content" 90 | :description "The server successfully processed the request but is not returning any content. Unlike a 204 response, this response requires that the requester reset the document view."} 91 | 206 {:name "Partial Content" 92 | :description "The server is delivering only part of the resource due to a range header sent by the client."} 93 | 207 {:name "Multi-Status" 94 | :description "The message body that follows is an XML message and can contain a number of separate response codes depending on how many sub-requests were made."} 95 | 208 {:name "Already Reported" 96 | :description "The members of a DAV binding have already been enumerated in a previous reply to this request and are not being included again."} 97 | 226 {:name "IM Used" 98 | :description "The server has fulfilled a GET request for the resource and the response is a representation of the result of one or more instance-manipulations applied to the current instance."} 99 | 300 {:name "Multiple Choices" 100 | :description "There are multiple options for the resource that the client may follow."} 101 | 301 {:name "Moved Permanently" 102 | :description "This and all future requests should be directed to the given URI."} 103 | 302 {:name "Found" 104 | :description "The resource was found but at a different URI."} 105 | 303 {:name "See Other" 106 | :description "The response to the request can be found under another URI using a GET method."} 107 | 304 {:name "Not Modified" 108 | :description "The resource has not been modified since last requested."} 109 | 305 {:name "Use Proxy" 110 | :description "This single request is to be repeated via the proxy given by the Location field."} 111 | 307 {:name "Temporary Redirect" 112 | :description "The request should be repeated with another URI but future requests can still use the original URI."} 113 | 308 {:name "Permanent Redirect" 114 | :description "The request and all future requests should be repeated using another URI."} 115 | 400 {:name "Bad Request" 116 | :description "The request contains bad syntax or cannot be fulfilled."} 117 | 401 {:name "Unauthorized" 118 | :description "Authentication is possible but has failed or not yet been provided."} 119 | 402 {:name "Payment Required" 120 | :description "Reserved for future use."} 121 | 403 {:name "Forbidden" 122 | :description "The request was a legal request but the server is refusing to respond to it."} 123 | 404 {:name "Not Found" 124 | :description "The requested resource could not be found but may be available again in the future."} 125 | 405 {:name "Method Not Allowed" 126 | :description "A request was made of a resource using a request method not supported by that resource;"} 127 | 406 {:name "Not Acceptable" 128 | :description "The requested resource is only capable of generating content not acceptable according to the Accept headers sent in the request."} 129 | 407 {:name "Proxy Authentication Required" 130 | :description "Proxy authentication is required to access the requested resource."} 131 | 408 {:name "Request Timeout" 132 | :description "The server timed out waiting for the request."} 133 | 409 {:name "Conflict" 134 | :description "The request could not be processed because of conflict in the request such as an edit conflict."} 135 | 410 {:name "Gone" 136 | :description "The resource requested is no longer available and will not be available again."} 137 | 411 {:name "Length Required" 138 | :description "The request did not specify the length of its content which is required by the requested resource."} 139 | 412 {:name "Precondition Failed" 140 | :description "The server does not meet one of the preconditions that the requester put on the request."} 141 | 413 {:name "Request Entity Too Large" 142 | :description "The request is larger than the server is willing or able to process."} 143 | 414 {:name "Request-URI Too Long" 144 | :description "The URI provided was too long for the server to process."} 145 | 415 {:name "Unsupported Media Type" 146 | :description "The request entity has a media type which the server or resource does not support."} 147 | 416 {:name "Requested Range Not Satisfiable" 148 | :description "The client has asked for a portion of the file but the server cannot supply that portion."} 149 | 417 {:name "Expectation Failed" 150 | :description "The server cannot meet the requirements of the Expect request-header field."} 151 | 418 {:name "I'm a teapot" 152 | :description "Any attempt to brew coffee with a teapot should result in the error code "418 I'm a teapot". The resulting entity body MAY be short and stout."} 153 | 420 {:name "Enhance Your Calm" 154 | :description "You are being rate-limited."} 155 | 422 {:name "Unprocessable Entity" 156 | :description "The request was well-formed but was unable to be followed due to semantic errors."} 157 | 423 {:name "Locked" 158 | :description "The resource that is being accessed is locked."} 159 | 424 {:name "Failed Dependency" 160 | :description "The request failed due to failure of a previous request."} 161 | 425 {:name "Unordered Collection" 162 | :description "The collection is unordered."} 163 | 426 {:name "Upgrade Required" 164 | :description "The client should switch to a different protocol."} 165 | 428 {:name "Precondition Required" 166 | :description "The server requires the request to be conditional."} 167 | 429 {:name "Too Many Requests" 168 | :description "The user has sent too many requests in a given amount of time."} 169 | 431 {:name "Request Header Fields Too Large" 170 | :description "The server is unwilling to process the request because either an individual header field or all the header fields collectively are too large."} 171 | 449 {:name "Retry With" 172 | :description "The request should be retried after doing the appropriate action."} 173 | 450 {:name "Blocked by Windows Parental Controls" 174 | :description "Windows Parental Controls are turned on and are blocking access to the given webpage."} 175 | 451 {:name "Unavailable For Legal Reasons" 176 | :description "Resource access is denied for legal reasons."} 177 | 500 {:name "Internal Server Error" 178 | :description "There was an internal server error."} 179 | 501 {:name "Not Implemented" 180 | :description "The server either does not recognize the request method or it lacks the ability to fulfill the request."} 181 | 502 {:name "Bad Gateway" 182 | :description "The server was acting as a gateway or proxy and received an invalid response from the upstream server."} 183 | 503 {:name "Service Unavailable" 184 | :description "The server is currently unavailable (because it is overloaded or down for maintenance)."} 185 | 504 {:name "Gateway Timeout" 186 | :description "The server was acting as a gateway or proxy and did not receive a timely request from the upstream server."} 187 | 505 {:name "HTTP Version Not Supported" 188 | :description "The server does not support the HTTP protocol version used in the request."} 189 | 506 {:name "Variant Also Negotiates" 190 | :description "Transparent content negotiation for the request results in a circular reference."} 191 | 507 {:name "Insufficient Storage" 192 | :description "Insufficient storage to complete the request."} 193 | 508 {:name "Loop Detected" 194 | :description "The server detected an infinite loop while processing the request."} 195 | 509 {:name "Bandwidth Limit Exceeded" 196 | :description "Bandwidth limit has been exceeded."} 197 | 510 {:name "Not Extended" 198 | :description "Further extensions to the request are required for the server to fulfill it."} 199 | 511 {:name "Network Authentication Required" 200 | :description "The client needs to authenticate to gain network access."} 201 | 598 {:name "Network read timeout" 202 | :description ""} 203 | 599 {:name "Network connect timeout" 204 | :description ""} 205 | }) 206 | 207 | (defn get-name 208 | "Returns http status name by code." 209 | [code] 210 | (get-in status [code :name])) 211 | 212 | (defn get-description 213 | "Returns http status description by code." 214 | [code] 215 | (get-in status [code :description])) 216 | -------------------------------------------------------------------------------- /src/ring/util/http_status.cljs: -------------------------------------------------------------------------------- 1 | (ns ring.util.http-status) 2 | 3 | (def continue 100) 4 | (def switching-protocols 101) 5 | (def processing 102) 6 | (def ok 200) 7 | (def created 201) 8 | (def accepted 202) 9 | (def non-authoritative-information 203) 10 | (def no-content 204) 11 | (def reset-content 205) 12 | (def partial-content 206) 13 | (def multi-status 207) 14 | (def already-reported 208) 15 | (def im-used 226) 16 | (def multiple-choices 300) 17 | (def moved-permanently 301) 18 | (def found 302) 19 | (def see-other 303) 20 | (def not-modified 304) 21 | (def use-proxy 305) 22 | (def temporary-redirect 307) 23 | (def permanent-redirect 308) 24 | (def bad-request 400) 25 | (def unauthorized 401) 26 | (def payment-required 402) 27 | (def forbidden 403) 28 | (def not-found 404) 29 | (def method-not-allowed 405) 30 | (def not-acceptable 406) 31 | (def proxy-authentication-required 407) 32 | (def request-timeout 408) 33 | (def conflict 409) 34 | (def gone 410) 35 | (def length-required 411) 36 | (def precondition-failed 412) 37 | (def request-entity-too-large 413) 38 | (def request-uri-too-long 414) 39 | (def unsupported-media-type 415) 40 | (def requested-range-not-satisfiable 416) 41 | (def expectation-failed 417) 42 | (def im-a-teapot 418) 43 | (def enhance-your-calm 420) 44 | (def unprocessable-entity 422) 45 | (def locked 423) 46 | (def failed-dependency 424) 47 | (def unordered-collection 425) 48 | (def upgrade-required 426) 49 | (def precondition-required 428) 50 | (def too-many-requests 429) 51 | (def request-header-fields-too-large 431) 52 | (def retry-with 449) 53 | (def blocked-by-windows-parental-controls 450) 54 | (def unavailable-for-legal-reasons 451) 55 | (def internal-server-error 500) 56 | (def not-implemented 501) 57 | (def bad-gateway 502) 58 | (def service-unavailable 503) 59 | (def gateway-timeout 504) 60 | (def http-version-not-supported 505) 61 | (def variant-also-negotiates 506) 62 | (def insufficient-storage 507) 63 | (def loop-detected 508) 64 | (def bandwidth-limit-exceeded 509) 65 | (def not-extended 510) 66 | (def network-authentication-required 511) 67 | (def network-read-timeout 598) 68 | (def network-connect-timeout 599) 69 | 70 | (def status 71 | "Maps status to name and description" 72 | { 73 | 100 {:name "Continue" 74 | :description "The server has received the request headers and the client should proceed to send the request body."} 75 | 101 {:name "Switching Protocols" 76 | :description "The server is switching protocols because the client requested the switch."} 77 | 102 {:name "Processing" 78 | :description "The server is processing the request but no response is available yet."} 79 | 200 {:name "OK" 80 | :description "OK"} 81 | 201 {:name "Created" 82 | :description "The request has been fulfilled and resulted in a new resource being created."} 83 | 202 {:name "Accepted" 84 | :description "The request has been accepted for processing but the processing has not been completed."} 85 | 203 {:name "Non-Authoritative Information" 86 | :description "The server successfully processed the request but is returning information that may be from another source."} 87 | 204 {:name "No Content" 88 | :description "The server successfully processed the request, but is not returning any content. Usually used as a response to a successful delete request."} 89 | 205 {:name "Reset Content" 90 | :description "The server successfully processed the request but is not returning any content. Unlike a 204 response, this response requires that the requester reset the document view."} 91 | 206 {:name "Partial Content" 92 | :description "The server is delivering only part of the resource due to a range header sent by the client."} 93 | 207 {:name "Multi-Status" 94 | :description "The message body that follows is an XML message and can contain a number of separate response codes depending on how many sub-requests were made."} 95 | 208 {:name "Already Reported" 96 | :description "The members of a DAV binding have already been enumerated in a previous reply to this request and are not being included again."} 97 | 226 {:name "IM Used" 98 | :description "The server has fulfilled a GET request for the resource and the response is a representation of the result of one or more instance-manipulations applied to the current instance."} 99 | 300 {:name "Multiple Choices" 100 | :description "There are multiple options for the resource that the client may follow."} 101 | 301 {:name "Moved Permanently" 102 | :description "This and all future requests should be directed to the given URI."} 103 | 302 {:name "Found" 104 | :description "The resource was found but at a different URI."} 105 | 303 {:name "See Other" 106 | :description "The response to the request can be found under another URI using a GET method."} 107 | 304 {:name "Not Modified" 108 | :description "The resource has not been modified since last requested."} 109 | 305 {:name "Use Proxy" 110 | :description "This single request is to be repeated via the proxy given by the Location field."} 111 | 307 {:name "Temporary Redirect" 112 | :description "The request should be repeated with another URI but future requests can still use the original URI."} 113 | 308 {:name "Permanent Redirect" 114 | :description "The request and all future requests should be repeated using another URI."} 115 | 400 {:name "Bad Request" 116 | :description "The request contains bad syntax or cannot be fulfilled."} 117 | 401 {:name "Unauthorized" 118 | :description "Authentication is possible but has failed or not yet been provided."} 119 | 402 {:name "Payment Required" 120 | :description "Reserved for future use."} 121 | 403 {:name "Forbidden" 122 | :description "The request was a legal request but the server is refusing to respond to it."} 123 | 404 {:name "Not Found" 124 | :description "The requested resource could not be found but may be available again in the future."} 125 | 405 {:name "Method Not Allowed" 126 | :description "A request was made of a resource using a request method not supported by that resource;"} 127 | 406 {:name "Not Acceptable" 128 | :description "The requested resource is only capable of generating content not acceptable according to the Accept headers sent in the request."} 129 | 407 {:name "Proxy Authentication Required" 130 | :description "Proxy authentication is required to access the requested resource."} 131 | 408 {:name "Request Timeout" 132 | :description "The server timed out waiting for the request."} 133 | 409 {:name "Conflict" 134 | :description "The request could not be processed because of conflict in the request such as an edit conflict."} 135 | 410 {:name "Gone" 136 | :description "The resource requested is no longer available and will not be available again."} 137 | 411 {:name "Length Required" 138 | :description "The request did not specify the length of its content which is required by the requested resource."} 139 | 412 {:name "Precondition Failed" 140 | :description "The server does not meet one of the preconditions that the requester put on the request."} 141 | 413 {:name "Request Entity Too Large" 142 | :description "The request is larger than the server is willing or able to process."} 143 | 414 {:name "Request-URI Too Long" 144 | :description "The URI provided was too long for the server to process."} 145 | 415 {:name "Unsupported Media Type" 146 | :description "The request entity has a media type which the server or resource does not support."} 147 | 416 {:name "Requested Range Not Satisfiable" 148 | :description "The client has asked for a portion of the file but the server cannot supply that portion."} 149 | 417 {:name "Expectation Failed" 150 | :description "The server cannot meet the requirements of the Expect request-header field."} 151 | 418 {:name "I'm a teapot" 152 | :description "Any attempt to brew coffee with a teapot should result in the error code "418 I'm a teapot". The resulting entity body MAY be short and stout."} 153 | 420 {:name "Enhance Your Calm" 154 | :description "You are being rate-limited."} 155 | 422 {:name "Unprocessable Entity" 156 | :description "The request was well-formed but was unable to be followed due to semantic errors."} 157 | 423 {:name "Locked" 158 | :description "The resource that is being accessed is locked."} 159 | 424 {:name "Failed Dependency" 160 | :description "The request failed due to failure of a previous request."} 161 | 425 {:name "Unordered Collection" 162 | :description "The collection is unordered."} 163 | 426 {:name "Upgrade Required" 164 | :description "The client should switch to a different protocol."} 165 | 428 {:name "Precondition Required" 166 | :description "The server requires the request to be conditional."} 167 | 429 {:name "Too Many Requests" 168 | :description "The user has sent too many requests in a given amount of time."} 169 | 431 {:name "Request Header Fields Too Large" 170 | :description "The server is unwilling to process the request because either an individual header field or all the header fields collectively are too large."} 171 | 449 {:name "Retry With" 172 | :description "The request should be retried after doing the appropriate action."} 173 | 450 {:name "Blocked by Windows Parental Controls" 174 | :description "Windows Parental Controls are turned on and are blocking access to the given webpage."} 175 | 451 {:name "Unavailable For Legal Reasons" 176 | :description "Resource access is denied for legal reasons."} 177 | 500 {:name "Internal Server Error" 178 | :description "There was an internal server error."} 179 | 501 {:name "Not Implemented" 180 | :description "The server either does not recognize the request method or it lacks the ability to fulfill the request."} 181 | 502 {:name "Bad Gateway" 182 | :description "The server was acting as a gateway or proxy and received an invalid response from the upstream server."} 183 | 503 {:name "Service Unavailable" 184 | :description "The server is currently unavailable (because it is overloaded or down for maintenance)."} 185 | 504 {:name "Gateway Timeout" 186 | :description "The server was acting as a gateway or proxy and did not receive a timely request from the upstream server."} 187 | 505 {:name "HTTP Version Not Supported" 188 | :description "The server does not support the HTTP protocol version used in the request."} 189 | 506 {:name "Variant Also Negotiates" 190 | :description "Transparent content negotiation for the request results in a circular reference."} 191 | 507 {:name "Insufficient Storage" 192 | :description "Insufficient storage to complete the request."} 193 | 508 {:name "Loop Detected" 194 | :description "The server detected an infinite loop while processing the request."} 195 | 509 {:name "Bandwidth Limit Exceeded" 196 | :description "Bandwidth limit has been exceeded."} 197 | 510 {:name "Not Extended" 198 | :description "Further extensions to the request are required for the server to fulfill it."} 199 | 511 {:name "Network Authentication Required" 200 | :description "The client needs to authenticate to gain network access."} 201 | 598 {:name "Network read timeout" 202 | :description ""} 203 | 599 {:name "Network connect timeout" 204 | :description ""} 205 | }) 206 | 207 | (defn get-name 208 | "Returns http status name by code." 209 | [code] 210 | (get-in status [code :name])) 211 | 212 | (defn get-description 213 | "Returns http status description by code." 214 | [code] 215 | (get-in status [code :description])) 216 | -------------------------------------------------------------------------------- /templates/http-predicates.mustache: -------------------------------------------------------------------------------- 1 | (ns ring.util.http-predicates) 2 | {{#types}} 3 | 4 | (defn {{fn-name}}? 5 | "Check whether the response type is {{type}} (status code is between 6 | {{start}} and {{end}})." 7 | [response] 8 | {:pre [(map? response)]} 9 | (<= {{start}} (:status response) {{end}})) 10 | {{/types}}{{#template}} 11 | (defn {{fn-name}}? 12 | "Checks whether the response has status code {{status}}" 13 | [response] 14 | {:pre [(map? response)]} 15 | (= (:status response) {{status}})) 16 | {{/template}} 17 | -------------------------------------------------------------------------------- /templates/http-response.mustache: -------------------------------------------------------------------------------- 1 | (ns ring.util.http-response 2 | (:require [potemkin.namespaces :as p] 3 | ring.util.response)) 4 | 5 | (defn throw! 6 | "Throwns an exception with ex-info: 7 | {:type :ring.util.http-response/response 8 | :response response}" 9 | [response] 10 | {:pre [(map? response)]} 11 | (throw (ex-info (str "HTTP "(:status response)) {:type ::response :response response}))) 12 | {{#template}} 13 | 14 | {{#location-entity?}} 15 | (defn {{fn-name}} 16 | "{{status}} {{name}} ({{type}}) 17 | {{description}}" 18 | ([] ({{fn-name}} nil)) 19 | ([url] ({{fn-name}} url nil)) 20 | ([url body] 21 | {:status {{status}} 22 | :headers {"Location" url} 23 | :body body})) 24 | {{/location-entity?}} 25 | {{^location-entity?}} 26 | (defn {{fn-name}} 27 | "{{status}} {{name}} ({{type}}) 28 | {{description}}" 29 | {{#entity?}}([] ({{fn-name}} nil)) 30 | {{/entity?}}([{{#entity?}}body{{/entity?}}{{#location?}}url{{/location?}}] 31 | {:status {{status}} 32 | :headers {{#location?}}{"Location" url}{{/location?}}{{^location?}}{}{{/location?}} 33 | :body {{#entity?}}body{{/entity?}}{{^entity?}}""{{/entity?}}})) 34 | {{/location-entity?}} 35 | {{^success?}} 36 | 37 | (defn {{fn-name}}! 38 | "{{status}} {{name}} ({{type}}) 39 | {{description}} 40 | Throws an exception with ex-info: 41 | {:type :ring.util.http-response/response 42 | :response response}" 43 | {{#entity?}}([] ({{fn-name}}! nil)){{/entity?}} 44 | ([body] 45 | (throw! 46 | {:status {{status}} 47 | :headers {} 48 | :body body}))) 49 | {{/success?}} 50 | {{/template}} 51 | 52 | ;; 53 | ;; Imported vars from ring.util.response 54 | ;; 55 | 56 | {{#imports}} 57 | ;; {{.}} 58 | (if-not (ns-resolve 'ring.util.response '{{.}}) 59 | (println "Can't import ring.util.response/{{.}}, try updating to Ring 1.6.0+")) 60 | (p/import-vars [ring.util.response {{{.}}}]) 61 | 62 | {{/imports}} 63 | -------------------------------------------------------------------------------- /templates/http-status.mustache: -------------------------------------------------------------------------------- 1 | (ns ring.util.http-status) 2 | 3 | {{#template}} 4 | (def {{fn-name}} {{status}}) 5 | {{/template}} 6 | 7 | (def status 8 | "Maps status to name and description" 9 | { 10 | {{#template}} 11 | {{status}} {:name "{{name}}" 12 | :description "{{description}}"} 13 | {{/template}} 14 | }) 15 | 16 | (defn get-name 17 | "Returns http status name by code." 18 | [code] 19 | (get-in status [code :name])) 20 | 21 | (defn get-description 22 | "Returns http status description by code." 23 | [code] 24 | (get-in status [code :description])) 25 | -------------------------------------------------------------------------------- /test/ring/middleware/http_response_test.clj: -------------------------------------------------------------------------------- 1 | (ns ring.middleware.http-response-test 2 | (:require [clojure.test :refer :all] 3 | [ring.middleware.http-response :refer :all] 4 | [ring.util.http-response :refer :all])) 5 | 6 | (def request {}) 7 | (defn failing [_] (throw (RuntimeException.))) 8 | 9 | (def bad (fn [_] (bad-request "BAD"))) 10 | (def bad! (fn [_] (bad-request! "BAD"))) 11 | (def bad-result (bad-request "BAD")) 12 | 13 | (deftest wrap-http-response-sync-test 14 | 15 | (testing "without middleware exception is thrown" 16 | (is (= bad-result (bad request))) 17 | (is (thrown? Exception (bad! request)))) 18 | 19 | (testing "with middleware exceptions are converted into responses" 20 | (is (= bad-result ((wrap-http-response bad) request))) 21 | (is (= bad-result ((wrap-http-response bad!) request)))) 22 | 23 | (testing "only response-exceptions are caugh" 24 | (is (thrown? Exception ((wrap-http-response failing) request))))) 25 | 26 | (def bad-async (fn [_ respond _] (respond (bad-request "BAD")))) 27 | (def bad-async! (fn [_ respond _] (respond (bad-request! "BAD")))) 28 | 29 | (deftest wrap-http-response-async-test 30 | 31 | (testing "without middleware exception is thrown" 32 | (let [respond (promise), raise (promise)] 33 | (bad-async request respond raise) 34 | (is (= bad-result @respond))) 35 | (let [respond (promise), raise (promise)] 36 | (is (thrown? Exception (bad-async! request respond raise))))) 37 | 38 | (testing "with middleware exceptions are converted into responses" 39 | (let [respond (promise), raise (promise)] 40 | ((wrap-http-response bad-async) request respond raise) 41 | (is (= bad-result @respond))) 42 | (let [respond (promise), raise (promise)] 43 | ((wrap-http-response bad-async!) request respond raise) 44 | (is (= bad-result @respond)))) 45 | 46 | (testing "only response-exceptions are caugh" 47 | (let [respond (promise), raise (promise)] 48 | (is (thrown? Exception ((wrap-http-response failing) request respond raise)))))) 49 | -------------------------------------------------------------------------------- /test/ring/util/http_predicates_test.clj: -------------------------------------------------------------------------------- 1 | (ns ring.util.http-predicates-test 2 | (:require [clojure.test :refer :all] 3 | [ring.util.http-predicates :refer :all])) 4 | 5 | 6 | (deftest http-status-code-predicates-test 7 | 8 | (testing "Informational" 9 | (is (continue? {:status 100})) 10 | (is (switching-protocols? {:status 101})) 11 | (is (processing? {:status 102})) 12 | (is (informational? {:status 101}))) 13 | 14 | (testing "Success" 15 | (is (ok? {:status 200})) 16 | (is (created? {:status 201})) 17 | (is (accepted? {:status 202})) 18 | (is (non-authoritative-information? {:status 203})) 19 | (is (no-content? {:status 204})) 20 | (is (reset-content? {:status 205})) 21 | (is (partial-content? {:status 206})) 22 | (is (multi-status? {:status 207})) 23 | (is (already-reported? {:status 208})) 24 | (is (im-used? {:status 226})) 25 | (is (success? {:status 205}))) 26 | 27 | (testing "Redirection" 28 | (is (multiple-choices? {:status 300})) 29 | (is (moved-permanently? {:status 301})) 30 | (is (found? {:status 302})) 31 | (is (see-other? {:status 303})) 32 | (is (not-modified? {:status 304})) 33 | (is (use-proxy? {:status 305})) 34 | (is (temporary-redirect? {:status 307})) 35 | (is (permanent-redirect? {:status 308})) 36 | (is (redirection? {:status 305}))) 37 | 38 | (testing "ClientError" 39 | (is (bad-request? {:status 400})) 40 | (is (unauthorized? {:status 401})) 41 | (is (payment-required? {:status 402})) 42 | (is (forbidden? {:status 403})) 43 | (is (not-found? {:status 404})) 44 | (is (method-not-allowed? {:status 405})) 45 | (is (not-acceptable? {:status 406})) 46 | (is (proxy-authentication-required? {:status 407})) 47 | (is (request-timeout? {:status 408})) 48 | (is (conflict? {:status 409})) 49 | (is (gone? {:status 410})) 50 | (is (length-required? {:status 411})) 51 | (is (precondition-failed? {:status 412})) 52 | (is (request-entity-too-large? {:status 413})) 53 | (is (request-uri-too-long? {:status 414})) 54 | (is (unsupported-media-type? {:status 415})) 55 | (is (requested-range-not-satisfiable? {:status 416})) 56 | (is (expectation-failed? {:status 417})) 57 | (is (enhance-your-calm? {:status 420})) 58 | (is (unprocessable-entity? {:status 422})) 59 | (is (locked? {:status 423})) 60 | (is (failed-dependency? {:status 424})) 61 | (is (unordered-collection? {:status 425})) 62 | (is (upgrade-required? {:status 426})) 63 | (is (precondition-required? {:status 428})) 64 | (is (too-many-requests? {:status 429})) 65 | (is (request-header-fields-too-large? {:status 431})) 66 | (is (retry-with? {:status 449})) 67 | (is (blocked-by-windows-parental-controls? {:status 450})) 68 | (is (unavailable-for-legal-reasons? {:status 451})) 69 | (is (client-error? {:status 431}))) 70 | 71 | (testing "ServerError" 72 | (is (internal-server-error? {:status 500})) 73 | (is (not-implemented? {:status 501})) 74 | (is (bad-gateway? {:status 502})) 75 | (is (service-unavailable? {:status 503})) 76 | (is (gateway-timeout? {:status 504})) 77 | (is (http-version-not-supported? {:status 505})) 78 | (is (variant-also-negotiates? {:status 506})) 79 | (is (insufficient-storage? {:status 507})) 80 | (is (loop-detected? {:status 508})) 81 | (is (bandwidth-limit-exceeded? {:status 509})) 82 | (is (not-extended? {:status 510})) 83 | (is (network-authentication-required? {:status 511})) 84 | (is (network-read-timeout? {:status 598})) 85 | (is (network-connect-timeout? {:status 599})) 86 | (is (server-error? {:status 504}))) 87 | 88 | (testing "Must throw assertion error when `response` parameter does not pass `map?` pre-condition" 89 | (is (thrown? AssertionError (informational? "not-map"))) 90 | (is (thrown? AssertionError (informational? :not-map))) 91 | (is (thrown? AssertionError (informational? nil))) 92 | (is (thrown? AssertionError (informational? 123))) 93 | 94 | (is (thrown? AssertionError (success? "not-map"))) 95 | (is (thrown? AssertionError (success? :not-map))) 96 | (is (thrown? AssertionError (success? nil))) 97 | (is (thrown? AssertionError (success? 123))) 98 | 99 | (is (thrown? AssertionError (redirection? "not-map"))) 100 | (is (thrown? AssertionError (redirection? :not-map))) 101 | (is (thrown? AssertionError (redirection? nil))) 102 | (is (thrown? AssertionError (redirection? 123))) 103 | 104 | (is (thrown? AssertionError (client-error? "not-map"))) 105 | (is (thrown? AssertionError (client-error? :not-map))) 106 | (is (thrown? AssertionError (client-error? nil))) 107 | (is (thrown? AssertionError (client-error? 123))) 108 | 109 | (is (thrown? AssertionError (server-error? "not-map"))) 110 | (is (thrown? AssertionError (server-error? :not-map))) 111 | (is (thrown? AssertionError (server-error? nil))) 112 | (is (thrown? AssertionError (server-error? 123))) 113 | 114 | (is (thrown? AssertionError (continue? "not-map"))) 115 | (is (thrown? AssertionError (continue? :not-map))) 116 | (is (thrown? AssertionError (continue? nil))) 117 | (is (thrown? AssertionError (continue? 123))) 118 | 119 | (is (thrown? AssertionError (switching-protocols? "not-map"))) 120 | (is (thrown? AssertionError (switching-protocols? :not-map))) 121 | (is (thrown? AssertionError (switching-protocols? nil))) 122 | (is (thrown? AssertionError (switching-protocols? 123))) 123 | 124 | (is (thrown? AssertionError (processing? "not-map"))) 125 | (is (thrown? AssertionError (processing? :not-map))) 126 | (is (thrown? AssertionError (processing? nil))) 127 | (is (thrown? AssertionError (processing? 123))) 128 | 129 | (is (thrown? AssertionError (ok? "not-map"))) 130 | (is (thrown? AssertionError (ok? :not-map))) 131 | (is (thrown? AssertionError (ok? nil))) 132 | (is (thrown? AssertionError (ok? 123))) 133 | 134 | (is (thrown? AssertionError (created? "not-map"))) 135 | (is (thrown? AssertionError (created? :not-map))) 136 | (is (thrown? AssertionError (created? nil))) 137 | (is (thrown? AssertionError (created? 123))) 138 | 139 | (is (thrown? AssertionError (accepted? "not-map"))) 140 | (is (thrown? AssertionError (accepted? :not-map))) 141 | (is (thrown? AssertionError (accepted? nil))) 142 | (is (thrown? AssertionError (accepted? 123))) 143 | 144 | (is (thrown? AssertionError (non-authoritative-information? "not-map"))) 145 | (is (thrown? AssertionError (non-authoritative-information? :not-map))) 146 | (is (thrown? AssertionError (non-authoritative-information? nil))) 147 | (is (thrown? AssertionError (non-authoritative-information? 123))) 148 | 149 | (is (thrown? AssertionError (no-content? "not-map"))) 150 | (is (thrown? AssertionError (no-content? :not-map))) 151 | (is (thrown? AssertionError (no-content? nil))) 152 | (is (thrown? AssertionError (no-content? 123))) 153 | 154 | (is (thrown? AssertionError (reset-content? "not-map"))) 155 | (is (thrown? AssertionError (reset-content? :not-map))) 156 | (is (thrown? AssertionError (reset-content? nil))) 157 | (is (thrown? AssertionError (reset-content? 123))) 158 | 159 | (is (thrown? AssertionError (partial-content? "not-map"))) 160 | (is (thrown? AssertionError (partial-content? :not-map))) 161 | (is (thrown? AssertionError (partial-content? nil))) 162 | (is (thrown? AssertionError (partial-content? 123))) 163 | 164 | (is (thrown? AssertionError (multi-status? "not-map"))) 165 | (is (thrown? AssertionError (multi-status? :not-map))) 166 | (is (thrown? AssertionError (multi-status? nil))) 167 | (is (thrown? AssertionError (multi-status? 123))) 168 | 169 | (is (thrown? AssertionError (already-reported? "not-map"))) 170 | (is (thrown? AssertionError (already-reported? :not-map))) 171 | (is (thrown? AssertionError (already-reported? nil))) 172 | (is (thrown? AssertionError (already-reported? 123))) 173 | 174 | (is (thrown? AssertionError (im-used? "not-map"))) 175 | (is (thrown? AssertionError (im-used? :not-map))) 176 | (is (thrown? AssertionError (im-used? nil))) 177 | (is (thrown? AssertionError (im-used? 123))) 178 | 179 | (is (thrown? AssertionError (multiple-choices? "not-map"))) 180 | (is (thrown? AssertionError (multiple-choices? :not-map))) 181 | (is (thrown? AssertionError (multiple-choices? nil))) 182 | (is (thrown? AssertionError (multiple-choices? 123))) 183 | 184 | (is (thrown? AssertionError (moved-permanently? "not-map"))) 185 | (is (thrown? AssertionError (moved-permanently? :not-map))) 186 | (is (thrown? AssertionError (moved-permanently? nil))) 187 | (is (thrown? AssertionError (moved-permanently? 123))) 188 | 189 | (is (thrown? AssertionError (found? "not-map"))) 190 | (is (thrown? AssertionError (found? :not-map))) 191 | (is (thrown? AssertionError (found? nil))) 192 | (is (thrown? AssertionError (found? 123))) 193 | 194 | (is (thrown? AssertionError (see-other? "not-map"))) 195 | (is (thrown? AssertionError (see-other? :not-map))) 196 | (is (thrown? AssertionError (see-other? nil))) 197 | (is (thrown? AssertionError (see-other? 123))) 198 | 199 | (is (thrown? AssertionError (not-modified? "not-map"))) 200 | (is (thrown? AssertionError (not-modified? :not-map))) 201 | (is (thrown? AssertionError (not-modified? nil))) 202 | (is (thrown? AssertionError (not-modified? 123))) 203 | 204 | (is (thrown? AssertionError (use-proxy? "not-map"))) 205 | (is (thrown? AssertionError (use-proxy? :not-map))) 206 | (is (thrown? AssertionError (use-proxy? nil))) 207 | (is (thrown? AssertionError (use-proxy? 123))) 208 | 209 | (is (thrown? AssertionError (temporary-redirect? "not-map"))) 210 | (is (thrown? AssertionError (temporary-redirect? :not-map))) 211 | (is (thrown? AssertionError (temporary-redirect? nil))) 212 | (is (thrown? AssertionError (temporary-redirect? 123))) 213 | 214 | (is (thrown? AssertionError (permanent-redirect? "not-map"))) 215 | (is (thrown? AssertionError (permanent-redirect? :not-map))) 216 | (is (thrown? AssertionError (permanent-redirect? nil))) 217 | (is (thrown? AssertionError (permanent-redirect? 123))) 218 | 219 | (is (thrown? AssertionError (bad-request? "not-map"))) 220 | (is (thrown? AssertionError (bad-request? :not-map))) 221 | (is (thrown? AssertionError (bad-request? nil))) 222 | (is (thrown? AssertionError (bad-request? 123))) 223 | 224 | (is (thrown? AssertionError (unauthorized? "not-map"))) 225 | (is (thrown? AssertionError (unauthorized? :not-map))) 226 | (is (thrown? AssertionError (unauthorized? nil))) 227 | (is (thrown? AssertionError (unauthorized? 123))) 228 | 229 | (is (thrown? AssertionError (payment-required? "not-map"))) 230 | (is (thrown? AssertionError (payment-required? :not-map))) 231 | (is (thrown? AssertionError (payment-required? nil))) 232 | (is (thrown? AssertionError (payment-required? 123))) 233 | 234 | (is (thrown? AssertionError (forbidden? "not-map"))) 235 | (is (thrown? AssertionError (forbidden? :not-map))) 236 | (is (thrown? AssertionError (forbidden? nil))) 237 | (is (thrown? AssertionError (forbidden? 123))) 238 | 239 | (is (thrown? AssertionError (not-found? "not-map"))) 240 | (is (thrown? AssertionError (not-found? :not-map))) 241 | (is (thrown? AssertionError (not-found? nil))) 242 | (is (thrown? AssertionError (not-found? 123))) 243 | 244 | (is (thrown? AssertionError (method-not-allowed? "not-map"))) 245 | (is (thrown? AssertionError (method-not-allowed? :not-map))) 246 | (is (thrown? AssertionError (method-not-allowed? nil))) 247 | (is (thrown? AssertionError (method-not-allowed? 123))) 248 | 249 | (is (thrown? AssertionError (not-acceptable? "not-map"))) 250 | (is (thrown? AssertionError (not-acceptable? :not-map))) 251 | (is (thrown? AssertionError (not-acceptable? nil))) 252 | (is (thrown? AssertionError (not-acceptable? 123))) 253 | 254 | (is (thrown? AssertionError (proxy-authentication-required? "not-map"))) 255 | (is (thrown? AssertionError (proxy-authentication-required? :not-map))) 256 | (is (thrown? AssertionError (proxy-authentication-required? nil))) 257 | (is (thrown? AssertionError (proxy-authentication-required? 123))) 258 | 259 | (is (thrown? AssertionError (request-timeout? "not-map"))) 260 | (is (thrown? AssertionError (request-timeout? :not-map))) 261 | (is (thrown? AssertionError (request-timeout? nil))) 262 | (is (thrown? AssertionError (request-timeout? 123))) 263 | 264 | (is (thrown? AssertionError (conflict? "not-map"))) 265 | (is (thrown? AssertionError (conflict? :not-map))) 266 | (is (thrown? AssertionError (conflict? nil))) 267 | (is (thrown? AssertionError (conflict? 123))) 268 | 269 | (is (thrown? AssertionError (gone? "not-map"))) 270 | (is (thrown? AssertionError (gone? :not-map))) 271 | (is (thrown? AssertionError (gone? nil))) 272 | (is (thrown? AssertionError (gone? 123))) 273 | 274 | (is (thrown? AssertionError (length-required? "not-map"))) 275 | (is (thrown? AssertionError (length-required? :not-map))) 276 | (is (thrown? AssertionError (length-required? nil))) 277 | (is (thrown? AssertionError (length-required? 123))) 278 | 279 | (is (thrown? AssertionError (precondition-failed? "not-map"))) 280 | (is (thrown? AssertionError (precondition-failed? :not-map))) 281 | (is (thrown? AssertionError (precondition-failed? nil))) 282 | (is (thrown? AssertionError (precondition-failed? 123))) 283 | 284 | (is (thrown? AssertionError (request-entity-too-large? "not-map"))) 285 | (is (thrown? AssertionError (request-entity-too-large? :not-map))) 286 | (is (thrown? AssertionError (request-entity-too-large? nil))) 287 | (is (thrown? AssertionError (request-entity-too-large? 123))) 288 | 289 | (is (thrown? AssertionError (request-uri-too-long? "not-map"))) 290 | (is (thrown? AssertionError (request-uri-too-long? :not-map))) 291 | (is (thrown? AssertionError (request-uri-too-long? nil))) 292 | (is (thrown? AssertionError (request-uri-too-long? 123))) 293 | 294 | (is (thrown? AssertionError (unsupported-media-type? "not-map"))) 295 | (is (thrown? AssertionError (unsupported-media-type? :not-map))) 296 | (is (thrown? AssertionError (unsupported-media-type? nil))) 297 | (is (thrown? AssertionError (unsupported-media-type? 123))) 298 | 299 | (is (thrown? AssertionError (requested-range-not-satisfiable? "not-map"))) 300 | (is (thrown? AssertionError (requested-range-not-satisfiable? :not-map))) 301 | (is (thrown? AssertionError (requested-range-not-satisfiable? nil))) 302 | (is (thrown? AssertionError (requested-range-not-satisfiable? 123))) 303 | 304 | (is (thrown? AssertionError (expectation-failed? "not-map"))) 305 | (is (thrown? AssertionError (expectation-failed? :not-map))) 306 | (is (thrown? AssertionError (expectation-failed? nil))) 307 | (is (thrown? AssertionError (expectation-failed? 123))) 308 | 309 | (is (thrown? AssertionError (im-a-teapot? "not-map"))) 310 | (is (thrown? AssertionError (im-a-teapot? :not-map))) 311 | (is (thrown? AssertionError (im-a-teapot? nil))) 312 | (is (thrown? AssertionError (im-a-teapot? 123))) 313 | 314 | (is (thrown? AssertionError (enhance-your-calm? "not-map"))) 315 | (is (thrown? AssertionError (enhance-your-calm? :not-map))) 316 | (is (thrown? AssertionError (enhance-your-calm? nil))) 317 | (is (thrown? AssertionError (enhance-your-calm? 123))) 318 | 319 | (is (thrown? AssertionError (unprocessable-entity? "not-map"))) 320 | (is (thrown? AssertionError (unprocessable-entity? :not-map))) 321 | (is (thrown? AssertionError (unprocessable-entity? nil))) 322 | (is (thrown? AssertionError (unprocessable-entity? 123))) 323 | 324 | (is (thrown? AssertionError (locked? "not-map"))) 325 | (is (thrown? AssertionError (locked? :not-map))) 326 | (is (thrown? AssertionError (locked? nil))) 327 | (is (thrown? AssertionError (locked? 123))) 328 | 329 | (is (thrown? AssertionError (failed-dependency? "not-map"))) 330 | (is (thrown? AssertionError (failed-dependency? :not-map))) 331 | (is (thrown? AssertionError (failed-dependency? nil))) 332 | (is (thrown? AssertionError (failed-dependency? 123))) 333 | 334 | (is (thrown? AssertionError (unordered-collection? "not-map"))) 335 | (is (thrown? AssertionError (unordered-collection? :not-map))) 336 | (is (thrown? AssertionError (unordered-collection? nil))) 337 | (is (thrown? AssertionError (unordered-collection? 123))) 338 | 339 | (is (thrown? AssertionError (upgrade-required? "not-map"))) 340 | (is (thrown? AssertionError (upgrade-required? :not-map))) 341 | (is (thrown? AssertionError (upgrade-required? nil))) 342 | (is (thrown? AssertionError (upgrade-required? 123))) 343 | 344 | (is (thrown? AssertionError (precondition-required? "not-map"))) 345 | (is (thrown? AssertionError (precondition-required? :not-map))) 346 | (is (thrown? AssertionError (precondition-required? nil))) 347 | (is (thrown? AssertionError (precondition-required? 123))) 348 | 349 | (is (thrown? AssertionError (too-many-requests? "not-map"))) 350 | (is (thrown? AssertionError (too-many-requests? :not-map))) 351 | (is (thrown? AssertionError (too-many-requests? nil))) 352 | (is (thrown? AssertionError (too-many-requests? 123))) 353 | 354 | (is (thrown? AssertionError (request-header-fields-too-large? "not-map"))) 355 | (is (thrown? AssertionError (request-header-fields-too-large? :not-map))) 356 | (is (thrown? AssertionError (request-header-fields-too-large? nil))) 357 | (is (thrown? AssertionError (request-header-fields-too-large? 123))) 358 | 359 | (is (thrown? AssertionError (retry-with? "not-map"))) 360 | (is (thrown? AssertionError (retry-with? :not-map))) 361 | (is (thrown? AssertionError (retry-with? nil))) 362 | (is (thrown? AssertionError (retry-with? 123))) 363 | 364 | (is (thrown? AssertionError (blocked-by-windows-parental-controls? "not-map"))) 365 | (is (thrown? AssertionError (blocked-by-windows-parental-controls? :not-map))) 366 | (is (thrown? AssertionError (blocked-by-windows-parental-controls? nil))) 367 | (is (thrown? AssertionError (blocked-by-windows-parental-controls? 123))) 368 | 369 | (is (thrown? AssertionError (unavailable-for-legal-reasons? "not-map"))) 370 | (is (thrown? AssertionError (unavailable-for-legal-reasons? :not-map))) 371 | (is (thrown? AssertionError (unavailable-for-legal-reasons? nil))) 372 | (is (thrown? AssertionError (unavailable-for-legal-reasons? 123))) 373 | 374 | (is (thrown? AssertionError (internal-server-error? "not-map"))) 375 | (is (thrown? AssertionError (internal-server-error? :not-map))) 376 | (is (thrown? AssertionError (internal-server-error? nil))) 377 | (is (thrown? AssertionError (internal-server-error? 123))) 378 | 379 | (is (thrown? AssertionError (not-implemented? "not-map"))) 380 | (is (thrown? AssertionError (not-implemented? :not-map))) 381 | (is (thrown? AssertionError (not-implemented? nil))) 382 | (is (thrown? AssertionError (not-implemented? 123))) 383 | 384 | (is (thrown? AssertionError (bad-gateway? "not-map"))) 385 | (is (thrown? AssertionError (bad-gateway? :not-map))) 386 | (is (thrown? AssertionError (bad-gateway? nil))) 387 | (is (thrown? AssertionError (bad-gateway? 123))) 388 | 389 | (is (thrown? AssertionError (service-unavailable? "not-map"))) 390 | (is (thrown? AssertionError (service-unavailable? :not-map))) 391 | (is (thrown? AssertionError (service-unavailable? nil))) 392 | (is (thrown? AssertionError (service-unavailable? 123))) 393 | 394 | (is (thrown? AssertionError (gateway-timeout? "not-map"))) 395 | (is (thrown? AssertionError (gateway-timeout? :not-map))) 396 | (is (thrown? AssertionError (gateway-timeout? nil))) 397 | (is (thrown? AssertionError (gateway-timeout? 123))) 398 | 399 | (is (thrown? AssertionError (http-version-not-supported? "not-map"))) 400 | (is (thrown? AssertionError (http-version-not-supported? :not-map))) 401 | (is (thrown? AssertionError (http-version-not-supported? nil))) 402 | (is (thrown? AssertionError (http-version-not-supported? 123))) 403 | 404 | (is (thrown? AssertionError (variant-also-negotiates? "not-map"))) 405 | (is (thrown? AssertionError (variant-also-negotiates? :not-map))) 406 | (is (thrown? AssertionError (variant-also-negotiates? nil))) 407 | (is (thrown? AssertionError (variant-also-negotiates? 123))) 408 | 409 | (is (thrown? AssertionError (insufficient-storage? "not-map"))) 410 | (is (thrown? AssertionError (insufficient-storage? :not-map))) 411 | (is (thrown? AssertionError (insufficient-storage? nil))) 412 | (is (thrown? AssertionError (insufficient-storage? 123))) 413 | 414 | (is (thrown? AssertionError (loop-detected? "not-map"))) 415 | (is (thrown? AssertionError (loop-detected? :not-map))) 416 | (is (thrown? AssertionError (loop-detected? nil))) 417 | (is (thrown? AssertionError (loop-detected? 123))) 418 | 419 | (is (thrown? AssertionError (bandwidth-limit-exceeded? "not-map"))) 420 | (is (thrown? AssertionError (bandwidth-limit-exceeded? :not-map))) 421 | (is (thrown? AssertionError (bandwidth-limit-exceeded? nil))) 422 | (is (thrown? AssertionError (bandwidth-limit-exceeded? 123))) 423 | 424 | (is (thrown? AssertionError (not-extended? "not-map"))) 425 | (is (thrown? AssertionError (not-extended? :not-map))) 426 | (is (thrown? AssertionError (not-extended? nil))) 427 | (is (thrown? AssertionError (not-extended? 123))) 428 | 429 | (is (thrown? AssertionError (network-authentication-required? "not-map"))) 430 | (is (thrown? AssertionError (network-authentication-required? :not-map))) 431 | (is (thrown? AssertionError (network-authentication-required? nil))) 432 | (is (thrown? AssertionError (network-authentication-required? 123))) 433 | 434 | (is (thrown? AssertionError (network-read-timeout? "not-map"))) 435 | (is (thrown? AssertionError (network-read-timeout? :not-map))) 436 | (is (thrown? AssertionError (network-read-timeout? nil))) 437 | (is (thrown? AssertionError (network-read-timeout? 123))) 438 | 439 | (is (thrown? AssertionError (network-connect-timeout? "not-map"))) 440 | (is (thrown? AssertionError (network-connect-timeout? :not-map))) 441 | (is (thrown? AssertionError (network-connect-timeout? nil))) 442 | (is (thrown? AssertionError (network-connect-timeout? 123))))) 443 | -------------------------------------------------------------------------------- /test/ring/util/http_response_test.clj: -------------------------------------------------------------------------------- 1 | (ns ring.util.http-response-test 2 | (:require [clojure.test :refer :all] 3 | [ring.util.http-response :refer :all])) 4 | 5 | (deftest http-responses-test 6 | 7 | (testing "Informational" 8 | (is (= {:status 100 :headers {} :body ""} (continue))) 9 | (is (= {:status 101 :headers {} :body ""} (switching-protocols))) 10 | (is (= {:status 102 :headers {} :body ""} (processing)))) 11 | 12 | (testing "Success" 13 | (is (= {:status 200 :headers {} :body "body"} (ok "body"))) 14 | (is (= {:status 201 :headers {"Location" "/url"} :body nil} (created "/url"))) 15 | (is (= {:status 201 :headers {"Location" "/url"} :body "body"} (created "/url" "body"))) 16 | (is (= {:status 202 :headers {} :body "body"} (accepted "body"))) 17 | (is (= {:status 203 :headers {} :body "body"} (non-authoritative-information "body"))) 18 | (is (= {:status 204 :headers {} :body ""} (no-content))) 19 | (is (= {:status 205 :headers {} :body ""} (reset-content))) 20 | (is (= {:status 206 :headers {} :body "body"} (partial-content "body"))) 21 | (is (= {:status 207 :headers {} :body "body"} (multi-status "body"))) 22 | (is (= {:status 208 :headers {} :body "body"} (already-reported "body"))) 23 | (is (= {:status 226 :headers {} :body "body"} (im-used "body")))) 24 | 25 | (testing "Redirection" 26 | (is (= {:status 300 :headers {"Location" "/url"} :body ""} (multiple-choices "/url"))) 27 | (is (= {:status 301 :headers {"Location" "/url"} :body ""} (moved-permanently "/url"))) 28 | (is (= {:status 302 :headers {"Location" "/url"} :body ""} (found "/url"))) 29 | (is (= {:status 303 :headers {"Location" "/url"} :body ""} (see-other "/url"))) 30 | (is (= {:status 304 :headers {} :body ""} (not-modified))) 31 | (is (= {:status 305 :headers {"Location" "/url"} :body ""} (use-proxy "/url"))) 32 | (is (= {:status 307 :headers {"Location" "/url"} :body ""} (temporary-redirect "/url"))) 33 | (is (= {:status 308 :headers {"Location" "/url"} :body ""} (permanent-redirect "/url")))) 34 | 35 | (testing "ClientError" 36 | (is (= {:status 400 :headers {} :body "body"} (bad-request "body"))) 37 | (is (= {:status 401 :headers {} :body "body"} (unauthorized "body"))) 38 | (is (= {:status 402 :headers {} :body "body"} (payment-required "body"))) 39 | (is (= {:status 403 :headers {} :body "body"} (forbidden "body"))) 40 | (is (= {:status 404 :headers {} :body "body"} (not-found "body"))) 41 | (is (= {:status 405 :headers {} :body "body"} (method-not-allowed "body"))) 42 | (is (= {:status 406 :headers {} :body "body"} (not-acceptable "body"))) 43 | (is (= {:status 407 :headers {} :body "body"} (proxy-authentication-required "body"))) 44 | (is (= {:status 408 :headers {} :body "body"} (request-timeout "body"))) 45 | (is (= {:status 409 :headers {} :body "body"} (conflict "body"))) 46 | (is (= {:status 410 :headers {} :body "body"} (gone "body"))) 47 | (is (= {:status 411 :headers {} :body "body"} (length-required "body"))) 48 | (is (= {:status 412 :headers {} :body "body"} (precondition-failed "body"))) 49 | (is (= {:status 413 :headers {} :body "body"} (request-entity-too-large "body"))) 50 | (is (= {:status 414 :headers {} :body "body"} (request-uri-too-long "body"))) 51 | (is (= {:status 415 :headers {} :body "body"} (unsupported-media-type "body"))) 52 | (is (= {:status 416 :headers {} :body "body"} (requested-range-not-satisfiable "body"))) 53 | (is (= {:status 417 :headers {} :body "body"} (expectation-failed "body"))) 54 | (is (= {:status 418 :headers {} :body "body"} (im-a-teapot "body"))) 55 | (is (= {:status 420 :headers {} :body "body"} (enhance-your-calm "body"))) 56 | (is (= {:status 422 :headers {} :body "body"} (unprocessable-entity "body"))) 57 | (is (= {:status 423 :headers {} :body "body"} (locked "body"))) 58 | (is (= {:status 424 :headers {} :body "body"} (failed-dependency "body"))) 59 | (is (= {:status 425 :headers {} :body "body"} (unordered-collection "body"))) 60 | (is (= {:status 426 :headers {} :body "body"} (upgrade-required "body"))) 61 | (is (= {:status 428 :headers {} :body "body"} (precondition-required "body"))) 62 | (is (= {:status 429 :headers {} :body "body"} (too-many-requests "body"))) 63 | (is (= {:status 431 :headers {} :body "body"} (request-header-fields-too-large "body"))) 64 | (is (= {:status 449 :headers {} :body "body"} (retry-with "body"))) 65 | (is (= {:status 450 :headers {} :body "body"} (blocked-by-windows-parental-controls "body"))) 66 | (is (= {:status 451 :headers {} :body "body"} (unavailable-for-legal-reasons "body")))) 67 | 68 | (testing "ServerError" 69 | (is (= {:status 500 :headers {} :body "body"} (internal-server-error "body"))) 70 | (is (= {:status 501 :headers {} :body "body"} (not-implemented "body"))) 71 | (is (= {:status 502 :headers {} :body "body"} (bad-gateway "body"))) 72 | (is (= {:status 503 :headers {} :body "body"} (service-unavailable "body"))) 73 | (is (= {:status 504 :headers {} :body "body"} (gateway-timeout "body"))) 74 | (is (= {:status 505 :headers {} :body "body"} (http-version-not-supported "body"))) 75 | (is (= {:status 506 :headers {} :body "body"} (variant-also-negotiates "body"))) 76 | (is (= {:status 507 :headers {} :body "body"} (insufficient-storage "body"))) 77 | (is (= {:status 508 :headers {} :body "body"} (loop-detected "body"))) 78 | (is (= {:status 509 :headers {} :body "body"} (bandwidth-limit-exceeded "body"))) 79 | (is (= {:status 510 :headers {} :body "body"} (not-extended "body"))) 80 | (is (= {:status 511 :headers {} :body "body"} (network-authentication-required "body"))) 81 | (is (= {:status 598 :headers {} :body "body"} (network-read-timeout "body"))) 82 | (is (= {:status 599 :headers {} :body "body"} (network-connect-timeout "body"))))) 83 | 84 | (declare slingshots?) 85 | (defmethod assert-expr 'slingshots? [msg form] 86 | (let [expected (second form) 87 | body (nthnext form 2)] 88 | `(try 89 | ~@body 90 | (do-report {:type :fail, :message ~msg, 91 | :expected ~expected, :actual nil}) 92 | (catch Exception e# 93 | (let [data# (ex-data e#)] 94 | (if (= :ring.util.http-response/response (:type data#)) 95 | (if (= ~expected (:response data#)) 96 | (do-report {:type :pass, :message ~msg, 97 | :expected (:response data#) :actual (:response data#)}) 98 | (do-report {:type :fail, :message ~msg, 99 | :expected ~expected, :actual (:response data#)})) 100 | (do-report {:type :fail, :message ~msg, 101 | :expected ~expected, :actual nil}))))))) 102 | 103 | (deftest slingshot-error-responses-test 104 | 105 | (testing "ClientError" 106 | (is (slingshots? {:status 400 :headers {} :body "body"} (bad-request! "body"))) 107 | (is (slingshots? {:status 401 :headers {} :body "body"} (unauthorized! "body"))) 108 | (is (slingshots? {:status 402 :headers {} :body "body"} (payment-required! "body"))) 109 | (is (slingshots? {:status 403 :headers {} :body "body"} (forbidden! "body"))) 110 | (is (slingshots? {:status 404 :headers {} :body "body"} (not-found! "body"))) 111 | (is (slingshots? {:status 405 :headers {} :body "body"} (method-not-allowed! "body"))) 112 | (is (slingshots? {:status 406 :headers {} :body "body"} (not-acceptable! "body"))) 113 | (is (slingshots? {:status 407 :headers {} :body "body"} (proxy-authentication-required! "body"))) 114 | (is (slingshots? {:status 408 :headers {} :body "body"} (request-timeout! "body"))) 115 | (is (slingshots? {:status 409 :headers {} :body "body"} (conflict! "body"))) 116 | (is (slingshots? {:status 410 :headers {} :body "body"} (gone! "body"))) 117 | (is (slingshots? {:status 411 :headers {} :body "body"} (length-required! "body"))) 118 | (is (slingshots? {:status 412 :headers {} :body "body"} (precondition-failed! "body"))) 119 | (is (slingshots? {:status 413 :headers {} :body "body"} (request-entity-too-large! "body"))) 120 | (is (slingshots? {:status 414 :headers {} :body "body"} (request-uri-too-long! "body"))) 121 | (is (slingshots? {:status 415 :headers {} :body "body"} (unsupported-media-type! "body"))) 122 | (is (slingshots? {:status 416 :headers {} :body "body"} (requested-range-not-satisfiable! "body"))) 123 | (is (slingshots? {:status 417 :headers {} :body "body"} (expectation-failed! "body"))) 124 | (is (slingshots? {:status 418 :headers {} :body "body"} (im-a-teapot! "body"))) 125 | (is (slingshots? {:status 420 :headers {} :body "body"} (enhance-your-calm! "body"))) 126 | (is (slingshots? {:status 422 :headers {} :body "body"} (unprocessable-entity! "body"))) 127 | (is (slingshots? {:status 423 :headers {} :body "body"} (locked! "body"))) 128 | (is (slingshots? {:status 424 :headers {} :body "body"} (failed-dependency! "body"))) 129 | (is (slingshots? {:status 425 :headers {} :body "body"} (unordered-collection! "body"))) 130 | (is (slingshots? {:status 426 :headers {} :body "body"} (upgrade-required! "body"))) 131 | (is (slingshots? {:status 428 :headers {} :body "body"} (precondition-required! "body"))) 132 | (is (slingshots? {:status 429 :headers {} :body "body"} (too-many-requests! "body"))) 133 | (is (slingshots? {:status 431 :headers {} :body "body"} (request-header-fields-too-large! "body"))) 134 | (is (slingshots? {:status 449 :headers {} :body "body"} (retry-with! "body"))) 135 | (is (slingshots? {:status 450 :headers {} :body "body"} (blocked-by-windows-parental-controls! "body"))) 136 | (is (slingshots? {:status 451 :headers {} :body "body"} (unavailable-for-legal-reasons! "body")))) 137 | 138 | (testing "ServerError" 139 | (is (slingshots? {:status 500 :headers {} :body "body"} (internal-server-error! "body"))) 140 | (is (slingshots? {:status 501 :headers {} :body "body"} (not-implemented! "body"))) 141 | (is (slingshots? {:status 502 :headers {} :body "body"} (bad-gateway! "body"))) 142 | (is (slingshots? {:status 503 :headers {} :body "body"} (service-unavailable! "body"))) 143 | (is (slingshots? {:status 504 :headers {} :body "body"} (gateway-timeout! "body"))) 144 | (is (slingshots? {:status 505 :headers {} :body "body"} (http-version-not-supported! "body"))) 145 | (is (slingshots? {:status 506 :headers {} :body "body"} (variant-also-negotiates! "body"))) 146 | (is (slingshots? {:status 507 :headers {} :body "body"} (insufficient-storage! "body"))) 147 | (is (slingshots? {:status 508 :headers {} :body "body"} (loop-detected! "body"))) 148 | (is (slingshots? {:status 509 :headers {} :body "body"} (bandwidth-limit-exceeded! "body"))) 149 | (is (slingshots? {:status 510 :headers {} :body "body"} (not-extended! "body"))) 150 | (is (slingshots? {:status 511 :headers {} :body "body"} (network-authentication-required! "body"))) 151 | (is (slingshots? {:status 598 :headers {} :body "body"} (network-read-timeout! "body"))) 152 | (is (slingshots? {:status 599 :headers {} :body "body"} (network-connect-timeout! "body"))))) 153 | 154 | (deftest throw!-test 155 | (is (slingshots? {:status 400 :headers {} :body "body"} (throw! (bad-request "body")))) 156 | (is (slingshots? {:status 400 :headers {"a" "1"} :body "body"} (throw! (header (bad-request "body") "a" "1"))))) 157 | 158 | (deftest throw!-parameter-validation-test 159 | (testing "Must throw assertion error when `response` parameter does not pass `map?` pre-condition" 160 | (is (thrown? AssertionError (throw! "not-map"))) 161 | (is (thrown? AssertionError (throw! :not-map))) 162 | (is (thrown? AssertionError (throw! nil))) 163 | (is (thrown? AssertionError (throw! 123))))) 164 | 165 | (deftest imported-vars-test 166 | (doseq [v [#'status 167 | #'header 168 | #'file-response 169 | #'content-type 170 | #'charset 171 | #'set-cookie 172 | #'response? 173 | #'url-response 174 | #'resource-response 175 | #'get-header]] 176 | (is (= 'ring.util.response (-> v meta :ns ns-name)) v))) 177 | -------------------------------------------------------------------------------- /test/ring/util/http_status_test.clj: -------------------------------------------------------------------------------- 1 | (ns ring.util.http-status-test 2 | (:require [clojure.test :refer :all] 3 | [ring.util.http-status :refer :all])) 4 | 5 | 6 | (deftest http-status-codes-test 7 | 8 | (testing "Informational" 9 | (is (= 100 continue)) 10 | (is (= 101 switching-protocols)) 11 | (is (= 102 processing))) 12 | 13 | (testing "Success" 14 | (is (= 200 ok)) 15 | (is (= 201 created)) 16 | (is (= 202 accepted)) 17 | (is (= 203 non-authoritative-information)) 18 | (is (= 204 no-content)) 19 | (is (= 205 reset-content)) 20 | (is (= 206 partial-content)) 21 | (is (= 207 multi-status)) 22 | (is (= 208 already-reported)) 23 | (is (= 226 im-used))) 24 | 25 | (testing "Redirection" 26 | (is (= 300 multiple-choices)) 27 | (is (= 301 moved-permanently)) 28 | (is (= 302 found)) 29 | (is (= 303 see-other)) 30 | (is (= 304 not-modified)) 31 | (is (= 305 use-proxy)) 32 | (is (= 307 temporary-redirect)) 33 | (is (= 308 permanent-redirect))) 34 | 35 | (testing "ClientError" 36 | (is (= 400 bad-request)) 37 | (is (= 401 unauthorized)) 38 | (is (= 402 payment-required)) 39 | (is (= 403 forbidden)) 40 | (is (= 404 not-found)) 41 | (is (= 405 method-not-allowed)) 42 | (is (= 406 not-acceptable)) 43 | (is (= 407 proxy-authentication-required)) 44 | (is (= 408 request-timeout)) 45 | (is (= 409 conflict)) 46 | (is (= 410 gone)) 47 | (is (= 411 length-required)) 48 | (is (= 412 precondition-failed)) 49 | (is (= 413 request-entity-too-large)) 50 | (is (= 414 request-uri-too-long)) 51 | (is (= 415 unsupported-media-type)) 52 | (is (= 416 requested-range-not-satisfiable)) 53 | (is (= 417 expectation-failed)) 54 | (is (= 420 enhance-your-calm)) 55 | (is (= 422 unprocessable-entity)) 56 | (is (= 423 locked)) 57 | (is (= 424 failed-dependency)) 58 | (is (= 425 unordered-collection)) 59 | (is (= 426 upgrade-required)) 60 | (is (= 428 precondition-required)) 61 | (is (= 429 too-many-requests)) 62 | (is (= 431 request-header-fields-too-large)) 63 | (is (= 449 retry-with)) 64 | (is (= 450 blocked-by-windows-parental-controls)) 65 | (is (= 451 unavailable-for-legal-reasons))) 66 | 67 | (testing "ServerError" 68 | (is (= 500 internal-server-error)) 69 | (is (= 501 not-implemented)) 70 | (is (= 502 bad-gateway)) 71 | (is (= 503 service-unavailable)) 72 | (is (= 504 gateway-timeout)) 73 | (is (= 505 http-version-not-supported)) 74 | (is (= 506 variant-also-negotiates)) 75 | (is (= 507 insufficient-storage)) 76 | (is (= 508 loop-detected)) 77 | (is (= 509 bandwidth-limit-exceeded)) 78 | (is (= 510 not-extended)) 79 | (is (= 511 network-authentication-required)) 80 | (is (= 598 network-read-timeout)) 81 | (is (= 599 network-connect-timeout)))) 82 | 83 | (deftest status-test 84 | (is {:name "Internal Server Error" 85 | :description "There was an internal server error."} 86 | (status 500))) 87 | --------------------------------------------------------------------------------