This commit is contained in:
eson 2023-07-11 13:07:44 +08:00
parent 8c2cfcb37b
commit fb06995b26
26 changed files with 334 additions and 41 deletions

View File

@ -4,5 +4,5 @@ Port: {{.port}}
SourceMysql: ""
Auth:
AccessSecret: fusen2023
AccessExpire: 604800
RefreshAfter: 345600
AccessExpire: 2592000
RefreshAfter: 1592000

View File

@ -4,5 +4,5 @@ Port: {{.port}}
SourceMysql: ""
Auth:
AccessSecret: fusen2023
AccessExpire: 604800
RefreshAfter: 345600
AccessExpire: 2592000
RefreshAfter: 1592000

View File

@ -0,0 +1,125 @@
package main
import (
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
"gopkg.in/yaml.v2"
)
type Config struct {
Host string `yaml:"Host"`
Port int `yaml:"Port"`
}
type Result struct {
FolderName string
Host string
Port int
PrefixRoute map[string]bool
}
func GetZeroInfo(rootDir string) (results []*Result) {
entries, err := ioutil.ReadDir(rootDir)
if err != nil {
log.Fatal(err)
}
for _, entry := range entries {
if entry.IsDir() {
result, err := findFoldersAndExtractInfo(rootDir, entry)
if err != nil {
log.Fatal(err)
}
results = append(results, result)
}
}
return
}
func findFoldersAndExtractInfo(rootDir string, entry os.FileInfo) (*Result, error) {
var result *Result
folderName := entry.Name()
path := filepath.Join(rootDir, folderName)
err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() {
return nil
}
relPath, err := filepath.Rel(path, path)
if err != nil {
return err
}
if strings.Contains(relPath, string(os.PathSeparator)) {
return filepath.SkipDir
}
configPath := filepath.Join(path, "etc", folderName+".yaml")
routesPath := filepath.Join(path, "internal", "handler", "routes.go")
configContent, err := ioutil.ReadFile(configPath)
if err != nil {
return err
}
var config Config
err = yaml.Unmarshal(configContent, &config)
if err != nil {
return err
}
routesContent, err := ioutil.ReadFile(routesPath)
if err != nil {
return err
}
PrefixRoute := extractPrefixRouteValues(string(routesContent))
result = &Result{
FolderName: folderName,
Host: config.Host,
Port: config.Port,
PrefixRoute: PrefixRoute,
}
return filepath.SkipDir
})
if err != nil {
return nil, err
}
return result, nil
}
func extractPrefixRouteValues(content string) map[string]bool {
lines := strings.Split(content, "\n")
var prefixPath map[string]bool = make(map[string]bool)
for _, line := range lines {
if strings.Contains(line, "Path:") {
path := strings.TrimSpace(strings.TrimPrefix(line, "Path:"))
path1 := strings.Split(strings.Trim(path, `"`), "/")[1]
path1 = "/" + path1
if _, ok := prefixPath[path1]; !ok {
prefixPath[path1] = true
}
}
}
return prefixPath
}

136
proxyserver/main.go Normal file
View File

