Skip to content

Commit bc20bbb

Browse files
committed
add example http server
1 parent 2dd01a7 commit bc20bbb

5 files changed

Lines changed: 111 additions & 0 deletions

File tree

BE/StdLib/syscall.a32.asm

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,3 +379,14 @@
379379
poparg res:S32
380380
pusharg res
381381
ret
382+
383+
.fun shutdown NORMAL [S32] = [S32 U32]
384+
.bbl entry
385+
poparg sockfd:S32
386+
poparg how:U32
387+
pusharg how
388+
pusharg sockfd
389+
syscall shutdown 293:U16
390+
poparg res:S32
391+
pusharg res
392+
ret

BE/StdLib/syscall.a64.asm

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,3 +376,14 @@
376376
poparg res:S64
377377
pusharg res
378378
ret
379+
380+
.fun shutdown NORMAL [S32] = [S32 U32]
381+
.bbl entry
382+
poparg sockfd:S32
383+
poparg how:U32
384+
pusharg how
385+
pusharg sockfd
386+
syscall shutdown 210:U8
387+
poparg res:S32
388+
pusharg res
389+
ret

BE/StdLib/syscall.x64.asm

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,3 +379,14 @@
379379
poparg res:S64
380380
pusharg res
381381
ret
382+
383+
.fun shutdown NORMAL [S32] = [S32 U32]
384+
.bbl entry
385+
poparg sockfd:S32
386+
poparg how:U32
387+
pusharg how
388+
pusharg sockfd
389+
syscall shutdown 48:U8
390+
poparg res:S32
391+
pusharg res
392+
ret

FE/Lib/os.cw

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,8 @@ pub global O_CLOEXEC = 0x80000_u32
277277
{{extern}} {{cdecl}} pub fun recvfrom(fd s32, buf ^!u8, buflen uint, flags u32,
278278
src_addr uint, src_addrlen uint) sint:
279279

280+
{{extern}} {{cdecl}} pub fun shutdown(fd s32, op u32) s32:
281+
280282

281283
pub fun FileWrite(fd FD, buffer span(u8)) union(uint, Error):
282284
let res = write(unwrap(fd), front(buffer), len(buffer))
@@ -568,3 +570,18 @@ pub fun SetSocketOptions(fd FD, level SocketLevel, option SocketOption, val span
568570
if res < 0:
569571
return wrap_as(res, Error)
570572
return void_val
573+
574+
575+
576+
577+
pub enum SHUT u32:
578+
WR 0
579+
RD 1
580+
RDWR 2
581+
582+
583+
pub fun Shutdown(fd FD, how SHUT) union(void, Error):
584+
let res = shutdown(unwrap(fd), unwrap(how))
585+
if res < 0:
586+
return wrap_as(res, Error)
587+
return void_val

FE/TestData/http_server.cw

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
module:
2+
3+
import fmt
4+
import os
5+
6+
global gPort = 8181_u16
7+
8+
global gReply = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 12\r\n\r\nHello World!";
9+
10+
pub fun htons(x u16) u16:
11+
return x << 8 | x >> 8
12+
13+
14+
macro make_blob# EXPR ($e EXPR) []:
15+
make_span(bitwise_as(@$e, ^u8), size_of(type_of($e)))
16+
17+
macro make_mut_blob# EXPR ($e EXPR) []:
18+
make_span(bitwise_as(@$e, ^!u8), size_of(type_of($e)))
19+
20+
fun main(argc s32, argv ^^u8) s32:
21+
trylet server_fd os\FD = os\Socket(os\AddressFamily.INET, os\SocketType.STREAM, 0), err:
22+
return 1
23+
24+
fmt\print#("Server fd: ", unwrap(server_fd), "\n")
25+
let! res void
26+
27+
ref let val = 1_u32
28+
tryset res = os\SetSocketOptions(server_fd, os\SocketLevel.SOCKET, os\SocketOption.SO_REUSEADDR,
29+
make_blob#(val)), err:
30+
return 1
31+
32+
ref let addr = {os\SockAddrIn: os\AddressFamily.INET, htons(gPort), {[4]u8: 0, 0, 0, 0}}
33+
34+
tryset res = os\Bind(server_fd, make_blob#(addr)), err:
35+
return 1
36+
37+
tryset res = os\Listen(server_fd, 3), err:
38+
return 1
39+
40+
fmt\print#("Listening on port: ", gPort, "\n")
41+
42+
while true:
43+
fmt\print#("Waiting for connection\n")
44+
ref let addr os\SockAddrIn = undef
45+
trylet client_fd os\FD = os\AcceptWithAddr(server_fd, make_mut_blob#(addr), 0), err:
46+
return 1
47+
trylet n uint = os\SendTo(client_fd, gReply, 0), err:
48+
return 1
49+
trylet n2 uint = os\SendTo(client_fd, "\r\n COOL\n\n\n", 0), err:
50+
return 1
51+
fmt\print#("Sent ", n, " bytes\n")
52+
tryset res = os\Close(client_fd), err:
53+
return 1
54+
55+
tryset res = os\Shutdown(server_fd, os\SHUT.RDWR), err:
56+
return 1
57+
58+
tryset res = os\Close(server_fd), err:
59+
return 1
60+
61+
return 0

0 commit comments

Comments
 (0)