Skip to content

Instantly share code, notes, and snippets.

@non-reai
Last active March 27, 2023 19:27
Show Gist options
  • Save non-reai/7f1fd4fe0cf44270871c15ea57901721 to your computer and use it in GitHub Desktop.
Save non-reai/7f1fd4fe0cf44270871c15ea57901721 to your computer and use it in GitHub Desktop.
Native nodejs websocket server with http module + no libraries
const http = require("http")
const crypto = require("crypto")
const server = http.createServer((req,res)=>{
res.write("hi")
res.end()
})
server.on("upgrade",(req,socket)=>{
const accept = crypto.Hash("sha1").update(req.headers["sec-websocket-key"]+"258EAFA5-E914-47DA-95CA-C5AB0DC85B11").digest("base64")
const headers = [
'HTTP/1.1 101 Switching Protocols',
'Upgrade: WebSocket',
'Connection: Upgrade',
'Sec-WebSocket-Accept: '+accept,
''
].map(line => line.concat('\r\n')).join('')
socket.write(headers)
socket.on('data', (bytes) => {
console.log(parseData(bytes))
sendData("hi from server")
})
const sendData = (data) => {
let obj = []
obj[0] = 129
if (data.length < 126) {
obj[1] = data.length
for (let i = 0; i < data.length; i++) {
obj[i+2] = parseInt(data[i].charCodeAt(0).toString(2),2)
}
} else if (data.length <= 65535) {
obj[1] = 126
for (let i = 0; i < 3; i++) {
obj[i+2] = parseInt(data.length.toString(2).padStart(16,"0").substring(i*8,i*8+8),2)
}
for (let i = 4; i < data.length; i++) {
obj[i] = parseInt(data[i].charCodeAt(0).toString(2),2)
}
} else if (data.length < 18446744073709551615) {
obj[1] = 127
for (let i = 0; i < 8; i++) {
obj[i+2] = parseInt(data.length.toString(2).padStart(64,"0").substring(i*8,i*8+8),2)
}
for (let i = 9; i < data.length; i++) {
obj[i] = parseInt(data[i].charCodeAt(0).toString(2),2)
}
} else {
console.log("data too big")
}
socket.write(Uint8Array.from(obj))
}
const parseData = (bytes) => {
const length = bytes[1] - 128 < 126 ? 1 : bytes == 126 ? 2 : 8
const maskKey = bytes.slice(length+1,length+5)
const data = bytes.slice(length+5)
return String.fromCharCode.apply(null,data.map((byte,i)=>byte^maskKey[i%4]))
}
socket.on("error",(err)=>{
console.log(err)
})
socket.on("end",()=>{
console.log("disconnect")
})
})
server.listen(80, () => {
console.log("Started.")
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment