Split utils out to a separate subpackage

This commit is contained in:
Daniel Oaks
2017-10-05 23:47:43 +10:00
parent 4aa52956e5
commit 207c1074df
7 changed files with 20 additions and 16 deletions

35
irc/utils/args.go Normal file
View File

@@ -0,0 +1,35 @@
// Copyright (c) 2016-2017 Daniel Oaks <daniel@danieloaks.net>
// released under the MIT license
package utils
// ArgsToStrings takes the arguments and splits them into a series of strings,
// each argument separated by delim and each string bounded by maxLength.
func ArgsToStrings(maxLength int, arguments []string, delim string) []string {
var messages []string
var buffer string
for {
if len(arguments) < 1 {
break
}
if len(buffer) > 0 && maxLength < len(buffer)+len(delim)+len(arguments[0]) {
messages = append(messages, buffer)
buffer = ""
continue
}
if len(buffer) > 1 {
buffer += delim
}
buffer += arguments[0]
arguments = arguments[1:]
}
if len(buffer) > 0 {
messages = append(messages, buffer)
}
return messages
}

70
irc/utils/net.go Normal file
View File

@@ -0,0 +1,70 @@
// Copyright (c) 2012-2014 Jeremy Latt
// Copyright (c) 2016 Daniel Oaks <daniel@danieloaks.net>
// released under the MIT license
package utils
import (
"net"
"strings"
)
// IPString returns a simple IP string from the given net.Addr.
func IPString(addr net.Addr) string {
addrStr := addr.String()
ipaddr, _, err := net.SplitHostPort(addrStr)
//TODO(dan): Why is this needed, does this happen?
if err != nil {
return addrStr
}
return ipaddr
}
// AddrLookupHostname returns the hostname (if possible) or address for the given `net.Addr`.
func AddrLookupHostname(addr net.Addr) string {
return LookupHostname(IPString(addr))
}
// LookupHostname returns the hostname for `addr` if it has one. Otherwise, just returns `addr`.
func LookupHostname(addr string) string {
names, err := net.LookupAddr(addr)
if err == nil && len(names) > 0 {
candidate := strings.TrimSuffix(names[0], ".")
if IsHostname(candidate) {
return candidate
}
}
// return original address if no hostname found
if len(addr) > 0 && addr[0] == ':' {
// fix for IPv6 hostnames (so they don't start with a colon), same as all other IRCds
addr = "0" + addr
}
return addr
}
var allowedHostnameChars = "abcdefghijklmnopqrstuvwxyz1234567890-."
// IsHostname returns whether we consider `name` a valid hostname.
func IsHostname(name string) bool {
// IRC hostnames specifically require a period
if !strings.Contains(name, ".") || len(name) < 1 || len(name) > 253 {
return false
}
// ensure each part of hostname is valid
for _, part := range strings.Split(name, ".") {
if len(part) < 1 || len(part) > 63 || strings.HasPrefix(part, "-") || strings.HasSuffix(part, "-") {
return false
}
}
// ensure all chars of hostname are valid
for _, char := range strings.Split(strings.ToLower(name), "") {
if !strings.Contains(allowedHostnameChars, char) {
return false
}
}
return true
}

49
irc/utils/net_test.go Normal file
View File

@@ -0,0 +1,49 @@
// Copyright (c) 2012-2014 Jeremy Latt
// Copyright (c) 2016 Daniel Oaks <daniel@danieloaks.net>
// released under the MIT license
package utils
import "testing"
// hostnames from https://github.com/DanielOaks/irc-parser-tests
var (
goodHostnames = []string{
"irc.example.com",
"i.coolguy.net",
"irc-srv.net.uk",
"iRC.CooLguY.NeT",
"gsf.ds342.co.uk",
"324.net.uk",
"xn--bcher-kva.ch",
}
badHostnames = []string{
"-lol-.net.uk",
"-lol.net.uk",
"_irc._sctp.lol.net.uk",
"irc",
"com",
"",
}
)
func TestIsHostname(t *testing.T) {
for _, name := range goodHostnames {
if !IsHostname(name) {
t.Error(
"Expected to pass, but could not validate hostname",
name,
)
}
}
for _, name := range badHostnames {
if IsHostname(name) {
t.Error(
"Expected to fail, but successfully validated hostname",
name,
)
}
}
}