annotate seobeo/tests/seobeo_http_framing_test.c @ 279:b3b547563ec7

Add Google connector service and agent wiki Implement the C/Seobeo Google Drive and Gmail connector with encrypted OAuth storage, Zenbu authentication, browser testing, AI tool discovery, chunked HTTP decoding, and Bazel coverage. Consolidate repository guidance into progressive wiki documentation and enforce arena-first allocation for new first-party C code. Co-authored-by: Copilot <[email protected]> Copilot-Session: 84c338fd-0939-4bb3-b7f3-1062eb213e5d
author MrJuneJune <me@mrjunejune.com>
date Mon, 17 Aug 2026 22:22:36 -0700
parents ce7f4400c2de
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 }