2017-10-05 48 views
2

我有一段标准的go http请求,我正试图在下面的代码中正确使用。使用基本身份验证在GO中获取http帖子

func IssueSearchQuery(conf Config) (string, error) { 

    tr := &http.Transport{ 
     TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, 
    } 

    var client = &http.Client{ 
     Timeout: time.Second * 60, 
     Transport: tr, 
    } 
    URL := conf.URL + "/api/search" 
    v := url.Values{} 
    v.Set("query_expression", "select * from test") 
    req, err := http.NewRequest("POST", URL, 
     bytes.NewBufferString(v.Encode())) 

    req.SetBasicAuth(conf.User, conf.Password) 
    resp, err := client.Do(req) 
    if err != nil { 
     log.Fatal(err) 
    } 
    bodyText, err := ioutil.ReadAll(resp.Body) 
    s := string(bodyText) 
    return s, err 
} 

在上面的代码,我连接到服务器上,基本身份验证工作,但服务器响应抱怨说所需query_expression查询参数丢失。如果我做curl -u user:pass -d "query_expression=select * from test" --insecure -XPOST 'https://ip:port/api/search'服务器响应所需的结果。

,如果我不使用url.Values {},而是手动我的查询编码为URL像URL := conf.URL + "/api/ariel/searches?query_expression=select%20*20from%20test"

我无法弄清楚我在做什么毛病我查询参数的代码也可以。有人可以帮忙吗?谢谢!

+2

'req.Header.Set(“Content-Type”,“application/x-www-form-urlencoded”)有什么区别吗? – hobbs

+0

Jeez,就是这样。我只是设置了内容类型并开始工作。所以,在我的版本中,服务器获取了一个url编码的查询字符串,但是将它看作纯文本/文本内容类型? –

+0

另外:当你完成它们的时候,你需要关闭响应体,并考虑使用strings.NewReader而不是缓冲区; “它与bytes.NewBufferString类似,但效率更高,只读。” – Peter

回答

3

您似乎试图将POST正文设置为url编码值。无论您Content-Type头设置为application/x-www-form-urlencoded,并把他们在身体,你正在做的(感谢@hobbs),或在实际的URL中使用的URL编码值,而不是身体:

u, err := url.Parse(conf.URL + "/api/search") 
v := url.Values{} 
v.Set("query_expression", "select * from test") 
u.RawQuery = v.Encode() 
req, err := http.NewRequest("POST", u.String(), nil) 

,通常人们期望POST数据在正文中,所以只需添加req.Header.Set("Content-Type", "application/x-www-form-urlencoded")可能是最好的。

+0

非常感谢;添加标题为我解决了它。仅供参考,代码现在看起来像...'req,err:= http.NewRequest(“POST”,URL,bytes.NewBufferString(v.Encode())) \t req.Header.Set(“Content-Type “,”application/x-www-form-urlencoded“) \t req.SetBasicAuth(conf.QRadar.User,conf.QRadar.Password)'... –