Support all HTTP status codes (#49)
This commit is contained in:
parent
023b4037fd
commit
930130b624
@ -1,5 +1,6 @@
|
|||||||
unreleased
|
unreleased
|
||||||
==========
|
==========
|
||||||
|
- Support all HTTP response statuses
|
||||||
- Support all HTTP request methods
|
- Support all HTTP request methods
|
||||||
- Added in v0.1.0
|
- Added in v0.1.0
|
||||||
- Get
|
- Get
|
||||||
|
@ -23,7 +23,7 @@ sayHello = HTTPure.OK responseHeaders <<< flip HTTPure.lookup "X-Input"
|
|||||||
-- | Route to the correct handler
|
-- | Route to the correct handler
|
||||||
router :: forall e. HTTPure.Request -> HTTPure.ResponseM e
|
router :: forall e. HTTPure.Request -> HTTPure.ResponseM e
|
||||||
router (HTTPure.Get headers _) = pure $ sayHello headers
|
router (HTTPure.Get headers _) = pure $ sayHello headers
|
||||||
router _ = pure $ HTTPure.OK StrMap.empty ""
|
router _ = pure $ HTTPure.NotFound StrMap.empty
|
||||||
|
|
||||||
-- | Boot up the server
|
-- | Boot up the server
|
||||||
main :: forall e. HTTPure.ServerM (console :: Console.CONSOLE | e)
|
main :: forall e. HTTPure.ServerM (console :: Console.CONSOLE | e)
|
||||||
|
@ -18,7 +18,7 @@ portS = show port
|
|||||||
router :: forall e. HTTPure.Request -> HTTPure.ResponseM e
|
router :: forall e. HTTPure.Request -> HTTPure.ResponseM e
|
||||||
router (HTTPure.Get _ "/hello") = pure $ HTTPure.OK StrMap.empty "hello"
|
router (HTTPure.Get _ "/hello") = pure $ HTTPure.OK StrMap.empty "hello"
|
||||||
router (HTTPure.Get _ "/goodbye") = pure $ HTTPure.OK StrMap.empty "goodbye"
|
router (HTTPure.Get _ "/goodbye") = pure $ HTTPure.OK StrMap.empty "goodbye"
|
||||||
router _ = pure $ HTTPure.OK StrMap.empty ""
|
router _ = pure $ HTTPure.NotFound StrMap.empty
|
||||||
|
|
||||||
-- | Boot up the server
|
-- | Boot up the server
|
||||||
main :: forall e. HTTPure.ServerM (console :: Console.CONSOLE | e)
|
main :: forall e. HTTPure.ServerM (console :: Console.CONSOLE | e)
|
||||||
|
@ -17,7 +17,7 @@ portS = show port
|
|||||||
-- | Route to the correct handler
|
-- | Route to the correct handler
|
||||||
router :: forall e. HTTPure.Request -> HTTPure.ResponseM e
|
router :: forall e. HTTPure.Request -> HTTPure.ResponseM e
|
||||||
router (HTTPure.Post _ _ body) = pure $ HTTPure.OK StrMap.empty body
|
router (HTTPure.Post _ _ body) = pure $ HTTPure.OK StrMap.empty body
|
||||||
router _ = pure $ HTTPure.OK StrMap.empty ""
|
router _ = pure $ HTTPure.NotFound StrMap.empty
|
||||||
|
|
||||||
-- | Boot up the server
|
-- | Boot up the server
|
||||||
main :: forall e. HTTPure.ServerM (console :: Console.CONSOLE | e)
|
main :: forall e. HTTPure.ServerM (console :: Console.CONSOLE | e)
|
||||||
|
@ -6,7 +6,6 @@ module HTTPure.Response
|
|||||||
|
|
||||||
import Prelude
|
import Prelude
|
||||||
|
|
||||||
import Data.Maybe as Maybe
|
|
||||||
import Node.HTTP as HTTP
|
import Node.HTTP as HTTP
|
||||||
|
|
||||||
import HTTPure.Body as Body
|
import HTTPure.Body as Body
|
||||||
@ -14,30 +13,241 @@ import HTTPure.Headers as Headers
|
|||||||
import HTTPure.HTTPureM as HTTPureM
|
import HTTPure.HTTPureM as HTTPureM
|
||||||
import HTTPure.Status as Status
|
import HTTPure.Status as Status
|
||||||
|
|
||||||
-- | A response is a status, and can have headers and a body. Different response
|
-- | A response is a status and headers, and for some statuses, a body. You can
|
||||||
-- | codes will allow different response components to be sent.
|
-- | use the data constructor `Response` to send non-standard status codes.
|
||||||
data Response
|
data Response
|
||||||
= OK Headers.Headers Body.Body
|
|
||||||
|
-- Non-standard status codes
|
||||||
|
= Response Int Headers.Headers Body.Body
|
||||||
|
|
||||||
|
-- 1xx
|
||||||
|
| Continue Headers.Headers
|
||||||
|
| SwitchingProtocols Headers.Headers
|
||||||
|
| Processing Headers.Headers
|
||||||
|
|
||||||
|
-- 2xx
|
||||||
|
| OK Headers.Headers Body.Body
|
||||||
|
| Created Headers.Headers
|
||||||
|
| Accepted Headers.Headers
|
||||||
|
| NonAuthoritativeInformation Headers.Headers Body.Body
|
||||||
|
| NoContent Headers.Headers
|
||||||
|
| ResetContent Headers.Headers
|
||||||
|
| PartialContent Headers.Headers Body.Body
|
||||||
|
| MultiStatus Headers.Headers Body.Body
|
||||||
|
| AlreadyReported Headers.Headers
|
||||||
|
| IMUsed Headers.Headers Body.Body
|
||||||
|
|
||||||
|
-- 3xx
|
||||||
|
| MultipleChoices Headers.Headers Body.Body
|
||||||
|
| MovedPermanently Headers.Headers Body.Body
|
||||||
|
| Found Headers.Headers Body.Body
|
||||||
|
| SeeOther Headers.Headers Body.Body
|
||||||
|
| NotModified Headers.Headers
|
||||||
|
| UseProxy Headers.Headers Body.Body
|
||||||
|
| TemporaryRedirect Headers.Headers Body.Body
|
||||||
|
| PermanentRedirect Headers.Headers Body.Body
|
||||||
|
|
||||||
|
-- 4xx
|
||||||
|
| BadRequest Headers.Headers Body.Body
|
||||||
|
| Unauthorized Headers.Headers
|
||||||
|
| PaymentRequired Headers.Headers
|
||||||
|
| Forbidden Headers.Headers
|
||||||
|
| NotFound Headers.Headers
|
||||||
|
| MethodNotAllowed Headers.Headers
|
||||||
|
| NotAcceptable Headers.Headers
|
||||||
|
| ProxyAuthenticationRequired Headers.Headers
|
||||||
|
| RequestTimeout Headers.Headers
|
||||||
|
| Conflict Headers.Headers Body.Body
|
||||||
|
| Gone Headers.Headers
|
||||||
|
| LengthRequired Headers.Headers
|
||||||
|
| PreconditionFailed Headers.Headers
|
||||||
|
| PayloadTooLarge Headers.Headers
|
||||||
|
| URITooLong Headers.Headers
|
||||||
|
| UnsupportedMediaType Headers.Headers
|
||||||
|
| RangeNotSatisfiable Headers.Headers
|
||||||
|
| ExpectationFailed Headers.Headers
|
||||||
|
| ImATeapot Headers.Headers
|
||||||
|
| MisdirectedRequest Headers.Headers
|
||||||
|
| UnprocessableEntity Headers.Headers
|
||||||
|
| Locked Headers.Headers
|
||||||
|
| FailedDependency Headers.Headers
|
||||||
|
| UpgradeRequired Headers.Headers
|
||||||
|
| PreconditionRequired Headers.Headers
|
||||||
|
| TooManyRequests Headers.Headers
|
||||||
|
| RequestHeaderFieldsTooLarge Headers.Headers
|
||||||
|
| UnavailableForLegalReasons Headers.Headers
|
||||||
|
|
||||||
|
-- 5xx
|
||||||
|
| InternalServerError Headers.Headers Body.Body
|
||||||
|
| NotImplemented Headers.Headers
|
||||||
|
| BadGateway Headers.Headers
|
||||||
|
| ServiceUnavailable Headers.Headers
|
||||||
|
| GatewayTimeout Headers.Headers
|
||||||
|
| HTTPVersionNotSupported Headers.Headers
|
||||||
|
| VariantAlsoNegotiates Headers.Headers
|
||||||
|
| InsufficientStorage Headers.Headers
|
||||||
|
| LoopDetected Headers.Headers
|
||||||
|
| NotExtended Headers.Headers
|
||||||
|
| NetworkAuthenticationRequired Headers.Headers
|
||||||
|
|
||||||
-- | The ResponseM type simply conveniently wraps up an HTTPure monad that
|
-- | The ResponseM type simply conveniently wraps up an HTTPure monad that
|
||||||
-- | returns a response. This type is the return type of all router/route
|
-- | returns a response. This type is the return type of all router/route
|
||||||
-- | methods.
|
-- | methods.
|
||||||
type ResponseM e = HTTPureM.HTTPureM e Response
|
type ResponseM e = HTTPureM.HTTPureM e Response
|
||||||
|
|
||||||
-- | Send a status, headers, and body to a HTTP response.
|
-- | Get the Status for a Response
|
||||||
send' :: forall e.
|
status :: Response -> Status.Status
|
||||||
HTTP.Response ->
|
status (Response s _ _) = s
|
||||||
Status.Status ->
|
status (Continue _) = 100
|
||||||
Headers.Headers ->
|
status (SwitchingProtocols _) = 101
|
||||||
Maybe.Maybe Body.Body ->
|
status (Processing _) = 102
|
||||||
HTTPureM.HTTPureM e Unit
|
status (OK _ _) = 200
|
||||||
send' response status headers body = do
|
status (Created _) = 201
|
||||||
Status.write response status
|
status (Accepted _) = 202
|
||||||
Headers.write response headers
|
status (NonAuthoritativeInformation _ _) = 203
|
||||||
Body.write response $ Maybe.fromMaybe "" body
|
status (NoContent _) = 204
|
||||||
|
status (ResetContent _) = 205
|
||||||
|
status (PartialContent _ _) = 206
|
||||||
|
status (MultiStatus _ _) = 207
|
||||||
|
status (AlreadyReported _) = 208
|
||||||
|
status (IMUsed _ _) = 226
|
||||||
|
status (MultipleChoices _ _) = 300
|
||||||
|
status (MovedPermanently _ _) = 301
|
||||||
|
status (Found _ _) = 302
|
||||||
|
status (SeeOther _ _) = 303
|
||||||
|
status (NotModified _) = 304
|
||||||
|
status (UseProxy _ _) = 305
|
||||||
|
status (TemporaryRedirect _ _) = 307
|
||||||
|
status (PermanentRedirect _ _) = 308
|
||||||
|
status (BadRequest _ _) = 400
|
||||||
|
status (Unauthorized _) = 401
|
||||||
|
status (PaymentRequired _) = 402
|
||||||
|
status (Forbidden _) = 403
|
||||||
|
status (NotFound _) = 404
|
||||||
|
status (MethodNotAllowed _) = 405
|
||||||
|
status (NotAcceptable _) = 406
|
||||||
|
status (ProxyAuthenticationRequired _) = 407
|
||||||
|
status (RequestTimeout _) = 408
|
||||||
|
status (Conflict _ _) = 409
|
||||||
|
status (Gone _) = 410
|
||||||
|
status (LengthRequired _) = 411
|
||||||
|
status (PreconditionFailed _) = 412
|
||||||
|
status (PayloadTooLarge _) = 413
|
||||||
|
status (URITooLong _) = 414
|
||||||
|
status (UnsupportedMediaType _) = 415
|
||||||
|
status (RangeNotSatisfiable _) = 416
|
||||||
|
status (ExpectationFailed _) = 417
|
||||||
|
status (ImATeapot _) = 418
|
||||||
|
status (MisdirectedRequest _) = 421
|
||||||
|
status (UnprocessableEntity _) = 422
|
||||||
|
status (Locked _) = 423
|
||||||
|
status (FailedDependency _) = 424
|
||||||
|
status (UpgradeRequired _) = 426
|
||||||
|
status (PreconditionRequired _) = 428
|
||||||
|
status (TooManyRequests _) = 429
|
||||||
|
status (RequestHeaderFieldsTooLarge _) = 431
|
||||||
|
status (UnavailableForLegalReasons _) = 451
|
||||||
|
status (InternalServerError _ _) = 500
|
||||||
|
status (NotImplemented _) = 501
|
||||||
|
status (BadGateway _) = 502
|
||||||
|
status (ServiceUnavailable _) = 503
|
||||||
|
status (GatewayTimeout _) = 504
|
||||||
|
status (HTTPVersionNotSupported _) = 505
|
||||||
|
status (VariantAlsoNegotiates _) = 506
|
||||||
|
status (InsufficientStorage _) = 507
|
||||||
|
status (LoopDetected _) = 508
|
||||||
|
status (NotExtended _) = 510
|
||||||
|
status (NetworkAuthenticationRequired _) = 511
|
||||||
|
|
||||||
|
-- | Extract the Headers from a Response
|
||||||
|
headers :: Response -> Headers.Headers
|
||||||
|
headers (Response _ h _) = h
|
||||||
|
headers (Continue h) = h
|
||||||
|
headers (SwitchingProtocols h) = h
|
||||||
|
headers (Processing h) = h
|
||||||
|
headers (OK h _) = h
|
||||||
|
headers (Created h) = h
|
||||||
|
headers (Accepted h) = h
|
||||||
|
headers (NonAuthoritativeInformation h _) = h
|
||||||
|
headers (NoContent h) = h
|
||||||
|
headers (ResetContent h) = h
|
||||||
|
headers (PartialContent h _) = h
|
||||||
|
headers (MultiStatus h _) = h
|
||||||
|
headers (AlreadyReported h) = h
|
||||||
|
headers (IMUsed h _) = h
|
||||||
|
headers (MultipleChoices h _) = h
|
||||||
|
headers (MovedPermanently h _) = h
|
||||||
|
headers (Found h _) = h
|
||||||
|
headers (SeeOther h _) = h
|
||||||
|
headers (NotModified h) = h
|
||||||
|
headers (UseProxy h _) = h
|
||||||
|
headers (TemporaryRedirect h _) = h
|
||||||
|
headers (PermanentRedirect h _) = h
|
||||||
|
headers (BadRequest h _) = h
|
||||||
|
headers (Unauthorized h) = h
|
||||||
|
headers (PaymentRequired h) = h
|
||||||
|
headers (Forbidden h) = h
|
||||||
|
headers (NotFound h) = h
|
||||||
|
headers (MethodNotAllowed h) = h
|
||||||
|
headers (NotAcceptable h) = h
|
||||||
|
headers (ProxyAuthenticationRequired h) = h
|
||||||
|
headers (RequestTimeout h) = h
|
||||||
|
headers (Conflict h _) = h
|
||||||
|
headers (Gone h) = h
|
||||||
|
headers (LengthRequired h) = h
|
||||||
|
headers (PreconditionFailed h) = h
|
||||||
|
headers (PayloadTooLarge h) = h
|
||||||
|
headers (URITooLong h) = h
|
||||||
|
headers (UnsupportedMediaType h) = h
|
||||||
|
headers (RangeNotSatisfiable h) = h
|
||||||
|
headers (ExpectationFailed h) = h
|
||||||
|
headers (ImATeapot h) = h
|
||||||
|
headers (MisdirectedRequest h) = h
|
||||||
|
headers (UnprocessableEntity h) = h
|
||||||
|
headers (Locked h) = h
|
||||||
|
headers (FailedDependency h) = h
|
||||||
|
headers (UpgradeRequired h) = h
|
||||||
|
headers (PreconditionRequired h) = h
|
||||||
|
headers (TooManyRequests h) = h
|
||||||
|
headers (RequestHeaderFieldsTooLarge h) = h
|
||||||
|
headers (UnavailableForLegalReasons h) = h
|
||||||
|
headers (InternalServerError h _) = h
|
||||||
|
headers (NotImplemented h) = h
|
||||||
|
headers (BadGateway h) = h
|
||||||
|
headers (ServiceUnavailable h) = h
|
||||||
|
headers (GatewayTimeout h) = h
|
||||||
|
headers (HTTPVersionNotSupported h) = h
|
||||||
|
headers (VariantAlsoNegotiates h) = h
|
||||||
|
headers (InsufficientStorage h) = h
|
||||||
|
headers (LoopDetected h) = h
|
||||||
|
headers (NotExtended h) = h
|
||||||
|
headers (NetworkAuthenticationRequired h) = h
|
||||||
|
|
||||||
|
-- | Extract the Body from a Response
|
||||||
|
body :: Response -> Body.Body
|
||||||
|
body (Response _ _ b) = b
|
||||||
|
body (OK _ b) = b
|
||||||
|
body (NonAuthoritativeInformation _ b) = b
|
||||||
|
body (PartialContent _ b) = b
|
||||||
|
body (MultiStatus _ b) = b
|
||||||
|
body (IMUsed _ b) = b
|
||||||
|
body (MultipleChoices _ b) = b
|
||||||
|
body (MovedPermanently _ b) = b
|
||||||
|
body (Found _ b) = b
|
||||||
|
body (SeeOther _ b) = b
|
||||||
|
body (UseProxy _ b) = b
|
||||||
|
body (TemporaryRedirect _ b) = b
|
||||||
|
body (PermanentRedirect _ b) = b
|
||||||
|
body (BadRequest _ b) = b
|
||||||
|
body (Conflict _ b) = b
|
||||||
|
body (InternalServerError _ b) = b
|
||||||
|
body _ = ""
|
||||||
|
|
||||||
-- | Given an HTTP response and a HTTPure response, this method will return a
|
-- | Given an HTTP response and a HTTPure response, this method will return a
|
||||||
-- | monad encapsulating writing the HTTPure response to the HTTP response and
|
-- | monad encapsulating writing the HTTPure response to the HTTP response and
|
||||||
-- | closing the HTTP response.
|
-- | closing the HTTP response.
|
||||||
send :: forall e. HTTP.Response -> Response -> HTTPureM.HTTPureM e Unit
|
send :: forall e. HTTP.Response -> Response -> HTTPureM.HTTPureM e Unit
|
||||||
send response (OK headers body) = send' response 200 headers (Maybe.Just body)
|
send httpresponse response = do
|
||||||
|
Status.write httpresponse $ status response
|
||||||
|
Headers.write httpresponse $ headers response
|
||||||
|
Body.write httpresponse $ body response
|
||||||
|
@ -13,25 +13,24 @@ import HTTPure.SpecHelpers ((?=))
|
|||||||
|
|
||||||
sendSpec :: SpecHelpers.Test
|
sendSpec :: SpecHelpers.Test
|
||||||
sendSpec = Spec.describe "send" do
|
sendSpec = Spec.describe "send" do
|
||||||
Spec.describe "with an OK" do
|
Spec.it "writes the headers" do
|
||||||
Spec.it "writes the headers" do
|
header <- EffClass.liftEff do
|
||||||
header <- EffClass.liftEff do
|
resp <- SpecHelpers.mockResponse
|
||||||
resp <- SpecHelpers.mockResponse
|
Response.send resp $ Response.OK (StrMap.singleton "X-Test" "test") ""
|
||||||
Response.send resp $ Response.OK (StrMap.singleton "X-Test" "test") ""
|
pure $ SpecHelpers.getResponseHeader "X-Test" resp
|
||||||
pure $ SpecHelpers.getResponseHeader "X-Test" resp
|
header ?= "test"
|
||||||
header ?= "test"
|
Spec.it "writes the status" do
|
||||||
Spec.it "writes the status" do
|
status <- EffClass.liftEff do
|
||||||
status <- EffClass.liftEff do
|
resp <- SpecHelpers.mockResponse
|
||||||
resp <- SpecHelpers.mockResponse
|
Response.send resp $ Response.Response 465 StrMap.empty ""
|
||||||
Response.send resp $ Response.OK StrMap.empty ""
|
pure $ SpecHelpers.getResponseStatus resp
|
||||||
pure $ SpecHelpers.getResponseStatus resp
|
status ?= 465
|
||||||
status ?= 200
|
Spec.it "writes the body" do
|
||||||
Spec.it "writes the body" do
|
body <- EffClass.liftEff do
|
||||||
body <- EffClass.liftEff do
|
resp <- SpecHelpers.mockResponse
|
||||||
resp <- SpecHelpers.mockResponse
|
Response.send resp $ Response.OK StrMap.empty "test"
|
||||||
Response.send resp $ Response.OK StrMap.empty "test"
|
pure $ SpecHelpers.getResponseBody resp
|
||||||
pure $ SpecHelpers.getResponseBody resp
|
body ?= "test"
|
||||||
body ?= "test"
|
|
||||||
|
|
||||||
responseSpec :: SpecHelpers.Test
|
responseSpec :: SpecHelpers.Test
|
||||||
responseSpec = Spec.describe "Response" do
|
responseSpec = Spec.describe "Response" do
|
||||||
|
Loading…
Reference in New Issue
Block a user