Ai
1 Star 0 Fork 0

Souki/go-framework

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
http_forward.go 2.25 KB
一键复制 编辑 原始数据 按行查看 历史
王少奇 提交于 2021-08-02 17:18 +08:00 . 新增 http转发
package httpserver
import (
"io/ioutil"
"net/http"
"net/url"
"strings"
"time"
)
//转发http的handler
type HttpForwardHandler struct {
forwardAddr string
forwardRules map[string]string
client http.Client
}
func NewHttpForwardHandler(forward string, timeout time.Duration) *HttpForwardHandler {
if !strings.HasPrefix(forward, "http") {
forward = "http://" + forward
}
return &HttpForwardHandler{
forwardAddr: forward,
forwardRules: map[string]string{},
client: http.Client{Timeout: timeout,},
}
}
func (h *HttpForwardHandler) AddForwardRule(rule map[string]string) {
rules := h.forwardRules
for path, forwardAddr := range rule {
rules[path] = forwardAddr
}
h.forwardRules = rules
}
func (h *HttpForwardHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
forwardReq, err := h.copyReq(r)
if err != nil {
panic(err)
}
httpResp, err := h.client.Do(forwardReq)
if err != nil {
panic(err)
}
defer httpResp.Body.Close()
repBody, err := ioutil.ReadAll(httpResp.Body)
if err != nil {
panic(err)
}
w.WriteHeader(httpResp.StatusCode)
w.Write(repBody)
}
func (h *HttpForwardHandler) getForwardAddr(request *http.Request) string {
uri := request.RequestURI
forwardAddr := h.forwardAddr
for path, addr := range h.forwardRules {
if path == uri {
forwardAddr = addr
}
if pos := strings.Index(path, "*"); pos >= 0 {
prefix := path[:pos]
suffix := path[pos+1:]
if strings.HasPrefix(uri, prefix) && strings.HasSuffix(uri, suffix) {
forwardAddr = addr
}
}
}
if !strings.HasPrefix(forwardAddr, "http") {
forwardAddr = "http://" + forwardAddr
}
return forwardAddr
}
func (h *HttpForwardHandler) copyReq(request *http.Request) (*http.Request, error) {
//
forwardAddr := h.getForwardAddr(request)
//
forwardUrl, err := url.Parse(forwardAddr)
if err != nil {
return nil, err
}
request.ParseForm()
forwardUrl.RawQuery = request.Form.Encode()
forwardMethod := request.Method
forwardReq, err := http.NewRequest(forwardMethod, forwardUrl.String(), request.Body)
if err != nil {
return nil, err
}
for headerKey := range request.Header {
forwardReq.Header.Add(headerKey, request.Header.Get(headerKey))
}
forwardReq.Header.Add("ForwardSource", request.RequestURI)
return forwardReq, nil
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/scottq/go-framework.git
git@gitee.com:scottq/go-framework.git
scottq
go-framework
go-framework
v1.1.21

搜索帮助