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