如何通过编程方式重放原始HTTP请求?
解决方案
你之前逐行解析出错的核心原因是没有正确处理请求头和请求体之间的空行分界,容易把JSON请求体的内容也当成请求头字段调用req.Header.Set,自然会触发异常。不用自己造轮子,直接用Go标准库net/http内置的http.ReadRequest方法即可原生解析完整的原始HTTP请求,支持所有GET、POST(包括带JSON请求体)的场景。
完整示例代码
package main import ( "bufio" "io" "net/http" "os" "strings" ) func parseRawRequest(filePath string) (*http.Request, error) { file, err := os.Open(filePath) if err != nil { return nil, err } defer file.Close() // 标准库方法直接解析原始请求流,自动区分请求行、请求头、请求体 return http.ReadRequest(bufio.NewReader(file)) } func main() { req, err := parseRawRequest("raw_req.txt") if err != nil { panic(err) } defer req.Body.Close() // 解析完成后可以直接获取所有字段 // 1. 请求基础信息 println("请求方法:", req.Method) println("请求路径:", req.URL.Path) println("Host:", req.Host) // 2. 请求头直接拿,不需要自己逐行Set println("User-Agent:", req.Header.Get("User-Agent")) // 3. POST JSON体直接读取 if req.Method == http.MethodPost && strings.Contains(req.Header.Get("Content-Type"), "application/json") { bodyBytes, err := io.ReadAll(req.Body) if err != nil { panic(err) } println("JSON请求体:", string(bodyBytes)) } // 如果需要发送解析好的请求,补全Scheme即可 // req.URL.Scheme = "https" // 或http,根据实际场景调整 // client := &http.Client{} // resp, err := client.Do(req) }
注意点
- 标准库方法会自动处理请求头末尾的空行、请求体长度判定、Chunked编码等特殊场景,不需要自己手动处理边界逻辑
- 如果你的原始请求是多个拼接在同一个文件里,循环调用
http.ReadRequest即可,方法会自动按请求边界拆分
内容的提问来源于stack exchange,提问作者Robert Zunr
相关产品推荐
相关产品推荐

