83 lines
1.6 KiB
Go
83 lines
1.6 KiB
Go
package simpleproxy
|
|
|
|
import (
|
|
"io"
|
|
"net/http"
|
|
"net/url"
|
|
)
|
|
|
|
type Proxy struct {
|
|
ListenAddr string
|
|
ServerAddr string
|
|
|
|
u *url.URL
|
|
}
|
|
|
|
// NewProxy creates a new proxy server.
|
|
func NewProxy(listenAddr, serverAddr string) *Proxy {
|
|
u, err := url.Parse(serverAddr)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return &Proxy{
|
|
ListenAddr: listenAddr,
|
|
ServerAddr: serverAddr,
|
|
u: u,
|
|
}
|
|
}
|
|
|
|
// ListenAndServe starts the proxy server.
|
|
func (p *Proxy) ListenAndServe() error {
|
|
srv := &http.Server{
|
|
Addr: p.ListenAddr,
|
|
Handler: p,
|
|
}
|
|
|
|
return srv.ListenAndServe()
|
|
|
|
}
|
|
|
|
// ServeHTTP is the main handler for the proxy server.
|
|
// all requests here should be proxied to the server.
|
|
func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
// all requests should be proxied to the server.
|
|
req, err := http.NewRequest(r.Method, p.ServerAddr+r.URL.String(), r.Body)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
// copy headers
|
|
for k, v := range r.Header {
|
|
req.Header[k] = v
|
|
}
|
|
|
|
// make the request
|
|
resp, err := http.DefaultClient.Do(req)
|
|
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
mirrorResponse(w, resp)
|
|
|
|
}
|
|
|
|
func mirrorResponse(w http.ResponseWriter, resp *http.Response) {
|
|
// Copy all headers from the original response
|
|
for key, values := range resp.Header {
|
|
for _, value := range values {
|
|
w.Header().Add(key, value)
|
|
}
|
|
}
|
|
|
|
// Copy the status code from the original response
|
|
w.WriteHeader(resp.StatusCode)
|
|
|
|
// Copy the response body
|
|
io.Copy(w, resp.Body)
|
|
resp.Body.Close()
|
|
}
|