请注意,本文编写于 1501 天前,最后修改于 1095 天前,其中某些信息可能已经过时。
群里面小伙伴讨论到了这个问题,之前自己写工具的时候有过这个需求,也想看看怎么解决这个问题,一直忙其他时间没顾得上看,正好蹭这个机会顺便看看,此代码仅作为示例,可能还存在未知的若干坑,需要用到生产环境什么的,还是要自己改改。
/*
Copyright © 2020 sky [email protected]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"bufio"
"bytes"
"fmt"
"io"
"io/ioutil"
"net/http"
"strings"
)
// golang发送raw原始包
func main() {
// todo: 如果原始包中有Accept-Encoding: gzip, deflate,就需要对结果进行解压缩,否则不需要。
text := `GET / HTTP/1.1
Host: www.jd.com
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Language: zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7
Cookie: shshshfpa=7532ce70-5ef2-356c-6415-612b38afaf0d-1562553861; shshshfpb=elVk9RiMJEjpRJgSXmaxRbQ%3D%3D; pinId=rAoCskijFO2mFCGlGaSsUrV9-x-f3wj7; o2State={%22webp%22:true%2C%22lastvisit%22:1590117695421}; __jdu=1589356080213213010261; TrackID=1f66bZEmBgflOgQQ-riAxljCfxI31h1DHdwb63bsI6fRVSwLI2BjnsRtFiUrgFEDdRBwi-aMsA-UUrK6LjipKIKPQuOU2xQYvJijbGwaKku9X1ryIZfA4rtMVs9mxWBBz; user-key=d9f87165-bd5f-4693-a1e1-21743e4df684; cn=0; shshshfp=8455b20ce11ca2c78659d4a8b1a5483c; areaId=6; ipLoc-djd=6-336-44145-0; 3AB9D23F7A4B3C9B=26JA6GSDM7337VO2FU7YWPCWWN3BQ7NCUVBY32KDFMG2SZXFAPDPEEEQXJ5HBEORGW2MCNNWZQNLJOT4SNHZIQE54E; unpl=V2_ZzNtbRACRR0lCxQEKU5dDWJWFVpLAkcQIg1DBn4cWAMzB0FZclRCFnQURlVnGF4UZAIZXENcRxdFCERkexhdBGcFElVHU3MldglHGXsYXWtkAl9tQVdzFEUIQl1zG1gCZgoTXkJVQBV3CUZVeB5cNVcDG15yVUoUdQhGU0saXQViBBZYQlBfE3EPQFdzKV01ZjMTbRQ5QxR0CUdVeBpZBSoDFlRKVUcSdAFHV3sbXwVlAhJcQVBDJXQ4RQ%3d%3d; __jdv=122270672|kong|t_1000171945_|jingfen|cd79a2cacf094d668d54f44c4457e5b5|1601726455179; mt_xid=V2_52007VwMWW1VaVl0eQBhfBWUAElBcWFNZGEkpWQQ3URRTDQpODU8bTUAAZ1caTlUPUVwDGk5VAGEGGwZUWQVeL0oYXwR7AxNOXFpDWR5CGFwOZgMiUG1bYl4cTxlZAlcDFlM%3D; __jda=122270672.1589356080213213010261.1589356080.1601725054.1602305925.371
Connection: close
`
const rawTextSpace = "\r\n "
body := strings.TrimLeft(text, rawTextSpace)
read := strings.NewReader(body)
req, err := http.ReadRequest(bufio.NewReader(read))
if err != nil {
fmt.Println(err)
return
}
// 此处似乎不会影响https的请求,因为golang默认会跟随跳转。
req.URL.Scheme = "http"
req.URL.Host = req.Host
req.RequestURI = ""
if req.GetBody == nil {
all, err := ioutil.ReadAll(req.Body)
if err != nil {
fmt.Println(err)
return
}
req.GetBody = func() (io.ReadCloser, error) {
return ioutil.NopCloser(bytes.NewReader(all)), nil
}
req.Body = ioutil.NopCloser(bytes.NewReader(all))
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Printf("read Body error: %v \n", err)
}
fmt.Println(string(b))
}