Skip to content

Instantly share code, notes, and snippets.

@JalfResi
Last active April 16, 2024 17:31
Show Gist options
  • Save JalfResi/6287706 to your computer and use it in GitHub Desktop.
Save JalfResi/6287706 to your computer and use it in GitHub Desktop.
Simple reverse proxy in Go
package main
import(
"log"
"net/url"
"net/http"
"net/http/httputil"
)
func main() {
remote, err := url.Parse("http://google.com")
if err != nil {
panic(err)
}
handler := func(p *httputil.ReverseProxy) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
log.Println(r.URL)
r.Host = remote.Host
w.Header().Set("X-Ben", "Rad")
p.ServeHTTP(w, r)
}
}
proxy := httputil.NewSingleHostReverseProxy(remote)
http.HandleFunc("/", handler(proxy))
err = http.ListenAndServe(":8080", nil)
if err != nil {
panic(err)
}
}
@semanticart
Copy link

This is great. Thanks!

@filewalkwithme
Copy link

awesome!!!

@elico
Copy link

elico commented Aug 10, 2015

Thanks!!

@pdxjohnny
Copy link

👍 :octocat:

@thurt
Copy link

thurt commented Jan 19, 2018

instead of using a closure, you may find creating a struct instance to be simpler. see my fork https://gist.github.com/thurt/2ae1be5fd12a3501e7f049d96dc68bb9 i think it is more idiomatic for golang

@WhyBeingAsianRapperIsSoHard

Thx

@ijt
Copy link

ijt commented Feb 24, 2020

I tried this and it came up 404 in Chrome and Safari.

@xdkxlk
Copy link

xdkxlk commented Mar 13, 2020

How to control the http timeout?

@BeforyDeath
Copy link

added r.Host = remote.Host

@nilskch
Copy link

nilskch commented May 22, 2020

I received a 404 as well. Does anyone have a solution?

@kubosuke
Copy link

kubosuke commented Jun 2, 2020

lovely!

@sokryptk
Copy link

This returns a 404, any solutions?

Copy link

ghost commented Sep 3, 2020

Does it forward the client IP?

@zack-wang
Copy link

Excellent

@dudigit
Copy link

dudigit commented Apr 3, 2021

Any solution to 404 ?

@eingress
Copy link

404 Fix - Set the request Host

r.Host = "google.com"

@JalfResi
Copy link
Author

Added "r.Host = remote.Host" to fix 404 issues

@lwzm
Copy link

lwzm commented Jul 16, 2021

Added "r.Host = remote.Host" to fix 404 issues

undeclared name: remote

function handler should be placed in function main:

	handler := func(p *httputil.ReverseProxy) func(http.ResponseWriter, *http.Request) {
		return func(w http.ResponseWriter, r *http.Request) {
			log.Println(r.URL)
			r.Host = remote.Host
			w.Header().Set("X-Ben", "Rad")
			p.ServeHTTP(w, r)
		}
	}

@JalfResi
Copy link
Author

Thanks @lwzm!

@abdennour
Copy link

Great!

@doolgibi
Copy link

hi, after saved this file, how can i try?

@samuelnihoul
Copy link

go run main.go
then
curl localhost:8080
I think

@c0d3kid
Copy link

c0d3kid commented Dec 22, 2022

Made some changes to add support for ssl. And cleanup handler.

`package main

import (
"log"
"net/http"
"net/http/httputil"
"net/url"
"crypto/tls"
)

func main() {
// Replace 'target' with the URL of the server you want to proxy to
target, err := url.Parse("https://example.com")
if err != nil {
panic(err)
}

// Create a new ReverseProxy instance
proxy := httputil.NewSingleHostReverseProxy(target)
// Configure the reverse proxy to use HTTPS
proxy.Transport = &http.Transport{
    TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
// Create a handler function that logs the URL and forwards the request to the proxy
handler := func(w http.ResponseWriter, r *http.Request) {
    log.Println(r.URL)
    r.Host = target.Host
	//w.Header().Set("X-Ben", "radi")
    proxy.ServeHTTP(w, r)
}

// Register the handler function with the HTTP server
http.HandleFunc("/", handler)

// Start the HTTP server
err = http.ListenAndServe(":3000", nil)
if err != nil {
    panic(err)
}

}`

@c0d3kid
Copy link

c0d3kid commented Dec 22, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment