-
Notifications
You must be signed in to change notification settings - Fork 7
/
proxy.go
118 lines (102 loc) · 3.29 KB
/
proxy.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package main
import (
"errors"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"regexp"
"runtime"
"strings"
"time"
)
const (
timeout = 10 * time.Second
servername = "服务器的地址"
remote = "www.google.com"
scheme = "http"
)
type Filter struct {
Rules []regexp.Regexp
Replacement []string
Count int
}
func GetFilter(rules map[string]string) *Filter {
ru := make([]regexp.Regexp, len(rules))
rp := make([]string, len(rules))
i := 0
for k, v := range rules {
ru[i] = *regexp.MustCompile(k)
rp[i] = v
i++
}
return &Filter{Rules: ru, Replacement: rp, Count: i}
}
func (this *Filter) Replace(str string) string {
for i := 0; i < this.Count; i++ {
str = this.Rules[i].ReplaceAllString(str, this.Replacement[i])
}
return str
}
var client *http.Client
var rules map[string]string = map[string]string{
"https": "http",
"([0-9A-Za-z.-]+\\.gstatic\\.com)": servername + "/!$1",
"((apis)\\.google\\.com)": servername + "/!$1",
"((www)|(images))\\.google\\.[0-9a-z.]+": servername,
"(img\\.youtube\\.com)": servername + "/!$1"}
var filter *Filter
var NotFollowRedirect error
func proxy(w http.ResponseWriter, req *http.Request) {
var u *url.URL
if strings.HasPrefix(req.URL.RequestURI(), "/!") {
u, _ = url.Parse(scheme + "://" + req.URL.RequestURI()[2:])
} else {
u, _ = url.Parse(scheme + "://" + remote + req.URL.RequestURI())
}
println(u.String())
reqHead := make(http.Header)
reqHead.Add("Accept:text/html", "application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")
//TODO:Implement Gzip Deflate...
reqHead.Add("Accept-Encoding", "")
reqHead.Add("Accept-Language", "en-US")
reqHead.Add("Cache-Control", "no-cache")
reqHead.Add("Pragma", "no-cache")
reqHead.Add("User-Agent", req.Header.Get("User-Agent"))
reqHead.Add("Cookie", "NID=76=KJwxX-SN2oOpNEkWTjdLvPLOp-sIhTAxIG-aOBIcxDqAxmjmNmg1q4Wfw_chL0GUSTeaRLfEbu6RqCvVOOq5-RZHmSQaRNOSBaHUjVYTwK_dqnYnTDXWmyrEW24aJrrz; expires=Sun, 14-Aug-2026 03:37:23 GMT; path=/; domain=.google.com; HttpOnly")
getgoogle, _ := client.Do(&http.Request{
URL: u,
Body: req.Body,
Close: false,
TransferEncoding: []string{"chunked"},
Header: reqHead,
Method: req.Method})
defer getgoogle.Body.Close()
if getgoogle.StatusCode == 302 || getgoogle.StatusCode == 301 {
uu, _ := url.Parse(getgoogle.Header.Get("Location"))
uu.Scheme = "http"
uu.Host = filter.Replace(uu.Host)
w.Header().Add("Location", uu.String())
}
w.Header().Add("Cache-Control", "no-cache")
w.Header().Add("Content-Type", getgoogle.Header.Get("Content-Type"))
w.WriteHeader(getgoogle.StatusCode)
str, _ := ioutil.ReadAll(getgoogle.Body)
fmt.Fprint(w, filter.Replace(string(str)))
}
func main() {
NotFollowRedirect = errors.New("Not Follow Redirect")
client = &http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error { return NotFollowRedirect },
Timeout: timeout}
server := http.NewServeMux()
filter = GetFilter(rules)
//状态信息
server.HandleFunc("/status", func(w http.ResponseWriter, req *http.Request) {
fmt.Fprintf(w, "Number Of Goroutines: %d", runtime.NumGoroutine())
})
//Proxy
server.HandleFunc("/", proxy)
http.TimeoutHandler(server, timeout, "Timeout")
panic(http.ListenAndServe(":3000", server))
}