将请求的一些方法改为可exported,方便以后扩展

This commit is contained in:
刘祥超
2021-12-30 11:19:11 +08:00
parent 2525cdc061
commit 7f3f7e21b8
18 changed files with 224 additions and 91 deletions

View File

@@ -39,7 +39,7 @@ type HTTPRequest struct {
RawReq *http.Request
RawWriter http.ResponseWriter
Server *serverconfigs.ServerConfig
Host string // 请求的Host
host string // 请求的Host
ServerName string // 实际匹配到的Host
ServerAddr string // 实际启动的服务器监听地址
IsHTTP bool
@@ -83,6 +83,9 @@ type HTTPRequest struct {
logAttrs map[string]string
disableLog bool // 此请求中关闭Log
// script相关操作
isDone bool
}
// 初始化
@@ -139,6 +142,13 @@ func (this *HTTPRequest) Do() {
return
}
// 回调事件
this.onInit()
if this.writer.isFinished {
this.doEnd()
return
}
// 特殊URL处理
if len(this.rawURI) > 1 && this.rawURI[1] == '.' {
// ACME
@@ -302,12 +312,12 @@ func (this *HTTPRequest) doEnd() {
// TODO 增加Header统计考虑从Conn中读取
if this.Server != nil {
if this.isCached {
stats.SharedTrafficStatManager.Add(this.Server.Id, this.Host, this.writer.sentBodyBytes, this.writer.sentBodyBytes, 1, 1, 0, 0, this.Server.ShouldCheckTrafficLimit(), this.Server.PlanId())
stats.SharedTrafficStatManager.Add(this.Server.Id, this.host, this.writer.sentBodyBytes, this.writer.sentBodyBytes, 1, 1, 0, 0, this.Server.ShouldCheckTrafficLimit(), this.Server.PlanId())
} else {
if this.isAttack {
stats.SharedTrafficStatManager.Add(this.Server.Id, this.Host, this.writer.sentBodyBytes, 0, 1, 0, 1, this.writer.sentBodyBytes, this.Server.ShouldCheckTrafficLimit(), this.Server.PlanId())
stats.SharedTrafficStatManager.Add(this.Server.Id, this.host, this.writer.sentBodyBytes, 0, 1, 0, 1, this.writer.sentBodyBytes, this.Server.ShouldCheckTrafficLimit(), this.Server.PlanId())
} else {
stats.SharedTrafficStatManager.Add(this.Server.Id, this.Host, this.writer.sentBodyBytes, 0, 1, 0, 0, 0, this.Server.ShouldCheckTrafficLimit(), this.Server.PlanId())
stats.SharedTrafficStatManager.Add(this.Server.Id, this.host, this.writer.sentBodyBytes, 0, 1, 0, 0, 0, this.Server.ShouldCheckTrafficLimit(), this.Server.PlanId())
}
}
}
@@ -452,6 +462,20 @@ func (this *HTTPRequest) configureWeb(web *serverconfigs.HTTPWebConfig, isTop bo
this.web.RequestLimit = web.RequestLimit
}
// request scripts
if web.RequestScripts != nil {
if this.web.RequestScripts == nil {
this.web.RequestScripts = web.RequestScripts
} else {
if web.RequestScripts.OnInitScript != nil && (web.RequestScripts.OnInitScript.IsPrior || isTop) {
this.web.RequestScripts.OnInitScript = web.RequestScripts.OnInitScript
}
if web.RequestScripts.OnRequestScript != nil && (web.RequestScripts.OnRequestScript.IsPrior || isTop) {
this.web.RequestScripts.OnRequestScript = web.RequestScripts.OnRequestScript
}
}
}
// 重写规则
if len(web.RewriteRefs) > 0 {
for index, ref := range web.RewriteRefs {
@@ -521,7 +545,7 @@ func (this *HTTPRequest) configureWeb(web *serverconfigs.HTTPWebConfig, isTop bo
}
if varMapping, isMatched := location.Match(rawPath, this.Format); isMatched {
// 检查专属域名
if len(location.Domains) > 0 && !configutils.MatchDomains(location.Domains, this.Host) {
if len(location.Domains) > 0 && !configutils.MatchDomains(location.Domains, this.host) {
continue
}
@@ -603,11 +627,11 @@ func (this *HTTPRequest) Format(source string) string {
if this.IsHTTPS {
scheme = "https"
}
return scheme + "://" + this.Host + this.rawURI
return scheme + "://" + this.host + this.rawURI
case "requestPath":
return this.requestPath()
return this.Path()
case "requestPathExtension":
return filepath.Ext(this.requestPath())
return filepath.Ext(this.Path())
case "requestLength":
return strconv.FormatInt(this.requestLength(), 10)
case "requestTime":
@@ -621,7 +645,7 @@ func (this *HTTPRequest) Format(source string) string {
}
if this.web.Root != nil && this.web.Root.IsOn {
return filepath.Clean(this.web.Root.Dir + this.requestPath())
return filepath.Clean(this.web.Root.Dir + this.Path())
}
return ""
@@ -650,7 +674,7 @@ func (this *HTTPRequest) Format(source string) string {
case "timestamp":
return strconv.FormatInt(this.requestFromTime.Unix(), 10)
case "host":
return this.Host
return this.host
case "referer":
return this.RawReq.Referer()
case "referer.host":
@@ -768,7 +792,7 @@ func (this *HTTPRequest) Format(source string) string {
// host
if prefix == "host" {
pieces := strings.Split(this.Host, ".")
pieces := strings.Split(this.host, ".")
switch suffix {
case "first":
if len(pieces) > 0 {
@@ -950,8 +974,8 @@ func (this *HTTPRequest) requestRemoteUser() string {
return username
}
// 请求的URL中路径部分
func (this *HTTPRequest) requestPath() string {
// Path 请求的URL中路径部分
func (this *HTTPRequest) Path() string {
uri, err := url.ParseRequestURI(this.rawURI)
if err != nil {
return ""
@@ -1061,9 +1085,105 @@ func (this *HTTPRequest) requestServerPort() int {
return 0
}
// 获取完整的URL
func (this *HTTPRequest) requestFullURL() string {
return this.requestScheme() + "://" + this.Host + this.uri
func (this *HTTPRequest) Id() string {
return this.requestId
}
// URL 获取完整的URL
func (this *HTTPRequest) URL() string {
return this.requestScheme() + "://" + this.host + this.uri
}
// Host 获取Host
func (this *HTTPRequest) Host() string {
return this.host
}
func (this *HTTPRequest) Proto() string {
return this.RawReq.Proto
}
func (this *HTTPRequest) ProtoMajor() int {
return this.RawReq.ProtoMajor
}
func (this *HTTPRequest) ProtoMinor() int {
return this.RawReq.ProtoMinor
}
func (this *HTTPRequest) RemoteAddr() string {
return this.requestRemoteAddr(true)
}
func (this *HTTPRequest) RawRemoteAddr() string {
addr := this.RawReq.RemoteAddr
host, _, err := net.SplitHostPort(addr)
if err == nil {
addr = host
}
return addr
}
func (this *HTTPRequest) RemotePort() int {
addr := this.RawReq.RemoteAddr
_, port, err := net.SplitHostPort(addr)
if err != nil {
return 0
}
return types.Int(port)
}
func (this *HTTPRequest) SetAttr(name string, value string) {
this.logAttrs[name] = value
}
func (this *HTTPRequest) SetVar(name string, value string) {
this.varMapping[name] = value
}
// ContentLength 请求内容长度
func (this *HTTPRequest) ContentLength() int64 {
return this.RawReq.ContentLength
}
// Method 请求方法
func (this *HTTPRequest) Method() string {
return this.RawReq.Method
}
func (this *HTTPRequest) TransferEncoding() string {
if len(this.RawReq.TransferEncoding) > 0 {
return this.RawReq.TransferEncoding[0]
}
return ""
}
// DeleteHeader 删除Header
func (this *HTTPRequest) DeleteHeader(name string) {
this.RawReq.Header.Del(name)
}
// SetHeader 设置Header
func (this *HTTPRequest) SetHeader(name string, values []string) {
this.RawReq.Header[name] = values
}
// Header 读取Header
func (this *HTTPRequest) Header() http.Header {
return this.RawReq.Header
}
func (this *HTTPRequest) URI() string {
return this.uri
}
func (this *HTTPRequest) SetURI(uri string) {
this.uri = uri
}
// Done 设置已完成
func (this *HTTPRequest) Done() {
this.isDone = true
}
// 设置代理相关头部信息
@@ -1119,7 +1239,7 @@ func (this *HTTPRequest) setForwardHeaders(header http.Header) {
if this.reverseProxy != nil && this.reverseProxy.ShouldAddXForwardedHostHeader() {
if _, ok := header["X-Forwarded-Host"]; !ok {
this.RawReq.Header.Set("X-Forwarded-Host", this.Host)
this.RawReq.Header.Set("X-Forwarded-Host", this.host)
}
}
@@ -1159,7 +1279,7 @@ func (this *HTTPRequest) processRequestHeaders(reqHeader http.Header) {
}
// 域名
if len(header.Domains) > 0 && !configutils.MatchDomains(header.Domains, this.Host) {
if len(header.Domains) > 0 && !configutils.MatchDomains(header.Domains, this.host) {
continue
}
@@ -1243,7 +1363,7 @@ func (this *HTTPRequest) processResponseHeaders(statusCode int) {
}
// 域名
if len(header.Domains) > 0 && !configutils.MatchDomains(header.Domains, this.Host) {
if len(header.Domains) > 0 && !configutils.MatchDomains(header.Domains, this.host) {
continue
}
@@ -1282,7 +1402,7 @@ func (this *HTTPRequest) processResponseHeaders(statusCode int) {
this.Server.HTTPS.SSLPolicy.IsOn &&
this.Server.HTTPS.SSLPolicy.HSTS != nil &&
this.Server.HTTPS.SSLPolicy.HSTS.IsOn &&
this.Server.HTTPS.SSLPolicy.HSTS.Match(this.Host) {
this.Server.HTTPS.SSLPolicy.HSTS.Match(this.host) {
responseHeader.Set(this.Server.HTTPS.SSLPolicy.HSTS.HeaderKey(), this.Server.HTTPS.SSLPolicy.HSTS.HeaderValue())
}
}

View File

@@ -27,7 +27,7 @@ func (this *HTTPRequest) doAuth() (shouldStop bool) {
subReq.ProtoMinor = this.RawReq.ProtoMinor
subReq.ProtoMajor = this.RawReq.ProtoMajor
subReq.Body = ioutil.NopCloser(bytes.NewReader([]byte{}))
subReq.Header.Set("Referer", this.requestFullURL())
subReq.Header.Set("Referer", this.URL())
var writer = NewEmptyResponseWriter(this.writer)
this.doSubRequest(writer, subReq)
return writer.StatusCode(), nil
@@ -45,7 +45,7 @@ func (this *HTTPRequest) doAuth() (shouldStop bool) {
if len(method.Realm) > 0 {
headerValue += method.Realm
} else {
headerValue += this.Host
headerValue += this.host
}
headerValue += "\""
if len(method.Charset) > 0 {

View File

@@ -138,7 +138,7 @@ func (this *HTTPRequest) doCacheRead(useStale bool) (shouldStop bool) {
if err == nil {
for _, rpcServerService := range rpcClient.ServerRPCList() {
_, err = rpcServerService.PurgeServerCache(rpcClient.Context(), &pb.PurgeServerCacheRequest{
Domains: []string{this.Host},
Domains: []string{this.host},
Keys: []string{key},
Prefixes: nil,
})
@@ -152,13 +152,19 @@ func (this *HTTPRequest) doCacheRead(useStale bool) (shouldStop bool) {
return true
}
// 调用回调
this.onRequest()
if this.writer.isFinished {
return
}
var reader caches.Reader
var err error
// 是否优先检查WebP
if this.web.WebP != nil &&
this.web.WebP.IsOn &&
this.web.WebP.MatchRequest(filepath.Ext(this.requestPath()), this.Format) &&
this.web.WebP.MatchRequest(filepath.Ext(this.Path()), this.Format) &&
this.web.WebP.MatchAccept(this.requestHeader("Accept")) {
reader, _ = storage.OpenReader(key+webpSuffix, useStale)
}

View File

@@ -13,7 +13,7 @@ func (this *HTTPRequest) write404() {
this.processResponseHeaders(http.StatusNotFound)
this.writer.WriteHeader(http.StatusNotFound)
_, _ = this.writer.Write([]byte("404 page not found: '" + this.requestFullURL() + "'" + " (Request Id: " + this.requestId + ")"))
_, _ = this.writer.Write([]byte("404 page not found: '" + this.URL() + "'" + " (Request Id: " + this.requestId + ")"))
}
func (this *HTTPRequest) writeCode(code int) {
@@ -23,7 +23,7 @@ func (this *HTTPRequest) writeCode(code int) {
this.processResponseHeaders(code)
this.writer.WriteHeader(code)
_, _ = this.writer.Write([]byte(types.String(code) + " " + http.StatusText(code) + ": '" + this.requestFullURL() + "'" + " (Request Id: " + this.requestId + ")"))
_, _ = this.writer.Write([]byte(types.String(code) + " " + http.StatusText(code) + ": '" + this.URL() + "'" + " (Request Id: " + this.requestId + ")"))
}
func (this *HTTPRequest) write50x(err error, statusCode int, canTryStale bool) {

View File

@@ -0,0 +1,11 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
//go:build !script
// +build !script
package nodes
func (this *HTTPRequest) onInit() {
}
func (this *HTTPRequest) onRequest() {
}

View File

@@ -52,13 +52,13 @@ func (this *HTTPRequest) doFastcgi() (shouldStop bool) {
}
}
if !env.Has("SERVER_NAME") {
env["SERVER_NAME"] = this.Host
env["SERVER_NAME"] = this.host
}
if !env.Has("REQUEST_URI") {
env["REQUEST_URI"] = this.uri
}
if !env.Has("HOST") {
env["HOST"] = this.Host
env["HOST"] = this.host
}
if len(this.ServerAddr) > 0 {
@@ -149,7 +149,7 @@ func (this *HTTPRequest) doFastcgi() (shouldStop bool) {
host, found := params["HTTP_HOST"]
if !found || len(host) == 0 {
params["HTTP_HOST"] = this.Host
params["HTTP_HOST"] = this.host
}
fcgiReq := fcgi.NewRequest()

View File

@@ -13,7 +13,7 @@ func (this *HTTPRequest) doHostRedirect() (blocked bool) {
if this.web.MergeSlashes {
urlPath = utils.CleanPath(urlPath)
}
fullURL := this.requestScheme() + "://" + this.Host + urlPath
fullURL := this.requestScheme() + "://" + this.host + urlPath
for _, u := range this.web.HostRedirects {
if !u.IsOn {
continue

View File

@@ -99,7 +99,7 @@ func (this *HTTPRequest) log() {
RemotePort: int32(this.requestRemotePort()),
RemoteUser: this.requestRemoteUser(),
RequestURI: this.rawURI,
RequestPath: this.requestPath(),
RequestPath: this.Path(),
RequestLength: this.requestLength(),
RequestTime: this.requestCost,
RequestMethod: this.RawReq.Method,
@@ -114,7 +114,7 @@ func (this *HTTPRequest) log() {
TimeLocal: this.requestFromTime.Format("2/Jan/2006:15:04:05 -0700"),
Msec: float64(this.requestFromTime.Unix()) + float64(this.requestFromTime.Nanosecond())/1000000000,
Timestamp: this.requestFromTime.Unix(),
Host: this.Host,
Host: this.host,
Referer: referer,
UserAgent: userAgent,
Request: this.requestString(),

View File

@@ -36,11 +36,11 @@ func (this *HTTPRequest) doReverseProxy() {
requestCall := shared.NewRequestCall()
requestCall.Request = this.RawReq
requestCall.Formatter = this.Format
requestCall.Domain = this.Host
requestCall.Domain = this.host
origin := this.reverseProxy.NextOrigin(requestCall)
requestCall.CallResponseCallbacks(this.writer)
if origin == nil {
err := errors.New(this.requestFullURL() + ": no available origin sites for reverse proxy")
err := errors.New(this.URL() + ": no available origin sites for reverse proxy")
remotelogs.ServerError(this.Server.Id, "HTTP_REQUEST_REVERSE_PROXY", err.Error(), "", nil)
this.write50x(err, http.StatusBadGateway, true)
return
@@ -60,7 +60,7 @@ func (this *HTTPRequest) doReverseProxy() {
// 处理Scheme
if origin.Addr == nil {
err := errors.New(this.requestFullURL() + ": origin '" + strconv.FormatInt(origin.Id, 10) + "' does not has a address")
err := errors.New(this.URL() + ": origin '" + strconv.FormatInt(origin.Id, 10) + "' does not has a address")
remotelogs.Error("HTTP_REQUEST_REVERSE_PROXY", err.Error())
this.write50x(err, http.StatusBadGateway, true)
return
@@ -129,7 +129,7 @@ func (this *HTTPRequest) doReverseProxy() {
this.RawReq.Host = hostname
this.RawReq.URL.Host = this.RawReq.Host
} else {
this.RawReq.URL.Host = this.Host
this.RawReq.URL.Host = this.host
}
// 重组请求URL
@@ -147,6 +147,12 @@ func (this *HTTPRequest) doReverseProxy() {
this.setForwardHeaders(this.RawReq.Header)
this.processRequestHeaders(this.RawReq.Header)
// 调用回调
this.onRequest()
if this.writer.isFinished {
return
}
// 判断是否为Websocket请求
if this.RawReq.Header.Get("Upgrade") == "websocket" {
this.doWebsocket()

View File

@@ -15,7 +15,7 @@ func (this *HTTPRequest) doRewrite() (shouldShop bool) {
if this.rewriteRule.Mode == serverconfigs.HTTPRewriteModeProxy {
// 外部URL
if this.rewriteIsExternalURL {
host := this.Host
host := this.host
if len(this.rewriteRule.ProxyHost) > 0 {
host = this.rewriteRule.ProxyHost
}

View File

@@ -200,6 +200,12 @@ func (this *HTTPRequest) doRoot() (isBreak bool) {
respHeader.Set("ETag", eTag)
}
// 调用回调
this.onRequest()
if this.writer.isFinished {
return
}
// 支持 If-None-Match
if this.requestHeader("If-None-Match") == eTag {
// 自定义Header

View File

@@ -11,7 +11,7 @@ func (this *HTTPRequest) doSubRequest(writer http.ResponseWriter, rawReq *http.R
RawReq: rawReq,
RawWriter: writer,
Server: this.Server,
Host: this.Host,
host: this.host,
ServerName: this.ServerName,
ServerAddr: this.ServerAddr,
IsHTTP: this.IsHTTP,

View File

@@ -67,7 +67,8 @@ type HTTPWriter struct {
cacheWriter caches.Writer // 缓存写入
cacheStorage caches.StorageInterface
isOk bool // 是否完全成功
isOk bool // 是否完全成功
isFinished bool // 是否已完成
}
// NewHTTPWriter 包装对象
@@ -128,6 +129,16 @@ func (this *HTTPWriter) Header() http.Header {
return this.writer.Header()
}
// DeleteHeader 删除Header
func (this *HTTPWriter) DeleteHeader(name string) {
this.writer.Header().Del(name)
}
// SetHeader 设置Header
func (this *HTTPWriter) SetHeader(name string, values []string) {
this.writer.Header()[name] = values
}
// AddHeaders 添加一组Header
func (this *HTTPWriter) AddHeaders(header http.Header) {
if this.writer == nil {
@@ -206,6 +217,13 @@ func (this *HTTPWriter) WriteHeader(statusCode int) {
this.statusCode = statusCode
}
// Send 发送响应
func (this *HTTPWriter) Send(status int, body string) {
this.WriteHeader(status)
_, _ = this.WriteString(body)
this.isFinished = true
}
// StatusCode 读取状态码
func (this *HTTPWriter) StatusCode() int {
if this.statusCode == 0 {
@@ -423,7 +441,7 @@ func (this *HTTPWriter) Close() {
StaleAt: expiredAt + int64(this.calculateStaleLife()),
HeaderSize: this.cacheWriter.HeaderSize(),
BodySize: this.cacheWriter.BodySize(),
Host: this.req.Host,
Host: this.req.host,
ServerId: this.req.Server.Id,
})
}
@@ -456,7 +474,7 @@ func (this *HTTPWriter) prepareWebP(size int64) {
if this.req.web != nil &&
this.req.web.WebP != nil &&
this.req.web.WebP.IsOn &&
this.req.web.WebP.MatchResponse(this.Header().Get("Content-Type"), size, filepath.Ext(this.req.requestPath()), this.req.Format) &&
this.req.web.WebP.MatchResponse(this.Header().Get("Content-Type"), size, filepath.Ext(this.req.Path()), this.req.Format) &&
this.req.web.WebP.MatchAccept(this.req.requestHeader("Accept")) &&
atomic.LoadInt64(&webpTotalBufferSize) < webpMaxBufferSize {
@@ -493,7 +511,7 @@ func (this *HTTPWriter) PrepareCompression(size int64) {
}
// 尺寸和类型
if !this.compressionConfig.MatchResponse(this.Header().Get("Content-Type"), size, filepath.Ext(this.req.requestPath()), this.req.Format) {
if !this.compressionConfig.MatchResponse(this.Header().Get("Content-Type"), size, filepath.Ext(this.req.Path()), this.req.Format) {
return
}

View File

@@ -209,7 +209,7 @@ func (this *HTTPListener) ServeHTTP(rawWriter http.ResponseWriter, rawReq *http.
RawReq: rawReq,
RawWriter: rawWriter,
Server: server,
Host: reqHost,
host: reqHost,
ServerName: serverName,
ServerAddr: this.addr,
IsHTTP: this.isHTTP,