1package main 2 3import ( 4 "bytes" 5 "crypto/rand" 6 "encoding/hex" 7 "fmt" 8) 9 10// These constants help to indicate the type of payload 11const ( 12 RequestPayload = '1' 13 ResponsePayload = '2' 14 ReplayedResponsePayload = '3' 15) 16 17func randByte(len int) []byte { 18 b := make([]byte, len/2) 19 rand.Read(b) 20 21 h := make([]byte, len) 22 hex.Encode(h, b) 23 24 return h 25} 26 27func uuid() []byte { 28 return randByte(24) 29} 30 31var payloadSeparator = "\n\n" 32 33func payloadScanner(data []byte, atEOF bool) (advance int, token []byte, err error) { 34 if atEOF && len(data) == 0 { 35 return 0, nil, nil 36 } 37 38 if i := bytes.Index(data, []byte(payloadSeparator)); i >= 0 { 39 // We have a full newline-terminated line. 40 return i + len([]byte(payloadSeparator)), data[0:i], nil 41 } 42 43 if atEOF { 44 return len(data), data, nil 45 } 46 return 0, nil, nil 47} 48 49// Timing is request start or round-trip time, depending on payloadType 50func payloadHeader(payloadType byte, uuid []byte, timing int64, latency int64) (header []byte) { 51 //Example: 52 // 3 f45590522cd1838b4a0d5c5aab80b77929dea3b3 13923489726487326 1231\n 53 return []byte(fmt.Sprintf("%c %s %d %d\n", payloadType, uuid, timing, latency)) 54} 55 56func payloadBody(payload []byte) []byte { 57 headerSize := bytes.IndexByte(payload, '\n') 58 return payload[headerSize+1:] 59} 60 61func payloadMeta(payload []byte) [][]byte { 62 headerSize := bytes.IndexByte(payload, '\n') 63 if headerSize < 0 { 64 return nil 65 } 66 return bytes.Split(payload[:headerSize], []byte{' '}) 67} 68 69func payloadID(payload []byte) (id []byte) { 70 meta := payloadMeta(payload) 71 72 if len(meta) < 2 { 73 return 74 } 75 // id is encoded in hex, we need to revert to how it was 76 id = make([]byte, 20) 77 hex.Decode(id, meta[1]) 78 return 79} 80 81func isOriginPayload(payload []byte) bool { 82 switch payload[0] { 83 case RequestPayload, ResponsePayload: 84 return true 85 default: 86 return false 87 } 88} 89 90func isRequestPayload(payload []byte) bool { 91 return payload[0] == RequestPayload 92} 93