Skip to content

Instantly share code, notes, and snippets.

@alpancs
Last active June 19, 2025 17:42
Show Gist options
  • Save alpancs/f80437104107d688ebd48a9e5e03ff91 to your computer and use it in GitHub Desktop.
Save alpancs/f80437104107d688ebd48a9e5e03ff91 to your computer and use it in GitHub Desktop.
reverse proxy within the same host, as a workaround to access ports inside WSL2 from local-network devices.
package main
import (
"bytes"
"flag"
"io"
"log"
"net/http"
"net/http/httputil"
"regexp"
)
func main() {
listenPort := flag.String("listenPort", "80", "Port for the proxy to listen on")
targetPort := flag.String("targetPort", "8081", "Target port on localhost to forward requests to")
flag.Parse()
proxy := &httputil.ReverseProxy{
Director: func(r *http.Request) {
r.URL.Host = "localhost:" + *targetPort
r.URL.Scheme = "http"
r.Header.Del("Accept-Encoding")
log.Printf("%s %s\n", r.Method, r.URL)
},
}
proxy.ModifyResponse = func(resp *http.Response) error {
if resp.StatusCode == http.StatusSwitchingProtocols || resp.Body == nil || resp.Body == http.NoBody {
return nil
}
for _, values := range resp.Header {
for i := range values {
values[i] = string(replacePort([]byte(values[i]), *targetPort, *listenPort))
}
}
bodyBytes, err := io.ReadAll(resp.Body)
defer resp.Body.Close()
if err != nil {
return err
}
modifiedBody := replacePort(bodyBytes, *targetPort, *listenPort)
resp.Body = io.NopCloser(bytes.NewReader(modifiedBody))
return nil
}
log.Println("starting reverse proxy server, listening on port", *listenPort)
log.Fatal(http.ListenAndServe(":"+*listenPort, proxy))
}
func replacePort(input []byte, port1, port2 string) []byte {
escapedPort := regexp.QuoteMeta(port1)
pattern := `((https?://)?[^:]+):` + escapedPort + `\b`
re := regexp.MustCompile(pattern)
replacement := []byte("${1}:" + port2)
return re.ReplaceAll(input, replacement)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment