Mercurial
diff 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 |
line wrap: on
line diff
--- a/seobeo/main.c Wed Sep 24 13:15:32 2025 -0700 +++ b/seobeo/main.c Wed Sep 24 18:49:09 2025 -0700 @@ -4,6 +4,8 @@ #include "seobeo/seobeo.h" +Dowa_PHashMap cache; + void SigchildHandler(int s) { (void)s; // quiet unused variable warning @@ -16,63 +18,76 @@ errno = saved_errno; } - -void *GetInternetaddr(struct sockaddr *sa) -{ - if (sa->sa_family == AF_INET) - { - return &(((struct sockaddr_in*)sa)->sin_addr); - } - - return &(((struct sockaddr_in6*)sa)->sin6_addr); -} - void HandleClientRequest(int client_fd) { - FILE *file = fopen("seobeo/index.html", "rb"); - if (!file) { - perror("fopen"); + size_t idx = Dowa_HashMap_GetPosition(cache, "index.html"); + Dowa_PHashEntry entry = cache->entries[idx]; + if (!entry) { + // 404 response if missing + const char *not_found = + "HTTP/1.1 404 Not Found\r\n" + "Content-Length: 0\r\n" + "Connection: close\r\n" + "\r\n"; + send(client_fd, not_found, strlen(not_found), 0); + close(client_fd); return; } - fseek(file, 0, SEEK_END); - size_t size = ftell(file); - fseek(file, 0, SEEK_SET); - - char *data = malloc(size); - fread(data, 1, size, file); - fclose(file); - - char *header = malloc(100); - sprintf( - header, + // 3) Prepare header with the correct contentālength + size_t body_size = entry->capacity; + const char *template = "HTTP/1.1 200 OK\r\n" "Content-Type: text/html\r\n" "Content-Length: %zu\r\n" "Connection: close\r\n" - "\r\n", - size - ); + "\r\n"; + + // Compute how large the header is and allocate just enough space + int header_len = snprintf(NULL, 0, template, body_size); + char *header = malloc(header_len + 1); + if (!header) { + perror("malloc"); + close(client_fd); + return; + } + snprintf(header, header_len + 1, template, body_size); + + // 4) Send header + send(client_fd, header, header_len, 0); + free(header); - send(client_fd, header, strlen(header), 0); + // 5) Stream the body in a loop until everything is sent ssize_t total_sent = 0; - while (total_sent < size) + const char *body = entry->buffer; + while ((size_t)total_sent < body_size) { - ssize_t sent = send(client_fd, data + total_sent, size - total_sent, 0); - if (sent <= 0) break; + ssize_t sent = send( + client_fd, + body + total_sent, + body_size - total_sent, + 0 + ); + if (sent <= 0) + { + // error or connection closed by client + break; + } total_sent += sent; } + // 6) Tear down close(client_fd); } int main(void) { - int32 client_fd; - struct sockaddr_storage client_addr; - socklen_t sin_size; - - char client_inet_addr[INET6_ADDRSTRLEN]; + cache = Dowa_HashMap_Create(1024); + if (Dowa_Cache_Folder(cache, "seobeo/pages") != 0) + { + perror("Dowa_Cache_Folder"); + return -1; + } struct sigaction sa; @@ -85,37 +100,7 @@ } int sock_fd = Seobeo_CreateSocket(1, "6969", 10); - - printf("server: waiting for connections...\n"); - - while (1) - { - sin_size = sizeof(client_addr); - client_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &sin_size); - - if (client_fd == -1) - { - perror("accept"); - break; - } - - inet_ntop( - client_addr.ss_family, - GetInternetaddr((struct sockaddr *)&client_addr), - client_inet_addr, sizeof client_inet_addr); - - printf("server: got connection from %s\n", client_inet_addr); - - // Create a child process - if (!fork()) - { - close(sock_fd); - HandleClientRequest(client_fd); - exit(0); - } - - close(client_fd); - } + Seobeo_ListenClient(sock_fd, &HandleClientRequest); return 0; }