2017-10-05 44 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)'... –