【发布时间】:2020-12-11 08:37:28
【问题描述】:
我试图通过GOLang中的TCP/TLS套接字发送HTTP请求,但是当我尝试发送它时,无论主机是什么,它总是返回(错误请求400),所以我认为它必须是我用来通过 TCP/TLS 发送请求的方式有问题,我进行了搜索,并寻找一种方法来做我想做的事情,但没有结果:
package main
import (
"crypto/rand"
"crypto/tls"
"fmt"
"net"
"strings"
)
func main() {
headers := make(map[string]string)
headers["Accept"] = "application/json"
request := parseRequest("httpbin.org", "/get", "get", headers, nil, "")
println(request)
tcpConn, err := net.Dial("tcp", "httpbin.org:443")
if err != nil {
panic(err)
}
cf := &tls.Config{Rand: rand.Reader, InsecureSkipVerify: true}
ssl := tls.Client(tcpConn, cf)
if err != nil {
panic(err)
}
defer ssl.Close()
n, err := ssl.Write([]byte(request))
if err != nil {
fmt.Println(n, err)
return
}
buf := make([]byte, 1024)
n, err = ssl.Read(buf)
if err != nil {
fmt.Println(n, err)
return
}
println(string(buf[:n]))
}
func parseRequest(host string, path string, method string, headers map[string]string, data map[string]string, rawData string) string {
method = strings.ToUpper(method)
rawRequest := fmt.Sprintf(`%s %s HTTP/1.1\r\n`, strings.ToUpper(method), path)
if method == `GET` && (data != nil || rawData != ``) {
var rawQuery string
if rawData != `` {
rawQuery = rawData
} else {
i := 0
for key, value := range data {
if i == len(data)-1 {
rawQuery += fmt.Sprintf(`%s=%s`, key, value)
} else {
rawQuery += fmt.Sprintf(`%s=%s&`, key, value)
}
i++
}
}
query := fmt.Sprintf(`%s?%s`, path, rawQuery)
rawRequest = fmt.Sprintf(`%s %s HTTP/1.1\r\n`, strings.ToUpper(method), query)
}
var rawHeaders string
for key, value := range headers {
rawHeaders += fmt.Sprintf(`%s: %s\r\n`, key, value)
}
if !strings.Contains(strings.ToLower(rawHeaders), `host`) {
rawRequest += fmt.Sprintf(`Host: %s\r\n`, host)
}
rawRequest += fmt.Sprintf(`%s\r\n`, rawHeaders)
if method == `POST` && (data != nil || rawData != ``) {
if rawData != `` {
rawRequest += rawData
} else {
i := 0
for key, value := range data {
if i == len(data)-1 {
rawRequest += fmt.Sprintf(`%s=%s`, key, value)
} else {
rawRequest += fmt.Sprintf(`%s=%s&`, key, value)
}
i++
}
}
}
return rawRequest
}
【问题讨论】:
-
使用解释的 string literals 而不是原始字符串文字,以便
\r\n被解释为字节 [13, 10]。
标签: go ssl tcp httprequest tcpclient