Mercurial
comparison seobeo/main.c @ 4:0b3b4f5887bb
[Seobeo] Updated so that it create socket for both server and clients.
| author | June Park <parkjune1995@gmail.com> |
|---|---|
| date | Fri, 26 Sep 2025 15:14:46 -0700 |
| parents | 2758f5527d2b |
| children | 3e12bf044589 |
comparison
equal
deleted
inserted
replaced
| 3:2758f5527d2b | 4:0b3b4f5887bb |
|---|---|
| 16 while(waitpid(-1, NULL, WNOHANG) > 0); | 16 while(waitpid(-1, NULL, WNOHANG) > 0); |
| 17 | 17 |
| 18 errno = saved_errno; | 18 errno = saved_errno; |
| 19 } | 19 } |
| 20 | 20 |
| 21 void HandleClientRequest(int client_fd) | 21 void HandleClientRequest(Seobeo_PHandle cli) |
| 22 { | 22 { |
| 23 size_t idx = Dowa_HashMap_GetPosition(cache, "index.html"); | 23 size_t idx = Dowa_HashMap_GetPosition(cache, "index.html"); |
| 24 Dowa_PHashEntry entry = cache->entries[idx]; | 24 Dowa_PHashEntry entry = cache->entries[idx]; |
| 25 | |
| 25 if (!entry) { | 26 if (!entry) { |
| 26 // 404 response if missing | 27 // 404 response if missing |
| 27 const char *not_found = | 28 const char *not_found = |
| 28 "HTTP/1.1 404 Not Found\r\n" | 29 "HTTP/1.1 404 Not Found\r\n" |
| 29 "Content-Length: 0\r\n" | 30 "Content-Length: 0\r\n" |
| 30 "Connection: close\r\n" | 31 "Connection: close\r\n" |
| 31 "\r\n"; | 32 "\r\n"; |
| 32 send(client_fd, not_found, strlen(not_found), 0); | 33 send(cli->socket, not_found, strlen(not_found), 0); |
| 33 close(client_fd); | 34 Seobeo_Handle_Destroy(cli); |
| 34 return; | 35 return; |
| 35 } | 36 } |
| 36 | 37 |
| 37 // 3) Prepare header with the correct content‐length | 38 // 3) Prepare header with the correct content‐length |
| 38 size_t body_size = entry->capacity; | 39 size_t body_size = entry->capacity; |
| 46 // Compute how large the header is and allocate just enough space | 47 // Compute how large the header is and allocate just enough space |
| 47 int header_len = snprintf(NULL, 0, template, body_size); | 48 int header_len = snprintf(NULL, 0, template, body_size); |
| 48 char *header = malloc(header_len + 1); | 49 char *header = malloc(header_len + 1); |
| 49 if (!header) { | 50 if (!header) { |
| 50 perror("malloc"); | 51 perror("malloc"); |
| 51 close(client_fd); | |
| 52 return; | 52 return; |
| 53 } | 53 } |
| 54 snprintf(header, header_len + 1, template, body_size); | 54 snprintf(header, header_len + 1, template, body_size); |
| 55 | 55 |
| 56 // 4) Send header | 56 Seobeo_Handle_QueueData(cli, |
| 57 send(client_fd, header, header_len, 0); | 57 (const uint8*)header, |
| 58 (uint32)(header_len + 1)); | |
| 58 free(header); | 59 free(header); |
| 59 | 60 |
| 60 // 5) Stream the body in a loop until everything is sent | 61 Seobeo_Handle_QueueData(cli, |
| 61 ssize_t total_sent = 0; | 62 (const uint8*)entry->buffer, |
| 62 const char *body = entry->buffer; | 63 (uint32)body_size); |
| 63 while ((size_t)total_sent < body_size) | |
| 64 { | |
| 65 ssize_t sent = send( | |
| 66 client_fd, | |
| 67 body + total_sent, | |
| 68 body_size - total_sent, | |
| 69 0 | |
| 70 ); | |
| 71 if (sent <= 0) | |
| 72 { | |
| 73 // error or connection closed by client | |
| 74 break; | |
| 75 } | |
| 76 total_sent += sent; | |
| 77 } | |
| 78 | 64 |
| 79 // 6) Tear down | 65 |
| 80 close(client_fd); | 66 Seobeo_Handle_Flush(cli); |
| 67 | |
| 68 Seobeo_Handle_Destroy(cli); | |
| 81 } | 69 } |
| 82 | 70 |
| 83 int main(void) | 71 int main(void) |
| 84 { | 72 { |
| 73 struct sigaction sa; | |
| 74 | |
| 85 cache = Dowa_HashMap_Create(1024); | 75 cache = Dowa_HashMap_Create(1024); |
| 86 if (Dowa_Cache_Folder(cache, "seobeo/pages") != 0) | 76 if (Dowa_Cache_Folder(cache, "seobeo/pages") != 0) |
| 87 { | 77 { |
| 88 perror("Dowa_Cache_Folder"); | 78 perror("Dowa_Cache_Folder"); |
| 89 return -1; | 79 return -1; |
| 90 } | 80 } |
| 91 | 81 |
| 92 struct sigaction sa; | 82 Seobeo_PHandle srv = Seobeo_Stream_Handle_Create(NULL, "8080"); |
| 83 | |
| 84 if (srv->socket < 0) return 1; | |
| 85 printf("Listening on port 8080\n"); | |
| 93 | 86 |
| 94 sa.sa_handler = SigchildHandler; // reap all dead processes | 87 sa.sa_handler = SigchildHandler; // reap all dead processes |
| 95 sigemptyset(&sa.sa_mask); | 88 sigemptyset(&sa.sa_mask); |
| 96 sa.sa_flags = SA_RESTART; | 89 sa.sa_flags = SA_RESTART; |
| 97 if (sigaction(SIGCHLD, &sa, NULL) == -1) { | 90 if (sigaction(SIGCHLD, &sa, NULL) == -1) { |
| 98 perror("sigaction"); | 91 perror("sigaction"); |
| 99 exit(1); | 92 exit(1); |
| 100 } | 93 } |
| 101 | |
| 102 int sock_fd = Seobeo_CreateSocket(1, "6969", 10); | |
| 103 Seobeo_ListenClient(sock_fd, &HandleClientRequest); | |
| 104 | 94 |
| 95 while (1) { | |
| 96 Seobeo_PHandle cli = Seobeo_Stream_Handle_Accept(srv); | |
| 97 if (cli == NULL) | |
| 98 { | |
| 99 continue; | |
| 100 } | |
| 101 printf("connected to %s\n", cli->host); | |
| 102 | |
| 103 if (!fork()) | |
| 104 { | |
| 105 HandleClientRequest(cli); | |
| 106 exit(0); | |
| 107 } | |
| 108 Seobeo_Handle_Destroy(cli); | |
| 109 } | |
| 110 | |
| 111 Seobeo_Handle_Destroy(srv); | |
| 105 return 0; | 112 return 0; |
| 106 } | 113 } |
| 107 |