http server
This commit is contained in:
@@ -278,7 +278,7 @@ func main[argc: i64, argv: ptr] : i64
|
||||
disassemble := false
|
||||
|
||||
for i in 1..argc
|
||||
arg := mem.read64(argv + i * 8) as str
|
||||
arg := os.arg(argv, i)
|
||||
if arg->equal("-d")
|
||||
disassemble = true
|
||||
else
|
||||
|
||||
@@ -6,7 +6,7 @@ func main[argc: i64, argv: ptr] : i64
|
||||
io.println("ERROR: url is missing")
|
||||
return 1
|
||||
|
||||
url := mem.read64(argv + 8) as str
|
||||
url := os.arg(argv, 1)
|
||||
|
||||
if url->len() <= 7
|
||||
io.println("ERROR: invalid url (Did you forget \"http://\"?)")
|
||||
@@ -34,9 +34,9 @@ func main[argc: i64, argv: ptr] : i64
|
||||
panic("failed to connect")
|
||||
|
||||
// seems reasonable
|
||||
req := _stackalloc(4096)
|
||||
req_size := str.format_into(req as str, 4096, "GET %s HTTP/1.0\r\nHost: %s\r\nConnection: close\r\n\r\n", path, host)
|
||||
net.send(s, req, req_size)
|
||||
req := _stackalloc(4096) as str
|
||||
req_size := req->format_into(4096, "GET %s HTTP/1.0\r\nHost: %s\r\nConnection: close\r\n\r\n", path, host)
|
||||
net.send(s, req as ptr, req_size)
|
||||
|
||||
header_buf := mem.alloc(8192) as str
|
||||
header_size := 0
|
||||
|
||||
96
examples/serve.zr
Normal file
96
examples/serve.zr
Normal file
@@ -0,0 +1,96 @@
|
||||
// needs to be compiled with -m -C "-lpthread"
|
||||
include "std/net.zr"
|
||||
|
||||
extern pthread_create
|
||||
extern pthread_detach
|
||||
|
||||
struct ConnData
|
||||
sock: i64
|
||||
addr: str
|
||||
|
||||
func handle_connection[conn: ConnData] : void
|
||||
req := _stackalloc(10001) as str
|
||||
n := net.read(conn->sock, req as ptr, 10000)
|
||||
if n <= 0
|
||||
net.close(conn->sock)
|
||||
conn->addr->free()
|
||||
(conn as ptr)->free()
|
||||
return
|
||||
|
||||
req[n] = 0
|
||||
|
||||
pos := req->find("\r\n")
|
||||
if pos == -1
|
||||
panic("TODO: bad request")
|
||||
|
||||
first_line := req->substr_n(0, pos)
|
||||
parts := first_line->split(" ")
|
||||
method := parts->nth(0) as str
|
||||
path := parts->nth(1) as str
|
||||
|
||||
if !method->equal("GET")
|
||||
// TODO: method not supported
|
||||
return
|
||||
|
||||
if path->equal("/")
|
||||
// TODO: index
|
||||
return
|
||||
|
||||
// TODO: ANY validation
|
||||
file_path := "."->concat(path)
|
||||
|
||||
file_size, ok := os.get_file_size(file_path)
|
||||
if !ok
|
||||
// TODO: not found
|
||||
return
|
||||
|
||||
fd := _builtin_syscall(SYS_openat, AT_FDCWD, file_path, O_RDONLY, 0)
|
||||
if fd < 0
|
||||
// TODO: not found
|
||||
return
|
||||
|
||||
resp := "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n"
|
||||
net.send(conn->sock, resp as ptr, resp->len())
|
||||
|
||||
offset := 0
|
||||
while offset < file_size
|
||||
sent := _builtin_syscall(SYS_sendfile, conn->sock, fd, ^offset, IP_MAXPACKET)
|
||||
if sent <= 0
|
||||
break
|
||||
|
||||
net.close(conn->sock)
|
||||
|
||||
_builtin_syscall(SYS_close, fd)
|
||||
file_path->free()
|
||||
first_line->free()
|
||||
parts->free_with_items()
|
||||
conn->addr->free()
|
||||
(conn as ptr)->free()
|
||||
|
||||
func main[argc: i64, argv: ptr] : i64
|
||||
port := 8000
|
||||
|
||||
if argc > 1
|
||||
port = os.arg(argv, 1)->parse_i64()
|
||||
|
||||
server_sock, ok := net.listen("0.0.0.0", port)
|
||||
if !ok
|
||||
panic("failed to listen")
|
||||
|
||||
io.printf("Listening on :%d...\n", port)
|
||||
|
||||
addr := _stackalloc(16)
|
||||
while true
|
||||
conn := net.accept(server_sock, addr)
|
||||
if conn < 0
|
||||
io.println("ERROR: failed to accept connection")
|
||||
continue
|
||||
|
||||
conn_data := new* ConnData
|
||||
conn_data->sock = conn
|
||||
conn_data->addr = mem.alloc(30) as str
|
||||
conn_data->addr->format_into(30, "%d.%d.%d.%d:%d", addr[4], addr[5], addr[6], addr[7], mem.read16be(addr + 2))
|
||||
|
||||
thread := 0
|
||||
pthread_create(^thread, 0, ^handle_connection, conn_data)
|
||||
pthread_detach(thread)
|
||||
@@ -1,26 +0,0 @@
|
||||
include "std/io.zr"
|
||||
include "std/net.zr"
|
||||
|
||||
func main[] : i64
|
||||
s, ok := net.listen("127.0.0.1", 8000)
|
||||
if !ok
|
||||
panic("failed to listen")
|
||||
|
||||
io.println("Listening on port 8000...")
|
||||
|
||||
resp := mem.alloc(IP_MAXPACKET)
|
||||
addr := _stackalloc(16)
|
||||
while true
|
||||
conn := net.accept(s, addr)
|
||||
if conn < 0
|
||||
continue
|
||||
|
||||
io.printf("%d.%d.%d.%d:%d\n", addr[4], addr[5], addr[6], addr[7], mem.read16be(addr + 2))
|
||||
|
||||
n := net.read(conn, resp, IP_MAXPACKET)
|
||||
|
||||
io.print_sized(resp, n)
|
||||
io.println("")
|
||||
|
||||
net.send(conn, resp, n)
|
||||
net.close(conn)
|
||||
Reference in New Issue
Block a user