Mercurial
comparison seobeo/s_websocket.c @ 173:827c6ac504cd hg-web
Merged in default here.
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Mon, 19 Jan 2026 18:59:10 -0800 |
| parents | 0face9898d04 |
| children |
comparison
equal
deleted
inserted
replaced
| 151:c033667da5f9 | 173:827c6ac504cd |
|---|---|
| 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 if (headers && strlen(headers) > 0) | |
| 138 { | |
| 139 const char *line_start = headers; | |
| 140 while (*line_start) | |
| 141 { | |
| 142 while (*line_start == ' ' || *line_start == '\t') line_start++; | |
| 143 if (*line_start == '\0') break; | |
| 144 | |
| 145 const char *line_end = line_start; | |
| 146 while (*line_end && *line_end != '\n') line_end++; | |
| 147 | |
| 148 size_t line_len = line_end - line_start; | |
| 149 if (line_len > 0 && memchr(line_start, ':', line_len) != NULL) | |
| 150 { | |
| 151 while (line_len > 0 && (line_start[line_len-1] == '\r' || | |
| 152 line_start[line_len-1] == ' ' || line_start[line_len-1] == '\t')) | |
| 153 line_len--; | |
| 154 | |
| 155 if (line_len > 0 && handshake_len + line_len + 4 < sizeof(handshake)) | |
| 156 { | |
| 157 memcpy(handshake + handshake_len, line_start, line_len); | |
| 158 handshake_len += line_len; | |
| 159 handshake[handshake_len++] = '\r'; | |
| 160 handshake[handshake_len++] = '\n'; | |
| 161 } | |
| 162 } | |
| 163 | |
| 164 line_start = (*line_end == '\n') ? line_end + 1 : line_end; | |
| 165 } | |
| 166 } | |
| 167 | |
| 168 handshake[handshake_len++] = '\r'; | |
| 169 handshake[handshake_len++] = '\n'; | |
| 170 handshake[handshake_len] = '\0'; | |
| 136 | 171 |
| 137 Seobeo_Handle_Queue(p_ws->p_handle, (uint8*)handshake, (uint32)handshake_len); | 172 Seobeo_Handle_Queue(p_ws->p_handle, (uint8*)handshake, (uint32)handshake_len); |
| 138 if (Seobeo_Handle_Flush(p_ws->p_handle) < 0) | 173 if (Seobeo_Handle_Flush(p_ws->p_handle) < 0) |
| 139 { | 174 { |
| 140 Seobeo_Log(SEOBEO_ERROR, "Failed to send WebSocket handshake\n"); | 175 Seobeo_Log(SEOBEO_ERROR, "Failed to send WebSocket handshake\n"); |
| 188 Seobeo_Log(SEOBEO_INFO, "WebSocket connected to %s\n", url); | 223 Seobeo_Log(SEOBEO_INFO, "WebSocket connected to %s\n", url); |
| 189 | 224 |
| 190 return p_ws; | 225 return p_ws; |
| 191 } | 226 } |
| 192 | 227 |
| 193 // Seobeo_WebSocket_Mask_Data moved to s_websocket_common.c | 228 Seobeo_WebSocket *Seobeo_WebSocket_Connect(const char *url) |
| 229 { | |
| 230 return Seobeo_WebSocket_Connect_With_Headers(url, NULL); | |
| 231 } | |
| 194 | 232 |
| 195 static int32 Seobeo_WebSocket_Send_Frame(Seobeo_WebSocket *p_ws, Seobeo_WebSocket_Opcode opcode, | 233 static int32 Seobeo_WebSocket_Send_Frame(Seobeo_WebSocket *p_ws, Seobeo_WebSocket_Opcode opcode, |
| 196 const uint8 *payload, size_t payload_length, boolean fin) | 234 const uint8 *payload, size_t payload_length, boolean fin) |
| 197 { | 235 { |
| 198 if (!p_ws || p_ws->state != SEOBEO_WS_STATE_OPEN) | 236 if (!p_ws || p_ws->state != SEOBEO_WS_STATE_OPEN) |
| 478 p_msg->is_final = fin; | 516 p_msg->is_final = fin; |
| 479 | 517 |
| 480 return p_msg; | 518 return p_msg; |
| 481 } | 519 } |
| 482 | 520 |
| 483 // Seobeo_WebSocket_Message_Destroy moved to s_websocket_common.c | |
| 484 | |
| 485 int32 Seobeo_WebSocket_Close(Seobeo_WebSocket *p_ws, uint16 code, const char *reason) | 521 int32 Seobeo_WebSocket_Close(Seobeo_WebSocket *p_ws, uint16 code, const char *reason) |
| 486 { | 522 { |
| 487 if (!p_ws || p_ws->state == SEOBEO_WS_STATE_CLOSED) | 523 if (!p_ws || p_ws->state == SEOBEO_WS_STATE_CLOSED) |
| 488 return -1; | 524 return -1; |
| 489 | 525 |