Golang解析原始HTTP请求后发送时报unexpected EOF错误求助
错误原因与修复方案
核心报错根因
- 你定义的原始HTTP请求字符串
stra不符合HTTP协议规范:HTTP请求头和请求体之间需要两个连续的换行符作为分隔标识,你当前的字符串末尾直接结束,http.ReadRequest读取完成后没找到请求结束标识,直接返回unexpected EOF错误。 - 代码存在变量不匹配问题:你通过
http.ReadRequest解析得到的请求对象是r,后续代码直接使用了未定义的req变量,且服务端模式的Request对象不能直接传递给http.Client发送,需要手动构造客户端请求实例。
修复后可运行代码
package main import ( "bufio" "crypto/tls" "fmt" "io" "net/http" "net/url" "os" "strings" ) func main() { // 原始请求末尾加两个空行,符合HTTP报文格式要求 stra := `GET / HTTP/1.1 Host: google.com Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.9 Connection: close ` // 解析原始请求 r, err := http.ReadRequest(bufio.NewReader(strings.NewReader(stra))) if err != nil { fmt.Println(err.Error()) os.Exit(1) } // 构造目标URL u, err := url.Parse("https://" + r.Host + r.URL.String()) if err != nil { panic(err) } // 构造客户端可用的Request对象 req, err := http.NewRequest(r.Method, u.String(), r.Body) if err != nil { panic(err) } // 复制原始请求的头部 req.Header = r.Header // 初始化HTTP客户端 transport := http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // 自动解压gzip响应,避免打印结果乱码 DisableCompression: false, } client := &http.Client{Transport: &transport} // 发送请求 resp, err := client.Do(req) if err != nil { panic(err) } defer resp.Body.Close() // 读取并打印响应 respBody, err := io.ReadAll(resp.Body) if err != nil { panic(err) } fmt.Println(string(respBody)) }
额外说明
- 代码补充了请求头复制逻辑,保证发送的请求和你定义的原始请求完全一致
- 增加了响应体资源释放的
defer语句,避免资源泄漏
内容的提问来源于stack exchange,提问作者Ninja Boy
相关产品推荐
相关产品推荐

