package header import ( "regexp" "fmt" "strings" "bytes" ) // parse tries to return a 'T' (httpHeader) from a byte array func Parse(b []byte) (*T, 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 := new(T) /* (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) Check format */ checker := regexp.MustCompile(`^(?:[^,]+,\s*)*[^,]+$`) if !checker.Match(parts[1]) { return nil, fmt.Errorf("Invalid HTTP header value format '%s'", parts[1]); } /* (5) Normalise format */ normaliser := regexp.MustCompile(`,\s+`) values := normaliser.ReplaceAll(parts[1], []byte(",")) /* (5) Split values */ inst.Values = bytes.Split(values, []byte(",")) return inst, nil }