httpLayer

package
v1.2.0-beta.4 Latest Latest
Warning

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

Go to latest
Published: May 3, 2022 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package httpLayer provides methods and definitions for http layer.

Fallback 由 本包 处理. 因为回落的目标只可能是http服务器.

http头 格式 可以参考:

https://datatracker.ietf.org/doc/html/rfc2616#section-4

https://datatracker.ietf.org/doc/html/rfc2616#section-5

Index

Constants

View Source
const (
	FallBack_default byte = 1 << iota //default 其实也是path,只不过path是通配符。

	Fallback_path
	Fallback_alpn
	Fallback_sni
)
View Source
const (
	H11_Str = "http/1.1"
	H2_Str  = "h2"

	CRLF = "\r\n"

	//参考 https://datatracker.ietf.org/doc/html/rfc2616#section-4.1
	//
	//http头的尾部. 每个header末尾都有一个 crlf, 整个头部结尾还有一个crlf, 所以是两个.
	HeaderENDING = CRLF + CRLF
)
View Source
const Err403response = `HTTP/1.1 403 Forbidden
Connection: close
Cache-Control: max-age=3600, public
Content-Length: 0

`
View Source
const (
	Fallback_none = 0
)

Variables

View Source
var (
	HeaderENDING_bytes = []byte(HeaderENDING)

	ErrNotHTTP_Request = errors.New("not http request")
)
View Source
var Err404response = `HTTP/1.1 404 Not Found\r\nContent-Type: text/html
Connection: keep-alive\r\n404 Not Found\r\n`
View Source
var ErrShouldFallback = errors.New("will fallback")

Functions

func AllHeadersIn added in v1.2.0

func AllHeadersIn(template map[string][]string, realh http.Header) (ok bool, firstNotMatchKey string)

all values in template is given by real

func GetRequestMethod_and_PATH_from_Bytes

func GetRequestMethod_and_PATH_from_Bytes(bs []byte, isproxy bool) (version, method string, path string, failreason int)

GetRequestMethod_and_PATH_from_Bytes 从一个字节串中试图获取 http请求的 path,和 method. failreason>0 表示获取失败. 不会返回小于0的值 同时可以用这个方法判断明文 是不是 http1.1, http1.0, http0.9的 http请求 如果是http代理的话,判断方式会有变化,所以需要 isproxy 参数 此方法亦可以用于 判断一个http请求头部是否合法

func HasFallbackType

func HasFallbackType(ftype, b byte) bool

判断 Fallback.SupportType 返回的 数值 是否具有特定的Fallback类型

func TrimHeaders added in v1.2.0

func TrimHeaders(m map[string][]string) (result map[string][]string)

return a clone of m with headers trimmed to one value

Types

type ClassicFallback

type ClassicFallback struct {
	Default *FallbackResult

	Map map[string]map[FallbackConditionSet]*FallbackResult
	// contains filtered or unexported fields
}

实现 Fallback,支持 path, alpn, sni 分流。 内部 map 我们使用通用的集合办法, 而不是多层map嵌套; 虽然目前就三个fallback类型,但是谁知道以后会加几个?所以这样更通用. 目前3种fallback性能是没问题的,不过如果 fallback继续增加的话, 最差情况下集合的子集总数会急剧上升,导致最差情况下性能不如多重 map;不过一般没人那么脑残会给出那种配置.

func NewClassicFallback

func NewClassicFallback() *ClassicFallback

func NewClassicFallbackFromConfList

func NewClassicFallbackFromConfList(fcl []*FallbackConf) *ClassicFallback

func (*ClassicFallback) GetFallback

func (cfb *ClassicFallback) GetFallback(fromServerTag string, ftype byte, ss ...string) *FallbackResult

GetFallback 使用给出的 ftype mask 和 对应参数 来试图匹配到 回落地址. ss 必须按 FallBack_* 类型 从小到大顺序排列

func (*ClassicFallback) InsertFallbackConditionSet

func (cfb *ClassicFallback) InsertFallbackConditionSet(condition FallbackConditionSet, forServerTag string, addr netLayer.Addr, xver int)

func (*ClassicFallback) SupportType

func (cfb *ClassicFallback) SupportType() byte

type Fallback

type Fallback interface {
	GetFallback(ftype byte, params ...string) *FallbackResult
	SupportType() byte //参考Fallback_开头的常量。如果支持多个,则返回它们 按位与 的结果
}

实现 Fallback. 这里的fallback只与http协议有关,所以只能按path,alpn 和 sni 进行分类

type FallbackConditionSet

type FallbackConditionSet struct {
	Path, Sni string
	AlpnMask  byte
}

func (*FallbackConditionSet) GetAllSubSets

func (fcs *FallbackConditionSet) GetAllSubSets() (rs []FallbackConditionSet)

返回不包括自己的所有子集

func (*FallbackConditionSet) GetSub

func (fcs *FallbackConditionSet) GetSub(subType byte) (r FallbackConditionSet)

func (*FallbackConditionSet) GetType

func (fcs *FallbackConditionSet) GetType() (r byte)

