Search code examples
httpgoget

Send unencoded GET requests in Go


I need to send an unencoded GET request to an API which is not conforming to the specs. The destination API doesn't accept encoded URLs, I can only send requests as it is without any query encoding. By default net/http encodes requests. I tried this:

client := &http.Client{}

req, _ := http.NewRequest("GET", `https://api.website.com/rest/v1/item/0?search=[{"key":"tag","value":"myvalue"}]`, nil)

req.Header.Set("Authorization", "Bearer " + viper.GetString("ACCESS_TOKEN"))
response, _ := client.Do(req)
defer req.Body.Close()

data, _ := ioutil.ReadAll(response.Body)
fmt.Printf("%s\n", data)

I tried to construct my own Request and manipulating RawQuery, without success. I keep getting a bad request, while if I send the same request through Postman, everything's fine.

EDIT: That's what I tried to do to set the URL myself, and if I print it I can see it's not encoded. The error I get is: panic: runtime error: invalid memory address or nil pointer dereference.

client := &http.Client{}
req, _ := http.NewRequest("GET", "", nil)

req.URL = &url.URL{
    Host:     "api.website.com",
    Scheme:   "https",
    RawQuery: `/rest/v1/item/0?search=[{"key":"tag","value":"myvalue"}]`,
}

req.Header.Set("Authorization", "Bearer " + viper.GetString("RAINDROP_TOKEN"))
res, _ := client.Do(req)
defer req.Body.Close()

data, _ := ioutil.ReadAll(res.Body)
fmt.Printf("%s\n", data)

Solution

  • Specify the protocol and host when creating the request. Set URL.Opaque to the desired request URI:

    req, _ := http.NewRequest("GET", "https://api.website.com/", nil)
    req.URL.Opaque = `/rest/v1/item/0?search=[{"key":"tag","value":"myvalue"}]`
    req.Header.Set("Authorization", "Bearer " + viper.GetString("RAINDROP_TOKEN"))
    res, _ := client.Do(req)
    defer req.Body.Close()
    data, _ := ioutil.ReadAll(res.Body)
    

    Run it on the playground.