This example shows you a Go HTTP Server that forwards requests to an upstream Server using a HTTP client. Note that this example does not stream the upstream server’s responses but downloads them to RAM and then serves them to the client (hence you might need to improve upon this example if you intend to serve large files).
Also, note that this example does not implement proper error handling for the upstream request since it’s only intended to serve as a basic starting point for you to develop your own reverse proxy implementation.
package main import ( "fmt" "io/ioutil" "log" "net/http" ) func main() { client := &http.Client{} http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { // Perform request url := "https://techoverflow.net" + r.URL.Path req, _ := http.NewRequest(r.Method, url, r.Body) req.Header = r.Header resp, _ := client.Do(req) // Cleanup when this function ends defer resp.Body.Close() // Copy headers from request to response header := w.Header() for name, headers := range resp.Header { // Iterate all headers with one name (e.g. Content-Type) for _, hdr := range headers { header.Add(name, hdr) } } // Read all the response data into a []byte body, _ := ioutil.ReadAll(resp.Body) // Write header & body w.WriteHeader(resp.StatusCode) w.Write(body) }) // log.Fatal shows you if there is an error like the // port already being used fmt.Println("Listening on port 8080") log.Fatal(http.ListenAndServe(":8080", nil)) }
Further reading:
- Go net/http package
- Iterating HTTP client response headers in Go (which we use as a basis to implement our header copying mechanism)