diff seobeo/s_websocket.c @ 163:058de208e640

[Config] Adding os ignore files.
author June Park <parkjune1995@gmail.com>
date Mon, 19 Jan 2026 04:52:02 -0800
parents f236c895604e
children 0face9898d04
line wrap: on
line diff
--- a/seobeo/s_websocket.c	Mon Jan 19 04:51:50 2026 -0800
+++ b/seobeo/s_websocket.c	Mon Jan 19 04:52:02 2026 -0800
@@ -88,7 +88,7 @@
   key_out[out_idx] = '\0';
 }
 
-Seobeo_WebSocket *Seobeo_WebSocket_Connect(const char *url)
+Seobeo_WebSocket *Seobeo_WebSocket_Connect_With_Headers(const char *url, const char *headers)
 {
   Seobeo_WebSocket *p_ws = malloc(sizeof(Seobeo_WebSocket));
   if (!p_ws)
@@ -123,17 +123,60 @@
   char ws_key[32];
   Seobeo_WebSocket_Generate_Key(ws_key, sizeof(ws_key));
 
-  char handshake[2048];
+  // Build handshake with optional custom headers
+  char handshake[4096];
   int handshake_len = snprintf(handshake, sizeof(handshake),
     "GET %s HTTP/1.1\r\n"
     "Host: %s\r\n"
     "Upgrade: websocket\r\n"
     "Connection: Upgrade\r\n"
     "Sec-WebSocket-Key: %s\r\n"
-    "Sec-WebSocket-Version: 13\r\n"
-    "\r\n",
+    "Sec-WebSocket-Version: 13\r\n",
     p_ws->path, p_ws->host, ws_key);
 
+  // Add custom headers if provided
+  if (headers && strlen(headers) > 0)
+  {
+    // Parse newline-separated headers and convert to HTTP format
+    const char *line_start = headers;
+    while (*line_start)
+    {
+      // Skip leading whitespace
+      while (*line_start == ' ' || *line_start == '\t') line_start++;
+      if (*line_start == '\0') break;
+
+      // Find end of line
+      const char *line_end = line_start;
+      while (*line_end && *line_end != '\n') line_end++;
+
+      // Copy line if it contains a colon (valid header)
+      size_t line_len = line_end - line_start;
+      if (line_len > 0 && memchr(line_start, ':', line_len) != NULL)
+      {
+        // Remove trailing whitespace/CR
+        while (line_len > 0 && (line_start[line_len-1] == '\r' ||
+               line_start[line_len-1] == ' ' || line_start[line_len-1] == '\t'))
+          line_len--;
+
+        if (line_len > 0 && handshake_len + line_len + 4 < sizeof(handshake))
+        {
+          memcpy(handshake + handshake_len, line_start, line_len);
+          handshake_len += line_len;
+          handshake[handshake_len++] = '\r';
+          handshake[handshake_len++] = '\n';
+        }
+      }
+
+      // Move to next line
+      line_start = (*line_end == '\n') ? line_end + 1 : line_end;
+    }
+  }
+
+  // End headers
+  handshake[handshake_len++] = '\r';
+  handshake[handshake_len++] = '\n';
+  handshake[handshake_len] = '\0';
+
   Seobeo_Handle_Queue(p_ws->p_handle, (uint8*)handshake, (uint32)handshake_len);
   if (Seobeo_Handle_Flush(p_ws->p_handle) < 0)
   {
@@ -190,6 +233,11 @@
   return p_ws;
 }
 
+Seobeo_WebSocket *Seobeo_WebSocket_Connect(const char *url)
+{
+  return Seobeo_WebSocket_Connect_With_Headers(url, NULL);
+}
+
 // Seobeo_WebSocket_Mask_Data moved to s_websocket_common.c
 
 static int32 Seobeo_WebSocket_Send_Frame(Seobeo_WebSocket *p_ws, Seobeo_WebSocket_Opcode opcode,