Documentation
¶
Overview ¶
Package uri is meant to be an RFC 3986 compliant URI builder and parser.
This is based on the work from ttacon/uri (credits: Trey Tacon).
This fork concentrates on RFC 3986 strictness for URI parsing and validation.
Reference: https://tools.ietf.org/html/rfc3986
Tests have been augmented with test suites of URI validators in other languages: perl, python, scala, .Net.
Extra features like MySQL URIs present in the original repo have been removed.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrInvalidURI = Error(newErr("not a valid URI")) ErrInvalidCharacter = Error(newErr("invalid character in URI")) ErrInvalidEscaping = Error(newErr("invalid percent-escaping sequence")) )
Generic validation errors.
var ( ErrNoSchemeFound = Error(newErr("no scheme found in URI")) ErrInvalidScheme = Error(newErr("invalid scheme in URI")) ErrInvalidQuery = Error(newErr("invalid query string in URI")) ErrInvalidFragment = Error(newErr("invalid fragment in URI")) )
URI-specific errors
var ( ErrInvalidPath = Error(newErr("invalid path in URI")) ErrInvalidHost = Error(newErr("invalid host in URI")) ErrInvalidPort = Error(newErr("invalid port in URI")) ErrInvalidUserInfo = Error(newErr("invalid userinfo in URI")) ErrMissingHost = Error(newErr("missing host in URI")) ErrInvalidHostAddress = Error(newErr("invalid address for host")) ErrInvalidRegisteredName = Error(newErr("invalid host (registered name)")) ErrInvalidDNSName = Error(newErr("invalid host (DNS name)")) )
Authority-specific errors
var ErrURI = Error(newErr("URI error"))
Sentinel error
var UsesDNSHostValidation = func(scheme string) bool { switch scheme { case "https", "http": return true case "file": return false case "aaa": return true case "aaas": return true case "acap": return true case "acct": return true case "cap": return true case "cid": return true case "coap", "coaps", "coap+tcp", "coap+ws", "coaps+tcp", "coaps+ws": return true case "dav": return true case "dict": return true case "dns": return true case "dntp": return true case "finger": return true case "ftp": return true case "git": return true case "gopher": return true case "h323": return true case "iax": return true case "icap": return true case "im": return true case "imap": return true case "ipp", "ipps": return true case "irc", "irc6", "ircs": return true case "jms": return true case "ldap": return true case "mailto": return true case "mid": return true case "msrp", "msrps": return true case "nfs": return true case "nntp": return true case "ntp": return true case "postgresql": return true case "radius": return true case "redis": return true case "rmi": return true case "rtsp", "rtsps", "rtspu": return true case "rsync": return true case "sftp": return true case "skype": return true case "smtp": return true case "snmp": return true case "soap": return true case "ssh": return true case "steam": return true case "svn": return true case "tcp": return true case "telnet": return true case "udp": return true case "vnc": return true case "wais": return true case "ws": return true case "wss": return true } return false }
UsesDNSHostValidation returns true if the provided scheme has host validation that does not follow RFC3986 (which is quite generic), and assumes a valid DNS hostname instead.
This function is declared as a global variable that may be overridden at the package level, in case you need specific schemes to validate the host as a DNS name.
See: https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml
Functions ¶
func IsURI ¶
IsURI tells if a URI is valid according to RFC3986/RFC397.
Example ¶
package main
import (
"fmt"
"github.com/fredbi/uri"
)
func main() {
isValid := uri.IsURI("urn://example.com?query=x#fragment/path") // true
fmt.Println(isValid)
isValid = uri.IsURI("//example.com?query=x#fragment/path") // false
fmt.Println(isValid)
}
Output: true false
func IsURIReference ¶
IsURIReference tells if a URI reference is valid according to RFC3986/RFC397
Reference: https://www.rfc-editor.org/rfc/rfc3986#section-4.1 and https://www.rfc-editor.org/rfc/rfc3986#section-4.2
Example ¶
package main
import (
"fmt"
"github.com/fredbi/uri"
)
func main() {
isValid := uri.IsURIReference("//example.com?query=x#fragment/path") // true
fmt.Println(isValid)
}
Output: true
Types ¶
type Authority ¶
type Authority interface {
UserInfo() string
Host() string
Port() string
Path() string
String() string
Validate(...string) error
IsIP() bool
IPAddr() netip.Addr
Err() error
}
Authority information that a URI contains as specified by RFC3986.
Username and password are given by UserInfo().
type Builder ¶
type Builder interface {
URI() URI
SetScheme(scheme string) Builder
SetUserInfo(userinfo string) Builder
SetHost(host string) Builder
SetPort(port string) Builder
SetPath(path string) Builder
SetQuery(query string) Builder
SetFragment(fragment string) Builder
// Returns the URI this Builder represents.
String() string
}
Builder builds URIs.
type Error ¶ added in v1.1.0
type Error interface {
error
}
Error from the github.com/fredbi/uri module.
type URI ¶
type URI interface {
// Scheme the URI conforms to.
Scheme() string
// Authority information for the URI, including the "//" prefix.
Authority() Authority
// Query returns a map of key/value pairs of all parameters
// in the query string of the URI.
Query() url.Values
// Fragment returns the fragment (component preceded by '#') in the
// URI if there is one.
Fragment() string
// Builder returns a Builder that can be used to modify the URI.
Builder() Builder
// String representation of the URI
String() string
// Validate the different components of the URI
Validate() error
// Is the current port the default for this scheme?
IsDefaultPort() bool
// Default port for this scheme
DefaultPort() int
Err() error
}
URI represents a general RFC3986 URI.
func Parse ¶
Parse attempts to parse a URI. It returns an error if the URI is not RFC3986-compliant.
Example ¶
package main
import (
"fmt"
"github.com/fredbi/uri"
)
func main() {
u, err := uri.Parse("https://example.com:8080/path")
if err != nil {
fmt.Println("Invalid URI:", err)
} else {
fmt.Println(u.String())
}
}
Output: https://example.com:8080/path
func ParseReference ¶
ParseReference attempts to parse a URI relative reference.
It returns an error if the URI is not RFC3986-compliant.
Example ¶
package main
import (
"fmt"
"github.com/fredbi/uri"
)
func main() {
u, err := uri.ParseReference("//example.com/path?a=1#fragment")
if err != nil {
fmt.Println("Invalid URI reference:", err)
} else {
fmt.Println(u.Fragment())
params := u.Query()
fmt.Println(params.Get("a"))
}
}
Output: fragment 1