| 1 | module websocket |
| 2 | |
| 3 | import rand |
| 4 | import crypto.sha1 |
| 5 | import encoding.base64 |
| 6 | import encoding.binary |
| 7 | import log |
| 8 | |
| 9 | const default_logger = setup_default_logger() |
| 10 | |
| 11 | fn setup_default_logger() &log.Log { |
| 12 | mut l := &log.Log{} |
| 13 | l.set_level(.info) |
| 14 | return l |
| 15 | } |
| 16 | |
| 17 | // htonl64 converts payload length to header bits |
| 18 | fn htonl64(payload_len u64) []u8 { |
| 19 | mut ret := []u8{len: 8} |
| 20 | binary.big_endian_put_u64(mut ret, payload_len) |
| 21 | return ret |
| 22 | } |
| 23 | |
| 24 | // create_masking_key returns a new masking key to use when masking websocket messages |
| 25 | fn create_masking_key() []u8 { |
| 26 | return rand.bytes(4) or { [u8(0), 0, 0, 0] } |
| 27 | } |
| 28 | |
| 29 | // create_key_challenge_response creates a key challenge response from security key |
| 30 | fn create_key_challenge_response(seckey string) !string { |
| 31 | if seckey.len == 0 { |
| 32 | return error('unexpected seckey length zero') |
| 33 | } |
| 34 | guid := '258EAFA5-E914-47DA-95CA-C5AB0DC85B11' |
| 35 | sha1buf := seckey + guid |
| 36 | shabytes := sha1buf.bytes() |
| 37 | hash := sha1.sum(shabytes) |
| 38 | b64 := base64.encode(hash) |
| 39 | unsafe { |
| 40 | hash.free() |
| 41 | shabytes.free() |
| 42 | } |
| 43 | return b64 |
| 44 | } |
| 45 | |
| 46 | // get_nonce creates a randomized array used in handshake process |
| 47 | fn get_nonce(nonce_size int) string { |
| 48 | return rand.string_from_set('0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz', |
| 49 | nonce_size) |
| 50 | } |
| 51 | |