go写的http工具
go build reverseProxy.go
reverseProxy http://192.168.50.148:12321
2024/08/15 15:14:47 program start......
2024/08/15 15:14:47 listen http proxy on :8001.....
浏览器中输入:http://127.0.0.1:8001/,即可访问指定网站,并打印http请求与返回数据包。
package main
import (
"bytes"
"fmt"
"log"
"io/ioutil"
"net/http"
"net/http/httputil"
"net/url"
"os"
)
type transport struct {
http.RoundTripper
}
func (t *transport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
// 获取请求报文的内容长度
len := req.ContentLength
if(len > 0){
log.Println("req.ContentLength", len)
b1, err1 := ioutil.ReadAll(req.Body)
if err1 != nil {
fmt.Println(err1.Error())
return nil, err1
}else{
fmt.Println(string(b1))
}
err1 = req.Body.Close()
if err1 != nil {
return nil, err1
}
// 重新生成可读取的
body1 := ioutil.NopCloser(bytes.NewReader(b1))
req.Body = body1
}
resp, err = t.RoundTripper.RoundTrip(req)
if err != nil {
return nil, err
}
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
err = resp.Body.Close()
if err != nil {
return nil, err
}
log.Println("resp.ContentLength", resp.ContentLength)
fmt.Println(string(b))
//读取响应并修改响应
b = bytes.Replace(b, []byte("Google"), []byte("GOOGLE"), -1)
body := ioutil.NopCloser(bytes.NewReader(b))
resp.Body = body
return resp, nil
}
func sameHost(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
r.Host = r.URL.Host
handler.ServeHTTP(w, r)
})
}
func main() {
var sz string
if(len(os.Args)<2){
fmt.Printf("请输入url:")//http://127.0.0.1:80 or http://192.168.50.148:12321
fmt.Scanf("%s",&sz)
}else{
sz=os.Args[1]
}
targetURL, err := url.Parse(sz)
log.Println("program start......")
if err != nil {
log.Println("bad url:", err)
return
}
reverseProxy := httputil.NewSingleHostReverseProxy(targetURL)
//http.HandleFunc("/myinfo/", httpUserInfo)
//http.Handle("/", reverseProxy)
reverseProxy.Transport = &transport{http.DefaultTransport}
// wrap that proxy with our sameHost function
singleHosted := sameHost(reverseProxy)
log.Println("listen http proxy on :8001.....")
http.ListenAndServe(":8001", singleHosted)
//http.ListenAndServe(":8001", nil)
}
go build Pxy.go
Pxy
Serve on :8180
浏览器代理服务器设置为127.0.0.1:8180,输入:http:
//192.168.50.148:12321,即可访问指定网站,并抓取http请求数据包。
package main
import (
"bytes"
"fmt"
"log"
"io"
"net"
"net/http"
"strings"
"io/ioutil"
)
type Pxy
struct
{}
func (p *Pxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
fmt.Printf(
"Received request %s %s %s\n"
, req.Method, req.Host, req.RemoteAddr)
transport := http.DefaultTransport
// 获取请求报文的内容长度
len := req.ContentLength
if
(len > 0){
log
.Println(
"req.ContentLength"
, len)
b1, err1 := ioutil.ReadAll(req.Body)
if
err1 != nil {
fmt.Println(err1.Error())
return
}
else
{
fmt.Println(string(b1))
}
err1 = req.Body.Close()
if
err1 != nil {
return
}
// 重新生成可读取的
body1 := ioutil.NopCloser(bytes.NewReader(b1))
req.Body = body1
}
// step 1
outReq :=
new
(http.Request)
*outReq = *req
// this only does shallow copies of maps
if
clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {
if
prior, ok := outReq.Header[
"X-Forwarded-For"
]; ok {
clientIP = strings.Join(prior,
", "
) +
", "
+ clientIP
}
outReq.Header.Set(
"X-Forwarded-For"
, clientIP)
}
// step 2
res, err := transport.RoundTrip(outReq)
if
err != nil {
rw.WriteHeader(http.StatusBadGateway)
return
}
// step 3
for
key, value := range res.Header {
for
_, v := range value {
rw.Header().Add(key, v)
}
}
rw.WriteHeader(res.StatusCode)
io.Copy(rw, res.Body)
res.Body.Close()
}
func main() {
fmt.Println(
"Serve on :8180"
)
http.Handle(
"/"
, &Pxy{})
http.ListenAndServe(
"0.0.0.0:8180"
, nil)
}