@ -0,0 +1,136 @@
package main
import (
"fmt"
"io"
"log"
"net"
"net/http"
"net/url"
"time"
)
var Backends []*Backend
func main() {
rootDir := "../server" // Change this to your root directory
vueBuild := "/home/eson/workspace/fusenpack-vue-created"
mux := http.NewServeMux()
// Define the static file server that serves the Vue dist folder
fs := http.FileServer(http.Dir(vueBuild))
// Define a handler function for the Vue static assets
mux.Handle("/", http.StripPrefix("/", fs))
results := GetZeroInfo(rootDir)
for _, result := range results {
fmt.Printf("FolderName: %s, Host: %s, Port: %d, PrefixRoute: %v\n", result.FolderName, result.Host, result.Port, result.PrefixRoute)
var routes []string
for k := range result.PrefixRoute {
routes = append(routes, k)
}
Backends = append(Backends,
NewBackend(mux,
fmt.Sprintf("http://%s:%d", result.Host, result.Port),
routes...))
}
ServerAddress := ":9900"
log.Println("listen on ", ServerAddress)
log.Fatal(http.ListenAndServe(ServerAddress, mux))
}
type Backend struct {
HttpAddress string
Client *http.Client
Handler http.HandlerFunc
}
func NewBackend(mux *http.ServeMux, httpAddress string, muxPaths ...string) *Backend {
for i, muxPath := range muxPaths {
if muxPath[len(muxPath)-1] != '/' {
muxPath = muxPath + "/"
muxPaths[i] = muxPath
}
}
client := &http.Client{
Transport: &http.Transport{
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
ForceAttemptHTTP2: true,
MaxIdleConns: 100,
MaxIdleConnsPerHost: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
},
}
backend := &Backend{
HttpAddress: httpAddress,
Client: client,
}
handleRequest := func(w http.ResponseWriter, r *http.Request) {
targetURL, err := url.Parse(httpAddress + r.URL.Path)
if err != nil {
http.Error(w, "Error parsing target URL", http.StatusInternalServerError)
return
}
// 解析目标URL时已经包含了查询参数
targetURL.RawQuery = r.URL.RawQuery
proxyReq, err := http.NewRequest(r.Method, targetURL.String(), r.Body)
if err != nil {
http.Error(w, "Error creating proxy request", http.StatusInternalServerError)
return
}
// 复制原始请求的 Header
for key, values := range r.Header {
for _, value := range values {
proxyReq.Header.Add(key, value)
}
}
// 设置 Content-Length 和 Content-Type
proxyReq.ContentLength = r.ContentLength
proxyReq.Header.Set("Content-Type", r.Header.Get("Content-Type"))
resp, err := backend.Client.Do(proxyReq)
if err != nil {
http.Error(w, "Error sending proxy request", http.StatusInternalServerError)
return
}
defer resp.Body.Close()
// 复制目标服务器的响应 Header
for key, values := range resp.Header {
for _, value := range values {
w.Header().Add(key, value)
}
}
// 转发目标服务器的响应状态码和主体
w.WriteHeader(resp.StatusCode)
_, err = io.Copy(w, resp.Body)
if err != nil {
http.Error(w, "Error copying proxy response", http.StatusInternalServerError)
return
}
}
for _, muxPath := range muxPaths {
mux.HandleFunc(muxPath, handleRequest)
}
return backend
}

18
proxyserver/main_test.go Normal file
View File

@ -0,0 +1,18 @@
package main
import (
"fmt"
"testing"
)
func TestProxy(t *testing.T) {
main()
}
func TestCapture(t *testing.T) {
rootDir := "../server" // Change this to your root directory
results := GetZeroInfo(rootDir)
for _, result := range results {
fmt.Printf("FolderName: %s, Host: %s, Port: %d, PrefixRoute: %v\n", result.FolderName, result.Host, result.Port, result.PrefixRoute)
}
}

View File

@ -4,5 +4,5 @@ Port: 9901
SourceMysql: fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest
Auth:
AccessSecret: fusen_backend_2023
AccessExpire: 604800
RefreshAfter: 345600
AccessExpire: 2592000
RefreshAfter: 1592000

View File

@ -4,5 +4,5 @@ Port: 9902
SourceMysql: fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest
Auth:
AccessSecret: fusen2023
AccessExpire: 60
RefreshAfter: 60
AccessExpire: 2592000
RefreshAfter: 1592000

View File

@ -4,5 +4,5 @@ Port: 9903
SourceMysql: fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest
Auth:
AccessSecret: fusen2023
AccessExpire: 60
RefreshAfter: 60
AccessExpire: 2592000
RefreshAfter: 1592000

View File

@ -6,7 +6,7 @@ SourceMysql: fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest
Auth:
AccessSecret: fusen2023
AccessExpire: 2592000
RefreshAfter: 2592000
RefreshAfter: 1592000
Stripe:
SK: "sk_test_51IisojHygnIJZeghPVSBhkwySfcyDV4SoAduIxu3J7bvSJ9cZMD96LY1LO6SpdbYquLJX5oKvgEBB67KT9pecfCy00iEC4pp9y"

View File

@ -4,5 +4,5 @@ Port: 9905
SourceMysql: fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest
Auth:
AccessSecret: fusen2023
AccessExpire: 604800
RefreshAfter: 345600
AccessExpire: 2592000
RefreshAfter: 1592000

View File

@ -4,5 +4,5 @@ Port: 9906
SourceMysql: fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest
Auth:
AccessSecret: fusen2023
AccessExpire: 60
RefreshAfter: 60
AccessExpire: 2592000
RefreshAfter: 1592000

View File

@ -4,5 +4,5 @@ Port: 9907
SourceMysql: fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest
Auth:
AccessSecret: fusen2023
AccessExpire: 60
RefreshAfter: 60
AccessExpire: 2592000
RefreshAfter: 1592000

View File

@ -4,5 +4,5 @@ Port: 9909
SourceMysql: fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest
Auth:
AccessSecret: fusen2023
AccessExpire: 60
RefreshAfter: 60
AccessExpire: 2592000
RefreshAfter: 1592000

View File

