There is an Update to this question at the bottom
So I am kinda new to Go and am currently trying to fix a bug in a small service of ours. Its basic funtion is to take in a request that needs (MSAL) authorization, getting that authorization and then forwarding the request to the specific endpoint.
It does it like this:
http.HandleFunc("/", ProxyRequest)
func ProxyRequest(wr http.ResponseWriter, req *http.Request) {
auth, err := tokenHelper.GetAuthorization()
client := &http.Client{}
req.URL = newUrl
req.Host = newUrl.Host
req.Header.Add("Authorization", *auth)
resp, err := client.Do(req)
}
This works fine, as in the header if printed looks like this: Authorization: Bearer eyJ0eXAiOiJ...
and the rest of the headers and body are still present.
If I copy the request into Postman everything works fine and the debugging Output on my server looks like this:
but if I sent the Request using Go the Servers Debugger Output looks like this:
The only difference being that with Postman it includes the authorization header while with Go it is not being sent. This of course results in the request being rejected.
I have searched the Internet and this site quite a bit but as of yet I can not seem to find the mistake in our code. Any help would be appreciated
Edit:
So I tried both things mentioned in the answers, but I am just going to post the complete new Request one as that is what @izca recommended:
newReq, err := http.NewRequest(req.Method, newUrl.String(), req.Body)
newReq.Header.Add("Authorization", *auth)
log.Println(newReq.Header)
resp, err := client.Do(newReq)
Which results in exactly the same behaviour. The Request is going to the correct endpoint and is completely barebone, without Authorization Header.
Log Output:
map[Authorization:[Bearer eyJ0eXAiOiJKV1QiL....]]
CodePudding user response:
req
is the HTTP request of the incoming connection. You can't (shouldn't) reuse that to outgoing HTTP requests.
Attempting to do so, client.Do()
will return an error:
http: Request.RequestURI can't be set in client requests
Do create a new http.Request
using http.NewRequest()
or http.NewRequestWithContext()
, and use that for an outgoing request, pass that to client.Do()
.
CodePudding user response:
In extension to what @icza has suggested, if you really want to forward the same request like in the case of reverse proxy scenario, you can use req.Clone(newCtx)
which will deep copy the original request and returns a new Request.