[internal.http.request.parser.header] multi-value header parser

This commit is contained in:
xdrm-brackets 2018-04-25 15:00:43 +02:00
parent b3ccc911ee
commit e375de0f33
2 changed files with 73 additions and 0 deletions

View File

@ -0,0 +1,51 @@
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
}

View File

@ -0,0 +1,22 @@
package header
// HeaderType represents all 'valid' HTTP request headers
type HeaderType byte
const (
UNKNOWN HeaderType = iota
HOST
UPGRADE
CONNECTION
ORIGIN
WSKEY
WSPROTOCOL
WSEXTENSIONS
WSVERSION
)
// T represents the data of a HTTP request header
type T struct{
Name HeaderType
Values [][]byte
}