51 lines
1.3 KiB
Go
51 lines
1.3 KiB
Go
|
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
|
||
|
|
||
|
}
|