7.6.4. HV-04 — Advanced HTTP Server Features
This tutorial covers advanced server capabilities — static file serving, CORS, HTTP redirects, binary responses, custom headers and caching, content-type control, and status codes.
Prerequisites: HV-03 — HTTP Server Basics (basic routes and JSON).
7.6.4.1. Static File Serving
STATIC(server, path, dir) maps a URL prefix to a filesystem
directory. All files under that directory are served with the correct
Content-Type based on their extension.
// After server->init(port) but before server->start():
STATIC(server.server, "/static", "/path/to/public")
Important
STATIC must be called after init() (which registers the
HTTP service with the router) and before start().
Clients can then fetch /static/index.html, /static/style.css,
etc.
7.6.4.2. CORS (Cross-Origin Resource Sharing)
allow_cors() enables CORS headers on all responses. Call it in
onInit:
def override onInit {
allow_cors()
// ... routes ...
}
The server will respond to OPTIONS preflight requests automatically
with Access-Control-Allow-Origin and related headers.
7.6.4.3. HTTP Redirects
REDIRECT(resp, location, status) sends a redirect response:
GET("/old-path") <| @(var req : HttpRequest?; var resp : HttpResponse?) : http_status {
return resp |> REDIRECT("/new-path", http_status.MOVED_PERMANENTLY)
}
Common redirect status codes:
http_status.MOVED_PERMANENTLY(301) — permanent redirect, browsers cache ithttp_status.FOUND(302) — temporary redirect
7.6.4.4. Custom Response Headers and Caching
Use set_header on the response to add cache-control, ETags, and
custom application headers:
GET("/cached") <| @(var req : HttpRequest?; var resp : HttpResponse?) : http_status {
set_header(resp, "Cache-Control", "max-age=3600, public")
set_header(resp, "ETag", "\"v1.0\"")
set_header(resp, "X-Server", "daslang")
return resp |> TEXT_PLAIN("cached response")
}
7.6.4.5. Binary Response
DATA(resp, data, length) sends raw bytes with
Content-Type: application/octet-stream:
GET("/binary") <| @(var req : HttpRequest?; var resp : HttpResponse?) : http_status {
var payload = "BINARY\x00DATA1234"
return resp |> DATA(payload, 16)
}
7.6.4.6. Content-Type and Status Codes
set_content_type(resp, type)
give full control over the response:
// HTML response
GET("/html") <| @(var req : HttpRequest?; var resp : HttpResponse?) : http_status {
set_content_type(resp, "text/html")
resp.body := "<h1>Hello from daslang!</h1>"
return http_status.OK
}
7.6.4.6.1. Non-200 JSON Responses
JSON() and TEXT_PLAIN() accept an optional status parameter
(defaults to http_status.OK):
GET("/not-found") <| @(var req : HttpRequest?; var resp : HttpResponse?) : http_status {
let payload : tuple<error:string; code:int> = ("resource not found", 404)
return resp |> JSON(write_json(JV(payload)), http_status.NOT_FOUND)
}
7.6.4.6.2. 201 Created with Location Header
POST("/items") <| @(var req : HttpRequest?; var resp : HttpResponse?) : http_status {
set_header(resp, "Location", "/items/42")
let payload : tuple<id:int; body:string> = (42, string(req.body))
return resp |> JSON(write_json(JV(payload)), http_status.CREATED)
}
7.6.4.6.3. 204 No Content
POST("/ack") <| @(var req : HttpRequest?; var resp : HttpResponse?) : http_status {
return http_status.NO_CONTENT
}
7.6.4.7. Quick Reference
Function |
Description |
|---|---|
|
Serve static files from directory |
|
Enable CORS headers on all routes |
|
Send 3xx redirect response |
|
JSON response (default 200) |
|
text response (default 200) |
|
Binary response (default 200) |
|
Set response header |
|
Set Content-Type header |
See also
Full source: tutorials/dasHV/04_http_server_advanced.das
Previous tutorial: HV-03 — HTTP Server Basics