make proxy yse directive and forbidden get/set admin by api
This commit is contained in:
parent
fab22c1c2d
commit
618a186298
|
@ -1,6 +1,7 @@
|
||||||
package admin
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
@ -28,6 +29,11 @@ func setConfig(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
t := data.(model.HttpServerConfig)
|
t := data.(model.HttpServerConfig)
|
||||||
|
if t.Name == "admin" {
|
||||||
|
w.WriteHeader(http.StatusForbidden)
|
||||||
|
resp := server.NewErrorResult(errors.New("不能通过api设置管理服务器"))
|
||||||
|
w.Write(resp)
|
||||||
|
}
|
||||||
err := model.SetServerConfig(&t)
|
err := model.SetServerConfig(&t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
@ -46,6 +52,12 @@ func getServerConfigure(w http.ResponseWriter, r *http.Request) {
|
||||||
ctxData := ctx.Value(server.RequestCtxKey("data")).(map[string]interface{})
|
ctxData := ctx.Value(server.RequestCtxKey("data")).(map[string]interface{})
|
||||||
id, ok := ctxData["id"]
|
id, ok := ctxData["id"]
|
||||||
if ok {
|
if ok {
|
||||||
|
if id.(string) == "admin" {
|
||||||
|
w.WriteHeader(http.StatusForbidden)
|
||||||
|
resp := server.NewErrorResult(errors.New("不能通过api获取管理服务器配置信息"))
|
||||||
|
w.Write(resp)
|
||||||
|
return
|
||||||
|
}
|
||||||
data := model.GetServerConfig(id.(string))
|
data := model.GetServerConfig(id.(string))
|
||||||
/// configContent, _ := json.Marshal(data)
|
/// configContent, _ := json.Marshal(data)
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
|
|
30
gohttp.go
30
gohttp.go
|
@ -6,7 +6,6 @@ import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"git.pyer.club/kingecg/gohttpd/admin"
|
"git.pyer.club/kingecg/gohttpd/admin"
|
||||||
handler "git.pyer.club/kingecg/gohttpd/hander"
|
|
||||||
"git.pyer.club/kingecg/gohttpd/model"
|
"git.pyer.club/kingecg/gohttpd/model"
|
||||||
"git.pyer.club/kingecg/gohttpd/server"
|
"git.pyer.club/kingecg/gohttpd/server"
|
||||||
"git.pyer.club/kingecg/gohttpd/utils"
|
"git.pyer.club/kingecg/gohttpd/utils"
|
||||||
|
@ -22,13 +21,13 @@ func (g *GoHttp) Start() {
|
||||||
g.logger = gologger.GetLogger("Server")
|
g.logger = gologger.GetLogger("Server")
|
||||||
g.logger.Info("start gohttpd")
|
g.logger.Info("start gohttpd")
|
||||||
// if g.conf != nil {
|
// if g.conf != nil {
|
||||||
adminHandler := g.assembleServerMux(conf.Admin.Paths)
|
adminHandler := server.NewServeMux(conf.Admin)
|
||||||
adminHandler.(*http.ServeMux).Handle("/api/", http.StripPrefix("/api", admin.AdminServerMux))
|
adminHandler.Handle("/api/", http.StripPrefix("/api", admin.AdminServerMux))
|
||||||
g.makeServer(conf.Admin, adminHandler)
|
g.makeServer(conf.Admin, adminHandler)
|
||||||
|
|
||||||
for _, server := range conf.Servers {
|
for _, s := range conf.Servers {
|
||||||
sHandler := g.assembleServerMux(server.Paths)
|
sHandler := server.NewServeMux(s)
|
||||||
g.makeServer(server, sHandler)
|
g.makeServer(s, sHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, listener := range server.ServerManager {
|
for _, listener := range server.ServerManager {
|
||||||
|
@ -52,25 +51,6 @@ func (g *GoHttp) makeServer(conf *model.HttpServerConfig, mux http.Handler) {
|
||||||
server.AddServer(name, ss, port)
|
server.AddServer(name, ss, port)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GoHttp) assembleServerMux(p []model.HttpPath) http.Handler {
|
|
||||||
s := http.NewServeMux()
|
|
||||||
for _, httpPath := range p {
|
|
||||||
if httpPath.Root != "" {
|
|
||||||
fileHandler := handler.NewFileHandler(handler.FileHandler{
|
|
||||||
Root: httpPath.Root,
|
|
||||||
Default: httpPath.Default,
|
|
||||||
})
|
|
||||||
s.Handle(httpPath.Path, fileHandler)
|
|
||||||
} else if len(httpPath.Upstreams) != 0 {
|
|
||||||
proxyHandler := handler.NewProxyHandler(&httpPath)
|
|
||||||
s.Handle(httpPath.Path, proxyHandler)
|
|
||||||
} else {
|
|
||||||
g.logger.Error("Not supportted server path type :", httpPath.Path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *GoHttp) Stop() {}
|
func (g *GoHttp) Stop() {}
|
||||||
|
|
||||||
func LoadConfig() {
|
func LoadConfig() {
|
||||||
|
|
|
@ -3,7 +3,6 @@ package handler
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httputil"
|
"net/http/httputil"
|
||||||
"net/url"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -30,39 +29,34 @@ func (p *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
p.proxy[proxyIndex].ServeHTTP(w, r)
|
p.proxy[proxyIndex].ServeHTTP(w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// init httputil.ReverseProxy instance and add path rewrite and add session-sticky cookie to response
|
/*
|
||||||
|
*
|
||||||
|
init httputil.ReverseProxy instance and add path rewrite and add session-sticky cookie to response
|
||||||
|
@param upstream upstream server url
|
||||||
|
@param path http path config
|
||||||
|
@param index the proxy index in upstreams
|
||||||
|
|
||||||
|
@return httputil.ReverseProxy instance
|
||||||
|
|
||||||
|
what is the directive? its stands for update of request, like HostSchemas, Path, RemoveCookie, etc.
|
||||||
|
eg: HostSchemas $target
|
||||||
|
it stande for replace req url host and schema according to $target url. $target == upstream
|
||||||
|
*/
|
||||||
func makeProxy(upstream string, path *model.HttpPath, index int) *httputil.ReverseProxy {
|
func makeProxy(upstream string, path *model.HttpPath, index int) *httputil.ReverseProxy {
|
||||||
p := &httputil.ReverseProxy{}
|
p := &httputil.ReverseProxy{}
|
||||||
|
directiveHandlers := []func(r *http.Request){}
|
||||||
|
if len(path.Directives) > 0 {
|
||||||
|
for _, directive := range path.Directives {
|
||||||
|
d := strings.Replace(string(directive), "$target", upstream, 1)
|
||||||
|
dh := GetUpdaterFn(d)
|
||||||
|
if dh != nil {
|
||||||
|
directiveHandlers = append(directiveHandlers, dh)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
p.Director = func(req *http.Request) {
|
p.Director = func(req *http.Request) {
|
||||||
turl, _ := url.Parse(upstream)
|
for _, handler := range directiveHandlers {
|
||||||
req.URL.Host = turl.Host
|
handler(req)
|
||||||
req.URL.Scheme = turl.Scheme
|
|
||||||
pw := path.Rewrite
|
|
||||||
if pw.Replace != "" {
|
|
||||||
req.URL.Path = strings.TrimPrefix(req.URL.Path, pw.Replace)
|
|
||||||
if req.URL.RawPath != "" {
|
|
||||||
req.URL.RawPath = strings.TrimPrefix(req.URL.RawPath, pw.Replace)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if pw.With != "" {
|
|
||||||
req.URL.Path = strings.TrimSuffix(pw.With, "/") + "/" + req.URL.Path
|
|
||||||
if req.URL.RawPath != "" {
|
|
||||||
req.URL.RawPath = strings.TrimSuffix(pw.With, "/") + "/" + req.URL.RawPath
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(path.Headers) > 0 {
|
|
||||||
for _, header := range path.Headers {
|
|
||||||
//req.Header.Add(header.Name, header.Value)
|
|
||||||
value := ""
|
|
||||||
switch header.Value {
|
|
||||||
case string(model.ProxyHost):
|
|
||||||
value = turl.Host
|
|
||||||
default:
|
|
||||||
value = header.Value
|
|
||||||
}
|
|
||||||
req.Header.Set(header.Name, value)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
package server
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
|
@ -10,9 +11,18 @@ import (
|
||||||
type ProxyRequestUpdater func(arg ...string) func(r *http.Request)
|
type ProxyRequestUpdater func(arg ...string) func(r *http.Request)
|
||||||
|
|
||||||
var ProxyRequestUpdateMap = map[string]ProxyRequestUpdater{
|
var ProxyRequestUpdateMap = map[string]ProxyRequestUpdater{
|
||||||
"Host": func(arg ...string) func(r *http.Request) {
|
"HostSchemas": func(arg ...string) func(r *http.Request) {
|
||||||
|
targetUrl := arg[0]
|
||||||
return func(r *http.Request) {
|
return func(r *http.Request) {
|
||||||
r.Host = arg[0]
|
turl, _ := url.Parse(targetUrl)
|
||||||
|
r.URL.Host = turl.Host
|
||||||
|
r.URL.Scheme = turl.Scheme
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"HeaderOrigin": func(arg ...string) func(r *http.Request) {
|
||||||
|
|
||||||
|
return func(r *http.Request) {
|
||||||
|
r.Header.Set("Origin", r.URL.Scheme+"://"+r.URL.Host)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Path": func(arg ...string) func(r *http.Request) {
|
"Path": func(arg ...string) func(r *http.Request) {
|
|
@ -9,22 +9,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type HttpPath struct {
|
type HttpPath struct {
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
Root string `json:"root"`
|
Root string `json:"root"`
|
||||||
Default string `json:"default"`
|
Default string `json:"default"`
|
||||||
Upstreams []string `json:"upstreams"`
|
Upstreams []string `json:"upstreams"`
|
||||||
Rewrite PathRewrite `json:"pathrewrite"`
|
Directives string `json:"directives"`
|
||||||
Headers []HeaderDefine `json:"headers"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type PathRewrite struct {
|
|
||||||
Replace string `json:"replace"`
|
|
||||||
With string `json:"with"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type HeaderDefine struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Value string `json:"value"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type HeaderValueConst string
|
type HeaderValueConst string
|
||||||
|
@ -43,6 +32,7 @@ type HttpServerConfig struct {
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
CertFile string `json:"certfile"`
|
CertFile string `json:"certfile"`
|
||||||
KeyFile string `json:"keyfile"`
|
KeyFile string `json:"keyfile"`
|
||||||
|
Directives string `json:"directives"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GoHttpdConfig struct {
|
type GoHttpdConfig struct {
|
||||||
|
|
|
@ -7,12 +7,14 @@ type Directive func(args ...string) Middleware
|
||||||
var Add_Header Directive = func(args ...string) Middleware {
|
var Add_Header Directive = func(args ...string) Middleware {
|
||||||
return func(w http.ResponseWriter, r *http.Request, next func()) {
|
return func(w http.ResponseWriter, r *http.Request, next func()) {
|
||||||
w.Header().Add(args[0], args[1])
|
w.Header().Add(args[0], args[1])
|
||||||
|
next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var Set_Header Directive = func(args ...string) Middleware {
|
var Set_Header Directive = func(args ...string) Middleware {
|
||||||
return func(w http.ResponseWriter, r *http.Request, next func()) {
|
return func(w http.ResponseWriter, r *http.Request, next func()) {
|
||||||
w.Header().Set(args[0], args[1])
|
w.Header().Set(args[0], args[1])
|
||||||
|
next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,10 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
handler "git.pyer.club/kingecg/gohttpd/hander"
|
||||||
|
"git.pyer.club/kingecg/gohttpd/model"
|
||||||
"git.pyer.club/kingecg/gologger"
|
"git.pyer.club/kingecg/gologger"
|
||||||
|
logger "git.pyer.club/kingecg/gologger"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RequestCtxKey string
|
type RequestCtxKey string
|
||||||
|
@ -228,3 +231,32 @@ func (s *ServerMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
http.NotFound(w, r)
|
http.NotFound(w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewServeMux(c *model.HttpServerConfig) *ServerMux {
|
||||||
|
l := logger.GetLogger("ServerMux")
|
||||||
|
l.Debug("NewServeMux")
|
||||||
|
s := &ServerMux{
|
||||||
|
directiveHandlers: NewMiddlewareLink(),
|
||||||
|
handlers: make(map[string]http.Handler),
|
||||||
|
paths: []string{},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, directive := range c.Directives {
|
||||||
|
s.AddDirective(string(directive))
|
||||||
|
}
|
||||||
|
for _, httpPath := range c.Paths {
|
||||||
|
if httpPath.Root != "" {
|
||||||
|
fileHandler := handler.NewFileHandler(handler.FileHandler{
|
||||||
|
Root: httpPath.Root,
|
||||||
|
Default: httpPath.Default,
|
||||||
|
})
|
||||||
|
s.Handle(httpPath.Path, fileHandler)
|
||||||
|
} else if len(httpPath.Upstreams) != 0 {
|
||||||
|
proxyHandler := handler.NewProxyHandler(&httpPath)
|
||||||
|
s.Handle(httpPath.Path, proxyHandler)
|
||||||
|
} else {
|
||||||
|
l.Error("Not supportted server path type :", httpPath.Path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue