use fastly::http::{header, HeaderValue, Method, StatusCode};
use fastly::{Error, Request, Response};
#[fastly::main]
fn main(req: Request) -> Result<Response, Error> {
if req.get_method() == Method::OPTIONS
&& req.contains_header(header::ORIGIN)
&& (req.contains_header(header::ACCESS_CONTROL_REQUEST_HEADERS)
|| req.contains_header(header::ACCESS_CONTROL_REQUEST_METHOD))
{
Ok(Response::new()
// Standard response to a preflight does not have a
// response body, so a 204 No Content is appropriate,
// though you can also send a 200 OK, that works too.
.with_status(StatusCode::NO_CONTENT)
// Echo the requested origin back to the client. You
// may like to check this against an allowlist of origins
// instead of blindly allowing potentially destructive
// requests from any origin
.with_header(
header::ACCESS_CONTROL_ALLOW_ORIGIN,
req.get_header(header::ORIGIN).unwrap(), // We checked the `Origin` header exists above.
)
.with_header(
header::ACCESS_CONTROL_ALLOW_HEADERS,
req.get_header(header::ACCESS_CONTROL_REQUEST_HEADERS)
.unwrap_or(&HeaderValue::from_str("")?),
)
// Client may use this preflight response to authorise
// future requests that would otherwise also require a
// preflight, so to maximise reuse, we'll list all allowed
// methods here, not just the one that was requested.
// (think carefully before adding 'DELETE' to this list!)
.with_header(
header::ACCESS_CONTROL_ALLOW_METHODS,
"GET,HEAD,POST,OPTIONS",
)
// Setting a cache TTL on the response allows the client
// to use this preflight response for other requests.
.with_header(header::ACCESS_CONTROL_MAX_AGE, "86400"))
} else {
Ok(
Response::from_body("The page you requested could not be found")
.with_status(StatusCode::NOT_FOUND),
)
}
}