Skip to content

Commit 6352378

Browse files
committed
init
1 parent 8858c43 commit 6352378

File tree

5 files changed

+222
-1
lines changed

5 files changed

+222
-1
lines changed

README.md

+38-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,39 @@
1-
# dev
1+
# dev-proxy
22
开发调试神器
3+
4+
# 设置示例
5+
```
6+
test=>http://127.0.0.1:8080
7+
8+
假如服务域名为 dev.com 映射如下
9+
dev.com/test/product/list => http://192.168.8.8:8080/product/
10+
11+
注意:dev.com机器能访问 IP 192.168.8.8
12+
```
13+
14+
# 使用方法
15+
```
16+
package main
17+
18+
import (
19+
"flag"
20+
"github.com/go-proxy/dev"
21+
"log"
22+
"net/http"
23+
"os"
24+
)
25+
26+
func main() {
27+
port := os.Getenv("port")
28+
if port == "" {
29+
p := flag.String("port", "8888", "port default 8888")
30+
port = *p
31+
}
32+
dev := proxy.NewProxy()
33+
log.Println("start port :" + port)
34+
err := http.ListenAndServe(":"+port, dev)
35+
if err != nil {
36+
log.Fatal(err)
37+
}
38+
}
39+
```

exapmle/main.go

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package main
2+
3+
import (
4+
"flag"
5+
"github.com/go-proxy/dev"
6+
"log"
7+
"net/http"
8+
"os"
9+
)
10+
11+
func main() {
12+
port := os.Getenv("port")
13+
if port == "" {
14+
p := flag.String("port", "8888", "port default 8888")
15+
port = *p
16+
}
17+
dev := proxy.NewProxy()
18+
log.Println("start port :" + port)
19+
err := http.ListenAndServe(":"+port, dev)
20+
if err != nil {
21+
log.Fatal(err)
22+
}
23+
}

go.mod

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module github.com/go-proxy/dev
2+
3+
go 1.14

proxy.go

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package proxy
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
"net/http/httputil"
7+
"net/url"
8+
"strings"
9+
)
10+
11+
type proxy struct {
12+
table *table
13+
}
14+
15+
func NewProxy() *proxy {
16+
return &proxy{
17+
table: newTable(),
18+
}
19+
}
20+
21+
//管理逻辑
22+
func (p *proxy) admin(w http.ResponseWriter, r *http.Request) {
23+
//重置路由表
24+
p.table.DelAll()
25+
data := r.FormValue("data")
26+
arr := strings.Split(data, "\n")
27+
var newArr []string
28+
for _, item := range arr {
29+
d := strings.Split(item, "=>")
30+
if len(d) < 2 {
31+
continue
32+
}
33+
_, err := url.Parse(d[1])
34+
if err != nil {
35+
continue
36+
}
37+
newArr = append(newArr, item)
38+
fmt.Println(d[0], d[1])
39+
p.table.Set(d[0], d[1])
40+
}
41+
newData := strings.Join(newArr, "\n")
42+
w.Header().Set("Content-Type", "text/html;charset=utf-8")
43+
w.Write([]byte("<form><center><textarea autofocus name=\"data\" rows=\"30\" cols=\"100\">" + newData + "</textarea><br><input type=\"submit\" value=\"提交\"></center></form>"))
44+
}
45+
46+
func (p *proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
47+
fmt.Println(r.RequestURI)
48+
u := strings.Split(r.URL.Path, "/")
49+
service := u[1]
50+
//管理后台
51+
if service == "admin" {
52+
p.admin(w, r)
53+
return
54+
}
55+
s := p.table.Get(service)
56+
if s == "" {
57+
w.Write([]byte("没有设置信息,请检查配置:" + GetURL(r) + "/admin"))
58+
return
59+
}
60+
target, err := url.Parse(p.table.Get(service))
61+
if err != nil {
62+
w.Write([]byte(err.Error()))
63+
return
64+
}
65+
r.URL.Path = strings.TrimLeft(r.URL.Path, "/"+service)
66+
targetQuery := target.RawQuery
67+
director := func(req *http.Request) {
68+
req.URL.Scheme = target.Scheme
69+
req.URL.Host = target.Host
70+
req.URL.Path = singleJoiningSlash(target.Path, req.URL.Path)
71+
if targetQuery == "" || req.URL.RawQuery == "" {
72+
req.URL.RawQuery = targetQuery + req.URL.RawQuery
73+
} else {
74+
req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery
75+
}
76+
if _, ok := req.Header["User-Agent"]; !ok {
77+
// explicitly disable User-Agent so it's not set to default value
78+
req.Header.Set("User-Agent", "")
79+
}
80+
}
81+
proxy := &httputil.ReverseProxy{Director: director}
82+
proxy.ServeHTTP(w, r)
83+
}
84+
85+
//获取url中的第一个参数
86+
func singleJoiningSlash(a, b string) string {
87+
aslash := strings.HasSuffix(a, "/")
88+
bslash := strings.HasPrefix(b, "/")
89+
switch {
90+
case aslash && bslash:
91+
return a + b[1:]
92+
case !aslash && !bslash:
93+
return a + "/" + b
94+
}
95+
return a + b
96+
}
97+
98+
func GetURL(r *http.Request) (Url string) {
99+
scheme := "http://"
100+
if r.TLS != nil {
101+
scheme = "https://"
102+
}
103+
return strings.Join([]string{scheme, r.Host}, "")
104+
}

table.go

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package proxy
2+
3+
import "sync"
4+
5+
//路由表
6+
type table struct {
7+
mu sync.RWMutex
8+
data map[string]string
9+
}
10+
11+
func newTable() *table {
12+
return &table{
13+
data: make(map[string]string),
14+
}
15+
}
16+
17+
//设置数据
18+
func (t *table) Set(key string, val string) {
19+
t.mu.Lock()
20+
t.data[key] = val
21+
t.mu.Unlock()
22+
}
23+
24+
//获取数据
25+
func (t *table) Get(key string) string {
26+
t.mu.RLock()
27+
defer t.mu.RUnlock()
28+
return t.data[key]
29+
}
30+
31+
//获取数据
32+
func (t *table) GetAll() map[string]string {
33+
t.mu.RLock()
34+
defer t.mu.RUnlock()
35+
return t.data
36+
}
37+
38+
//删除
39+
func (t *table) DelAll() {
40+
t.mu.Lock()
41+
t.data = make(map[string]string)
42+
t.mu.Unlock()
43+
}
44+
45+
//长度
46+
func (t *table) Len() int {
47+
return len(t.data)
48+
}
49+
50+
//Key是否存在
51+
func (t *table) Exists(key string) bool {
52+
_, ok := t.data[key]
53+
return ok
54+
}

0 commit comments

Comments
 (0)