package upgrade import ( "bytes" "fmt" "strings" ) // HeaderType represents all 'valid' HTTP request headers type HeaderType uint8 // header types const ( Unknown HeaderType = iota Host Upgrade Connection Origin WSKey WSProtocol WSExtensions WSVersion ) // HeaderValue represents a unique or multiple header value(s) type HeaderValue [][]byte // Header represents the data of a HTTP request header type Header struct { Name HeaderType Values HeaderValue } // ReadHeader tries to parse an HTTP header from a byte array func ReadHeader(b []byte) (*Header, error) { // 1. Split by ':' parts := bytes.Split(b, []byte(": ")) if len(parts) != 2 { return nil, fmt.Errorf("invalid HTTP header format '%s'", b) } // 2. Create instance inst := &Header{} // 3. Check for header name switch strings.ToLower(string(parts[0])) { case "host": inst.Name = Host case "upgrade": inst.Name = Upgrade case "connection": inst.Name = Connection case "origin": inst.Name = Origin case "sec-websocket-key": inst.Name = WSKey case "sec-websocket-protocol": inst.Name = WSProtocol case "sec-websocket-extensions": inst.Name = WSExtensions case "sec-websocket-version": inst.Name = WSVersion default: inst.Name = Unknown } // 4. Split values inst.Values = bytes.Split(parts[1], []byte(", ")) return inst, nil }