'Golang: io.Reader w/io.NopCloser
I cannot for the life of me figure out why this isn't working... it returns a 404... however it works when I remove io.NopCloser
200: req, err := http.NewRequest("POST", uri, body)
404: req, err := http.NewRequest("POST", uri, io.NopCloser(body))
Why does this matter? Because while the signature of NewRequest accepts io.Reader inside the method its converted to a io.ReadCloser
rc, ok := body.(io.ReadCloser)
if !ok && body != nil {
rc = io.NopCloser(body)
}
Additionally the property Request.Body is of type io.ReadCloser (not io.Reader)
Ultimately my goal is to acheive this... hence why I do not want to set body when calling http.NewRequest
req, err := http.NewRequest("POST", uri, nil)
if someCondition {
req.Body = getBody()//some method that returns a io.ReaderCloser
}
//the real getBody method is more complex than this...
func getBody() io.ReaderCloser {
data := map[string][]string{
"scope": {"https://graph.microsoft.com/.default"},
"client_id": {"0000-0000-0000-0000"},
"client_secret": {"REDACTED_CLIENT_SECRET"},
"grant_type": {"client_credentials"},
}
return io.NopCloser(strings.NewReader(url.Values(data).Encode()))
}
Complete code that returns a 404 below...
uri := "https://login.microsoftonline.com/REDACTED.onmicrosoft.com/oauth2/v2.0/token"
data := map[string][]string{
"scope": {"https://graph.microsoft.com/.default"},
"client_id": {"0000-0000-0000-0000"},
"client_secret": {"REDACTED_CLIENT_SECRET"},
"grant_type": {"client_credentials"},
}
body := strings.NewReader(url.Values(data).Encode())
req, err := http.NewRequest("POST", uri, io.NopCloser(body))
if err != nil {
panic(err)
}
client := &http.Client{Timeout: 10 * time.Second}
res, err := client.Do(req)
if err != nil {
panic(err)
}
b, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
fmt.Println(res.StatusCode)
fmt.Println(string(b))
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
