diff --git a/internal/nodes/http_request.go b/internal/nodes/http_request.go index 9151929..a96e6e0 100644 --- a/internal/nodes/http_request.go +++ b/internal/nodes/http_request.go @@ -121,7 +121,7 @@ func (this *HTTPRequest) Do() { // Web配置 err := this.configureWeb(this.Server.Web, true, 0) if err != nil { - this.write500(err) + this.write50x(err, http.StatusInternalServerError) this.doEnd() return } diff --git a/internal/nodes/http_request_auth.go b/internal/nodes/http_request_auth.go index f36d667..2728b97 100644 --- a/internal/nodes/http_request_auth.go +++ b/internal/nodes/http_request_auth.go @@ -33,7 +33,7 @@ func (this *HTTPRequest) doAuth() (shouldStop bool) { return writer.StatusCode(), nil }, this.Format) if err != nil { - this.write502(err) + this.write50x(err, http.StatusInternalServerError) return } if b { diff --git a/internal/nodes/http_request_error.go b/internal/nodes/http_request_error.go index 3266b67..cac642c 100644 --- a/internal/nodes/http_request_error.go +++ b/internal/nodes/http_request_error.go @@ -1,6 +1,7 @@ package nodes import ( + "github.com/iwind/TeaGo/types" "net/http" ) @@ -17,30 +18,15 @@ func (this *HTTPRequest) write404() { _, _ = this.writer.Write([]byte(msg)) } -func (this *HTTPRequest) write500(err error) { +func (this *HTTPRequest) write50x(err error, statusCode int) { if err != nil { this.addError(err) } - statusCode := http.StatusInternalServerError if this.doPage(statusCode) { return } this.processResponseHeaders(statusCode) this.writer.WriteHeader(statusCode) - _, _ = this.writer.Write([]byte(http.StatusText(statusCode))) -} - -func (this *HTTPRequest) write502(err error) { - if err != nil { - this.addError(err) - } - - statusCode := http.StatusBadGateway - if this.doPage(statusCode) { - return - } - this.processResponseHeaders(statusCode) - this.writer.WriteHeader(statusCode) - _, _ = this.writer.Write([]byte("502 Bad Gateway")) + _, _ = this.writer.Write([]byte(types.String(statusCode) + " " + http.StatusText(statusCode))) } diff --git a/internal/nodes/http_request_fastcgi.go b/internal/nodes/http_request_fastcgi.go index a82e8f2..82a095f 100644 --- a/internal/nodes/http_request_fastcgi.go +++ b/internal/nodes/http_request_fastcgi.go @@ -15,6 +15,7 @@ import ( "github.com/iwind/gofcgi/pkg/fcgi" "io" "net" + "net/http" "net/url" "path/filepath" "strings" @@ -80,7 +81,7 @@ func (this *HTTPRequest) doFastcgi() (shouldStop bool) { client, err := fcgi.SharedPool(fastcgi.Network(), fastcgi.RealAddress(), uint(poolSize)).Client() if err != nil { - this.write500(err) + this.write50x(err, http.StatusInternalServerError) return } @@ -158,13 +159,13 @@ func (this *HTTPRequest) doFastcgi() (shouldStop bool) { resp, stderr, err := client.Call(fcgiReq) if err != nil { - this.write500(err) + this.write50x(err, http.StatusInternalServerError) return } if len(stderr) > 0 { err := errors.New("Fastcgi Error: " + strings.TrimSpace(string(stderr)) + " script: " + maps.NewMap(params).GetString("SCRIPT_FILENAME")) - this.write500(err) + this.write50x(err, http.StatusInternalServerError) return } diff --git a/internal/nodes/http_request_reverse_proxy.go b/internal/nodes/http_request_reverse_proxy.go index a90a45b..5fe8772 100644 --- a/internal/nodes/http_request_reverse_proxy.go +++ b/internal/nodes/http_request_reverse_proxy.go @@ -8,6 +8,7 @@ import ( "github.com/TeaOSLab/EdgeNode/internal/remotelogs" "github.com/TeaOSLab/EdgeNode/internal/utils" "io" + "net/http" "net/url" "strconv" "strings" @@ -36,7 +37,7 @@ func (this *HTTPRequest) doReverseProxy() { if origin == nil { err := errors.New(this.requestPath() + ": no available backends for reverse proxy") remotelogs.Error("HTTP_REQUEST_REVERSE_PROXY", err.Error()) - this.write502(err) + this.write50x(err, http.StatusBadGateway) return } this.origin = origin // 设置全局变量是为了日志等处理 @@ -56,7 +57,7 @@ func (this *HTTPRequest) doReverseProxy() { if origin.Addr == nil { err := errors.New(this.requestPath() + ": origin '" + strconv.FormatInt(origin.Id, 10) + "' does not has a address") remotelogs.Error("HTTP_REQUEST_REVERSE_PROXY", err.Error()) - this.write502(err) + this.write50x(err, http.StatusBadGateway) return } this.RawReq.URL.Scheme = origin.Addr.Protocol.Primary().Scheme() @@ -143,7 +144,7 @@ func (this *HTTPRequest) doReverseProxy() { client, err := SharedHTTPClientPool.Client(this.RawReq, origin, originAddr) if err != nil { remotelogs.Error("HTTP_REQUEST_REVERSE_PROXY", err.Error()) - this.write502(err) + this.write50x(err, http.StatusBadGateway) return } @@ -158,13 +159,23 @@ func (this *HTTPRequest) doReverseProxy() { if err != nil { // 客户端取消请求,则不提示 httpErr, ok := err.(*url.Error) - if !ok || httpErr.Err != context.Canceled { - // TODO 如果超过最大失败次数,则下线 + if !ok { SharedOriginStateManager.Fail(origin, this.reverseProxy, func() { this.reverseProxy.ResetScheduling() }) - - this.write502(err) + this.write50x(err, http.StatusBadGateway) + remotelogs.Warn("HTTP_REQUEST_REVERSE_PROXY", this.RawReq.URL.String()+"': "+err.Error()) + } else if httpErr.Err != context.Canceled { + SharedOriginStateManager.Fail(origin, this.reverseProxy, func() { + this.reverseProxy.ResetScheduling() + }) + if httpErr.Timeout() { + this.write50x(err, http.StatusGatewayTimeout) + } else if httpErr.Temporary() { + this.write50x(err, http.StatusServiceUnavailable) + } else { + this.write50x(err, http.StatusBadGateway) + } remotelogs.Warn("HTTP_REQUEST_REVERSE_PROXY", this.RawReq.URL.String()+"': "+err.Error()) } else { // 是否为客户端方面的错误 @@ -178,7 +189,7 @@ func (this *HTTPRequest) doReverseProxy() { } if !isClientError { - this.write502(err) + this.write50x(err, http.StatusBadGateway) } } if resp != nil && resp.Body != nil { diff --git a/internal/nodes/http_request_root.go b/internal/nodes/http_request_root.go index 6170c6a..63767bc 100644 --- a/internal/nodes/http_request_root.go +++ b/internal/nodes/http_request_root.go @@ -109,7 +109,7 @@ func (this *HTTPRequest) doRoot() (isBreak bool) { } return } else { - this.write500(err) + this.write50x(err, http.StatusInternalServerError) logs.Error(err) return true } @@ -138,7 +138,7 @@ func (this *HTTPRequest) doRoot() (isBreak bool) { } return } else { - this.write500(err) + this.write50x(err, http.StatusInternalServerError) logs.Error(err) return true } @@ -283,8 +283,7 @@ func (this *HTTPRequest) doRoot() (isBreak bool) { reader, err := os.OpenFile(filePath, os.O_RDONLY, 0444) if err != nil { - this.write500(err) - logs.Error(err) + this.write50x(err, http.StatusInternalServerError) return true } diff --git a/internal/nodes/http_request_url.go b/internal/nodes/http_request_url.go index f8a2689..10b6bdc 100644 --- a/internal/nodes/http_request_url.go +++ b/internal/nodes/http_request_url.go @@ -36,7 +36,7 @@ func (this *HTTPRequest) doURL(method string, url string, host string, statusCod resp, err := client.Do(req) if err != nil { logs.Error(errors.New(req.URL.String() + ": " + err.Error())) - this.write500(err) + this.write50x(err, http.StatusInternalServerError) return } defer func() { diff --git a/internal/nodes/http_request_websocket.go b/internal/nodes/http_request_websocket.go index 772257b..5bb4b25 100644 --- a/internal/nodes/http_request_websocket.go +++ b/internal/nodes/http_request_websocket.go @@ -2,7 +2,6 @@ package nodes import ( "errors" - "github.com/iwind/TeaGo/logs" "io" "net/http" "net/url" @@ -43,8 +42,7 @@ func (this *HTTPRequest) doWebsocket() { // TODO 增加N次错误重试,重试的时候需要尝试不同的源站 originConn, err := OriginConnect(this.origin, this.RawReq.RemoteAddr) if err != nil { - logs.Error(err) - this.write500(err) + this.write50x(err, http.StatusBadGateway) return } defer func() { @@ -53,15 +51,13 @@ func (this *HTTPRequest) doWebsocket() { err = this.RawReq.Write(originConn) if err != nil { - logs.Error(err) - this.write500(err) + this.write50x(err, http.StatusBadGateway) return } clientConn, _, err := this.writer.Hijack() if err != nil { - logs.Error(err) - this.write500(err) + this.write50x(err, http.StatusInternalServerError) return } defer func() {