猿问

golang - tcpclient 当我发送 http 请求时,它总是返回(错误请求 400)

我正在尝试通过 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 != ``) {



holdtom
浏览 355回答 1
1回答

jeck猫

在 Go 中,根据规范`,后引号用于表示原始字符串:原始字符串文字是反引号之间的字符序列,如 `foo`。在引号内,可以出现除反引号外的任何字符。原始字符串文字的值是由引号之间的未解释(隐式 UTF-8 编码)字符组成的字符串;特别是,反斜杠没有特殊含义,并且字符串可能包含换行符。原始字符串文字中的回车符 ('\r') 会从原始字符串值中丢弃。这意味着,\r\n您的代码中的所有内容都不会被解释为回车或换行符。您应该更改为使用双引号"。作为一般风格准则,除非需要大量转义,否则应该使用双引号。
随时随地看视频慕课网APP

相关分类

Go
我要回答