class Server
class Server
lib/net/http/server.tya:12
Server is a minimal Sinatra-style HTTP/1.1 server.
Routes are registered with .get / .post / .put / .delete; each handler is a function request -> response_dict. Call .run(port) to start listening. Accepted connections run on the lightweight task scheduler so a handler that yields, for example with time.sleep, does not block other ready clients.
Source
# Server is a minimal Sinatra-style HTTP/1.1 server.
#
# Routes are registered with .get / .post / .put / .delete; each
# handler is a function `request -> response_dict`. Call .run(port)
# to start listening. Accepted connections run on the lightweight task
# scheduler so a handler that yields, for example with time.sleep, does
# not block other ready clients.
class Server
# Server.error_handler stores instance state.
# @type Nil
error_handler: nil
# Server.middlewares stores instance state.
# @type Array
middlewares: []
# Server.named_routes stores instance state.
# @type Dict
named_routes: {}
# Server.not_found_handler stores instance state.
# @type Nil
not_found_handler: nil
# Server.prefix stores instance state.
# @type String
prefix: ""
# Server.routes stores instance state.
# @type Array
routes: []
# Server.initialize provides the net/http/Server standard library operation.
# @return Self the initialized object.
initialize: ->
self.routes = []
self.prefix = ""
self.middlewares = []
self.named_routes = {}
self.not_found_handler = nil
self.error_handler = nil
# Server.child provides the net/http/Server standard library operation.
# @param parent Any parent value.
# @param prefix Any prefix value.
# @return Any the resulting value.
child: parent, prefix ->
child = Server()
child.routes = parent.routes
child.prefix = self.join_paths(parent.prefix, prefix)
child.middlewares = self.copy_array(parent.middlewares)
child.named_routes = parent.named_routes
child.not_found_handler = parent.not_found_handler
child.error_handler = parent.error_handler
return child
# Server.get provides the net/http/Server standard library operation.
# get registers a GET route and returns the server.
# @param path String path value.
# @param handler Any handler value.
# @param options Dict options value.
# @return Any the resulting value.
get: path, handler, options ->
return self.route("GET", path, handler, options)
# Server.post provides the net/http/Server standard library operation.
# post registers a POST route and returns the server.
# @param path String path value.
# @param handler Any handler value.
# @param options Dict options value.
# @return Any the resulting value.
post: path, handler, options ->
return self.route("POST", path, handler, options)
# Server.put provides the net/http/Server standard library operation.
# @param path String path value.
# @param handler Any handler value.
# @param options Dict options value.
# @return Any the resulting value.
put: path, handler, options ->
return self.route("PUT", path, handler, options)
# Server.delete provides the net/http/Server standard library operation.
# @param path String path value.
# @param handler Any handler value.
# @param options Dict options value.
# @return Any the resulting value.
delete: path, handler, options ->
return self.route("DELETE", path, handler, options)
# Server.patch provides the net/http/Server standard library operation.
# @param path String path value.
# @param handler Any handler value.
# @param options Dict options value.
# @return Any the resulting value.
patch: path, handler, options ->
return self.route("PATCH", path, handler, options)
# Server.options provides the net/http/Server standard library operation.
# @param path String path value.
# @param handler Any handler value.
# @param options Dict options value.
# @return Dict the resulting value.
options: path, handler, options ->
return self.route("OPTIONS", path, handler, options)
# Server.head provides the net/http/Server standard library operation.
# @param path String path value.
# @param handler Any handler value.
# @param options Dict options value.
# @return Any the resulting value.
head: path, handler, options ->
return self.route("HEAD", path, handler, options)
# Server.any provides the net/http/Server standard library operation.
# @param path String path value.
# @param handler Any handler value.
# @param options Dict options value.
# @return Any the resulting value.
any: path, handler, options ->
return self.route("ANY", path, handler, options)
# Server.route provides the net/http/Server standard library operation.
# route registers a handler for method and path.
# Raises when the path pattern or route options are invalid.
# @param method String method value.
# @param path String path value.
# @param handler Any handler value.
# @param options Dict options value.
# @return Any the resulting value.
route: method, path, handler, options ->
opts = self.route_options(options)
full_path = self.join_paths(self.prefix, path)
self.validate_pattern(full_path)
route = { method: method.upper(), path: full_path, handler: handler, middlewares: self.copy_array(self.middlewares), trailing_slash: opts["trailing_slash"], name: opts["name"] }
self.routes.push(route)
if opts["name"] != nil
self.named_routes[opts["name"]] = route
return self
# Server.use provides the net/http/Server standard library operation.
# @param middleware Any middleware value.
# @return Any the resulting value.
use: middleware ->
self.middlewares.push(middleware)
return self
# Server.group provides the net/http/Server standard library operation.
# @param prefix Any prefix value.
# @param fn Function fn value.
# @return Any the resulting value.
group: prefix, fn ->
child = self.child(self, prefix)
fn(child)
return self
# Server.not_found provides the net/http/Server standard library operation.
# @param handler Any handler value.
# @return Any the resulting value.
not_found: handler ->
self.not_found_handler = handler
self.routes.push({ method: "__NOT_FOUND__", path: "*", handler: handler })
return self
# Server.error provides the net/http/Server standard library operation.
# @param handler Any handler value.
# @return Any the resulting value.
error: handler ->
self.error_handler = handler
self.routes.push({ method: "__ERROR__", path: "*", handler: handler })
return self
# Server.path provides the net/http/Server standard library operation.
# @param name String name value.
# @param params Any params value.
# @return String the resulting value.
path: name, params ->
route = self.named_routes.get(name, nil)
if route == nil
raise error("http.path: unknown route " + name)
return self.build_path(route["path"], params)
# Server.redirect provides the net/http/Server standard library operation.
# redirect returns a response dictionary with Location set.
# Raises when status is not a supported redirect status.
# @param path String path value.
# @param status Any status value.
# @return Any the resulting value.
redirect: path, status ->
if status == nil
status = 302
if status != 301 and status != 302 and status != 303 and status != 307 and status != 308
raise error("http.redirect: unsupported redirect status")
headers = {}
headers["Location"] = path
return { status: status, headers: headers, body: "" }
# render returns an HTML response by rendering a template file or source string.
# @param tmpl Any tmpl value.
# @param data Array data value.
# @param options Dict options value.
# @return Any the resulting value.
render: tmpl, data, options ->
return self.render_with_mode(tmpl, data, options, false)
# render_html returns an HTML response and forces HTML escaping.
# @param tmpl Any tmpl value.
# @param data Array data value.
# @param options Dict options value.
# @return Any the resulting value.
render_html: tmpl, data, options ->
return self.render_with_mode(tmpl, data, options, true)
# render_with_mode builds an HTML response from a template source.
# @param tmpl Any tmpl value.
# @param data Array data value.
# @param options Dict options value.
# @param html Any html value.
# @return Any the resulting value.
render_with_mode: tmpl, data, options, html ->
if options == nil
options = {}
headers = {}
headers["Content-Type"] = options.get("content_type", "text/html; charset=utf-8")
extra = options.get("headers", nil)
if extra != nil
keys = extra.keys()
i = 0
while i < keys.len()
headers[keys[i]] = extra[keys[i]]
i = i + 1
template_options = options.get("template_options", {})
if html
template_options["escape"] = "html"
source = tmpl
if tmpl.class != String
source = bytes.Bytes(tmpl).to_text()
body = ""
if tmpl.class == String and file.File(tmpl).exists?()
body = template.Template(tmpl).render_file(data, template_options)
else
body = template.Template(source).render(data, template_options)
return { status: options.get("status", 200), headers: headers, body: body }
# cookie returns a validated Set-Cookie header value.
# Options may include path, domain, max_age, expires, secure, http_only, and same_site.
# @param name String name value.
# @param value String value value.
# @param options Dict options value.
# @return Any the resulting value.
cookie: name, value, options ->
return self.cookie_value(name, value, options)
# with_cookie appends a Set-Cookie header value to response and returns response.
# @param response Any response value.
# @param name String name value.
# @param value String value value.
# @param options Dict options value.
# @return Any the resulting value.
with_cookie: response, name, value, options ->
if response["header_values"] == nil
response["header_values"] = {}
if response["header_values"]["Set-Cookie"] == nil
response["header_values"]["Set-Cookie"] = []
response["header_values"]["Set-Cookie"].push(self.cookie_value(name, value, options))
return response
# Server.dispatch provides the net/http/Server standard library operation.
# @param method String method value.
# @param path String path value.
# @return Any the resulting value.
dispatch: method, path ->
method = method.upper()
route = self.find_route(method, path)
if route == nil and method == "HEAD"
route = self.find_route("GET", path)
if route != nil
resp = self.call_route(route, method, path)
resp["body"] = ""
return resp
if route == nil and method == "OPTIONS"
allow = self.allow_for(path)
if allow != ""
headers = {}
headers["Allow"] = allow
return { status: 204, headers: headers, body: "" }
if route == nil
if self.not_found_handler != nil
return self.not_found_handler({ method: method, path: path, params: {}, path_params: {}, query: {}, headers: {}, body: b"" })
return { status: 404, body: "Not Found" }
return self.call_route(route, method, path)
# Server.call_route provides the net/http/Server standard library operation.
# @param route Any route value.
# @param method String method value.
# @param path String path value.
# @return Any the resulting value.
call_route: route, method, path ->
params = self.match_params(route, path)
req = { method: method, path: path, params: params, path_params: params, query: {}, headers: {}, body: b"", route: route }
next = Next(route["middlewares"], 0, route["handler"])
result = nil
try
result = next.call(req)
catch err
if self.error_handler != nil
return self.error_handler(err, req)
return { status: 500, body: "Internal Server Error" }
return result
# Server.find_route provides the net/http/Server standard library operation.
# @param method String method value.
# @param path String path value.
# @return Any the resulting value.
find_route: method, path ->
i = 0
while i < self.routes.len()
route = self.routes[i]
if (route["method"] == method or route["method"] == "ANY") and self.match_params(route, path) != nil
return route
i = i + 1
return nil
# Server.allow_for provides the net/http/Server standard library operation.
# @param path String path value.
# @return Any the resulting value.
allow_for: path ->
methods = []
i = 0
while i < self.routes.len()
route = self.routes[i]
if route["method"] != "__NOT_FOUND__" and route["method"] != "__ERROR__" and self.match_params(route, path) != nil
method = route["method"]
if method == "ANY"
method = "GET,POST,PUT,DELETE,PATCH,OPTIONS,HEAD"
if not self.array_has?(methods, method)
methods.push(method)
if method == "GET" and not self.array_has?(methods, "HEAD")
methods.push("HEAD")
i = i + 1
return methods.join(", ")
# Server.static provides the net/http/Server standard library operation.
# @param prefix Any prefix value.
# @param assets Any assets value.
# @return Any the resulting value.
serve_static: prefix, assets ->
for entry in assets.entries()
path = entry[0]
asset = entry[1]
if asset.class == Dict
self.static_one(prefix, path, asset, false)
hashed = asset["hashed_path"]
if hashed != nil and hashed != path
self.static_one(prefix, hashed, asset, true)
else
self.static_one(prefix, path, asset, false)
self
# Server.static_one provides the net/http/Server standard library operation.
# @param prefix Any prefix value.
# @param path String path value.
# @param asset Any asset value.
# @param hashed_route Any hashed route value.
# @return Any the resulting value.
static_one: prefix, path, asset, hashed_route ->
self.routes.push({
method: "GET",
path: prefix + "/" + path,
static_asset: asset,
static_hashed: hashed_route,
middlewares: [],
trailing_slash: "strict"
})
# Server.content_type provides the net/http/Server standard library operation.
# @param path String path value.
# @return Any the resulting value.
content_type: path ->
if path.ends_with(".html")
return "text/html; charset=utf-8"
if path.ends_with(".css")
return "text/css; charset=utf-8"
if path.ends_with(".js")
return "application/javascript; charset=utf-8"
if path.ends_with(".json")
return "application/json"
if path.ends_with(".svg")
return "image/svg+xml"
return "application/octet-stream"
# run binds `port` (0 = OS picks a free port) and enters the
# accept loop. Blocks forever; the only ways out are a fatal
# error or SIGINT.
# @param port Any port value.
# @return Any the resulting value.
run: port ->
http_server_run(self.routes, port)
# run_tls starts an HTTPS server with a PEM certificate and private key.
# @param port Any port value.
# @param cert_file Any cert file value.
# @param key_file Any key file value.
# @param options Dict options value.
# @return Any the resulting value.
run_tls: port, cert_file, key_file, options ->
if options == nil
options = {}
http_server_run_tls(self.routes, port, cert_file, key_file, options)
# Server.route_options provides the net/http/Server standard library operation.
# @param options Dict options value.
# @return Dict the resulting value.
route_options: options ->
opts = { trailing_slash: "strict", name: nil }
if options == nil
return opts
keys = options.keys()
i = 0
while i < keys.len()
key = keys[i]
if key != "trailing_slash" and key != "name"
raise error("http.route: unknown option " + key)
opts[key] = options[key]
i = i + 1
if opts["trailing_slash"] != "strict" and opts["trailing_slash"] != "ignore"
raise error("http.route: invalid trailing_slash option")
return opts
# cookie_value formats a Set-Cookie header value.
# @param name String name value.
# @param value String value value.
# @param options Dict options value.
# @return Any the resulting value.
cookie_value: name, value, options ->
self.validate_cookie_name(name)
self.validate_cookie_value(value)
if options == nil
options = {}
out = name + "=" + value
if options.get("path", nil) != nil
out = out + "; Path=" + options["path"].to_s()
if options.get("domain", nil) != nil
out = out + "; Domain=" + options["domain"].to_s()
if options.get("max_age", nil) != nil
out = out + "; Max-Age=" + options["max_age"].to_s()
if options.get("expires", nil) != nil
out = out + "; Expires=" + options["expires"].to_s()
if options.get("secure", false)
out = out + "; Secure"
if options.get("http_only", false)
out = out + "; HttpOnly"
same_site = options.get("same_site", nil)
if same_site != nil
if same_site != "Lax" and same_site != "Strict" and same_site != "None"
raise error("http.cookie: unsupported SameSite")
if same_site == "None" and not options.get("secure", false)
raise error("http.cookie: SameSite=None requires Secure")
out = out + "; SameSite=" + same_site
return out
# validate_cookie_name raises when name is not a valid cookie name.
# @param name String name value.
# @return Boolean the resulting value.
validate_cookie_name: name ->
if name == nil or name == ""
raise error("http.cookie: invalid cookie name")
i = 0
while i < name.byte_len()
c = name[i]
code = ord(c)
if code < 32 or code == 127 or c == " " or c == "=" or c == ";" or c == ","
raise error("http.cookie: invalid cookie name")
i = i + 1
# validate_cookie_value raises when value cannot be used in a cookie.
# @param value String value value.
# @return Boolean the resulting value.
validate_cookie_value: value ->
if value == nil
raise error("http.cookie: invalid cookie value")
i = 0
while i < value.byte_len()
c = value[i]
code = ord(c)
if code < 32 or code == 127 or c == ";" or c == ","
raise error("http.cookie: invalid cookie value")
i = i + 1
# Server.validate_pattern provides the net/http/Server standard library operation.
# @param path String path value.
# @return Boolean the resulting value.
validate_pattern: path ->
if not path.starts_with("/")
raise error("http.route: path must start with /")
names = []
parts = path.split("/")
i = 0
while i < parts.len()
part = parts[i]
if part.starts_with("*") and i != parts.len() - 1
raise error("http.route: wildcard must be final segment")
if part.starts_with(":") or part.starts_with("*")
name = part.slice(1, part.len())
if name == "" or self.array_has?(names, name)
raise error("http.route: duplicate or empty parameter " + name)
names.push(name)
i = i + 1
# Server.match_params provides the net/http/Server standard library operation.
# @param route Any route value.
# @param path String path value.
# @return Any the resulting value.
match_params: route, path ->
pattern = route["path"]
if route.get("trailing_slash", "strict") == "ignore"
pattern = self.strip_trailing(pattern)
path = self.strip_trailing(path)
p = pattern.split("/")
r = path.split("/")
params = {}
i = 0
while i < p.len()
part = p[i]
if part.starts_with("*")
name = part.slice(1, part.len())
rest = []
j = i
while j < r.len()
rest.push(r[j])
j = j + 1
params[name] = rest.join("/")
return params
if i >= r.len()
return nil
if part.starts_with(":")
params[part.slice(1, part.len())] = r[i]
elseif part != r[i]
return nil
i = i + 1
if i != r.len()
return nil
return params
# Server.build_path provides the net/http/Server standard library operation.
# @param pattern String pattern value.
# @param params Any params value.
# @return String the resulting value.
build_path: pattern, params ->
out = []
parts = pattern.split("/")
i = 0
while i < parts.len()
part = parts[i]
if part.starts_with(":") or part.starts_with("*")
name = part.slice(1, part.len())
if params == nil or not params.has?(name)
raise error("http.path: missing param " + name)
out.push(params[name])
else
out.push(part)
i = i + 1
result = out.join("/")
if result == ""
return "/"
return result
# Server.join_paths provides the net/http/Server standard library operation.
# @param prefix Any prefix value.
# @param path String path value.
# @return String the resulting value.
join_paths: prefix, path ->
if prefix == nil or prefix == ""
if path == ""
return "/"
return path
if path == nil or path == "" or path == "/"
return prefix
return self.strip_trailing(prefix) + "/" + self.strip_leading(path)
# Server.strip_trailing provides the net/http/Server standard library operation.
# @param path String path value.
# @return Any the resulting value.
strip_trailing: path ->
while path.byte_len() > 1 and path.ends_with("/")
path = path.slice(0, path.len() - 1)
return path
# Server.strip_leading provides the net/http/Server standard library operation.
# @param path String path value.
# @return Any the resulting value.
strip_leading: path ->
while path.byte_len() > 0 and path.starts_with("/")
path = path.slice(1, path.len())
return path
# Server.copy_array provides the net/http/Server standard library operation.
# @param values Array values value.
# @return Array the resulting value.
copy_array: values ->
out = []
i = 0
while i < values.len()
out.push(values[i])
i = i + 1
return out
# Server.array_has? provides the net/http/Server standard library operation.
# @param values Array values value.
# @param value String value value.
# @return Boolean whether the condition is true.
array_has?: values, value ->
i = 0
while i < values.len()
if values[i] == value
return true
i = i + 1
return false
Instance Variables
error_handler
Server.error_handler
lib/net/http/server.tya:15
Server.error_handler stores instance state.
Source
# Server.error_handler stores instance state.
# @type Nil
error_handler: nil
middlewares
Server.middlewares
lib/net/http/server.tya:19
Server.middlewares stores instance state.
Source
# Server.middlewares stores instance state.
# @type Array
middlewares: []
named_routes
Server.named_routes
lib/net/http/server.tya:23
Server.named_routes stores instance state.
Source
# Server.named_routes stores instance state.
# @type Dict
named_routes: {}
not_found_handler
Server.not_found_handler
lib/net/http/server.tya:27
Server.not_found_handler stores instance state.
Source
# Server.not_found_handler stores instance state.
# @type Nil
not_found_handler: nil
prefix
Server.prefix
lib/net/http/server.tya:31
Server.prefix stores instance state.
Source
# Server.prefix stores instance state.
# @type String
prefix: ""
routes
Server.routes
lib/net/http/server.tya:35
Server.routes stores instance state.
Source
# Server.routes stores instance state.
# @type Array
routes: []
Methods
allow_for
Server.allow_for(path)
lib/net/http/server.tya:331
Server.allow_for provides the net/http/Server standard library operation.
Source
# Server.allow_for provides the net/http/Server standard library operation.
# @param path String path value.
# @return Any the resulting value.
allow_for: path ->
methods = []
i = 0
while i < self.routes.len()
route = self.routes[i]
if route["method"] != "__NOT_FOUND__" and route["method"] != "__ERROR__" and self.match_params(route, path) != nil
method = route["method"]
if method == "ANY"
method = "GET,POST,PUT,DELETE,PATCH,OPTIONS,HEAD"
if not self.array_has?(methods, method)
methods.push(method)
if method == "GET" and not self.array_has?(methods, "HEAD")
methods.push("HEAD")
i = i + 1
return methods.join(", ")
any
Server.any(path, handler, options)
lib/net/http/server.tya:124
Server.any provides the net/http/Server standard library operation.
Source
# Server.any provides the net/http/Server standard library operation.
# @param path String path value.
# @param handler Any handler value.
# @param options Dict options value.
# @return Any the resulting value.
any: path, handler, options ->
return self.route("ANY", path, handler, options)
array_has?
Server.array_has?(values, value)
lib/net/http/server.tya:616
Server.array_has? provides the net/http/Server standard library operation.
Source
# Server.array_has? provides the net/http/Server standard library operation.
# @param values Array values value.
# @param value String value value.
# @return Boolean whether the condition is true.
array_has?: values, value ->
i = 0
while i < values.len()
if values[i] == value
return true
i = i + 1
return false
build_path
Server.build_path(pattern, params)
lib/net/http/server.tya:553
Server.build_path provides the net/http/Server standard library operation.
Source
# Server.build_path provides the net/http/Server standard library operation.
# @param pattern String pattern value.
# @param params Any params value.
# @return String the resulting value.
build_path: pattern, params ->
out = []
parts = pattern.split("/")
i = 0
while i < parts.len()
part = parts[i]
if part.starts_with(":") or part.starts_with("*")
name = part.slice(1, part.len())
if params == nil or not params.has?(name)
raise error("http.path: missing param " + name)
out.push(params[name])
else
out.push(part)
i = i + 1
result = out.join("/")
if result == ""
return "/"
return result
call_route
Server.call_route(route, method, path)
lib/net/http/server.tya:302
Server.call_route provides the net/http/Server standard library operation.
Source
# Server.call_route provides the net/http/Server standard library operation.
# @param route Any route value.
# @param method String method value.
# @param path String path value.
# @return Any the resulting value.
call_route: route, method, path ->
params = self.match_params(route, path)
req = { method: method, path: path, params: params, path_params: params, query: {}, headers: {}, body: b"", route: route }
next = Next(route["middlewares"], 0, route["handler"])
result = nil
try
result = next.call(req)
catch err
if self.error_handler != nil
return self.error_handler(err, req)
return { status: 500, body: "Internal Server Error" }
return result
child
Server.child(parent, prefix)
lib/net/http/server.tya:51
Server.child provides the net/http/Server standard library operation.
Source
# Server.child provides the net/http/Server standard library operation.
# @param parent Any parent value.
# @param prefix Any prefix value.
# @return Any the resulting value.
child: parent, prefix ->
child = Server()
child.routes = parent.routes
child.prefix = self.join_paths(parent.prefix, prefix)
child.middlewares = self.copy_array(parent.middlewares)
child.named_routes = parent.named_routes
child.not_found_handler = parent.not_found_handler
child.error_handler = parent.error_handler
return child
content_type
Server.content_type(path)
lib/net/http/server.tya:383
Server.content_type provides the net/http/Server standard library operation.
Source
# Server.content_type provides the net/http/Server standard library operation.
# @param path String path value.
# @return Any the resulting value.
content_type: path ->
if path.ends_with(".html")
return "text/html; charset=utf-8"
if path.ends_with(".css")
return "text/css; charset=utf-8"
if path.ends_with(".js")
return "application/javascript; charset=utf-8"
if path.ends_with(".json")
return "application/json"
if path.ends_with(".svg")
return "image/svg+xml"
return "application/octet-stream"
copy_array
Server.copy_array(values)
lib/net/http/server.tya:604
Server.copy_array provides the net/http/Server standard library operation.
Source
# Server.copy_array provides the net/http/Server standard library operation.
# @param values Array values value.
# @return Array the resulting value.
copy_array: values ->
out = []
i = 0
while i < values.len()
out.push(values[i])
i = i + 1
return out
delete
Server.delete(path, handler, options)
lib/net/http/server.tya:92
Server.delete provides the net/http/Server standard library operation.
Source
# Server.delete provides the net/http/Server standard library operation.
# @param path String path value.
# @param handler Any handler value.
# @param options Dict options value.
# @return Any the resulting value.
delete: path, handler, options ->
return self.route("DELETE", path, handler, options)
dispatch
Server.dispatch(method, path)
lib/net/http/server.tya:276
Server.dispatch provides the net/http/Server standard library operation.
Source
# Server.dispatch provides the net/http/Server standard library operation.
# @param method String method value.
# @param path String path value.
# @return Any the resulting value.
dispatch: method, path ->
method = method.upper()
route = self.find_route(method, path)
if route == nil and method == "HEAD"
route = self.find_route("GET", path)
if route != nil
resp = self.call_route(route, method, path)
resp["body"] = ""
return resp
if route == nil and method == "OPTIONS"
allow = self.allow_for(path)
if allow != ""
headers = {}
headers["Allow"] = allow
return { status: 204, headers: headers, body: "" }
if route == nil
if self.not_found_handler != nil
return self.not_found_handler({ method: method, path: path, params: {}, path_params: {}, query: {}, headers: {}, body: b"" })
return { status: 404, body: "Not Found" }
return self.call_route(route, method, path)
error
Server.error(handler)
lib/net/http/server.tya:172
Server.error provides the net/http/Server standard library operation.
Source
# Server.error provides the net/http/Server standard library operation.
# @param handler Any handler value.
# @return Any the resulting value.
error: handler ->
self.error_handler = handler
self.routes.push({ method: "__ERROR__", path: "*", handler: handler })
return self
find_route
Server.find_route(method, path)
lib/net/http/server.tya:319
Server.find_route provides the net/http/Server standard library operation.
Source
# Server.find_route provides the net/http/Server standard library operation.
# @param method String method value.
# @param path String path value.
# @return Any the resulting value.
find_route: method, path ->
i = 0
while i < self.routes.len()
route = self.routes[i]
if (route["method"] == method or route["method"] == "ANY") and self.match_params(route, path) != nil
return route
i = i + 1
return nil
get
Server.get(path, handler, options)
lib/net/http/server.tya:67
Server.get provides the net/http/Server standard library operation. get registers a GET route and returns the server.
Source
# Server.get provides the net/http/Server standard library operation.
# get registers a GET route and returns the server.
# @param path String path value.
# @param handler Any handler value.
# @param options Dict options value.
# @return Any the resulting value.
get: path, handler, options ->
return self.route("GET", path, handler, options)
group
Server.group(prefix, fn)
lib/net/http/server.tya:156
Server.group provides the net/http/Server standard library operation.
Source
# Server.group provides the net/http/Server standard library operation.
# @param prefix Any prefix value.
# @param fn Function fn value.
# @return Any the resulting value.
group: prefix, fn ->
child = self.child(self, prefix)
fn(child)
return self
head
Server.head(path, handler, options)
lib/net/http/server.tya:116
Server.head provides the net/http/Server standard library operation.
Source
# Server.head provides the net/http/Server standard library operation.
# @param path String path value.
# @param handler Any handler value.
# @param options Dict options value.
# @return Any the resulting value.
head: path, handler, options ->
return self.route("HEAD", path, handler, options)
initialize
Server.initialize()
lib/net/http/server.tya:39
Server.initialize provides the net/http/Server standard library operation.
Source
# Server.initialize provides the net/http/Server standard library operation.
# @return Self the initialized object.
initialize: ->
self.routes = []
self.prefix = ""
self.middlewares = []
self.named_routes = {}
self.not_found_handler = nil
self.error_handler = nil
join_paths
Server.join_paths(prefix, path)
lib/net/http/server.tya:576
Server.join_paths provides the net/http/Server standard library operation.
Source
# Server.join_paths provides the net/http/Server standard library operation.
# @param prefix Any prefix value.
# @param path String path value.
# @return String the resulting value.
join_paths: prefix, path ->
if prefix == nil or prefix == ""
if path == ""
return "/"
return path
if path == nil or path == "" or path == "/"
return prefix
return self.strip_trailing(prefix) + "/" + self.strip_leading(path)
match_params
Server.match_params(route, path)
lib/net/http/server.tya:518
Server.match_params provides the net/http/Server standard library operation.
Source
# Server.match_params provides the net/http/Server standard library operation.
# @param route Any route value.
# @param path String path value.
# @return Any the resulting value.
match_params: route, path ->
pattern = route["path"]
if route.get("trailing_slash", "strict") == "ignore"
pattern = self.strip_trailing(pattern)
path = self.strip_trailing(path)
p = pattern.split("/")
r = path.split("/")
params = {}
i = 0
while i < p.len()
part = p[i]
if part.starts_with("*")
name = part.slice(1, part.len())
rest = []
j = i
while j < r.len()
rest.push(r[j])
j = j + 1
params[name] = rest.join("/")
return params
if i >= r.len()
return nil
if part.starts_with(":")
params[part.slice(1, part.len())] = r[i]
elseif part != r[i]
return nil
i = i + 1
if i != r.len()
return nil
return params
not_found
Server.not_found(handler)
lib/net/http/server.tya:164
Server.not_found provides the net/http/Server standard library operation.
Source
# Server.not_found provides the net/http/Server standard library operation.
# @param handler Any handler value.
# @return Any the resulting value.
not_found: handler ->
self.not_found_handler = handler
self.routes.push({ method: "__NOT_FOUND__", path: "*", handler: handler })
return self
options
Server.options(path, handler, options)
lib/net/http/server.tya:108
Server.options provides the net/http/Server standard library operation.
Source
# Server.options provides the net/http/Server standard library operation.
# @param path String path value.
# @param handler Any handler value.
# @param options Dict options value.
# @return Dict the resulting value.
options: path, handler, options ->
return self.route("OPTIONS", path, handler, options)
patch
Server.patch(path, handler, options)
lib/net/http/server.tya:100
Server.patch provides the net/http/Server standard library operation.
Source
# Server.patch provides the net/http/Server standard library operation.
# @param path String path value.
# @param handler Any handler value.
# @param options Dict options value.
# @return Any the resulting value.
patch: path, handler, options ->
return self.route("PATCH", path, handler, options)
path
Server.path(name, params)
lib/net/http/server.tya:181
Server.path provides the net/http/Server standard library operation.
Source
# Server.path provides the net/http/Server standard library operation.
# @param name String name value.
# @param params Any params value.
# @return String the resulting value.
path: name, params ->
route = self.named_routes.get(name, nil)
if route == nil
raise error("http.path: unknown route " + name)
return self.build_path(route["path"], params)
post
Server.post(path, handler, options)
lib/net/http/server.tya:76
Server.post provides the net/http/Server standard library operation. post registers a POST route and returns the server.
Source
# Server.post provides the net/http/Server standard library operation.
# post registers a POST route and returns the server.
# @param path String path value.
# @param handler Any handler value.
# @param options Dict options value.
# @return Any the resulting value.
post: path, handler, options ->
return self.route("POST", path, handler, options)
put
Server.put(path, handler, options)
lib/net/http/server.tya:84
Server.put provides the net/http/Server standard library operation.
Source
# Server.put provides the net/http/Server standard library operation.
# @param path String path value.
# @param handler Any handler value.
# @param options Dict options value.
# @return Any the resulting value.
put: path, handler, options ->
return self.route("PUT", path, handler, options)
redirect
Server.redirect(path, status)
lib/net/http/server.tya:193
Server.redirect provides the net/http/Server standard library operation. redirect returns a response dictionary with Location set. Raises when status is not a supported redirect status.
Source
# Server.redirect provides the net/http/Server standard library operation.
# redirect returns a response dictionary with Location set.
# Raises when status is not a supported redirect status.
# @param path String path value.
# @param status Any status value.
# @return Any the resulting value.
redirect: path, status ->
if status == nil
status = 302
if status != 301 and status != 302 and status != 303 and status != 307 and status != 308
raise error("http.redirect: unsupported redirect status")
headers = {}
headers["Location"] = path
return { status: status, headers: headers, body: "" }
render
Server.render(tmpl, data, options)
lib/net/http/server.tya:207
render returns an HTML response by rendering a template file or source string.
Source
# render returns an HTML response by rendering a template file or source string.
# @param tmpl Any tmpl value.
# @param data Array data value.
# @param options Dict options value.
# @return Any the resulting value.
render: tmpl, data, options ->
return self.render_with_mode(tmpl, data, options, false)
render_html
Server.render_html(tmpl, data, options)
lib/net/http/server.tya:215
render_html returns an HTML response and forces HTML escaping.
Source
# render_html returns an HTML response and forces HTML escaping.
# @param tmpl Any tmpl value.
# @param data Array data value.
# @param options Dict options value.
# @return Any the resulting value.
render_html: tmpl, data, options ->
return self.render_with_mode(tmpl, data, options, true)
render_with_mode
Server.render_with_mode(tmpl, data, options, html)
lib/net/http/server.tya:224
render_with_mode builds an HTML response from a template source.
Source
# render_with_mode builds an HTML response from a template source.
# @param tmpl Any tmpl value.
# @param data Array data value.
# @param options Dict options value.
# @param html Any html value.
# @return Any the resulting value.
render_with_mode: tmpl, data, options, html ->
if options == nil
options = {}
headers = {}
headers["Content-Type"] = options.get("content_type", "text/html; charset=utf-8")
extra = options.get("headers", nil)
if extra != nil
keys = extra.keys()
i = 0
while i < keys.len()
headers[keys[i]] = extra[keys[i]]
i = i + 1
template_options = options.get("template_options", {})
if html
template_options["escape"] = "html"
source = tmpl
if tmpl.class != String
source = bytes.Bytes(tmpl).to_text()
body = ""
if tmpl.class == String and file.File(tmpl).exists?()
body = template.Template(tmpl).render_file(data, template_options)
else
body = template.Template(source).render(data, template_options)
return { status: options.get("status", 200), headers: headers, body: body }
route
Server.route(method, path, handler, options)
lib/net/http/server.tya:135
Server.route provides the net/http/Server standard library operation. route registers a handler for method and path. Raises when the path pattern or route options are invalid.
Source
# Server.route provides the net/http/Server standard library operation.
# route registers a handler for method and path.
# Raises when the path pattern or route options are invalid.
# @param method String method value.
# @param path String path value.
# @param handler Any handler value.
# @param options Dict options value.
# @return Any the resulting value.
route: method, path, handler, options ->
opts = self.route_options(options)
full_path = self.join_paths(self.prefix, path)
self.validate_pattern(full_path)
route = { method: method.upper(), path: full_path, handler: handler, middlewares: self.copy_array(self.middlewares), trailing_slash: opts["trailing_slash"], name: opts["name"] }
self.routes.push(route)
if opts["name"] != nil
self.named_routes[opts["name"]] = route
return self
route_options
Server.route_options(options)
lib/net/http/server.tya:418
Server.route_options provides the net/http/Server standard library operation.
Source
# Server.route_options provides the net/http/Server standard library operation.
# @param options Dict options value.
# @return Dict the resulting value.
route_options: options ->
opts = { trailing_slash: "strict", name: nil }
if options == nil
return opts
keys = options.keys()
i = 0
while i < keys.len()
key = keys[i]
if key != "trailing_slash" and key != "name"
raise error("http.route: unknown option " + key)
opts[key] = options[key]
i = i + 1
if opts["trailing_slash"] != "strict" and opts["trailing_slash"] != "ignore"
raise error("http.route: invalid trailing_slash option")
return opts
run
Server.run(port)
lib/net/http/server.tya:401
run binds port (0 = OS picks a free port) and enters the accept loop. Blocks forever; the only ways out are a fatal error or SIGINT.
Source
# run binds `port` (0 = OS picks a free port) and enters the
# accept loop. Blocks forever; the only ways out are a fatal
# error or SIGINT.
# @param port Any port value.
# @return Any the resulting value.
run: port ->
http_server_run(self.routes, port)
run_tls
Server.run_tls(port, cert_file, key_file, options)
lib/net/http/server.tya:410
run_tls starts an HTTPS server with a PEM certificate and private key.
Source
# run_tls starts an HTTPS server with a PEM certificate and private key.
# @param port Any port value.
# @param cert_file Any cert file value.
# @param key_file Any key file value.
# @param options Dict options value.
# @return Any the resulting value.
run_tls: port, cert_file, key_file, options ->
if options == nil
options = {}
http_server_run_tls(self.routes, port, cert_file, key_file, options)
serve_static
Server.serve_static(prefix, assets)
lib/net/http/server.tya:351
Server.static provides the net/http/Server standard library operation.
Source
# Server.static provides the net/http/Server standard library operation.
# @param prefix Any prefix value.
# @param assets Any assets value.
# @return Any the resulting value.
serve_static: prefix, assets ->
for entry in assets.entries()
path = entry[0]
asset = entry[1]
if asset.class == Dict
self.static_one(prefix, path, asset, false)
hashed = asset["hashed_path"]
if hashed != nil and hashed != path
self.static_one(prefix, hashed, asset, true)
else
self.static_one(prefix, path, asset, false)
self
static_one
Server.static_one(prefix, path, asset, hashed_route)
lib/net/http/server.tya:370
Server.static_one provides the net/http/Server standard library operation.
Source
# Server.static_one provides the net/http/Server standard library operation.
# @param prefix Any prefix value.
# @param path String path value.
# @param asset Any asset value.
# @param hashed_route Any hashed route value.
# @return Any the resulting value.
static_one: prefix, path, asset, hashed_route ->
self.routes.push({
method: "GET",
path: prefix + "/" + path,
static_asset: asset,
static_hashed: hashed_route,
middlewares: [],
trailing_slash: "strict"
})
strip_leading
Server.strip_leading(path)
lib/net/http/server.tya:596
Server.strip_leading provides the net/http/Server standard library operation.
Source
# Server.strip_leading provides the net/http/Server standard library operation.
# @param path String path value.
# @return Any the resulting value.
strip_leading: path ->
while path.byte_len() > 0 and path.starts_with("/")
path = path.slice(1, path.len())
return path
strip_trailing
Server.strip_trailing(path)
lib/net/http/server.tya:588
Server.strip_trailing provides the net/http/Server standard library operation.
Source
# Server.strip_trailing provides the net/http/Server standard library operation.
# @param path String path value.
# @return Any the resulting value.
strip_trailing: path ->
while path.byte_len() > 1 and path.ends_with("/")
path = path.slice(0, path.len() - 1)
return path
use
Server.use(middleware)
lib/net/http/server.tya:148
Server.use provides the net/http/Server standard library operation.
Source
# Server.use provides the net/http/Server standard library operation.
# @param middleware Any middleware value.
# @return Any the resulting value.
use: middleware ->
self.middlewares.push(middleware)
return self
validate_pattern
Server.validate_pattern(path)
lib/net/http/server.tya:497
Server.validate_pattern provides the net/http/Server standard library operation.
Source
# Server.validate_pattern provides the net/http/Server standard library operation.
# @param path String path value.
# @return Boolean the resulting value.
validate_pattern: path ->
if not path.starts_with("/")
raise error("http.route: path must start with /")
names = []
parts = path.split("/")
i = 0
while i < parts.len()
part = parts[i]
if part.starts_with("*") and i != parts.len() - 1
raise error("http.route: wildcard must be final segment")
if part.starts_with(":") or part.starts_with("*")
name = part.slice(1, part.len())
if name == "" or self.array_has?(names, name)
raise error("http.route: duplicate or empty parameter " + name)
names.push(name)
i = i + 1