├── README.md ├── demo.png └── proxy.go /README.md: -------------------------------------------------------------------------------- 1 | # google_proxy_by_golang 2 | 一个用基于Golang的服务器端Google搜索代理 3 | 4 | ### 使用 5 | 6 | - 基础的Golang环境 7 | - 下载proxy.go,配置文件`const()`区域的参数 8 | - 运行`go build proxy.go`编译,`./proxy`执行 9 | - 访问前面配置的地址,就能看到下图了~~ 10 | 11 | ![DEMO](https://github.com/lingmm/google_proxy_by_golang/raw/master/demo.png) 12 | 13 | --- 14 | 15 | *参考了* 16 | -------------------------------------------------------------------------------- /demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/impasse/google_proxy_by_golang/505a537807e24fcc723897d78ff2f60af4823e2e/demo.png -------------------------------------------------------------------------------- /proxy.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "io/ioutil" 7 | "net/http" 8 | "net/url" 9 | "regexp" 10 | "runtime" 11 | "strings" 12 | "time" 13 | ) 14 | 15 | const ( 16 | timeout = 10 * time.Second 17 | servername = "服务器的地址" 18 | remote = "www.google.com" 19 | scheme = "http" 20 | ) 21 | 22 | type Filter struct { 23 | Rules []regexp.Regexp 24 | Replacement []string 25 | Count int 26 | } 27 | 28 | func GetFilter(rules map[string]string) *Filter { 29 | ru := make([]regexp.Regexp, len(rules)) 30 | rp := make([]string, len(rules)) 31 | i := 0 32 | for k, v := range rules { 33 | ru[i] = *regexp.MustCompile(k) 34 | rp[i] = v 35 | i++ 36 | } 37 | return &Filter{Rules: ru, Replacement: rp, Count: i} 38 | } 39 | 40 | func (this *Filter) Replace(str string) string { 41 | for i := 0; i < this.Count; i++ { 42 | str = this.Rules[i].ReplaceAllString(str, this.Replacement[i]) 43 | } 44 | return str 45 | } 46 | 47 | var client *http.Client 48 | var rules map[string]string = map[string]string{ 49 | "https": "http", 50 | "([0-9A-Za-z.-]+\\.gstatic\\.com)": servername + "/!$1", 51 | "((apis)\\.google\\.com)": servername + "/!$1", 52 | "((www)|(images))\\.google\\.[0-9a-z.]+": servername, 53 | "(img\\.youtube\\.com)": servername + "/!$1"} 54 | var filter *Filter 55 | var NotFollowRedirect error 56 | 57 | func proxy(w http.ResponseWriter, req *http.Request) { 58 | var u *url.URL 59 | 60 | if strings.HasPrefix(req.URL.RequestURI(), "/!") { 61 | u, _ = url.Parse(scheme + "://" + req.URL.RequestURI()[2:]) 62 | } else { 63 | u, _ = url.Parse(scheme + "://" + remote + req.URL.RequestURI()) 64 | } 65 | println(u.String()) 66 | reqHead := make(http.Header) 67 | reqHead.Add("Accept:text/html", "application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8") 68 | //TODO:Implement Gzip Deflate... 69 | reqHead.Add("Accept-Encoding", "") 70 | reqHead.Add("Accept-Language", "en-US") 71 | reqHead.Add("Cache-Control", "no-cache") 72 | reqHead.Add("Pragma", "no-cache") 73 | reqHead.Add("User-Agent", req.Header.Get("User-Agent")) 74 | 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") 75 | getgoogle, _ := client.Do(&http.Request{ 76 | URL: u, 77 | Body: req.Body, 78 | Close: false, 79 | TransferEncoding: []string{"chunked"}, 80 | Header: reqHead, 81 | Method: req.Method}) 82 | 83 | defer getgoogle.Body.Close() 84 | if getgoogle.StatusCode == 302 || getgoogle.StatusCode == 301 { 85 | uu, _ := url.Parse(getgoogle.Header.Get("Location")) 86 | uu.Scheme = "http" 87 | uu.Host = filter.Replace(uu.Host) 88 | w.Header().Add("Location", uu.String()) 89 | } 90 | w.Header().Add("Cache-Control", "no-cache") 91 | w.Header().Add("Content-Type", getgoogle.Header.Get("Content-Type")) 92 | w.WriteHeader(getgoogle.StatusCode) 93 | 94 | str, _ := ioutil.ReadAll(getgoogle.Body) 95 | fmt.Fprint(w, filter.Replace(string(str))) 96 | 97 | } 98 | 99 | func main() { 100 | NotFollowRedirect = errors.New("Not Follow Redirect") 101 | 102 | client = &http.Client{ 103 | CheckRedirect: func(req *http.Request, via []*http.Request) error { return NotFollowRedirect }, 104 | Timeout: timeout} 105 | server := http.NewServeMux() 106 | filter = GetFilter(rules) 107 | 108 | //状态信息 109 | server.HandleFunc("/status", func(w http.ResponseWriter, req *http.Request) { 110 | fmt.Fprintf(w, "Number Of Goroutines: %d", runtime.NumGoroutine()) 111 | }) 112 | //Proxy 113 | server.HandleFunc("/", proxy) 114 | 115 | http.TimeoutHandler(server, timeout, "Timeout") 116 | 117 | panic(http.ListenAndServe(":3000", server)) 118 | } 119 | --------------------------------------------------------------------------------