comparison seobeo/main.c @ 6:1e61008b9980

[Seobeo] Updated seobeo so that API is more opinionated. Added my webpage./build.sh
author June Park <parkjune1995@gmail.com>
date Mon, 29 Sep 2025 16:00:44 -0700
parents 3e12bf044589
children 114cad94008f
comparison
equal deleted inserted replaced
5:3e12bf044589 6:1e61008b9980
2 ** server.c -- a stream socket server demo 2 ** server.c -- a stream socket server demo
3 */ 3 */
4 4
5 #include "seobeo/seobeo.h" 5 #include "seobeo/seobeo.h"
6 6
7 Dowa_PHashMap cache;
8
9 void SigchildHandler(int s)
10 {
11 (void)s; // quiet unused variable warning
12
13 // waitpid() might overwrite errno, so we save and restore it:
14 int saved_errno = errno;
15
16 while(waitpid(-1, NULL, WNOHANG) > 0);
17
18 errno = saved_errno;
19 }
20
21 void HandleClientRequest(Seobeo_PHandle cli)
22 {
23 Dowa_PArena response_arena = Dowa_Arena_Create(8192);
24 if (!response_arena)
25 {
26 perror("Dowa_Arena_Initialize");
27 goto clean_up;
28 }
29
30 size_t idx = Dowa_HashMap_GetPosition(cache, "index.html");
31 Dowa_PHashEntry entry = cache->entries[idx];
32 if (!entry)
33 {
34 // 404 response if missing
35 const char *not_found =
36 "HTTP/2.0 404 Not Found\r\n"
37 "Content-Length: 0\r\n"
38 "Connection: close\r\n"
39 "\r\n";
40 send(cli->socket, not_found, strlen(not_found), 0);
41 goto clean_up;
42 }
43
44 // 3) Prepare header with the correct content‐length
45 size_t body_size = entry->capacity;
46 const char *template =
47 "HTTP/2.0 200 OK\r\n"
48 "Content-Type: text/html\r\n"
49 "Content-Length: %zu\r\n"
50 "Connection: close\r\n"
51 "\r\n";
52
53 // Compute how large the header is and allocate just enough space
54 int header_len = snprintf(NULL, 0, template, body_size);
55 void *header = Dowa_Arena_Allocate(response_arena, (size_t)(header_len+1));
56 if (header == NULL)
57 {
58 perror("Dowa_Arena_Allocate");
59 goto clean_up;
60 }
61
62 snprintf((char *)header, header_len + 1, template, body_size);
63 Seobeo_Handle_QueueData(cli,
64 (const uint8*)header,
65 (uint32)(header_len + 1));
66 Seobeo_Handle_QueueData(cli,
67 (const uint8*)entry->buffer,
68 (uint32)body_size);
69 Seobeo_Handle_Flush(cli);
70 goto clean_up;
71
72 clean_up:
73 Seobeo_Handle_Destroy(cli);
74 Dowa_Arena_Free(response_arena);
75 return ;
76 }
77 7
78 int main(void) 8 int main(void)
79 { 9 {
80 struct sigaction sa; 10 Seobeo_Web_StartBasicHTTPServer("seobeo/pages", "8080");
81
82 cache = Dowa_HashMap_Create(1024);
83 if (Dowa_Cache_Folder(cache, "seobeo/pages") != 0)
84 {
85 perror("Dowa_Cache_Folder");
86 return -1;
87 }
88
89 Seobeo_PHandle srv = Seobeo_Stream_Handle_Create(NULL, "8080");
90
91 if (srv->socket < 0) return 1;
92 printf("Listening on port 8080\n");
93
94 // TODO: Use epoll or something else.
95 // Code from Beej's book
96 // Handling child processes
97 sa.sa_handler = SigchildHandler;
98 sigemptyset(&sa.sa_mask);
99 sa.sa_flags = SA_RESTART;
100 if (sigaction(SIGCHLD, &sa, NULL) == -1)
101 {
102 perror("sigaction");
103 exit(1);
104 }
105
106 while (1)
107 {
108 Seobeo_PHandle cli = Seobeo_Stream_Handle_Accept(srv);
109 if (cli == NULL)
110 {
111 continue;
112 }
113 printf("client connected from %s\n", cli->host);
114
115 if (!fork())
116 {
117 HandleClientRequest(cli);
118 exit(0);
119 }
120 Seobeo_Handle_Destroy(cli);
121 }
122
123 Seobeo_Handle_Destroy(srv);
124 return 0;
125 } 11 }