comparison seobeo/tests/seobeo_http_framing_test.c @ 221:ce7f4400c2de hg-web

[hg-web] Harden forge and add changeset UI
author MrJuneJune <me@mrjunejune.com>
date Sun, 02 Aug 2026 09:01:24 -0700
parents
children
comparison
equal deleted inserted replaced
219:8c9bb0b0759e 221:ce7f4400c2de
1 #include "seobeo/seobeo.h"
2
3 #include <arpa/inet.h>
4 #include <pthread.h>
5 #include <stdio.h>
6 #include <string.h>
7
8 typedef struct {
9 int listener;
10 } Framing_Server;
11
12 static void *serve_close_delimited_response(void *argument)
13 {
14 Framing_Server *server = argument;
15 int client = accept(server->listener, NULL, NULL);
16 if (client >= 0) {
17 char request[1024];
18 (void)read(client, request, sizeof(request));
19 const char response[] =
20 "HTTP/1.1 200 OK\r\n"
21 "Content-Type: text/plain\r\n"
22 "Connection: close\r\n"
23 "\r\n"
24 "buffered-body";
25 (void)write(client, response, sizeof(response) - 1);
26 close(client);
27 }
28 return NULL;
29 }
30
31 int main(void)
32 {
33 int listener = socket(AF_INET, SOCK_STREAM, 0);
34 if (listener < 0)
35 return 1;
36
37 struct sockaddr_in address = {
38 .sin_family = AF_INET,
39 .sin_addr.s_addr = htonl(INADDR_LOOPBACK),
40 .sin_port = 0,
41 };
42 if (bind(listener, (struct sockaddr *)&address, sizeof(address)) != 0 ||
43 listen(listener, 1) != 0) {
44 close(listener);
45 return 1;
46 }
47
48 socklen_t address_length = sizeof(address);
49 if (getsockname(listener, (struct sockaddr *)&address, &address_length) != 0) {
50 close(listener);
51 return 1;
52 }
53
54 Framing_Server server = {.listener = listener};
55 pthread_t thread;
56 if (pthread_create(&thread, NULL, serve_close_delimited_response, &server) != 0) {
57 close(listener);
58 return 1;
59 }
60
61 char url[128];
62 snprintf(url, sizeof(url), "http://127.0.0.1:%u/", ntohs(address.sin_port));
63 Seobeo_Client_Request *request = Seobeo_Client_Request_Create(url);
64 Seobeo_Client_Request_Set_Timeout_Milliseconds(request, 1000);
65 Seobeo_Client_Response *response = Seobeo_Client_Request_Execute(request);
66
67 int failed = !response ||
68 response->status_code != 200 ||
69 response->body_length != strlen("buffered-body") ||
70 memcmp(response->body, "buffered-body", strlen("buffered-body")) != 0;
71 if (failed)
72 fprintf(stderr, "Close-delimited response body was not preserved\n");
73
74 Seobeo_Client_Response_Destroy(response);
75 Seobeo_Client_Request_Destroy(request);
76 pthread_join(thread, NULL);
77 close(listener);
78 return failed;
79 }