func (FallbackConditionSet) TestAllSubSets

func (fcs FallbackConditionSet) TestAllSubSets(allsupportedTypeMask byte, theMap map[FallbackConditionSet]*FallbackResult) *FallbackResult

TestAllSubSets 传入一个map, 对fcs自己以及其所有子集依次测试, 看是否有匹配的。 对比 GetAllSubSets 内存占用较大, 而本方法开销则小很多, 因为1是复用内存, 2是匹配到就会返回,一般不会到遍历全部子集.

type FallbackConf

type FallbackConf struct {
	//可选
	FromTag string `toml:"from" json:"from"` //which inServer triggered this fallback

	Xver int `toml:"xver" json:"xver"` //if fallback, whether to use PROXY protocol, and which version

	//必填
	Dest any `toml:"dest" json:"dest"` //see netLayer.NewAddrFromAny for details about "any" addr

	Path string   `toml:"path" json:"path"`
	Sni  string   `toml:"sni" json:"sni"`
	Alpn []string `toml:"alpn" json:"alpn"`
}

type FallbackMeta added in v1.2.0

type FallbackMeta struct {
	net.Conn
	H1RequestBuf *bytes.Buffer
	Path         string
	Method       string
	IsH2         bool

	H2Request *http.Request
}

http level fallback metadata

type FallbackResult added in v1.2.0

type FallbackResult struct {
	Addr netLayer.Addr
	Xver int
}

func (*FallbackResult) GetFallback added in v1.2.0

func (ef *FallbackResult) GetFallback(ftype byte, _ ...string) *FallbackResult

func (FallbackResult) SupportType added in v1.2.0

func (FallbackResult) SupportType() byte

type H1RequestParser added in v1.2.0

type H1RequestParser struct {
	Version         string
	Path            string
	Method          string
	WholeRequestBuf *bytes.Buffer
	Failreason      int //为0表示没错误
}

H1RequestParser被用于 预读一个链接,判断该连接是否是有效的http请求, 并将Version,Path,Method 记录在结构中.

只能过滤 http 0.9, 1.0 和 1.1. 无法过滤h2和h3.

func (*H1RequestParser) ReadAndParse added in v1.2.0

func (rhr *H1RequestParser) ReadAndParse(r io.Reader) error

尝试读取数据并解析HTTP请求, 解析道道 数据会存入 RequestParser 结构中. 如果读取错误,会返回该错误; 如果读到的不是HTTP请求,返回 ErrNotHTTP_Request;

type HeaderConn

type HeaderConn struct {
	net.Conn
	H           *HeaderPreset
	IsServerEnd bool
	// contains filtered or unexported fields
}

func (*HeaderConn) Read

func (pc *HeaderConn) Read(p []byte) (n int, err error)

func (*HeaderConn) Write

func (pc *HeaderConn) Write(p []byte) (n int, err error)

type HeaderPreset

type HeaderPreset struct {
	Request  *RequestHeader  `toml:"request"`
	Response *ResponseHeader `toml:"response"`
}

http 头 预设, 分客户端的request 和 服务端的 response这两部分.

func (*HeaderPreset) AssignDefaultValue

func (hh *HeaderPreset) AssignDefaultValue()

默认值保持与v2ray的配置相同

func (*HeaderPreset) Prepare added in v1.2.0

func (hh *HeaderPreset) Prepare()

将Header改为首字母大写

func (*HeaderPreset) ReadRequest

func (h *HeaderPreset) ReadRequest(underlay net.Conn) (err error, leftBuf *bytes.Buffer)

func (*HeaderPreset) ReadResponse

func (p *HeaderPreset) ReadResponse(underlay net.Conn) (err error, leftBuf *bytes.Buffer)

func (*HeaderPreset) WriteRequest

func (p *HeaderPreset) WriteRequest(underlay net.Conn, payload []byte) error

func (*HeaderPreset) WriteResponse

func (p *HeaderPreset) WriteResponse(underlay net.Conn, payload []byte) error

type RequestErr

type RequestErr struct {
	Path   string
	Method string
}

func (*RequestErr) Error

func (pe *RequestErr) Error() string

func (*RequestErr) Is added in v1.2.0

func (e *RequestErr) Is(err error) bool

type RequestHeader

type RequestHeader struct {
	Version string              `toml:"version"` //默认值为 "1.1"
	Method  string              `toml:"method"`  //默认值为 "GET"。
	Path    []string            `toml:"path"`    //默认值为 ["/"]。当有多个值时,每次请求随机选择一个值。
	Headers map[string][]string `toml:"headers"` //一个键值对,每个键表示一个 HTTP 头的名称,对应的值是一个数组。每次请求会附上所有的键,并随机选择一个对应的值。
}

type ResponseHeader

type ResponseHeader struct {
	Version    string              `toml:"version"` // 1.1
	StatusCode string              `toml:"status"`  // 200
	Reason     string              `toml:"reason"`  // OK
	Headers    map[string][]string `toml:"headers"`
}

Jump to

Keyboard shortcuts

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