Mercurial
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 162:8ceb5d3c6bdd | 163:058de208e640 |
|---|---|
| 86 } | 86 } |
| 87 | 87 |
| 88 key_out[out_idx] = '\0'; | 88 key_out[out_idx] = '\0'; |
| 89 } | 89 } |
| 90 | 90 |
| 91 Seobeo_WebSocket *Seobeo_WebSocket_Connect(const char *url) | 91 Seobeo_WebSocket *Seobeo_WebSocket_Connect_With_Headers(const char *url, const char *headers) |
| 92 { | 92 { |
| 93 Seobeo_WebSocket *p_ws = malloc(sizeof(Seobeo_WebSocket)); | 93 Seobeo_WebSocket *p_ws = malloc(sizeof(Seobeo_WebSocket)); |
| 94 if (!p_ws) | 94 if (!p_ws) |
| 95 return NULL; | 95 return NULL; |
| 96 | 96 |
| 121 } | 121 } |
| 122 | 122 |
| 123 char ws_key[32]; | 123 char ws_key[32]; |
| 124 Seobeo_WebSocket_Generate_Key(ws_key, sizeof(ws_key)); | 124 Seobeo_WebSocket_Generate_Key(ws_key, sizeof(ws_key)); |
| 125 | 125 |
| 126 char handshake[2048]; | 126 // Build handshake with optional custom headers |
| 127 char handshake[4096]; | |
| 127 int handshake_len = snprintf(handshake, sizeof(handshake), | 128 int handshake_len = snprintf(handshake, sizeof(handshake), |
| 128 "GET %s HTTP/1.1\r\n" | 129 "GET %s HTTP/1.1\r\n" |
| 129 "Host: %s\r\n" | 130 "Host: %s\r\n" |
| 130 "Upgrade: websocket\r\n" | 131 "Upgrade: websocket\r\n" |
| 131 "Connection: Upgrade\r\n" | 132 "Connection: Upgrade\r\n" |
| 132 "Sec-WebSocket-Key: %s\r\n" | 133 "Sec-WebSocket-Key: %s\r\n" |
| 133 "Sec-WebSocket-Version: 13\r\n" | 134 "Sec-WebSocket-Version: 13\r\n", |
| 134 "\r\n", | |
| 135 p_ws->path, p_ws->host, ws_key); | 135 p_ws->path, p_ws->host, ws_key); |
| 136 | |
| 137 // Add custom headers if provided | |
| 138 if (headers && strlen(headers) > 0) | |
| 139 { | |
| 140 // Parse newline-separated headers and convert to HTTP format | |
| 141 const char *line_start = headers; | |
| 142 while (*line_start) | |
| 143 { | |
| 144 // Skip leading whitespace | |
| 145 while (*line_start == ' ' || *line_start == '\t') line_start++; | |
| 146 if (*line_start == '\0') break; | |
| 147 | |
| 148 // Find end of line | |
| 149 const char *line_end = line_start; | |
| 150 while (*line_end && *line_end != '\n') line_end++; | |
| 151 | |
| 152 // Copy line if it contains a colon (valid header) | |
| 153 size_t line_len = line_end - line_start; | |
| 154 if (line_len > 0 && memchr(line_start, ':', line_len) != NULL) | |
| 155 { | |
| 156 // Remove trailing whitespace/CR | |
| 157 while (line_len > 0 && (line_start[line_len-1] == '\r' || | |
| 158 line_start[line_len-1] == ' ' || line_start[line_len-1] == '\t')) | |
| 159 line_len--; | |
| 160 | |
| 161 if (line_len > 0 && handshake_len + line_len + 4 < sizeof(handshake)) | |
| 162 { | |
| 163 memcpy(handshake + handshake_len, line_start, line_len); | |
| 164 handshake_len += line_len; | |
| 165 handshake[handshake_len++] = '\r'; | |
| 166 handshake[handshake_len++] = '\n'; | |
| 167 } | |
| 168 } | |
| 169 | |
| 170 // Move to next line | |
| 171 line_start = (*line_end == '\n') ? line_end + 1 : line_end; | |
| 172 } | |
| 173 } | |
| 174 | |
| 175 // End headers | |
| 176 handshake[handshake_len++] = '\r'; | |
| 177 handshake[handshake_len++] = '\n'; | |
| 178 handshake[handshake_len] = '\0'; | |
| 136 | 179 |
| 137 Seobeo_Handle_Queue(p_ws->p_handle, (uint8*)handshake, (uint32)handshake_len); | 180 Seobeo_Handle_Queue(p_ws->p_handle, (uint8*)handshake, (uint32)handshake_len); |
| 138 if (Seobeo_Handle_Flush(p_ws->p_handle) < 0) | 181 if (Seobeo_Handle_Flush(p_ws->p_handle) < 0) |
| 139 { | 182 { |
| 140 Seobeo_Log(SEOBEO_ERROR, "Failed to send WebSocket handshake\n"); | 183 Seobeo_Log(SEOBEO_ERROR, "Failed to send WebSocket handshake\n"); |
| 188 Seobeo_Log(SEOBEO_INFO, "WebSocket connected to %s\n", url); | 231 Seobeo_Log(SEOBEO_INFO, "WebSocket connected to %s\n", url); |
| 189 | 232 |
| 190 return p_ws; | 233 return p_ws; |
| 191 } | 234 } |
| 192 | 235 |
| 236 Seobeo_WebSocket *Seobeo_WebSocket_Connect(const char *url) | |
| 237 { | |
| 238 return Seobeo_WebSocket_Connect_With_Headers(url, NULL); | |
| 239 } | |
| 240 | |
| 193 // Seobeo_WebSocket_Mask_Data moved to s_websocket_common.c | 241 // Seobeo_WebSocket_Mask_Data moved to s_websocket_common.c |
| 194 | 242 |
| 195 static int32 Seobeo_WebSocket_Send_Frame(Seobeo_WebSocket *p_ws, Seobeo_WebSocket_Opcode opcode, | 243 static int32 Seobeo_WebSocket_Send_Frame(Seobeo_WebSocket *p_ws, Seobeo_WebSocket_Opcode opcode, |
| 196 const uint8 *payload, size_t payload_length, boolean fin) | 244 const uint8 *payload, size_t payload_length, boolean fin) |
| 197 { | 245 { |