Loading...

Blog > How to Write a Reverse Proxy Using Go

How to Write a Reverse Proxy Using Go

How to Write a Reverse Proxy Using Go

Learn how to write a reverse proxy using Go's standard library.

Published: April 23, 2023

Last updated: March 14, 2024

If you're here, you're probably working with Golang and have heard about its extensive standard library support. Frankly, this is one of the most influential factors in my choice of Golang. So let's dive in.

Golang provides an example in its documentation that allows you to set up a reverse proxy easily. I've included the link to this example at the bottom of this blog post.

Prerequisites

To use a reverse proxy, you need:

  • A working service that you want to serve to the network.

If you don't have a server, don't worry. Golang's standard library also solves this for you. The code snippet below will help you start a test server.

package main

import (
    "fmt"
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        log.Println("Request received at test server.")
        fmt.Fprintf(w, "Hello, World!")
    })
    fmt.Println("Test server started at localhost:8080")
    log.Fatal(http.ListenAndServe(":8080", nil))
}

Now that we have an HTTP server, we can create our single host reverse proxy. All we need is the target URL of our HTTP server, which we can obtain with the following code:

package main

import (
    "fmt"
    "log"
    "net/http"
    "net/http/httputil"
    "net/url"
)

func main() {
    target, err := url.Parse("http://localhost:8080")
    if err != nil {
        log.Fatal(err)
    }

    proxy := httputil.NewSingleHostReverseProxy(target)

    fmt.Println("Reverse proxy server is ready.")
    fmt.Println("Starting server on port 4000...")

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        log.Println("Request received at reverse proxy server.")
        proxy.ServeHTTP(w, r)
    })

    log.Fatal(http.ListenAndServe(":4000", nil))
}

The reverse proxy server is ready. However, I prefer to structure it in a way that allows me to control requests over an HTTP handler.

Once the proxy server is set up, running the script will start it and it will serve on port 4000.

To start the server, run:

go run single_host_reverse_proxy.go

Testing

You can test the server with cURL. Here's how you can do it:

To check the server logs when a request is made:

curl -i localhost:4000

You'll receive the cURL request's response from the reverse proxy.

Conclusion

Using Golang's standard library for reverse proxy is straightforward and easy-to-use. However, it's important to note that this method is suitable for single-host reverse proxying and might not scale well for larger applications. But I am planning to write a blog post on how to write a reverse proxy which is more scalable and can handle multiple hosts. Stay tuned!

References

Categories

GoReverse Proxy2023