Go代理浏览器HTTP请求

178 阅读1分钟

Go代理浏览器http请求

问题

因为网络问题,有些网页访问不了,于是想通过自己的云服务器,去代理浏览器的请求。在网上查阅如何用Go代理http请求,有些用Proxy转发,结果发现没用,返回的是一个文本,甚至无法请求。通过查阅浏览器网页请求原理后,自己写了段代码,简单实现了http请求代理,网页成功可以渲染出来。

原理

通过go自带的"net/http"包发送http请求

client := http.Client{}

//"http://www.XiuRen/12276.html"
resp, err := client.Get(r.URL.Scheme + ":" + r.URL.Host + "/" + r.URL.Path)

之后把结果返回到写回浏览器,在写回的时候要注意写好请求头的文件格式,不写文件格式都是文本格式

w.Header().Set("Content-Type", resp.Header.Get("Content-Type")) w.WriteHeader(resp.StatusCode)

全部代码

package main

import (
   "fmt"
   "io"
   "os"
   "os/signal"
   "strings"
   "syscall"

   "log"
   "net/http"
)

var logger log.Logger

type proxy struct {
}

func NewRoutes() http.Handler {
   return &proxy{}
}

func (router *proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {

   fmt.Println("URL:", r.URL.Path)
   var err error

   //按照分隔符'/'对路径进行分解,获取服务名称serviceName

   r.URL.Scheme = "http"
   r.URL.Path = r.URL.Path
   client := http.Client{}
   if r.Referer() == "" {
      pathArray := strings.Split(r.URL.Path, "/")
      r.URL.Host = pathArray[0]
   } else {
      pathArray := strings.Split(r.Referer(), "/")
      r.URL.Host = "/" + pathArray[len(pathArray)-1]
   }

   fmt.Println("compare:", "host:", r.URL.Host, "referer:", r.Referer())
   fmt.Println("client:", r.URL.Scheme+":"+r.URL.Host+"/"+r.URL.Path)
   resp, err := client.Get(r.URL.Scheme + ":/" + r.URL.Host + r.URL.Path)

   if err != nil {
      log.Println(err)
   }

   w.Header().Set("Content-Type", resp.Header.Get("Content-Type"))
   w.WriteHeader(resp.StatusCode)

   defer resp.Body.Close()
   io.Copy(w, resp.Body)

}

func main() {
   var handle http.Handler
   handle = NewRoutes()
   errchan := make(chan error)

   go func() {
      errchan <- http.ListenAndServe(":9001", handle)
      fmt.Println("http server at:", "127.0.0.1"+":"+"9001")
   }()
   go func() {
      c := make(chan os.Signal)
      signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
      errchan <- fmt.Errorf("%s", <-c)
   }()
   error := <-errchan
   fmt.Println("err:", error)
}

例子

请求:www.howzhi.com(只是随便找的网站)

运行后修改浏览器的请求域名
http://127.0.0.1:9001/www.howzhi.com

由于只是简单实现,所以有些网站还不能很好代理,根据具体网站修改下便可以用。