diff options
| author | Melonai <einebeere@gmail.com> | 2021-09-10 23:40:49 +0200 |
|---|---|---|
| committer | Melonai <einebeere@gmail.com> | 2021-09-10 23:43:57 +0200 |
| commit | a32b9fe723c633cf5349bb0479d97e1f6d04445d (patch) | |
| tree | f45869da615f5efcd0b2dd8d1baade6831dd3f4f /destination.go | |
| parent | 175da8f22cd791e81338fe61e6099125868cf5a0 (diff) | |
| download | portgate-a32b9fe723c633cf5349bb0479d97e1f6d04445d.tar.zst portgate-a32b9fe723c633cf5349bb0479d97e1f6d04445d.zip | |
Refactor path into destination
Diffstat (limited to 'destination.go')
| -rw-r--r-- | destination.go | 75 |
1 files changed, 75 insertions, 0 deletions
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 |
