From a32b9fe723c633cf5349bb0479d97e1f6d04445d Mon Sep 17 00:00:00 2001 From: Melonai Date: Fri, 10 Sep 2021 23:40:49 +0200 Subject: Refactor path into destination --- destination.go | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 destination.go (limited to 'destination.go') diff --git a/destination.go b/destination.go new file mode 100644 index 0000000..d911e3e --- /dev/null +++ b/destination.go @@ -0,0 +1,75 @@ +package portgate + +import ( + "net/url" + "path" + "strconv" + "strings" +) + +// Destination represents a routing destination the user gave. +type Destination struct { + // Identifier to which port of the destination host the path points to and to which the + // user's request will be proxied to. + Port int + // The path without the port identifier. + // This is the path which will be requested from the destination. + Path string + IsPortgatePath bool +} + +// ParseDestinationFromURL creates a Path from the requested URL. +func DestinationFromURL(p string) Destination { + p = path.Clean("/" + p) + + // Get first path part, which is the potential port identifier. + destinationIdentifierEnd := strings.Index(p[1:], "/") + 1 + + // If there is no '/' in the path, apart from the root, the first part is the entire path + if destinationIdentifierEnd == 0 { + destinationIdentifierEnd = len(p) + } + + destinationIdentifier := p[1:destinationIdentifierEnd] + + // We have to to check that destinationIdentifier is a port + port, err := strconv.Atoi(destinationIdentifier) + if err == nil { + // We got an identifier and can split the path + resourcePath := path.Clean("/" + p[destinationIdentifierEnd:]) + + return Destination{ + Port: port, + Path: resourcePath, + } + } else { + destination := Destination{ + Port: 0, + Path: p, + } + + if strings.HasPrefix(destination.Path, "/_portgate") { + destination.IsPortgatePath = true + return destination + } + + return destination + } +} + +// DestinationFromReferer tries to create a Path from the Referer header of the request. +func (d Destination) AddReferer(referer string) Destination { + u, err := url.Parse(referer) + if err != nil { + return Destination{} + } + + // d has the correct resource path but the wrong port, so we create a new destination + // with the correct data from both. + newDestination := DestinationFromURL(u.Path) + + return Destination{ + Port: newDestination.Port, + Path: d.Path, + } +} \ No newline at end of file -- cgit 1.4.1