src/cors.bend checks
raw source on the hub · import emerging-ezhttp@0.8.0.0/src/cors.bend as Cors
ezhttp/src/cors: Fetch CORS response headers for a simple request and an OPTIONS
preflight. Origins are reflected, or *, and credentials never pair with *.
See https://fetch.spec.whatwg.org/#cors-protocol.
2 imports
import Base import ./http.bend as Http
Types
type Cfg source · line 8 · raw
Data
allow-list for a server. origins of ["*"] allows any origin.
Cfg@origins:List<&2, String> -> @methods:List<&2, String> -> @headers:List<&2, String> -> @credentials:Bool -> @max_age:String -> @expose:List<&2, String> -> Cfg
Definitions
def cors.star.step source · line 19 · raw
@hit:Bool -> @rest:(@_:Unit -> Bool) -> Bool
whether * is one of the allowed origins
def cors.star source · line 27 · raw
@os:List<&2, String> -> Bool
walk origins for *
def cors.hit.step source · line 35 · raw
@hit:Bool -> @rest:(@_:Unit -> Bool) -> Bool
case-sensitive membership
def cors.hit source · line 43 · raw
@+needle:String -> @xs:List<&2, String> -> Bool
whether the needle is in the list
def cors.lower source · line 51 · raw
@xs:List<&2, String> -> List<&2, String>
lowercase a list of names
def cors.hit_ci source · line 59 · raw
@+needle:String -> @xs:List<&2, String> -> Bool
case-insensitive membership (header names, RFC 9110 §5.1)
def cors.allowed source · line 63 · raw
@+os:List<&2, String> -> @origin:String -> Bool
*, or an explicit origin
def cors.acao.star source · line 67 · raw
@origin:String -> @star:Bool -> String
* when every origin is allowed and credentials are off; else the origin
def cors.acao.cred source · line 75 · raw
@+os:List<&2, String> -> @origin:String -> @credentials:Bool -> String
credentials always reflect the origin (Fetch: * cannot be used)
def cors.acao.ok source · line 84 · raw
@+os:List<&2, String> -> @credentials:Bool -> @origin:String -> @ok:Bool -> String
empty when the origin is not allowed
def cors.acao source · line 93 · raw
@+os:List<&2, String> -> @credentials:Bool -> @+origin:String -> String
Access-Control-Allow-Origin value, or "" when the origin is refused
def cors.vary source · line 97 · raw
@+acao:String -> Bool
true when ACAO is a specific origin and Vary: Origin should be set
def cors.names.step source · line 101 · raw
@ok:Bool -> @rest:(@_:Unit -> Bool) -> Bool
every requested header name is allowed. Empty means none were requested.
def cors.names source · line 109 · raw
@ps:List<&2, String> -> @+allow:List<&2, String> -> Bool
requested header names against the allow list
def cors.headers_empty source · line 117 · raw
@+requested:String -> @+allow:List<&2, String> -> @empty:Bool -> Bool
an empty request-header list asks for nothing
def cors.headers_ok source · line 126 · raw
@+requested:String -> @+allow:List<&2, String> -> Bool
Access-Control-Request-Headers, comma-separated
def cors.join source · line 130 · raw
@xs:List<&2, String> -> String
join with ", "
def cors.vary_on source · line 134 · raw
@hs:List<&2, 0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Header> -> @_acao:String -> @vary:Bool -> List<&2, 0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Header>
append Vary when the origin is reflected
def cors.cred_on source · line 143 · raw
@hs:List<&2, 0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Header> -> @credentials:Bool -> List<&2, 0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Header>
append credentials when they are allowed
def cors.preflight_hs source · line 152 · raw
@+acao:String -> @methods:List<&2, String> -> @headers:List<&2, String> -> @credentials:Bool -> @max_age:String -> List<&2, 0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Header>
preflight response headers
def cors.preflight.headers source · line 163 · raw
@acao:String -> @methods:List<&2, String> -> @headers:List<&2, String> -> @credentials:Bool -> @max_age:String -> @_req:String -> @ok:Bool -> 0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Reply
400 when a requested header is not allowed; otherwise 200
def cors.preflight.method source · line 174 · raw
@acao:String -> @methods:List<&2, String> -> @+headers:List<&2, String> -> @credentials:Bool -> @max_age:String -> @+req_headers:String -> @_method:String -> @ok:Bool -> 0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Reply
400 when the method is not allowed
def cors.preflight.denied source · line 185 · raw
@acao:String -> @+methods:List<&2, String> -> @headers:List<&2, String> -> @credentials:Bool -> @max_age:String -> @req_headers:String -> @+method:String -> @denied:Bool -> 0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Reply
skip the method check when the origin was refused
def cors.preflight source · line 196 · raw
@cfg:Cfg -> @origin:String -> @method:String -> @req_headers:String -> 0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Reply
OPTIONS preflight (Fetch CORS). Refused origins and methods are 400.
def cors.expose_of source · line 205 · raw
@hs:List<&2, 0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Header> -> @expose:List<&2, String> -> @empty:Bool -> List<&2, 0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Header>
Access-Control-Expose-Headers when the list is not empty
def cors.expose_on source · line 214 · raw
@hs:List<&2, 0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Header> -> @+expose:List<&2, String> -> List<&2, 0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Header>
Access-Control-Expose-Headers when the list is not empty
def cors.simple_hs source · line 219 · raw
@+acao:String -> @credentials:Bool -> @expose:List<&2, String> -> List<&2, 0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Header>
simple-response CORS headers (ACAO, optional credentials, expose, vary)
def cors.simple.skip source · line 226 · raw
@add:Bool -> @reply:0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Reply -> @hs:List<&2, 0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Header> -> 0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Reply
leave a reply alone when there is nothing to add
def cors.simple.add source · line 237 · raw
@reply:0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Reply -> @acao:String -> @credentials:Bool -> @expose:List<&2, String> -> @add:Bool -> 0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Reply
append CORS headers when the origin is allowed
def cors.simple source · line 242 · raw
@cfg:Cfg -> @origin:String -> @reply:0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Reply -> 0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Reply
a non-preflight response. A missing or refused origin is unchanged.
def cors.origin source · line 250 · raw
@origin:String -> 0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Header
Origin request header
def cors.request_method source · line 254 · raw
@method:String -> 0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Header
Access-Control-Request-Method
def cors.request_headers source · line 258 · raw
@names:String -> 0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Header
Access-Control-Request-Headers
def cors.is_preflight.method source · line 262 · raw
@method:String -> @asked:String -> Bool
OPTIONS with Access-Control-Request-Method is a preflight
def cors.is_preflight source · line 266 · raw
@req:0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Request -> Bool
whether this request is a CORS preflight
def cors.preflight_req source · line 275 · raw
@cfg:Cfg -> @req:0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Request -> 0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Reply
preflight from the request's CORS headers
def cors.simple_req source · line 285 · raw
@cfg:Cfg -> @req:0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Request -> @reply:0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Reply -> 0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Reply
simple CORS from the request Origin
def cors.route source · line 293 · raw
@cfg:Cfg -> @req:0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Request -> @+reply:0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Reply -> @pre:Bool -> 0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Reply
preflight, or CORS headers on the handler reply
def cors.on source · line 302 · raw
@cfg:Cfg -> @+req:0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Request -> @reply:0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Reply -> 0xf1c957a470368870a6d1d62a8c0cbe32/src/http.Reply
answer a request: preflight or simple CORS on top of reply