Skip to content
File

Blob: src/workerd/api/tests/websocket-client-error-sidecar.js

javascript98 lines
1// Copyright (c) 2025 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4 
5const http = require('http');
6const crypto = require('crypto');
7 
8// Handle upgrade requests to switch from HTTP to WebSocket protocol
9function upgradeToWebSocketConnection(req, socket, head) {
10 // Check if it's a WebSocket upgrade request
11 if (req.headers['upgrade'] !== 'websocket') {
12 socket.end('HTTP/1.1 400 Bad Request');
13 return;
14 }
15 
16 // Get the WebSocket key from the client
17 const webSocketKey = req.headers['sec-websocket-key'];
18 const GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'; // WebSocket protocol GUID
19 
20 // Create the accept key by concatenating the key and GUID, then hashing
21 const acceptKey = crypto
22 .createHash('sha1')
23 .update(webSocketKey + GUID)
24 .digest('base64');
25 
26 // Write WebSocket handshake response headers
27 socket.write(
28 'HTTP/1.1 101 Switching Protocols\r\n' +
29 'Upgrade: websocket\r\n' +
30 'Connection: Upgrade\r\n' +
31 `Sec-WebSocket-Accept: ${acceptKey}\r\n` +
32 '\r\n'
33 );
34 
35 // Socket is now a WebSocket connection
36 handleWebSocketConnection(socket);
37}
38 
39// Function to send a message to the client
40function sendMessage(socket, message) {
41 const payload = Buffer.from(message);
42 const payloadLength = payload.length;
43 
44 // Create frame header
45 let header;
46 
47 if (payloadLength <= 125) {
48 header = Buffer.alloc(2);
49 header[1] = payloadLength;
50 } else if (payloadLength <= 65535) {
51 header = Buffer.alloc(4);
52 header[1] = 126;
53 header.writeUInt16BE(payloadLength, 2);
54 } else {
55 header = Buffer.alloc(10);
56 header[1] = 127;
57 // Write length as 64-bit integer (simplified here)
58 header.writeBigUInt64BE(BigInt(payloadLength), 2);
59 }
60 
61 // Set the first byte: FIN bit (0x80) + opcode 0x01 for text data
62 header[0] = 0x81;
63 
64 // Combine header and payload
65 const frame = Buffer.concat([header, payload]);
66 
67 // Send the frame
68 socket.write(frame);
69}
70 
71// Get the port and host from environment variables
72const port = process.env.BIG_MESSAGE_SERVER_PORT;
73const host = process.env.SIDECAR_HOSTNAME;
74 
75function reportAddress(server) {
76 const address = server.address();
77 console.info(`Listening on ${address.address}:${address.port}`);
78}
79 
80// Create HTTP server to handle the WebSocket handshake
81const server = http.createServer((req, res) => {
82 res.writeHead(200, { 'Content-Type': 'text/plain' });
83 res.end('WebSocket server is running');
84});
85server.on('upgrade', upgradeToWebSocketConnection);
86server.on('error', (event) => {
87 console.log(event);
88 console.log(event.message);
89});
90// Start the server
91server.listen(port, host, () => reportAddress(server));
92 
93// Function to handle WebSocket connections
94function handleWebSocketConnection(socket) {
95 // Send a welcome message
96 sendMessage(socket, new Uint8Array(33 * 1024 * 1024));
97}