2020-09-26 19:54:26 +08:00
|
|
|
|
package nodes
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
2020-11-30 15:29:02 +08:00
|
|
|
|
"errors"
|
2021-12-19 11:32:26 +08:00
|
|
|
|
"github.com/TeaOSLab/EdgeNode/internal/utils"
|
2020-09-26 19:54:26 +08:00
|
|
|
|
"io"
|
|
|
|
|
|
"net/http"
|
|
|
|
|
|
"net/url"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// 处理Websocket请求
|
|
|
|
|
|
func (this *HTTPRequest) doWebsocket() {
|
|
|
|
|
|
if this.web.WebsocketRef == nil || !this.web.WebsocketRef.IsOn || this.web.Websocket == nil || !this.web.Websocket.IsOn {
|
|
|
|
|
|
this.writer.WriteHeader(http.StatusForbidden)
|
2020-11-30 15:29:02 +08:00
|
|
|
|
this.addError(errors.New("websocket have not been enabled yet"))
|
2020-09-26 19:54:26 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-09-27 10:02:54 +08:00
|
|
|
|
// TODO 实现handshakeTimeout
|
|
|
|
|
|
|
2020-09-26 19:54:26 +08:00
|
|
|
|
// 校验来源
|
2022-05-23 20:01:26 +08:00
|
|
|
|
var requestOrigin = this.RawReq.Header.Get("Origin")
|
2020-09-26 19:54:26 +08:00
|
|
|
|
if len(requestOrigin) > 0 {
|
|
|
|
|
|
u, err := url.Parse(requestOrigin)
|
|
|
|
|
|
if err == nil {
|
|
|
|
|
|
if !this.web.Websocket.MatchOrigin(u.Host) {
|
|
|
|
|
|
this.writer.WriteHeader(http.StatusForbidden)
|
2020-11-30 15:29:02 +08:00
|
|
|
|
this.addError(errors.New("websocket origin '" + requestOrigin + "' not been allowed"))
|
2020-09-26 19:54:26 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 设置指定的来源域
|
|
|
|
|
|
if !this.web.Websocket.RequestSameOrigin && len(this.web.Websocket.RequestOrigin) > 0 {
|
2022-05-23 20:01:26 +08:00
|
|
|
|
var newRequestOrigin = this.web.Websocket.RequestOrigin
|
2020-09-26 19:54:26 +08:00
|
|
|
|
if this.web.Websocket.RequestOriginHasVariables() {
|
|
|
|
|
|
newRequestOrigin = this.Format(newRequestOrigin)
|
|
|
|
|
|
}
|
|
|
|
|
|
this.RawReq.Header.Set("Origin", newRequestOrigin)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-09-27 10:02:54 +08:00
|
|
|
|
// TODO 增加N次错误重试,重试的时候需要尝试不同的源站
|
2020-12-03 10:17:28 +08:00
|
|
|
|
originConn, err := OriginConnect(this.origin, this.RawReq.RemoteAddr)
|
2020-09-26 19:54:26 +08:00
|
|
|
|
if err != nil {
|
2021-12-16 17:27:21 +08:00
|
|
|
|
this.write50x(err, http.StatusBadGateway, false)
|
2022-05-23 20:01:26 +08:00
|
|
|
|
|
|
|
|
|
|
// 增加失败次数
|
|
|
|
|
|
SharedOriginStateManager.Fail(this.origin, this.reverseProxy, func() {
|
|
|
|
|
|
this.reverseProxy.ResetScheduling()
|
|
|
|
|
|
})
|
|
|
|
|
|
|
2020-09-26 19:54:26 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
2022-05-23 20:01:26 +08:00
|
|
|
|
|
|
|
|
|
|
if !this.origin.IsOk {
|
|
|
|
|
|
SharedOriginStateManager.Success(this.origin, func() {
|
|
|
|
|
|
this.reverseProxy.ResetScheduling()
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-09-26 19:54:26 +08:00
|
|
|
|
defer func() {
|
|
|
|
|
|
_ = originConn.Close()
|
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
|
|
err = this.RawReq.Write(originConn)
|
|
|
|
|
|
if err != nil {
|
2021-12-16 17:27:21 +08:00
|
|
|
|
this.write50x(err, http.StatusBadGateway, false)
|
2020-09-26 19:54:26 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
clientConn, _, err := this.writer.Hijack()
|
2021-10-25 19:42:12 +08:00
|
|
|
|
if err != nil || clientConn == nil {
|
2021-12-16 17:27:21 +08:00
|
|
|
|
this.write50x(err, http.StatusInternalServerError, false)
|
2020-09-26 19:54:26 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
defer func() {
|
|
|
|
|
|
_ = clientConn.Close()
|
|
|
|
|
|
}()
|
|
|
|
|
|
|
2022-05-23 20:01:26 +08:00
|
|
|
|
go func() {
|
2021-12-19 11:32:26 +08:00
|
|
|
|
var buf = utils.BytePool4k.Get()
|
|
|
|
|
|
defer utils.BytePool4k.Put(buf)
|
2020-12-11 17:27:35 +08:00
|
|
|
|
for {
|
|
|
|
|
|
n, err := originConn.Read(buf)
|
|
|
|
|
|
if n > 0 {
|
|
|
|
|
|
this.writer.sentBodyBytes += int64(n)
|
|
|
|
|
|
_, err = clientConn.Write(buf[:n])
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-09-26 19:54:26 +08:00
|
|
|
|
_ = clientConn.Close()
|
|
|
|
|
|
_ = originConn.Close()
|
2022-05-23 20:01:26 +08:00
|
|
|
|
}()
|
2020-09-26 19:54:26 +08:00
|
|
|
|
_, _ = io.Copy(originConn, clientConn)
|
|
|
|
|
|
}
|