httphead
packagemoduleThis package is not in the latest version of its module.
Details
Validgo.mod file
The Go module system was introduced in Go 1.11 and is the official dependency management solution for Go.
Redistributable license
Redistributable licenses place minimal restrictions on how software can be used, modified, and redistributed.
Tagged version
Modules with tagged versions give importers more predictable builds.
Stable version
When a project reaches major version v1 it is considered stable.
- Learn more about best practices
Repository
Links
README¶
httphead.go
Tiny HTTP header value parsing library in go.
Overview
This library contains low-level functions for scanning HTTP RFC2616 compatible header value grammars.
Install
go get github.com/gobwas/httphead
Example
The example below shows how multiple-choise HTTP header value could be parsed with this library:
options, ok := httphead.ParseOptions([]byte(`foo;bar=1,baz`), nil)fmt.Println(options, ok)// Output: [{foo map[bar:1]} {baz map[]}] true
The low-level example below shows how to optimize keys skipping and selectionof some key:
// The right part of full header line like:// X-My-Header: key;foo=bar;baz,key;bazheader := []byte(`foo;a=0,foo;a=1,foo;a=2,foo;a=3`)// We want to search key "foo" with an "a" parameter that equal to "2".var (foo = []byte(`foo`)a = []byte(`a`)v = []byte(`2`))var found boolhttphead.ScanOptions(header, func(i int, key, param, value []byte) Control {if !bytes.Equal(key, foo) {return ControlSkip}if !bytes.Equal(param, a) {if bytes.Equal(value, v) {// Found it!found = truereturn ControlBreak}return ControlSkip}return ControlContinue})
For more usage examples please seedocs or package tests.
Documentation¶
Overview¶
Package httphead contains utils for parsing HTTP and HTTP-grammar compatibletext protocols headers.
That is, this package first aim is to bring ability to easily parseconstructions, described herehttps://tools.ietf.org/html/rfc2616#section-2
Index¶
- Variables
- func CanonicalizeHeaderKey(k []byte)
- func IntFromASCII(bts []byte) (ret int, ok bool)
- func ParseHeaderLine(line []byte) (k, v []byte, ok bool)
- func ParseVersion(bts []byte) (major, minor int, ok bool)
- func ReadLine(br *bufio.Reader) ([]byte, error)
- func RemoveByte(data []byte, c byte) []byte
- func ScanCookie(data []byte, it func(key, value []byte) bool) bool
- func ScanOptions(data []byte, it func(index int, option, attribute, value []byte) Control) bool
- func ScanPairGreedy(data []byte, open, close byte) (n int)
- func ScanTokens(data []byte, it func([]byte) bool) bool
- func ScanUntil(data []byte, c byte) (n int)
- func SkipSpace(p []byte) (n int)
- func SplitRequestLine(line []byte) (method, uri, version []byte)
- func SplitResponseLine(line []byte) (version, status, reason []byte)
- func ValidCookieName(name []byte) bool
- func ValidCookieValue(value []byte, strict bool) bool
- func WriteOptions(dest io.Writer, options []Option) (n int, err error)
- type Control
- type CookieScanner
- type ItemType
- type OctetType
- type Option
- type OptionSelector
- type Parameters
- func (p *Parameters) Copy(dst []byte) (Parameters, []byte)
- func (p Parameters) Equal(b Parameters) bool
- func (p *Parameters) ForEach(cb func(k, v []byte) bool)
- func (p *Parameters) Get(key string) (value []byte, ok bool)
- func (p *Parameters) Set(key, value []byte)
- func (p *Parameters) Size() int
- func (p *Parameters) String() (ret string)
- type RequestLine
- type ResponseLine
- type Scanner
- func (l *Scanner) Advance(n int) bool
- func (l *Scanner) Buffered() int
- func (l *Scanner) Bytes() []byte
- func (l *Scanner) FetchUntil(c byte) bool
- func (l *Scanner) Next() bool
- func (l *Scanner) Peek() byte
- func (l *Scanner) Peek2() (a, b byte)
- func (l *Scanner) Skip(c byte)
- func (l *Scanner) SkipEscaped(c byte)
- func (l *Scanner) Type() ItemType
- type SelectFlag
- type Version
Examples¶
Constants¶
This section is empty.
Variables¶
var DefaultCookieScanner =CookieScanner{}
DefaultCookieScanner is a CookieScanner which is used by ScanCookie().Note that it is intended to have the same behavior as http.Request.Cookies()has.
var OctetTypes [256]OctetType
OctetTypes is a table of octets.
Functions¶
funcCanonicalizeHeaderKey¶
func CanonicalizeHeaderKey(k []byte)
CanonicalizeHeaderKey is like standard textproto/CanonicalMIMEHeaderKey,except that it operates with slice of bytes and modifies it inplace withoutcopying.
funcIntFromASCII¶
IntFromASCII converts ascii encoded decimal numeric value from HTTP entitiesto an integer.
funcParseHeaderLine¶
ParseHeaderLine parses HTTP header as key-value pair. It returns parsedvalues and true if parse is ok.
funcParseVersion¶
ParseVersion parses major and minor version of HTTP protocol.It returns parsed values and true if parse is ok.
funcReadLine¶
ReadLine reads line from br. It reads until '\n' and returns bytes without'\n' or '\r\n' at the end.It returns err if and only if line does not end in '\n'. Note that readbytes returned in any case of error.
It is much like the textproto/Reader.ReadLine() except the thing that itreturns raw bytes, instead of string. That is, it avoids copying bytes readfrom br.
textproto/Reader.ReadLineBytes() is also makes copy of resulting bytes to besafe with future I/O operations on br.
We could control I/O operations on br and do not need to make additionalcopy for safety.
funcRemoveByte¶
RemoveByte returns data without c. If c is not present in data it returnsthe same slice. If not, it copies data without c.
funcScanCookie¶
ScanCookie scans cookie pairs from data using DefaultCookieScanner.Scan()method.
funcScanOptions¶
ScanOptions parses data in this form:
values = 1#valuevalue = token *( ";" param )param = token [ "=" (token | quoted-string) ]
It calls given callback with the index of the option, option itself and itsparameter (attribute and its value, both could be nil). Index is useful whenheader contains multiple choises for the same named option.
Given callback should return one of the defined Control* values.ControlSkip means that passed key is not in caller's interest. That is, allparameters of that key will be skipped.ControlBreak means that no more keys and parameters should be parsed. Thatis, it must break parsing immediately.ControlContinue means that caller want to receive next parameter and itsvalue or the next key.
It returns false if data is malformed.
Example¶
foo := map[string]string{}ScanOptions([]byte(`foo;bar=1;baz`), func(index int, key, param, value []byte) Control {foo[string(param)] = string(value)return ControlContinue})fmt.Printf("bar:%s baz:%s", foo["bar"], foo["baz"])
Output:bar:1 baz:
funcScanPairGreedy¶
ScanPairGreedy scans for complete pair of opening and closing chars in greedy manner.Note that first opening byte must not be present in data.
funcScanTokens¶
ScanTokens parses data in this form:
list = 1#token
It returns false if data is malformed.
Example¶
var values []stringScanTokens([]byte(`a,b,c`), func(v []byte) bool {values = append(values, string(v))return v[0] != 'b'})fmt.Println(values)
Output:[a b]
funcScanUntil¶
ScanUntil scans for first non-escaped character c in given data.It returns index of matched c and -1 if c is not found.
funcSplitRequestLine¶
SplitRequestLine splits given slice of bytes into three chunks withoutparsing.
funcSplitResponseLine¶
SplitResponseLine splits given slice of bytes into three chunks withoutparsing.
funcValidCookieName¶
ValidCookieName reports wheter given bytes is a valid RFC2616 "token" bytes.
funcValidCookieValue¶
ValidCookieValue reports whether given value is a valid RFC6265"cookie-octet" bytes.
cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
; US-ASCII characters excluding CTLs,; whitespace DQUOTE, comma, semicolon,; and backslash
Note that the false strict parameter disables errors on space 0x20 and comma0x2c. This could be useful to bring some compatibility with non-compliantclients/servers in the real world.It acts the same as standard library cookie parser if strict is false.
funcWriteOptions¶
WriteOptions write options list to the dest.It uses the same form as {Scan,Parse}Options functions:values = 1#valuevalue = token *( ";" param )param = token [ "=" (token | quoted-string) ]
It wraps valuse into the quoted-string sequence if it contains anynon-token characters.
Example¶
opts := []Option{NewOption("foo", map[string]string{"param": "hello, world!",}),NewOption("bar", nil),NewOption("b a z", nil),}buf := bytes.Buffer{}bw := bufio.NewWriter(&buf)WriteOptions(bw, opts)bw.Flush()
Output:foo;param="hello, world!",bar,"b a z"
Types¶
typeCookieScanner¶
type CookieScanner struct {// DisableNameValidation disables name validation of a cookie. If false,// only RFC2616 "tokens" are accepted.DisableNameValidationbool// DisableValueValidation disables value validation of a cookie. If false,// only RFC6265 "cookie-octet" characters are accepted.//// Note that Strict option also affects validation of a value.//// If Strict is false, then scanner begins to allow space and comma// characters inside the value for better compatibility with non standard// cookies implementations.DisableValueValidationbool// BreakOnPairError sets scanner to immediately return after first pair syntax// validation error.// If false, scanner will try to skip invalid pair bytes and go ahead.BreakOnPairErrorbool// Strict enables strict RFC6265 mode scanning. It affects name and value// validation, as also some other rules.// If false, it is intended to bring the same behavior as// http.Request.Cookies().Strictbool}
CookieScanner contains options for scanning cookie pairs.Seehttps://tools.ietf.org/html/rfc6265#section-4.1.1
typeItemType¶
type ItemTypeint
ItemType encodes type of the lexing token.
const (// ItemUndef reports that token is undefined.ItemUndefItemType =iota// ItemToken reports that token is RFC2616 token.ItemToken// ItemSeparator reports that token is RFC2616 separator.ItemSeparator// ItemString reports that token is RFC2616 quouted string.ItemString// ItemComment reports that token is RFC2616 comment.ItemComment// ItemOctet reports that token is octet slice.ItemOctet)
typeOctetType¶
type OctetTypebyte
OctetType desribes character type.
From the "Basic Rules" chapter of RFC2616Seehttps://tools.ietf.org/html/rfc2616#section-2.2
OCTET = <any 8-bit sequence of data>CHAR = <any US-ASCII character (octets 0 - 127)>UPALPHA = <any US-ASCII uppercase letter "A".."Z">LOALPHA = <any US-ASCII lowercase letter "a".."z">ALPHA = UPALPHA | LOALPHADIGIT = <any US-ASCII digit "0".."9">CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>CR = <US-ASCII CR, carriage return (13)>LF = <US-ASCII LF, linefeed (10)>SP = <US-ASCII SP, space (32)>HT = <US-ASCII HT, horizontal-tab (9)><"> = <US-ASCII double-quote mark (34)>CRLF = CR LFLWS = [CRLF] 1*( SP | HT )
Many HTTP/1.1 header field values consist of words separated by LWSor special characters. These special characters MUST be in a quotedstring to be used within a parameter value (as defined in section3.6).
token = 1*<any CHAR except CTLs or separators>separators = "(" | ")" | "<" | ">" | "@"| "," | ";" | ":" | "\" | <">| "/" | "[" | "]" | "?" | "="| "{" | "}" | SP | HT
func (OctetType)IsSeparator¶
IsSeparator reports whether octet is separator.
typeOption¶
type Option struct {Name []byteParametersParameters}
Option represents a header option.
funcParseOptions¶
ParseOptions parses all header options and appends it to given slice ofOption. It returns flag of successful (wellformed input) parsing.
Note that appended options are all consist of subslices of data. That is,mutation of data will mutate appended options.
Example¶
options, ok := ParseOptions([]byte(`foo;bar=1,baz`), nil)fmt.Println(options, ok)
Output:[{foo [bar:1]} {baz []}] true
func (Option)Copy¶
Copy copies all underlying []byte slices into p and returns new Option.Note that p must be at least of opt.Size() length.
typeOptionSelector¶
type OptionSelector struct {// Check is a filter function that applied to every Option that possibly// could be selected.// If Check is nil all options will be selected.Check func(Option)bool// Flags contains flags for options selection.FlagsSelectFlag// Alloc used to allocate slice of bytes when selector is configured with// SelectCopy flag. It will be called with number of bytes needed for copy// of single Option.// If Alloc is nil make is used.Alloc func(nint) []byte}
OptionSelector contains configuration for selecting Options from header value.
typeParameters¶
type Parameters struct {// contains filtered or unexported fields}
Parameters represents option's parameters.
func (*Parameters)Copy¶
func (p *Parameters) Copy(dst []byte) (Parameters, []byte)
Copy copies all underlying []byte slices into dst and returns newParameters.Note that dst must be at least of p.Size() length.
func (*Parameters)ForEach¶
func (p *Parameters) ForEach(cb func(k, v []byte)bool)
ForEach iterates over parameters key-value pairs and calls cb for each one.
func (*Parameters)Get¶
func (p *Parameters) Get(keystring) (value []byte, okbool)
Get returns value by key and flag about existence such value.
func (*Parameters)Size¶
func (p *Parameters) Size()int
Size returns number of bytes that needed to copy p.
func (*Parameters)String¶
func (p *Parameters) String() (retstring)
String represents parameters as a string.
typeRequestLine¶
RequestLine contains parameters parsed from the first request line.
funcParseRequestLine¶
func ParseRequestLine(line []byte) (rRequestLine, okbool)
ParseRequestLine parses http request line like "GET / HTTP/1.0".
typeResponseLine¶
ResponseLine contains parameters parsed from the first response line.
funcParseResponseLine¶
func ParseResponseLine(line []byte) (rResponseLine, okbool)
ParseResponseLine parses first response line into ResponseLine struct.
typeScanner¶
type Scanner struct {// contains filtered or unexported fields}
Scanner represents header tokens scanner.Seehttps://tools.ietf.org/html/rfc2616#section-2
func (*Scanner)Advance¶
Advance moves current position index at n bytes. It returns true onsuccessful move.
func (*Scanner)FetchUntil¶
FetchUntil fetches ItemOctet from current scanner position to firstoccurence of the c or to the end of the underlying data.
func (*Scanner)Next¶
Next scans for next token. It returns true on successful scanning, and falseon error or EOF.
func (*Scanner)Peek¶
Peek reads byte at current position without advancing it. On end of data itreturns 0.
func (*Scanner)Peek2¶
Peek2 reads two first bytes at current position without advancing it.If there not enough data it returs 0.
func (*Scanner)SkipEscaped¶
SkipEscaped skips all bytes until first occurence of non-escaped c.
typeSelectFlag¶
type SelectFlagbyte
SelectFlag encodes way of options selection.
const (// SelectCopy causes selector to copy selected option before appending it// to resulting slice.// If SelectCopy flag is not passed to selector, then appended options will// contain sub-slices of the initial data.SelectCopySelectFlag = 1 <<iota// SelectUnique causes selector to append only not yet existing option to// resulting slice. Unique is checked by comparing option names.SelectUnique)