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