Mercurial
annotate seobeo/main.c @ 3:2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
| author | June Park <parkjune1995@gmail.com> |
|---|---|
| date | Wed, 24 Sep 2025 18:49:09 -0700 |
| parents | adcfad6e86fb |
| children | 0b3b4f5887bb |
| rev | line source |
|---|---|
|
0
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
1 /* |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
2 ** server.c -- a stream socket server demo |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
3 */ |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
4 |
|
1
adcfad6e86fb
Updated naming and separated out some logic within seobeo.
June Park <parkjune1995@gmail.com>
parents:
0
diff
changeset
|
5 #include "seobeo/seobeo.h" |
|
0
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
6 |
|
3
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
7 Dowa_PHashMap cache; |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
8 |
|
0
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
9 void SigchildHandler(int s) |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
10 { |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
11 (void)s; // quiet unused variable warning |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
12 |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
13 // waitpid() might overwrite errno, so we save and restore it: |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
14 int saved_errno = errno; |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
15 |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
16 while(waitpid(-1, NULL, WNOHANG) > 0); |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
17 |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
18 errno = saved_errno; |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
19 } |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
20 |
|
1
adcfad6e86fb
Updated naming and separated out some logic within seobeo.
June Park <parkjune1995@gmail.com>
parents:
0
diff
changeset
|
21 void HandleClientRequest(int client_fd) |
|
adcfad6e86fb
Updated naming and separated out some logic within seobeo.
June Park <parkjune1995@gmail.com>
parents:
0
diff
changeset
|
22 { |
|
3
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
23 size_t idx = Dowa_HashMap_GetPosition(cache, "index.html"); |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
24 Dowa_PHashEntry entry = cache->entries[idx]; |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
25 if (!entry) { |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
26 // 404 response if missing |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
27 const char *not_found = |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
28 "HTTP/1.1 404 Not Found\r\n" |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
29 "Content-Length: 0\r\n" |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
30 "Connection: close\r\n" |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
31 "\r\n"; |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
32 send(client_fd, not_found, strlen(not_found), 0); |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
33 close(client_fd); |
|
1
adcfad6e86fb
Updated naming and separated out some logic within seobeo.
June Park <parkjune1995@gmail.com>
parents:
0
diff
changeset
|
34 return; |
|
adcfad6e86fb
Updated naming and separated out some logic within seobeo.
June Park <parkjune1995@gmail.com>
parents:
0
diff
changeset
|
35 } |
|
adcfad6e86fb
Updated naming and separated out some logic within seobeo.
June Park <parkjune1995@gmail.com>
parents:
0
diff
changeset
|
36 |
|
3
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
37 // 3) Prepare header with the correct contentālength |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
38 size_t body_size = entry->capacity; |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
39 const char *template = |
|
1
adcfad6e86fb
Updated naming and separated out some logic within seobeo.
June Park <parkjune1995@gmail.com>
parents:
0
diff
changeset
|
40 "HTTP/1.1 200 OK\r\n" |
|
adcfad6e86fb
Updated naming and separated out some logic within seobeo.
June Park <parkjune1995@gmail.com>
parents:
0
diff
changeset
|
41 "Content-Type: text/html\r\n" |
|
adcfad6e86fb
Updated naming and separated out some logic within seobeo.
June Park <parkjune1995@gmail.com>
parents:
0
diff
changeset
|
42 "Content-Length: %zu\r\n" |
|
adcfad6e86fb
Updated naming and separated out some logic within seobeo.
June Park <parkjune1995@gmail.com>
parents:
0
diff
changeset
|
43 "Connection: close\r\n" |
|
3
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
44 "\r\n"; |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
45 |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
46 // Compute how large the header is and allocate just enough space |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
47 int header_len = snprintf(NULL, 0, template, body_size); |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
48 char *header = malloc(header_len + 1); |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
49 if (!header) { |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
50 perror("malloc"); |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
51 close(client_fd); |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
52 return; |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
53 } |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
54 snprintf(header, header_len + 1, template, body_size); |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
55 |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
56 // 4) Send header |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
57 send(client_fd, header, header_len, 0); |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
58 free(header); |
|
1
adcfad6e86fb
Updated naming and separated out some logic within seobeo.
June Park <parkjune1995@gmail.com>
parents:
0
diff
changeset
|
59 |
|
3
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
60 // 5) Stream the body in a loop until everything is sent |
|
1
adcfad6e86fb
Updated naming and separated out some logic within seobeo.
June Park <parkjune1995@gmail.com>
parents:
0
diff
changeset
|
61 ssize_t total_sent = 0; |
|
3
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
62 const char *body = entry->buffer; |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
63 while ((size_t)total_sent < body_size) |
|
1
adcfad6e86fb
Updated naming and separated out some logic within seobeo.
June Park <parkjune1995@gmail.com>
parents:
0
diff
changeset
|
64 { |
|
3
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
65 ssize_t sent = send( |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
66 client_fd, |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
67 body + total_sent, |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
68 body_size - total_sent, |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
69 0 |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
70 ); |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
71 if (sent <= 0) |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
72 { |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
73 // error or connection closed by client |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
74 break; |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
75 } |
|
1
adcfad6e86fb
Updated naming and separated out some logic within seobeo.
June Park <parkjune1995@gmail.com>
parents:
0
diff
changeset
|
76 total_sent += sent; |
|
adcfad6e86fb
Updated naming and separated out some logic within seobeo.
June Park <parkjune1995@gmail.com>
parents:
0
diff
changeset
|
77 } |
|
adcfad6e86fb
Updated naming and separated out some logic within seobeo.
June Park <parkjune1995@gmail.com>
parents:
0
diff
changeset
|
78 |
|
3
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
79 // 6) Tear down |
|
1
adcfad6e86fb
Updated naming and separated out some logic within seobeo.
June Park <parkjune1995@gmail.com>
parents:
0
diff
changeset
|
80 close(client_fd); |
|
adcfad6e86fb
Updated naming and separated out some logic within seobeo.
June Park <parkjune1995@gmail.com>
parents:
0
diff
changeset
|
81 } |
|
adcfad6e86fb
Updated naming and separated out some logic within seobeo.
June Park <parkjune1995@gmail.com>
parents:
0
diff
changeset
|
82 |
|
0
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
83 int main(void) |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
84 { |
|
3
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
85 cache = Dowa_HashMap_Create(1024); |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
86 if (Dowa_Cache_Folder(cache, "seobeo/pages") != 0) |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
87 { |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
88 perror("Dowa_Cache_Folder"); |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
89 return -1; |
|
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
90 } |
|
0
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
91 |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
92 struct sigaction sa; |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
93 |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
94 sa.sa_handler = SigchildHandler; // reap all dead processes |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
95 sigemptyset(&sa.sa_mask); |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
96 sa.sa_flags = SA_RESTART; |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
97 if (sigaction(SIGCHLD, &sa, NULL) == -1) { |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
98 perror("sigaction"); |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
99 exit(1); |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
100 } |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
101 |
|
1
adcfad6e86fb
Updated naming and separated out some logic within seobeo.
June Park <parkjune1995@gmail.com>
parents:
0
diff
changeset
|
102 int sock_fd = Seobeo_CreateSocket(1, "6969", 10); |
|
3
2758f5527d2b
[Seobeo] Working on simple TCP server and client logic.
June Park <parkjune1995@gmail.com>
parents:
1
diff
changeset
|
103 Seobeo_ListenClient(sock_fd, &HandleClientRequest); |
|
0
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
104 |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
105 return 0; |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
106 } |
|
5695ef413be0
Initialized mono repo with bazels with few examples.
June Park <parkjune1995@gmail.com>
parents:
diff
changeset
|
107 |