net/http
HTTP servers and clients: handlers, text and JSON responses, cookies and sending requests.
import net.http
The Salam HTTP server hands requests to a router, and the router calls the handler function. Every handler takes one i64, the context id of the request; you read the request and write the response with the Ctx_... functions, or turn it into a Context struct with Ctx so the names get shorter.
To send a request, Get and Post are the simplest way; Client keeps cookies the way a browser does. The examples run the server with RunBackground on 127.0.0.1 and send requests to it from the same program.
Types
Cookie
struct Cookie| Name | Type | Description |
|---|---|---|
name | str = "" | The name. |
value | str = "" | The value. |
path | str = "/" | The path the cookie is sent for; / by default. |
domain | str = "" | The domain; empty means this host. |
max_age | int = 0 | The lifetime in seconds. |
has_max_age | bool = false | A lifetime was set; without one the cookie goes when the browser closes. |
secure | bool = false | Send it over HTTPS only. |
http_only | bool = true | Keep it out of reach of the page JavaScript; true by default. |
same_site | str = "Lax" | The SameSite policy; Lax by default. |
import net.http
func main:
c := http.NewCookie("theme", "dark")
println c.name, c.value, c.path, c.http_only, c.same_site, c.has_max_age
mut s := http.ExpiringCookie("sid", "x1", 3600)
s.secure = true
s.domain = "salamlang.ir"
println s.max_age, s.has_max_age, s.secure, s.domain
gone := http.ExpiredCookie("sid", "/", "salamlang.ir")
println gone.max_age, gone.has_max_age
println http.UrlDecode("a%20b+c")
endResponse
struct Response| Name | Type | Description |
|---|---|---|
status | int = 0 | The status code. |
body | str = "" | The body. |
head | str = "" | The raw headers. |
err | str = "" | The error message, when the request did not get through. |
import net.http
import net.router
func echo(ctx: i64):
http.Ctx_set_header(ctx, "X-Tag", "a")
http.Ctx_set_cookie(ctx, http.NewCookie("sid", "abc"))
http.Ctx_text(ctx, http.Ctx_method(ctx) + " " + http.Ctx_header(ctx, "X-Token") + " " + http.Ctx_body(ctx))
end
func cookies(ctx: i64):
all := http.Ctx_cookies(ctx)
http.Ctx_text(ctx, "" + all.size() + " " + http.Ctx_cookie(ctx, "lang") + " " + http.Ctx_has_cookie(ctx, "sid"))
http.Ctx_clear_cookie(ctx, "old")
http.Ctx_clear_cookie_at(ctx, "scoped", "/admin", "")
end
func main:
mut r := router.NewRouter()
each method in ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"]:
router.Method(r, method, "/echo", echo)
end
router.Get(r, "/cookies", cookies)
mut s := http.NewServer(19623)
http.Use(s, r)
_ := http.RunBackground(s)
url := "http://127.0.0.1:19623/echo"
mut headers := http.NewHeaders()
headers.insert("X-Token", "t1")
a := http.GetWith(url, headers)
println http.Ok(a), http.Status(a), http.Body(a), "[" + http.Error(a) + "]"
println http.Headers(a).has("X-Tag"), http.HeaderValues(a, "set-cookie")
println http.CookieMap(a).get("sid"), http.RawHeaders(a).len() > 0, http.Raw(a).len() > 0
println http.Body(http.Post(url, "a")), http.Body(http.PutWith(url, "b", headers))
println http.Body(http.Delete(url)), http.Body(http.DeleteWith(url, headers))
println http.Body(http.Patch(url, "c")), http.Body(http.PatchWith(url, "d", headers))
println http.Body(http.Options(url)), http.Body(http.OptionsWith(url, headers))
println http.Status(http.Head(url)), http.Status(http.HeadWith(url, headers))
println http.Body(http.Put(url, "e")), http.Body(http.Get(url))
println http.Body(http.RequestRaw("POST", url, "X-Token: raw\r\n", "f"))
mut params := http.NewHeaders()
params.insert("q", "hello world")
println http.EncodeForm(params), http.WithQuery("http://x.ir/s", params)
mut jar := http.NewHeaders()
jar.insert("lang", "en")
jar.insert("sid", "abc")
headers.insert("Cookie", http.CookieHeader(jar))
b := http.GetWith("http://127.0.0.1:19623/cookies", headers)
println http.Body(b), http.SetCookieLines(b).len()
mut c := http.NewClient()
c.SetCookie("lang", "en")
println http.Body(c.Get("http://127.0.0.1:19623/cookies"))
c.ClearCookies()
mut extra := http.NewHeaders()
extra.insert("X-Token", "c1")
println http.Body(c.RequestWith("PUT", url, "g", extra)), http.Body(c.Request("PATCH", url, "h"))
println http.Body(c.Put(url, "i")), http.Body(c.Delete(url)), http.Body(c.Patch(url, "j")), http.Body(c.Options(url)), http.Status(c.Head(url))
bad := http.Get("http://127.0.0.1:1/")
println http.Ok(bad), http.Error(bad) != ""
endClient
struct Client| Name | Type | Description |
|---|---|---|
cookies | HashMap | The cookies it took from the responses. |
headers | HashMap | The headers sent with every request. |
import net.http
import net.router
func hello(h: i64):
ctx := http.Ctx(h)
name := http.Query(ctx, "name")
if http.HasCookie(ctx, "seen"):
http.Text(ctx, "hello again " + name + " (" + http.CookieValue(ctx, "seen") + ")")
else:
http.SetCookie(ctx, http.ExpiringCookie("seen", "1", 3600))
http.Text(ctx, "hello " + name + " (" + http.RawQuery(ctx) + ")")
end
end
func book(h: i64):
ctx := http.Ctx(h)
http.SetHeader(ctx, "X-Method", http.Method(ctx))
http.SetStatus(ctx, 202)
http.Json(ctx, `{"id": "` + http.Param(ctx, "id") + `", "path": "` + http.Path(ctx) + `"}`)
end
func form(h: i64):
ctx := http.Ctx(h)
http.Text(ctx, http.Form(ctx, "a") + "|" + http.Body(ctx) + "|" + http.Header(ctx, "Content-Type"))
end
func logout(h: i64):
ctx := http.Ctx(h)
http.ClearCookie(ctx, "seen")
http.Redirect(ctx, "/hello")
end
func page(h: i64):
ctx := http.Ctx(h)
cookies := http.Cookies(ctx)
http.Html(ctx, "<p>" + cookies.size() + "</p>")
end
func main:
mut r := router.NewRouter()
router.Get(r, "/hello", hello)
router.Get(r, "/books/:id", book)
router.Post(r, "/form", form)
router.Get(r, "/logout", logout)
router.Get(r, "/page", page)
mut s := http.NewServer(19622)
http.Use(s, r)
_ := http.RunBackground(s)
base := "http://127.0.0.1:19622"
mut c := http.NewClient()
println http.Body(c.Get(base + "/hello?name=Maryam"))
println http.Body(c.Get(base + "/hello?name=Maryam"))
println http.Body(c.Get(base + "/page"))
a := c.Get(base + "/books/7")
println http.Status(a), http.Body(a), http.GetHeader(a, "x-method")
c.SetHeader("Content-Type", "application/x-www-form-urlencoded")
println http.Body(c.Post(base + "/form", "a=1&b=2"))
b := c.Get(base + "/logout")
println http.Status(b), http.SetCookieLines(b).len() > 0
endSetHeader
func SetHeader(name: str, value: str)The example for this item is shown with the ones above: net-http-Context.salam
SetCookie
func SetCookie(name: str, value: str)The example for this item is shown with the ones above: net-http-Client.salam
ClearCookies
func ClearCookies()The example for this item is shown with the ones above: net-http-Client.salam
Request
func Request(method: str, url: str, body: str): ResponseThe example for this item is shown with the ones above: net-http-Client.salam
RequestWith
func RequestWith(method: str, url: str, body: str, extra: HashMap<str, str>): ResponseThe example for this item is shown with the ones above: net-http-Client.salam
Get
func Get(url: str): ResponseThe example for this item is shown with the ones above: net-http-Context.salam
Post
func Post(url: str, body: str): ResponseThe example for this item is shown with the ones above: net-http-Context.salam
Put
func Put(url: str, body: str): ResponseThe example for this item is shown with the ones above: net-http-Client.salam
Delete
func Delete(url: str): ResponseThe example for this item is shown with the ones above: net-http-Client.salam
Patch
func Patch(url: str, body: str): ResponseThe example for this item is shown with the ones above: net-http-Client.salam
Options
func Options(url: str): ResponseThe example for this item is shown with the ones above: net-http-Client.salam
Head
func Head(url: str): ResponseThe example for this item is shown with the ones above: net-http-Client.salam
Context
struct Context| Name | Type | Description |
|---|---|---|
h | i64 | The context id. |
The example for this item is shown with the ones above: net-http-Context.salam
Server
struct Server| Name | Type | Description |
|---|---|---|
port | int = 0 | The port. |
host | str = "0.0.0.0" | The listen address; 0.0.0.0 by default, meaning every address. |
router | router.Router | The router for the requests. |
hide_tokens | bool = false | Hide the server version in the responses. |
access_log | bool = false | Log every request to the output. |
import net.http
import net.router
import net.tcp
func hello(h: i64):
ctx := http.Ctx(h)
conn := http.ConnOf(ctx)
http.Text(ctx, "hello " + tcp.ConnOk(conn))
end
func main:
http.SetKeepAliveIdle(5000)
http.SetKeepAliveMaxRequests(100)
http.SetMaxHeaderBytes(16384)
http.SetMaxBodyBytes(1048576)
mut r := router.NewRouter()
router.Get(r, "/", hello)
mut s := http.NewServer(8080)
http.SetHost(s, "0.0.0.0")
http.HideTokens(s)
http.EnableAccessLog(s)
http.Use(s, r)
println http.SERVER_VERSION, http.IsEdge()
if not http.IsEdge():
http.RunTLS(s, "cert.pem", "key.pem")
end
http.Run(s)
endConstants and variables
SERVER_VERSION
const SERVER_VERSION: str = "0.5.5"Server header of the responses.The example for this item is shown with the ones above: net-http-Server.salam
Functions
Ctx_method
func Ctx_method(h: i64): strimport net.http
import net.router
func home(ctx: i64):
http.Ctx_text(ctx, "hello from the server")
end
func book(ctx: i64):
id := http.Ctx_param(ctx, "id")
format := http.Ctx_query(ctx, "format")
http.Ctx_set_header(ctx, "X-Book", id)
http.Ctx_json(ctx, `{"id": "` + id + `", "format": "` + format + `", "raw": "` + http.Ctx_raw_query(ctx) + `"}`)
end
func create(ctx: i64):
name := http.Ctx_form(ctx, "name")
http.Ctx_status(ctx, 201)
http.Ctx_text(ctx, http.Ctx_method(ctx) + " " + http.Ctx_path(ctx) + " " + name + " " + http.Ctx_header(ctx, "X-Client"))
end
func raw(ctx: i64):
answer := http.Ctx_own(ctx, "body: " + http.Ctx_body(ctx))
http.Ctx_text(ctx, answer)
end
func page(ctx: i64):
http.Ctx_html(ctx, "<h1>hello</h1>")
end
func old(ctx: i64):
http.Ctx_redirect(ctx, "/")
end
func main:
mut r := router.NewRouter()
router.Get(r, "/", home)
router.Get(r, "/books/:id", book)
router.Post(r, "/books", create)
router.Put(r, "/raw", raw)
router.Get(r, "/page", page)
router.Get(r, "/old", old)
mut s := http.NewServer(19621)
http.Use(s, r)
println http.RunBackground(s)
base := "http://127.0.0.1:19621"
a := http.Get(base + "/")
println http.Status(a), http.Body(a)
b := http.Get(base + "/books/42?format=pdf")
println http.Body(b), http.GetHeader(b, "x-book")
mut headers := http.NewHeaders()
headers.insert("Content-Type", "application/x-www-form-urlencoded")
headers.insert("X-Client", "salam")
c := http.PostWith(base + "/books", "name=Maryam", headers)
println http.Status(c), http.Body(c)
println http.Body(http.Put(base + "/raw", "data"))
d := http.Get(base + "/page")
println http.GetHeader(d, "content-type"), http.Body(d)
e := http.Request("GET", base + "/old", http.NewHeaders(), "")
println http.Status(e), http.GetHeader(e, "location")
println http.Status(http.Get(base + "/nope"))
endCtx_path
func Ctx_path(h: i64): strThe example for this item is shown with the ones above: net-http-Handle.salam
Ctx_body
func Ctx_body(h: i64): strThe example for this item is shown with the ones above: net-http-Handle.salam
Ctx_query
func Ctx_query(h: i64, key: str): strThe example for this item is shown with the ones above: net-http-Handle.salam
Ctx_raw_query
func Ctx_raw_query(h: i64): str?, undecoded.The example for this item is shown with the ones above: net-http-Handle.salam
Ctx_header
func Ctx_header(h: i64, name: str): strThe example for this item is shown with the ones above: net-http-Handle.salam
Ctx_param
func Ctx_param(h: i64, name: str): strid in /books/:id.The example for this item is shown with the ones above: net-http-Handle.salam
Ctx_form
func Ctx_form(h: i64, field: str): strapplication/x-www-form-urlencoded body.The example for this item is shown with the ones above: net-http-Handle.salam
Ctx_status
func Ctx_status(h: i64, code: int)The example for this item is shown with the ones above: net-http-Handle.salam
Ctx_set_header
func Ctx_set_header(h: i64, k: str, v: str)The example for this item is shown with the ones above: net-http-Handle.salam
Ctx_html
func Ctx_html(h: i64, html: str)The example for this item is shown with the ones above: net-http-Handle.salam
Ctx_json
func Ctx_json(h: i64, json: str)The example for this item is shown with the ones above: net-http-Handle.salam
Ctx_text
func Ctx_text(h: i64, text: str)The example for this item is shown with the ones above: net-http-Handle.salam
Ctx_own
func Ctx_own(h: i64, s: str): strThe example for this item is shown with the ones above: net-http-Handle.salam
Ctx_redirect
func Ctx_redirect(h: i64, loc: str)The example for this item is shown with the ones above: net-http-Handle.salam
NewCookie
func NewCookie(name: str, value: str): CookieThe example for this item is shown with the ones above: net-http-Client.salam
ExpiringCookie
func ExpiringCookie(name: str, value: str, max_age_seconds: int): CookieThe example for this item is shown with the ones above: net-http-Cookie.salam
ExpiredCookie
func ExpiredCookie(name: str, path: str, domain: str): CookieThe example for this item is shown with the ones above: net-http-Cookie.salam
Ctx_cookies
func Ctx_cookies(h: i64): HashMap<str, str>The example for this item is shown with the ones above: net-http-Client.salam
Ctx_cookie
func Ctx_cookie(h: i64, name: str): strThe example for this item is shown with the ones above: net-http-Client.salam
Ctx_has_cookie
func Ctx_has_cookie(h: i64, name: str): boolThe example for this item is shown with the ones above: net-http-Client.salam
Ctx_set_cookie
func Ctx_set_cookie(h: i64, c: Cookie)The example for this item is shown with the ones above: net-http-Client.salam
Ctx_clear_cookie
func Ctx_clear_cookie(h: i64, name: str)The example for this item is shown with the ones above: net-http-Client.salam
Ctx_clear_cookie_at
func Ctx_clear_cookie_at(h: i64, name: str, path: str, domain: str)The example for this item is shown with the ones above: net-http-Client.salam
UrlDecode
func UrlDecode(s: str): str+ into a space.The example for this item is shown with the ones above: net-http-Cookie.salam
NewServer
func NewServer(port: int): ServerThe example for this item is shown with the ones above: net-http-Handle.salam
Use
func Use(s &: Server, r: router.Router)The example for this item is shown with the ones above: net-http-Handle.salam
HideTokens
func HideTokens(s &: Server)The example for this item is shown with the ones above: net-http-Server.salam
SetHost
func SetHost(s &: Server, host: str)127.0.0.1, for instance, for access from this machine only.The example for this item is shown with the ones above: net-http-Server.salam
EnableAccessLog
func EnableAccessLog(s &: Server)The example for this item is shown with the ones above: net-http-Server.salam
Run
func Run(s: Server)The example for this item is shown with the ones above: net-http-Server.salam
RunBackground
func RunBackground(s: Server): boolThe example for this item is shown with the ones above: net-http-Handle.salam
RunTLS
func RunTLS(s: Server, cert_file: str, key_file: str)The example for this item is shown with the ones above: net-http-Server.salam
IsEdge
func IsEdge(): boolThe example for this item is shown with the ones above: net-http-Server.salam
Ctx
func Ctx(h: i64): ContextContext, so the shorter functions below can be used.The example for this item is shown with the ones above: net-http-Context.salam
Method
func Method(ctx: Context): strThe example for this item is shown with the ones above: net-http-Context.salam
Path
func Path(ctx: Context): strThe example for this item is shown with the ones above: net-http-Context.salam
Body
func Body(ctx: Context): strThe example for this item is shown with the ones above: net-http-Handle.salam
RawQuery
func RawQuery(ctx: Context): str?, exactly as it came and undecoded; for signing a request or passing it on to another service.The example for this item is shown with the ones above: net-http-Context.salam
Query
func Query(ctx: Context, key: str): strThe example for this item is shown with the ones above: net-http-Context.salam
Header
func Header(ctx: Context, name: str): strThe example for this item is shown with the ones above: net-http-Context.salam
Param
func Param(ctx: Context, name: str): strThe example for this item is shown with the ones above: net-http-Context.salam
Form
func Form(ctx: Context, field: str): strThe example for this item is shown with the ones above: net-http-Context.salam
SetStatus
func SetStatus(ctx: Context, code: int)The example for this item is shown with the ones above: net-http-Context.salam
SetHeader
func SetHeader(ctx: Context, k: str, v: str)The example for this item is shown with the ones above: net-http-Context.salam
Html
func Html(ctx: Context, html: str)The example for this item is shown with the ones above: net-http-Context.salam
Json
func Json(ctx: Context, json: str)The example for this item is shown with the ones above: net-http-Context.salam
Text
func Text(ctx: Context, text: str)The example for this item is shown with the ones above: net-http-Context.salam
Redirect
func Redirect(ctx: Context, url: str)The example for this item is shown with the ones above: net-http-Context.salam
Cookies
func Cookies(ctx: Context): HashMap<str, str>The example for this item is shown with the ones above: net-http-Context.salam
CookieValue
func CookieValue(ctx: Context, name: str): strThe example for this item is shown with the ones above: net-http-Context.salam
HasCookie
func HasCookie(ctx: Context, name: str): boolThe example for this item is shown with the ones above: net-http-Context.salam
SetCookie
func SetCookie(ctx: Context, c: Cookie)The example for this item is shown with the ones above: net-http-Context.salam
ClearCookie
func ClearCookie(ctx: Context, name: str)The example for this item is shown with the ones above: net-http-Context.salam
ConnOf
func ConnOf(ctx: Context): tcp.ConnThe example for this item is shown with the ones above: net-http-Server.salam
NewHeaders
func NewHeaders(): HashMap<str, str>The example for this item is shown with the ones above: net-http-Handle.salam
Get
func Get(url: str): ResponseThe example for this item is shown with the ones above: net-http-Handle.salam
Post
func Post(url: str, body: str): ResponseThe example for this item is shown with the ones above: net-http-Client.salam
GetWith
func GetWith(url: str, headers: HashMap<str, str>): ResponseGet, with extra headers.The example for this item is shown with the ones above: net-http-Client.salam
PostWith
func PostWith(url: str, body: str, headers: HashMap<str, str>): ResponsePost, with extra headers.The example for this item is shown with the ones above: net-http-Handle.salam
Request
func Request(method: str, url: str, headers: HashMap<str, str>, body: str): ResponseThe example for this item is shown with the ones above: net-http-Handle.salam
RequestRaw
func RequestRaw(method: str, url: str, header_block: str, body: str): Response\r\n.The example for this item is shown with the ones above: net-http-Client.salam
Ok
func Ok(r: Response): boolThe example for this item is shown with the ones above: net-http-Client.salam
Status
func Status(r: Response): intThe example for this item is shown with the ones above: net-http-Handle.salam
Body
func Body(r: Response): strThe example for this item is shown with the ones above: net-http-Handle.salam
Error
func Error(r: Response): strThe example for this item is shown with the ones above: net-http-Client.salam
Headers
func Headers(r: Response): HashMap<str, str>The example for this item is shown with the ones above: net-http-Client.salam
GetHeader
func GetHeader(r: Response, name: str): strThe example for this item is shown with the ones above: net-http-Handle.salam
Raw
func Raw(r: Response): strThe example for this item is shown with the ones above: net-http-Client.salam
RawHeaders
func RawHeaders(r: Response): strThe example for this item is shown with the ones above: net-http-Client.salam
HeaderValues
func HeaderValues(r: Response, name: str): Vector<str>Set-Cookie.The example for this item is shown with the ones above: net-http-Client.salam
Put
func Put(url: str, body: str): ResponseThe example for this item is shown with the ones above: net-http-Handle.salam
PutWith
func PutWith(url: str, body: str, headers: HashMap<str, str>): ResponsePut, with extra headers.The example for this item is shown with the ones above: net-http-Client.salam
Delete
func Delete(url: str): ResponseThe example for this item is shown with the ones above: net-http-Client.salam
DeleteWith
func DeleteWith(url: str, headers: HashMap<str, str>): ResponseDelete, with extra headers.The example for this item is shown with the ones above: net-http-Client.salam
Patch
func Patch(url: str, body: str): ResponseThe example for this item is shown with the ones above: net-http-Client.salam
PatchWith
func PatchWith(url: str, body: str, headers: HashMap<str, str>): ResponsePatch, with extra headers.The example for this item is shown with the ones above: net-http-Client.salam
Options
func Options(url: str): ResponseThe example for this item is shown with the ones above: net-http-Client.salam
OptionsWith
func OptionsWith(url: str, headers: HashMap<str, str>): ResponseOptions, with extra headers.The example for this item is shown with the ones above: net-http-Client.salam
Head
func Head(url: str): ResponseThe example for this item is shown with the ones above: net-http-Client.salam
HeadWith
func HeadWith(url: str, headers: HashMap<str, str>): ResponseHead, with extra headers.The example for this item is shown with the ones above: net-http-Client.salam
EncodeForm
func EncodeForm(params: HashMap<str, str>): stra=1&b=2, with percent encoding.The example for this item is shown with the ones above: net-http-Client.salam
WithQuery
func WithQuery(base: str, params: HashMap<str, str>): strThe example for this item is shown with the ones above: net-http-Client.salam
SetCookieLines
func SetCookieLines(r: Response): Vector<str>Set-Cookie header of the response.The example for this item is shown with the ones above: net-http-Context.salam
CookieMap
func CookieMap(r: Response): HashMap<str, str>The example for this item is shown with the ones above: net-http-Client.salam
CookieHeader
func CookieHeader(cookies: HashMap<str, str>): strCookie header.The example for this item is shown with the ones above: net-http-Client.salam
NewClient
func NewClient(): ClientThe example for this item is shown with the ones above: net-http-Context.salam
SetKeepAliveIdle
func SetKeepAliveIdle(millis: int)The example for this item is shown with the ones above: net-http-Server.salam
SetMaxHeaderBytes
func SetMaxHeaderBytes(n: int)The example for this item is shown with the ones above: net-http-Server.salam
SetMaxBodyBytes
func SetMaxBodyBytes(n: int)The example for this item is shown with the ones above: net-http-Server.salam
SetKeepAliveMaxRequests
func SetKeepAliveMaxRequests(n: int)The example for this item is shown with the ones above: net-http-Server.salam