Skip to content

Commit

Permalink
feat: enable HTTP redirection
Browse files Browse the repository at this point in the history
  • Loading branch information
rurreac committed Aug 3, 2024
1 parent fefe269 commit 4830456
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 11 deletions.
22 changes: 20 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,16 @@ When the flag `-keystore` is provided, Slider will store a new KeyPair in disk,
By default, Slider listens in port `8080`. Specify any other port using this flag.

##### `-template`:
Mimic default web page and HTTP header of web server passed as parameter.
Mimic "server" HTTP Response Header, web page and status code of web server passed as parameter.

Apache and Nginx are presented with their default web pages and a 200 status code. Other templates might be presented
in the form of error pages with their respective status code.

##### `-redirect`:
A redirect parameter must be at least a URL with a valid scheme and host (`http[s]://<host>[:<port>]`).

HTTP connections will be redirected to the given URL while Slider connections will proceed as usual.
Can be used in combination with `-template` to include a server header in the response headers.

##### `-verbose`:
Choose the log level verbosity between debug, info, warn and error. When verbosity is set to `off` only non labeled and
Expand Down Expand Up @@ -431,7 +440,16 @@ a different Slider Server. This is useful when we want to be able to authorize s
A connection from a Server with a fingerprint not successfully verified will be rejected.

##### `-template`:
Mimic default web page and HTTP header of web server passed as parameter.
Mimic "server" HTTP Response Header, web page and status code of web server passed as parameter.

Apache and Nginx are presented with their default web pages and a 200 status code. Other templates might be presented
in the form of error pages with their respective status code.

##### `-redirect`:
A redirect parameter must be at least a URL with a valid scheme and host (`http[s]://<host>[:<port>]`).

HTTP connections will be redirected to the given URL while Slider connections will proceed as usual.
Can be used in combination with `-template` to include a server header in the response headers.

#### Reverse Client Flags

Expand Down
16 changes: 15 additions & 1 deletion client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ type client struct {
isListener bool
firstRun bool
webTemplate web.Template
webRedirect string
}

