Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Release 3.4.0 (unreleased)

### Added

- #472: Added `joinHostPort` and `splitHostPort` network functions

## Release 3.3.0 (2024-08-29)

### Added
Expand Down
21 changes: 21 additions & 0 deletions docs/network.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,24 @@ The `getHostByName` receives a domain name and returns the ip address.
```
getHostByName "www.google.com" would return the corresponding ip address of www.google.com
```

## joinHostPort

`joinHostPort` combines a host and port into a network address of the form `host:port`. For IPv6 addresses the host is enclosed in square brackets: `[host]:port`. This is the inverse of `splitHostPort`.

```
joinHostPort "192.0.2.1" "80" -> "192.0.2.1:80"
joinHostPort "2001:db8::1" "80" -> "[2001:db8::1]:80"
joinHostPort "example.com" "443" -> "example.com:443"
```

## splitHostPort

`splitHostPort` splits a network address of the form `host:port` or `[host]:port` into its host and port components, returning a map with keys `host` and `port`. This is the inverse of `joinHostPort`.

```
{{- with splitHostPort "192.0.2.1:80" }}
host: {{ .host }}
port: {{ .port }}
{{- end }}
```
4 changes: 4 additions & 0 deletions functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ var nonhermeticFunctions = []string{

// Network
"getHostByName",
"joinHostPort",
"splitHostPort",
}

var genericMap = map[string]interface{}{
Expand Down Expand Up @@ -272,6 +274,8 @@ var genericMap = map[string]interface{}{

// Network:
"getHostByName": getHostByName,
"joinHostPort": joinHostPort,
"splitHostPort": splitHostPort,

// Paths:
"base": path.Base,
Expand Down
9 changes: 9 additions & 0 deletions network.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,12 @@ func getHostByName(name string) string {
//TODO: add error handing when release v3 comes out
return addrs[rand.Intn(len(addrs))]
}

func joinHostPort(host, port string) string {
return net.JoinHostPort(host, port)
}

func splitHostPort(hostport string) map[string]string {
host, port, _ := net.SplitHostPort(hostport)
return map[string]string{"host": host, "port": port}
}
33 changes: 33 additions & 0 deletions network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,36 @@ func TestGetHostByName(t *testing.T) {
assert.NotNil(t, ip)
assert.NotEmpty(t, ip)
}

func TestJoinHostPort(t *testing.T) {
tests := []struct {
tpl string
expected string
}{
{`{{joinHostPort "192.0.2.1" "80"}}`, "192.0.2.1:80"},
{`{{joinHostPort "2001:db8::1" "80"}}`, "[2001:db8::1]:80"},
{`{{joinHostPort "example.com" "443"}}`, "example.com:443"},
}
for _, tt := range tests {
result, err := runRaw(tt.tpl, nil)
assert.NoError(t, err)
assert.Equal(t, tt.expected, result)
}
}

func TestSplitHostPort(t *testing.T) {
tests := []struct {
tpl string
expectedHost string
expectedPort string
}{
{`{{with splitHostPort "192.0.2.1:80"}}{{.host}}/{{.port}}{{end}}`, "192.0.2.1", "80"},
{`{{with splitHostPort "[2001:db8::1]:80"}}{{.host}}/{{.port}}{{end}}`, "2001:db8::1", "80"},
{`{{with splitHostPort "example.com:443"}}{{.host}}/{{.port}}{{end}}`, "example.com", "443"},
}
for _, tt := range tests {
result, err := runRaw(tt.tpl, nil)
assert.NoError(t, err)
assert.Equal(t, tt.expectedHost+"/"+tt.expectedPort, result)
}
}