httparser

package module
v0.0.10 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 28, 2022 License: Apache-2.0 Imports: 7 Imported by: 0

README

httparser

Go codecov

高性能http 1.1解析器,为你的异步io库插上解析的翅膀[从零实现]

出发点

本来想基于异步io库写些好玩的代码,发现没有适用于这些库的http解析库,索性就自己写个,弥补golang生态一小片空白领域。

特性

  • url解析
  • request or response header field解析
  • request or response header value解析
  • Content-Length数据包解析
  • chunked数据包解析

parser request

	var data = []byte(
		"POST /joyent/http-parser HTTP/1.1\r\n" +
			"Host: github.com\r\n" +
			"DNT: 1\r\n" +
			"Accept-Encoding: gzip, deflate, sdch\r\n" +
			"Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4\r\n" +
			"User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) " +
			"AppleWebKit/537.36 (KHTML, like Gecko) " +
			"Chrome/39.0.2171.65 Safari/537.36\r\n" +
			"Accept: text/html,application/xhtml+xml,application/xml;q=0.9," +
			"image/webp,*/*;q=0.8\r\n" +
			"Referer: https://github.com/joyent/http-parser\r\n" +
			"Connection: keep-alive\r\n" +
			"Transfer-Encoding: chunked\r\n" +
			"Cache-Control: max-age=0\r\n\r\nb\r\nhello world\r\n0\r\n\r\n")

	var setting = httparser.Setting{
		MessageBegin: func(*httparser.Parser) {
			//解析器开始工作
			fmt.Printf("begin\n")
		},
		URL: func(_ *httparser.Parser, buf []byte) {
			//url数据
			fmt.Printf("url->%s\n", buf)
		},
		Status: func(*httparser.Parser, []byte) {
			// 响应包才需要用到
		},
		HeaderField: func(_ *httparser.Parser, buf []byte) {
			// http header field
			fmt.Printf("header field:%s\n", buf)
		},
		HeaderValue: func(_ *httparser.Parser, buf []byte) {
			// http header value
			fmt.Printf("header value:%s\n", buf)
		},
		HeadersComplete: func(_ *httparser.Parser) {
			// http header解析结束
			fmt.Printf("header complete\n")
		},
		Body: func(_ *httparser.Parser, buf []byte) {
			fmt.Printf("%s", buf)
			// Content-Length 或者chunked数据包
		},
		MessageComplete: func(_ *httparser.Parser) {
			// 消息解析结束
			fmt.Printf("\n")
		},
	}

	p := httparser.New(httparser.REQUEST)
	success, err := p.Execute(&setting, data)

	fmt.Printf("success:%d, err:%v\n", success, err)

response

response

request or response

如果你不确定数据包是请求还是响应,可看下面的例子
request or response

编译

生成 unhex表和tokens表

如果需要修改这两个表,可以到_cmd目录下面修改生成代码的代码

make gen
编译example
make example
运行示例
make example.run
return value
  • err != nil 错误
  • sucess == len(data) 所有数据成功解析
  • sucess < len(data) 只解析部分数据,未解析的数据需再送一次
吞吐量

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrMethod 错误的method
	ErrMethod = errors.New("http method fail")
	// ErrStatusLineHTTP 状态行前面的HTTP错误
	ErrStatusLineHTTP = errors.New("http status line http")
	// ErrHTTPVersionNum 错误的http版本号
	ErrHTTPVersionNum = errors.New("http version number")
	// ErrHeaderOverflow http header包太大
	ErrHeaderOverflow = errors.New("http header overflow")
	// ErrNoEndLF 没有\n
	ErrNoEndLF = errors.New("http there is no end symbol")
	// ErrChunkSize chunked表示长度的字符串错了
	ErrChunkSize = errors.New("http wrong chunk size")
	// ErrReqMethod 错误的请求方法字符串
	ErrReqMethod = errors.New("http request wrong method")
	// ErrRequestLineLF 请求行没有\n
	ErrRequestLineLF = errors.New("http request line wrong LF")
)
View Source
var (

	// MaxHeaderSize 表示 http header单行最大限制为4k
	MaxHeaderSize int32 = 4096
)

Functions

func BytesToString

func BytesToString(b []byte) string

BytesToString 没有内存开销的转换

func Split added in v0.0.8

func Split(s, sep []byte, cb func([]byte) error) error

Split 分割字符串

Types

type Method added in v0.0.7

type Method int8

Method 类型 表示http 方法

