sidoxy/proxy.go
Elia el Lazkani 95c29b1f4b
All checks were successful
continuous-integration/drone/push Build is passing
fix(): Fixing a minor issue preventing tests from initiating
2023-07-11 03:18:58 +02:00

94 lines
2.2 KiB
Go

package main
import (
"fmt"
"io"
"net"
"log"
"net/http"
"net/url"
"time"
)
type ReverseProxy struct {
URL *url.URL
jwtKey string
}
func (rp *ReverseProxy) reverseProxyHandlerFunc() http.Handler {
return http.HandlerFunc(rp.reverseProxyHandler)
}
func (rp *ReverseProxy) reverseProxyHandler(rw http.ResponseWriter, req *http.Request) {
fmt.Printf("[sidoxy] Reverse proxy received request at: %s\n", time.Now())
// set req Host, URL and Request URI to forward a request to the origin server
req.Host = rp.URL.Host
req.URL.Host = rp.URL.Host
req.URL.Scheme = rp.URL.Scheme
req.RequestURI = ""
// set X-FORWARDED-FOR
xForwardedFor := req.Header.Get("X-Forwarded-For")
var remoteAddr string
if xForwardedFor != "" {
remoteAddr = xForwardedFor
} else {
remoteAddr, _, _ = net.SplitHostPort(req.RemoteAddr)
}
req.Header.Set("X-Forwarded-For", remoteAddr)
fmt.Printf("[sidoxy] Reverse proxy setting X-Forwarded-For to %s\n", remoteAddr)
// TODO: To be implemented
// decode JWT if key present
if rp.jwtKey != "" {
jwtDecode(rp.jwtKey, req.Header.Get("JWT_TOKEN"), req)
}
// save the response from the origin server
originServerResponse, err := http.DefaultClient.Do(req)
if err != nil {
rw.WriteHeader(http.StatusInternalServerError)
_, _ = fmt.Fprint(rw, err)
return
}
fmt.Printf("[sidoxy] Reverse proxy setting the following return headers\n")
// return Header response
for key, values := range originServerResponse.Header {
for _, value := range values {
fmt.Printf("[sidoxy] \t%v: %v\n", key, value)
rw.Header().Set(key, value)
}
}
// support stream
done := make(chan bool)
defer close(done)
go func() {
for {
select {
case <-time.Tick(10 * time.Millisecond):
rw.(http.Flusher).Flush()
case <-done:
return
}
}
}()
// return response to the client
rw.WriteHeader(http.StatusOK)
io.Copy(rw, originServerResponse.Body)
}
func parse_url(host_url string) *url.URL {
h_url, err := url.Parse(host_url)
if err != nil {
log.Fatal("[sidoxy] Invalid server URL: " + host_url)
}
return h_url
}
func listen_and_serve(address string, handler http.Handler) error {
return http.ListenAndServe(address, handler)
}