Difference between revisions of "Gorelay"
Jump to navigation
Jump to search
Line 1: | Line 1: | ||
# Simple HTTP Relay written in go | # Simple HTTP Relay written in go | ||
+ | |||
+ | ## run.sh | ||
+ | ``` | ||
+ | #!/bin/bash | ||
+ | set -eu | ||
+ | |||
+ | go build gorelay.go | ||
+ | pkill gorelay || true | ||
+ | sleep 2 | ||
+ | ./gorelay -fqdn="192.168.254.22" -port=8443 -username="admin" -password="admin" -skip_tls_verify=true -uri_reg_old "/api/v1/foo/" -uri_reg_new "/api/v1/bar/" | ||
+ | ``` | ||
+ | ## curl | ||
+ | ``` | ||
+ | cat <<EOF > example.json | ||
+ | { | ||
+ | "foo": "bar" | ||
+ | } | ||
+ | |||
+ | curl -sku $AUTH -X POST -d @example.json https://proxyhost.example.com/foo | ||
+ | ``` | ||
+ | |||
+ | ## gorelay.go | ||
``` | ``` | ||
package main | package main | ||
Line 42: | Line 64: | ||
password := flag.String("password", "", "Password for basic authentication") | password := flag.String("password", "", "Password for basic authentication") | ||
skipTLS := flag.Bool("skip_tls_verify", false, "Skip TLS certificate verification") | skipTLS := flag.Bool("skip_tls_verify", false, "Skip TLS certificate verification") | ||
+ | uriRegOld := flag.String("uri_reg_old", "", "Regex to replace in URI") | ||
+ | uriRegNew := flag.String("uri_reg_new", "", "String to replace old URI") | ||
flag.Parse() | flag.Parse() | ||
Line 63: | Line 87: | ||
} | } | ||
} | } | ||
− | + | regex := regexp.MustCompile(*uriRegOld) | |
− | + | replaceStr := *uriRegNew | |
− | requestURI := | + | requestURI := regex.ReplaceAllString(req.RequestURI, replaceStr) |
− | |||
newReq, err := http.NewRequest(req.Method, uriBase+requestURI, req.Body) | newReq, err := http.NewRequest(req.Method, uriBase+requestURI, req.Body) | ||
if err != nil { | if err != nil { |
Revision as of 02:38, 3 May 2024
Simple HTTP Relay written in go
run.sh
#!/bin/bash set -eu go build gorelay.go pkill gorelay || true sleep 2 ./gorelay -fqdn="192.168.254.22" -port=8443 -username="admin" -password="admin" -skip_tls_verify=true -uri_reg_old "/api/v1/foo/" -uri_reg_new "/api/v1/bar/"
curl
cat <<EOF > example.json { "foo": "bar" } curl -sku $AUTH -X POST -d @example.json https://proxyhost.example.com/foo
gorelay.go
package main import ( "crypto/tls" "flag" "fmt" "io" "log" "net/http" "regexp" "time" "github.com/labstack/echo/v4" ) func syslogLogger(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { start := time.Now() err := next(c) stop := time.Now() req := c.Request() res := c.Response() log.Printf("%s - [%s] \"%s %s %s\" %d %d %v", c.RealIP(), stop.Format(time.RFC3339), req.Method, req.RequestURI, req.Proto, res.Status, res.Size, stop.Sub(start), ) return err } } func main() { schema := flag.String("schema", "https", "URI schema (http or https)") port := flag.Int("port", 443, "Port number of the remote HTTPS endpoint") fqdn := flag.String("fqdn", "", "Fully Qualified Domain Name (required)") username := flag.String("username", "", "Username for basic authentication") password := flag.String("password", "", "Password for basic authentication") skipTLS := flag.Bool("skip_tls_verify", false, "Skip TLS certificate verification") uriRegOld := flag.String("uri_reg_old", "", "Regex to replace in URI") uriRegNew := flag.String("uri_reg_new", "", "String to replace old URI") flag.Parse() if *fqdn == "" { panic("FQDN argument is required") } uriBase := fmt.Sprintf("%s://%s:%d", *schema, *fqdn, *port) e := echo.New() e.Use(syslogLogger) e.Any("/*", func(c echo.Context) error { req := c.Request() client := &http.Client{} if *skipTLS { client.Transport = &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } } regex := regexp.MustCompile(*uriRegOld) replaceStr := *uriRegNew requestURI := regex.ReplaceAllString(req.RequestURI, replaceStr) newReq, err := http.NewRequest(req.Method, uriBase+requestURI, req.Body) if err != nil { return err } if *username != "" && *password != "" { newReq.SetBasicAuth(*username, *password) } for k, v := range req.Header { newReq.Header[k] = v } resp, err := client.Do(newReq) if err != nil { return err } defer resp.Body.Close() for k, v := range resp.Header { c.Response().Header().Set(k, v[0]) } io.Copy(c.Response().Writer, resp.Body) return nil }) e.Logger.Fatal(e.Start(":8080")) }