const (
	// GET 表示GET方法
	GET Method = iota + 1
	// HEAD 表示HEAD方法
	HEAD
	// POST 表示POST方法
	POST
	// PUT 表示PUT方法
	PUT
	// DELETE 表示DELETE方法
	DELETE
	// CONNECT 表示CONNECT方法
	CONNECT
	// OPTIONS 表示OPTIONS方法
	OPTIONS
	// TRACE 表示TRACE方法
	TRACE
	// ACL 表示ACL方法
	ACL
	// BIND 表示BIND方法
	BIND
	// COPY 表示COPY方法
	COPY
	// CHECKOUT 表示CHECKOUT方法
	CHECKOUT
	// LOCK 表示LOCK方法
	LOCK
	// UNLOCK 表示UNLOCK方法
	UNLOCK
	// LINK 表示LINK方法
	LINK
	// MKCOL 表示MKCOL方法
	MKCOL
	// MOVE 表示MOVE方法
	MOVE
	// MKACTIVITY 表示MKACTIVITY方法
	MKACTIVITY
	// MERGE 表示MERGE方法
	MERGE
	// MSEARCH 表示M-SEARCH方法
	MSEARCH
	// MKCALENDAR 表示MKCALENDAR方法
	MKCALENDAR
	// NOTIFY 表示NOTIFY方法
	NOTIFY
	// PROPFIND 表示PROPFIND方法
	PROPFIND
	// PROPPATCH 表示PROPPATCH方法
	PROPPATCH
	// PATCH 表示PATCH方法
	PATCH
	// PURGE 表示PURGE方法
	PURGE
	// REPORT 表示REPORT方法
	REPORT
	// REBIND 表示REBIND方法
	REBIND
	// SUBSCRIBE 表示SUBSCRIBE方法
	SUBSCRIBE
	// SEARCH 表示SEARCH方法
	SEARCH
	// SOURCE 表示SOURCE方法
	SOURCE
	// UNSUBSCRIBE 表示UNSUBSCRIBE方法
	UNSUBSCRIBE
	// UNBIND 表示UNBIND方法
	UNBIND
	// UNLINK 表示UNLINK方法
	UNLINK
)

type Parser

type Parser struct {
	Method Method //记录request的method

	Major         uint8 //主版本号
	Minor         uint8 //次版本号
	MaxHeaderSize int32 //最大头长度

	StatusCode uint16 //状态码

	Upgrade bool //从http升级为别的协议, 比如websocket
	// contains filtered or unexported fields
}

Parser http 1.1 or http 1.0解析器

func New

func New(t ReqOrRsp) *Parser

New 解析器构造函数

func (*Parser) EOF added in v0.0.10

func (p *Parser) EOF() bool

EOF 表示结束

func (*Parser) Execute

func (p *Parser) Execute(setting *Setting, buf []byte) (success int, err error)

Execute 执行解析器

func (*Parser) GetUserData added in v0.0.5

func (p *Parser) GetUserData() interface{}

GetUserData 获取SetuserData函数设置的私有变量

func (*Parser) Init

func (p *Parser) Init(t ReqOrRsp)

Init 解析器Init函数

func (*Parser) ReadyUpgradeData added in v0.0.7

func (p *Parser) ReadyUpgradeData() bool

ReadyUpgradeData 如果ReadyUpgradeData为true 说明已经有Upgrade Data数据, 并且http数据已经成功解析完成

func (*Parser) Reset

func (p *Parser) Reset()

Reset 重置状态

func (*Parser) SetUserData added in v0.0.3

func (p *Parser) SetUserData(d interface{})

SetUserData 的设计出发点和作用 一般情况,可以使用Setting里面函数闭包特性捕获调用者私有变量 好像提供SetUserData没有必要性 但是从 1.节约内存角度 2.数据和行为解耦的角度,提供一个Setting函数集,通过SetUserData,保存调用者私有变量 通过GetUserData拿需要的变量,还是比较爽的,不需要写一堆闭包

func (*Parser) Status added in v0.0.2

func (p *Parser) Status() string

Status debug专用

type ReqOrRsp

type ReqOrRsp uint8

ReqOrRsp 请求还是响应

const (
	// REQUEST 解析请求包
	REQUEST ReqOrRsp = iota + 1
	// RESPONSE 解析响应包
	RESPONSE
	// BOTH 让解析器根据报文自己判断
	BOTH
)

type Setting

type Setting struct {
	// 解析开始
	MessageBegin func(*Parser)
	// url 回调函数, 只有在request包才会回调
	// 解析一个包时,URL回调可能会多次调用
	URL func(*Parser, []byte)
	// 状态短语
	// 解析一个包时, Status回调可能会多次调用
	Status func(*Parser, []byte)
	// http field 回调函数
	HeaderField func(*Parser, []byte)
	// http value 回调函数
	HeaderValue func(*Parser, []byte)
	// http 解析完成之后的回调函数
	HeadersComplete func(*Parser)
	// body的回调函数
	Body func(*Parser, []byte)
	// 所有消息成功解析
	MessageComplete func(*Parser)
}

Setting 查阅#6 看设计变更原因

type TwoBuf added in v0.0.4

type TwoBuf struct {
	// contains filtered or unexported fields
}

TwoBuf 数据结构

func NewTwoBuf added in v0.0.4

func NewTwoBuf(size int) *TwoBuf

NewTwoBuf 新建twobuf, size表明单个块的大小

func (*TwoBuf) All added in v0.0.4

func (t *TwoBuf) All(right int) []byte

All 获取全部buf, 如果没有溢出数据,就取右边 如果有溢出数据,就把溢出数据也包含进来

func (*TwoBuf) MoveLeft added in v0.0.4

func (t *TwoBuf) MoveLeft(leftBuf []byte)

MoveLeft 移动到左边buf 如果写入数据超过left空间,会直接panic

func (*TwoBuf) Reset added in v0.0.4

func (t *TwoBuf) Reset()

Reset 重置

func (*TwoBuf) Right added in v0.0.4

func (t *TwoBuf) Right() []byte

Right 获取右边buf

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL