diff options
Diffstat (limited to 'examples/http-server')
| -rw-r--r-- | examples/http-server/connection-queue.tm | 10 | ||||
| -rw-r--r-- | examples/http-server/http-server.tm | 66 | ||||
| -rwxr-xr-x | examples/http-server/sample-site/random.tm | 2 |
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> |
