aboutsummaryrefslogtreecommitdiff
path: root/examples/http-server
diff options
context:
space:
mode:
Diffstat (limited to 'examples/http-server')
-rw-r--r--examples/http-server/connection-queue.tm10
-rw-r--r--examples/http-server/http-server.tm66
-rwxr-xr-xexamples/http-server/sample-site/random.tm2
3 files changed, 39 insertions, 39 deletions
diff --git a/examples/http-server/connection-queue.tm b/examples/http-server/connection-queue.tm
index 3c8058d5..29759f38 100644
--- a/examples/http-server/connection-queue.tm
+++ b/examples/http-server/connection-queue.tm
@@ -1,22 +1,22 @@
use pthreads
-func _assert_success(name:Text, val:Int32; inline):
+func _assert_success(name:Text, val:Int32; inline)
fail("$name() failed!") if val < 0
-struct ConnectionQueue(_connections:@[Int32]=@[], _mutex=pthread_mutex_t.new(), _cond=pthread_cond_t.new()):
- func enqueue(queue:ConnectionQueue, connection:Int32):
+struct ConnectionQueue(_connections:@[Int32]=@[], _mutex=pthread_mutex_t.new(), _cond=pthread_cond_t.new())
+ func enqueue(queue:ConnectionQueue, connection:Int32)
queue._mutex.lock()
queue._connections.insert(connection)
queue._mutex.unlock()
queue._cond.signal()
- func dequeue(queue:ConnectionQueue -> Int32):
+ func dequeue(queue:ConnectionQueue -> Int32)
conn : Int32? = none
queue._mutex.lock()
- while queue._connections.length == 0:
+ while queue._connections.length == 0
queue._cond.wait(queue._mutex)
conn = queue._connections.pop(1)
diff --git a/examples/http-server/http-server.tm b/examples/http-server/http-server.tm
index 649a9e12..b814cdcb 100644
--- a/examples/http-server/http-server.tm
+++ b/examples/http-server/http-server.tm
@@ -15,12 +15,12 @@ use patterns
use ./connection-queue.tm
-func serve(port:Int32, handler:func(request:HTTPRequest -> HTTPResponse), num_threads=16):
+func serve(port:Int32, handler:func(request:HTTPRequest -> HTTPResponse), num_threads=16)
connections := ConnectionQueue()
workers : &[@pthread_t] = &[]
- for i in num_threads:
- workers.insert(pthread_t.new(func():
- repeat:
+ for i in num_threads
+ workers.insert(pthread_t.new(func()
+ repeat
connection := connections.dequeue()
request_text := inline C : Text {
Text_t request = EMPTY_TEXT;
@@ -62,17 +62,17 @@ func serve(port:Int32, handler:func(request:HTTPRequest -> HTTPResponse), num_th
s
}
- repeat:
+ repeat
conn := inline C : Int32 { accept(_$sock, NULL, NULL) }
stop if conn < 0
connections.enqueue(conn)
say("Shutting down...")
- for w in workers:
+ for w in workers
w.cancel()
-struct HTTPRequest(method:Text, path:Text, version:Text, headers:[Text], body:Text):
- func from_text(text:Text -> HTTPRequest?):
+struct HTTPRequest(method:Text, path:Text, version:Text, headers:[Text], body:Text)
+ func from_text(text:Text -> HTTPRequest?)
m := text.pattern_captures($Pat'{word} {..} HTTP/{..}{crlf}{..}') or return none
method := m[1]
path := m[2].replace_pattern($Pat'{2+ /}', '/')
@@ -82,8 +82,8 @@ struct HTTPRequest(method:Text, path:Text, version:Text, headers:[Text], body:Te
body := rest[-1]
return HTTPRequest(method, path, version, headers, body)
-struct HTTPResponse(body:Text, status=200, content_type="text/plain", headers:{Text=Text}={}):
- func bytes(r:HTTPResponse -> [Byte]):
+struct HTTPResponse(body:Text, status=200, content_type="text/plain", headers:{Text=Text}={})
+ func bytes(r:HTTPResponse -> [Byte])
body_bytes := r.body.bytes()
extra_headers := (++: "$k: $v$(\r\n)" for k,v in r.headers) or ""
return "
@@ -95,55 +95,55 @@ struct HTTPResponse(body:Text, status=200, content_type="text/plain", headers:{T
$\r$\n
".bytes() ++ body_bytes
-func _content_type(file:Path -> Text):
- when file.extension() is "html": return "text/html"
- is "tm": return "text/html"
- is "js": return "text/javascript"
- is "css": return "text/css"
- else: return "text/plain"
-
-enum RouteEntry(ServeFile(file:Path), Redirect(destination:Text)):
- func respond(entry:RouteEntry, request:HTTPRequest -> HTTPResponse):
- when entry is ServeFile(file):
- body := if file.can_execute():
+func _content_type(file:Path -> Text)
+ when file.extension() is "html" return "text/html"
+ is "tm" return "text/html"
+ is "js" return "text/javascript"
+ is "css" return "text/css"
+ else return "text/plain"
+
+enum RouteEntry(ServeFile(file:Path), Redirect(destination:Text))
+ func respond(entry:RouteEntry, request:HTTPRequest -> HTTPResponse)
+ when entry is ServeFile(file)
+ body := if file.can_execute()
Command(Text(file)).get_output()!
- else:
+ else
file.read()!
return HTTPResponse(body, content_type=_content_type(file))
- is Redirect(destination):
+ is Redirect(destination)
return HTTPResponse("Found", 302, headers={"Location"=destination})
-func load_routes(directory:Path -> {Text=RouteEntry}):
+func load_routes(directory:Path -> {Text=RouteEntry})
routes : &{Text=RouteEntry} = &{}
- for file in (directory ++ (./*)).glob():
+ for file in (directory ++ (./*)).glob()
skip unless file.is_file()
contents := file.read() or skip
server_path := "/" ++ "/".join(file.relative_to(directory).components)
- if file.base_name() == "index.html":
+ if file.base_name() == "index.html"
canonical := server_path.without_suffix("index.html")
routes[server_path] = Redirect(canonical)
routes[canonical] = ServeFile(file)
- else if file.extension() == "html":
+ else if file.extension() == "html"
canonical := server_path.without_suffix(".html")
routes[server_path] = Redirect(canonical)
routes[canonical] = ServeFile(file)
- else if file.extension() == "tm":
+ else if file.extension() == "tm"
canonical := server_path.without_suffix(".tm")
routes[server_path] = Redirect(canonical)
routes[canonical] = ServeFile(file)
- else:
+ else
routes[server_path] = ServeFile(file)
return routes[]
-func main(directory:Path, port=Int32(8080)):
+func main(directory:Path, port=Int32(8080))
say("Serving on port $port")
routes := load_routes(directory)
say(" Hosting: $routes")
- serve(port, func(request:HTTPRequest):
- if handler := routes[request.path]:
+ serve(port, func(request:HTTPRequest)
+ if handler := routes[request.path]
return handler.respond(request)
- else:
+ else
return HTTPResponse("Not found!", 404)
)
diff --git a/examples/http-server/sample-site/random.tm b/examples/http-server/sample-site/random.tm
index 29b93be7..153ac2af 100755
--- a/examples/http-server/sample-site/random.tm
+++ b/examples/http-server/sample-site/random.tm
@@ -1,7 +1,7 @@
#!/bin/env tomo
use random
-func main():
+func main()
say("
<!DOCTYPE HTML>
<html>