群里面小伙伴讨论到了这个问题,之前自己写工具的时候有过这个需求,也想看看怎么解决这个问题,一直忙其他时间没顾得上看,正好蹭这个机会顺便看看,此代码仅作为示例,可能还存在未知的若干坑,需要用到生产环境什么的,还是要自己改改。

/*
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))
}

-w1073

最后修改:2021 年 11 月 22 日
如果觉得我的文章对你有用,请随意赞赏