Go HTTP: Forwarding Incoming Requests to Another Server
Suppose you have legacy and versioned services ("legacy" and "version_2_of_doom") running alongside each other. You want all POST requests to be handled by both services simultaneously for a smooth transition.
Initially, you attempted to modify the legacy service's handler to duplicate the request to "version_2_of_doom" directly. However, this approach failed with the error "http: Request.RequestURI can't be set in client requests."
The preferred solution is to create a new request and copy only the necessary parts from the incoming request. This process resembles what a reverse proxy does, which you can examine in the "net/http/httputil" package.
Here's an example implementation:
func handler(w http.ResponseWriter, req *http.Request) { body, err := ioutil.ReadAll(req.Body) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } req.Body = ioutil.NopCloser(bytes.NewReader(body)) url := fmt.Sprintf("%s://%s%s", proxyScheme, proxyHost, req.RequestURI) proxyReq, err := http.NewRequest(req.Method, url, bytes.NewReader(body)) proxyReq.Header = make(http.Header) for h, val := range req.Header { proxyReq.Header[h] = val } resp, err := httpClient.Do(proxyReq) if err != nil { http.Error(w, err.Error(), http.StatusBadGateway) return } defer resp.Body.Close() // legacy code }
This approach allows you to selectively copy headers and create a new request URI to send to the other server. By following this pattern, you can seamlessly forward incoming HTTP requests to multiple services without altering the request details.
The above is the detailed content of How Can I Forward Go HTTP Requests to Another Server While Avoiding 'http: Request.RequestURI can't be set in client requests'?. For more information, please follow other related articles on the PHP Chinese website!