const clientHelp = `
Expand All @@ -74,7 +75,8 @@ func NewClient(args []string) {
port := clientFlags.Int("port", 8081, "Listener Port")
address := clientFlags.String("address", "0.0.0.0", "Address the Listener will bind to")
retry := clientFlags.Bool("retry", false, "Retries reconnection indefinitely")
webTemplate := clientFlags.String("template", "", "Mimic web server page [apache|iis|nginx|tomcat]")
webTemplate := clientFlags.String("template", "default", "Mimic web server page [apache|iis|nginx|tomcat]")
webRedirect := clientFlags.String("redirect", "", "Redirect incoming HTTP connections to given URL")
clientFlags.Usage = func() {
fmt.Println(clientHelp)
clientFlags.PrintDefaults()
Expand Down Expand Up @@ -145,12 +147,21 @@ func NewClient(args []string) {
if *listener {
c.isListener = *listener

c.Logger.Debugf("Using \"%s\" web server template", *webTemplate)
t, tErr := web.GetTemplate(*webTemplate)
if tErr != nil {
c.Logger.Errorf("%v", tErr)
}
c.webTemplate = t

if *webRedirect != "" {
if wErr := web.CheckURL(*webRedirect); wErr != nil {
c.Logger.Fatalf("Redirect: %v", wErr)
}
c.webRedirect = *webRedirect
c.Logger.Debugf("Redirecting incomming HTTP requests to \"%s\"", c.webRedirect)
}

fmtAddress := fmt.Sprintf("%s:%d", *address, *port)
clientAddr, rErr := net.ResolveTCPAddr("tcp", fmtAddress)
if rErr != nil {
Expand Down Expand Up @@ -222,6 +233,9 @@ func flagSanityCheck(clientFlags *flag.FlagSet) error {
if conf.FlagIsDefined(clientFlags, "template") {
flagExclusion = append(flagExclusion, "-template")
}
if conf.FlagIsDefined(clientFlags, "redirect") {
flagExclusion = append(flagExclusion, "-redirect")
}
argNumber := len(clientFlags.Args())
if argNumber != 1 {
return fmt.Errorf("%s client requires exactly one valid server address as an argument", clientType)
Expand Down
8 changes: 7 additions & 1 deletion client/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,16 @@ func (c *client) handleHTTPConn(w http.ResponseWriter, r *http.Request) {
return
}

w.Header().Add("server", c.webTemplate.ServerHeader)

if c.webRedirect != "" {
http.Redirect(w, r, c.webRedirect, http.StatusFound)
return
}

var wErr error
switch r.URL.Path {
case "/":
w.Header().Add("server", c.webTemplate.ServerHeader)
w.WriteHeader(c.webTemplate.StatusCode)
_, wErr = w.Write([]byte(c.webTemplate.HtmlTemplate))
default:
Expand Down
24 changes: 19 additions & 5 deletions pkg/web/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package web
import (
"fmt"
"net/http"
"net/url"
"strings"
)

Expand Down Expand Up @@ -34,18 +35,31 @@ var (
ServerHeader: "Apache Tomcat",
StatusCode: http.StatusNotFound,
},
"default": {
HtmlTemplate: "OK",
StatusCode: http.StatusOK,
ServerHeader: "",
},
}
)

func GetTemplate(n string) (Template, error) {
t, ok := enabledTemplates[strings.ToLower(n)]
if !ok {
return Template{
HtmlTemplate: "OK",
StatusCode: http.StatusOK,
ServerHeader: "",
}, fmt.Errorf("template not found, using default")
return enabledTemplates["default"], fmt.Errorf("template not found, using default")
}

return t, nil
}

func CheckURL(u string) error {
pURL, uErr := url.Parse(u)
if uErr != nil {
return fmt.Errorf("not a valid URL")
}
if pURL.Scheme == "" || pURL.Host == "" {
return fmt.Errorf("expecting a full URL including scheme and host")
}

return nil
}
8 changes: 7 additions & 1 deletion server/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,16 @@ func (s *server) handleHTTPClient(w http.ResponseWriter, r *http.Request) {
return
}

w.Header().Add("server", s.webTemplate.ServerHeader)

if s.webRedirect != "" {
http.Redirect(w, r, s.webRedirect, http.StatusFound)
return
}

var wErr error
switch r.URL.Path {
case "/":
w.Header().Add("server", s.webTemplate.ServerHeader)
w.WriteHeader(s.webTemplate.StatusCode)
_, wErr = w.Write([]byte(s.webTemplate.HtmlTemplate))
default:
Expand Down
12 changes: 11 additions & 1 deletion server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ type server struct {
certSaveOn bool
keepalive time.Duration
webTemplate web.Template
webRedirect string
}

func NewServer(args []string) {
Expand All @@ -64,7 +65,8 @@ func NewServer(args []string) {
certJarFile := serverFlags.String("certs", "", "Path of a valid slider-certs json file")
keyStore := serverFlags.Bool("keystore", false, "Store Server key for later use")
keyPath := serverFlags.String("keypath", "", "Path for reading or storing a Server key")
webTemplate := serverFlags.String("template", "", "Mimic web server page [apache|iis|nginx|tomcat]")
webTemplate := serverFlags.String("template", "default", "Mimic web server page [apache|iis|nginx|tomcat]")
webRedirect := serverFlags.String("redirect", "", "Redirect incoming HTTP connections to given URL")
serverFlags.Usage = func() {
fmt.Println(serverHelp)
serverFlags.PrintDefaults()
Expand Down Expand Up @@ -179,6 +181,14 @@ func NewServer(args []string) {
}
s.webTemplate = t

if *webRedirect != "" {
if wErr := web.CheckURL(*webRedirect); wErr != nil {
s.Logger.Fatalf("Redirect: %v", wErr)
}
s.webRedirect = *webRedirect
s.Logger.Debugf("Redirect incomming HTTP requests to \"%s\"", s.webRedirect)
}

fmtAddress := fmt.Sprintf("%s:%d", *address, *port)
serverAddr, rErr := net.ResolveTCPAddr("tcp", fmtAddress)
if rErr != nil {
Expand Down

0 comments on commit 4830456

Please sign in to comment.