Mercurial
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 } |