@ -4,5 +4,5 @@ Port: 9910
SourceMysql: fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest
Auth:
AccessSecret: fusen2023
AccessExpire: 60
RefreshAfter: 60
AccessExpire: 2592000
RefreshAfter: 1592000

View File

@ -4,5 +4,5 @@ Port: 9908
SourceMysql: fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest
Auth:
AccessSecret: fusen2023
AccessExpire: 60
RefreshAfter: 60
AccessExpire: 2592000
RefreshAfter: 1592000

View File

@ -4,5 +4,5 @@ Port: 9911
SourceMysql: fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest
Auth:
AccessSecret: fusen2023
AccessExpire: 604800
RefreshAfter: 345600
AccessExpire: 2592000
RefreshAfter: 1592000

View File

@ -5,8 +5,8 @@ SourceMysql: "fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest"
Env: "test"
Auth:
AccessSecret: fusen2023
AccessExpire: 604800
RefreshAfter: 345600
AccessExpire: 2592000
RefreshAfter: 1592000
AWS:
S3:
Credentials:

View File

@ -1,8 +1,8 @@
Name: wetset
Name: webset
Host: 0.0.0.0
Port: 8888
Port: 9914
SourceMysql: "fusentest:XErSYmLELKMnf3Dh@tcp(110.41.19.98:3306)/fusentest"
Auth:
AccessSecret: fusen2023
AccessExpire: 604800
RefreshAfter: 345600
AccessExpire: 2592000
RefreshAfter: 1592000

View File

@ -15,7 +15,7 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
{
Method: http.MethodGet,
Path: "/web-set/setting",
Handler: WetSetSettingHandler(serverCtx),
Handler: WebSetSettingHandler(serverCtx),
},
},
)

View File

@ -15,7 +15,7 @@ import (
"fusenapi/server/webset/internal/types"
)
func WetSetSettingHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
func WebSetSettingHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var (
@ -65,7 +65,7 @@ func WetSetSettingHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
}
// 创建一个业务逻辑层实例
l := logic.NewWetSetSettingLogic(r.Context(), svcCtx)
resp := l.WetSetSetting(&req, userinfo)
resp := l.WebSetSetting(&req, userinfo)
// 如果响应不为nil则使用httpx.OkJsonCtx方法返回JSON响应;
if resp != nil {
httpx.OkJsonCtx(r.Context(), w, resp)

View File

@ -29,7 +29,7 @@ func NewWetSetSettingLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Wet
}
}
func (l *WetSetSettingLogic) WetSetSetting(req *types.RequestWebSet, userinfo *auth.UserInfo) (resp *basic.Response) {
func (l *WetSetSettingLogic) WebSetSetting(req *types.RequestWebSet, userinfo *auth.UserInfo) (resp *basic.Response) {
// 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data)
// userinfo 传入值时, 一定不为null

View File

@ -9,7 +9,7 @@ type RequestWebSet struct {
Type string `form:"type"`
}
type DataWetSet struct {
type DataWebSet struct {
Title string `json:"title"`
Introduction string `json:"introduction"`
List interface{} `json:"list"`
@ -30,6 +30,20 @@ type Auth struct {
RefreshAfter int64 `json:"refreshAfter"`
}
type File struct {
Filename string `fsfile:"filename"`
Header map[string][]string `fsfile:"header"`
Size int64 `fsfile:"size"`
Data []byte `fsfile:"data"`
}
type Meta struct {
TotalCount int64 `json:"totalCount"`
PageCount int64 `json:"pageCount"`
CurrentPage int `json:"currentPage"`
PerPage int `json:"perPage"`
}
// Set 设置Response的Code和Message值
func (resp *Response) Set(Code int, Message string) *Response {
return &Response{

View File

@ -1,4 +1,4 @@
package wetset_test
package webset_test
import (
"fmt"

View File

@ -1,4 +1,4 @@
package wetset_test
package webset_test
import (
"fmt"

View File

@ -12,7 +12,7 @@ import (
"github.com/zeromicro/go-zero/rest"
)
var configFile = flag.String("f", "etc/wetset.yaml", "the config file")
var configFile = flag.String("f", "etc/webset.yaml", "the config file")
func main() {
flag.Parse()

View File

@ -9,7 +9,7 @@ info (
import "basic.api"
service wetset {
service webset {
@handler WetSetSettingHandler
get /web-set/setting(RequestWebSet) returns (response);
}
@ -18,7 +18,7 @@ type RequestWebSet {
Type string `form:"type"`
}
type DataWetSet {
type DataWebSet {
Title string `json:"title"`
Introduction string `json:"introduction"`
List interface{} `json:"list"`