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&`,value)
            }
            i++
        }
    }
    query := fmt.Sprintf(`%s?%s`,path,rawQuery)
    rawRequest = fmt.Sprintf(`%s %s HTTP/1.1\r\n`,query)
}

var rawHeaders string
for key,value := range headers {
    rawHeaders += fmt.Sprintf(`%s: %s\r\n`,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`,value)
            } else {
                rawRequest += fmt.Sprintf(`%s=%s&`,value)
            }
            i++
        }
    }

}

return rawRequest
}

解决方法

在Go语言中,按照spec,后引号`用于表示原始字符串:

原始字符串文字是反引号之间的字符序列,例如 foo在引号内,除反引号外,任何字符都可以出现。 原始字符串文字的值是由 之间的未解释(隐式UTF-8编码)字符 引号特别是反斜杠没有特殊含义,并且 字符串可能包含换行符。内部的回车符('\ r') 从原始字符串值中丢弃原始字符串文字。

这意味着您代码中的所有\r\n都不会被解释为回车或换行符。您应该更改为使用双引号"

作为一般样式指南,除非需要大量转义,否则应使用双引号。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...