-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhttp_server.ion
More file actions
107 lines (88 loc) · 2.99 KB
/
Copy pathhttp_server.ion
File metadata and controls
107 lines (88 loc) · 2.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// HTTP server on port 8080. FFI sockets and spawn per client.
//
// recv and send are Ion keywords; FFI uses recv_sys and send_sys.
// Link with: gcc ... -Drecv_sys=recv -Dsend_sys=send
// On Windows add: -Dclose=closesocket -lws2_32
extern "C" {
fn ion_net_init();
fn socket(domain: int, sock_type: int, protocol: int) -> int;
fn bind(sockfd: &int, addr: &SockAddrIn, addrlen: int) -> int;
fn listen(sockfd: &int, backlog: int) -> int;
fn accept(sockfd: &int, addr: &mut u8, addrlen: &mut int) -> int;
fn recv_sys(sockfd: &int, buf: &mut u8, len: int, flags: int) -> int;
fn send_sys(sockfd: &int, buf: *u8, len: int, flags: int) -> int;
fn close(fd: &int) -> int;
fn htons(hostshort: u16) -> u16;
}
struct SockAddrIn {
sin_family: u16;
sin_port: u16;
sin_addr: u32;
sin_zero: [u8; 8];
}
fn create_sockaddr_in(port: u16) -> SockAddrIn {
unsafe {
return SockAddrIn {
sin_family: 2,
sin_port: htons(port),
sin_addr: 0,
sin_zero: [0; 8],
};
}
}
fn handle_client(client_fd: int) -> int {
let mut buffer: [u8; 128] = [0; 128];
unsafe {
let received: int = recv_sys(&client_fd, &mut buffer[0], 128, 0);
if received < 1 {
close(&client_fd);
return 0;
}
let _sent1: int = send_sys(&client_fd, "HTTP/1.1 200 OK\r\n", 17, 0);
let _sent2: int = send_sys(&client_fd, "Content-Type: text/html\r\n", 25, 0);
let _sent3: int = send_sys(&client_fd, "Content-Length: 89\r\n", 20, 0);
let _sent4: int = send_sys(&client_fd, "Connection: close\r\n", 19, 0);
let _sent5: int = send_sys(&client_fd, "\r\n", 2, 0);
let _sent6: int = send_sys(&client_fd, "<html><head><title>Ion HTTP Server</title></head><body><h1>Hello from Ion!</h1><p>This is a simple HTTP server written in Ion.</p></body></html>", 89, 0);
close(&client_fd);
}
return 0;
}
fn dispatch_client(client_fd: int) {
if client_fd < 0 {
return;
}
spawn {
let _result: int = handle_client(client_fd);
};
}
fn main() -> int {
unsafe {
ion_net_init();
let af_inet: int = 2;
let sock_stream: int = 1;
let ipproto_tcp: int = 6;
let server_fd: int = socket(af_inet, sock_stream, ipproto_tcp);
if server_fd < 0 {
return 1;
}
let sockaddr: SockAddrIn = create_sockaddr_in(8080);
let bind_result: int = bind(&server_fd, &sockaddr, 16);
if bind_result < 0 {
close(&server_fd);
return 2;
}
let listen_result: int = listen(&server_fd, 10);
if listen_result < 0 {
close(&server_fd);
return 3;
}
loop {
let mut client_addr: [u8; 16] = [0; 16];
let mut addrlen: int = 16;
let client_fd: int = accept(&server_fd, &mut client_addr[0], &mut addrlen);
dispatch_client(client_fd);
}
}
return 0;
}