annotate seobeo/tests/seobeo_http_framing_test.c @ 281:c57149ad216e default tip

Copilot-Session: f68442b1-fa8f-46a0-9689-81710613bbd4
author MrJuneJune <me@mrjunejune.com>
date Tue, 18 Aug 2026 22:18:15 -0700
parents b3b547563ec7
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1 #include "seobeo/seobeo.h"
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
3 #include <arpa/inet.h>
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
4 #include <pthread.h>
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
5 #include <stdio.h>
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
6 #include <string.h>
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
7
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
8 typedef struct {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
9 int listener;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
10 } Framing_Server;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
11
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
12 static void *serve_close_delimited_response(void *argument)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
13 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
14 Framing_Server *server = argument;
279
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
15 for (int response_index = 0; response_index < 2; response_index++) {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
16 int client = accept(server->listener, NULL, NULL);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
17 if (client < 0)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
18 continue;
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
19 char request[1024];
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
20 (void)read(client, request, sizeof(request));
279
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
21 if (response_index == 0) {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
22 const char response[] =
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
23 "HTTP/1.1 200 OK\r\n"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
24 "Content-Type: text/plain\r\n"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
25 "Connection: close\r\n"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
26 "\r\n"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
27 "buffered-body";
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
28 (void)write(client, response, sizeof(response) - 1);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
29 } else {
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
30 const char response[] =
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
31 "HTTP/1.1 200 OK\r\n"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
32 "Content-Type: application/json\r\n"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
33 "Transfer-Encoding: chunked\r\n"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
34 "Connection: close\r\n"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
35 "\r\n"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
36 "7;sample=yes\r\n"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
37 "{\"ok\":t\r\n"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
38 "4\r\n"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
39 "rue}\r\n"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
40 "0\r\n"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
41 "X-Trailer: ignored\r\n"
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
42 "\r\n";
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
43 (void)write(client, response, sizeof(response) - 1);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
44 }
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
45 close(client);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
46 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
47 return NULL;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
48 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
49
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
50 int main(void)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
51 {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
52 int listener = socket(AF_INET, SOCK_STREAM, 0);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
53 if (listener < 0)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
54 return 1;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
55
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
56 struct sockaddr_in address = {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
57 .sin_family = AF_INET,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
58 .sin_addr.s_addr = htonl(INADDR_LOOPBACK),
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
59 .sin_port = 0,
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
60 };
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
61 if (bind(listener, (struct sockaddr *)&address, sizeof(address)) != 0 ||
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
62 listen(listener, 1) != 0) {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
63 close(listener);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
64 return 1;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
65 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
66
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
67 socklen_t address_length = sizeof(address);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
68 if (getsockname(listener, (struct sockaddr *)&address, &address_length) != 0) {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
69 close(listener);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
70 return 1;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
71 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
72
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
73 Framing_Server server = {.listener = listener};
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
74 pthread_t thread;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
75 if (pthread_create(&thread, NULL, serve_close_delimited_response, &server) != 0) {
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
76 close(listener);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
77 return 1;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
78 }
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
79
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
80 char url[128];
279
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
81 snprintf(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
82 url, sizeof(url), "http://127.0.0.1:%u/close",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
83 ntohs(address.sin_port));
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
84 Seobeo_Client_Request *request = Seobeo_Client_Request_Create(url);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
85 Seobeo_Client_Request_Set_Timeout_Milliseconds(request, 1000);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
86 Seobeo_Client_Response *response = Seobeo_Client_Request_Execute(request);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
87
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
88 int failed = !response ||
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
89 response->status_code != 200 ||
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
90 response->body_length != strlen("buffered-body") ||
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
91 memcmp(response->body, "buffered-body", strlen("buffered-body")) != 0;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
92 if (failed)
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
93 fprintf(stderr, "Close-delimited response body was not preserved\n");
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
94
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
95 Seobeo_Client_Response_Destroy(response);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
96 Seobeo_Client_Request_Destroy(request);
279
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
97
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
98 snprintf(
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
99 url, sizeof(url), "http://127.0.0.1:%u/chunked",
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
100 ntohs(address.sin_port));
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
101 request = Seobeo_Client_Request_Create(url);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
102 Seobeo_Client_Request_Set_Timeout_Milliseconds(request, 1000);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
103 response = Seobeo_Client_Request_Execute(request);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
104 int chunked_failed = !response ||
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
105 response->status_code != 200 ||
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
106 response->body_length != strlen("{\"ok\":true}") ||
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
107 memcmp(response->body, "{\"ok\":true}", strlen("{\"ok\":true}")) != 0;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
108 if (chunked_failed)
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
109 fprintf(stderr, "Chunked response body was not decoded\n");
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
110 failed = failed || chunked_failed;
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
111
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
112 Seobeo_Client_Response_Destroy(response);
b3b547563ec7 Add Google connector service and agent wiki
MrJuneJune <me@mrjunejune.com>
parents: 221
diff changeset
113 Seobeo_Client_Request_Destroy(request);
221
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
114 pthread_join(thread, NULL);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
115 close(listener);
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
116 return failed;
ce7f4400c2de [hg-web] Harden forge and add changeset UI
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
117 }