uri – github.com/fredbi/uri Index | Examples | Files

package uri

import "github.com/fredbi/uri"

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

Variables

var (
	ErrNoSchemeFound         = Error(newErr("no scheme found in URI"))
	ErrInvalidURI            = Error(newErr("not a valid URI"))
	ErrInvalidCharacter      = Error(newErr("invalid character in URI"))
	ErrInvalidScheme         = Error(newErr("invalid scheme in URI"))
	ErrInvalidQuery          = Error(newErr("invalid query string in URI"))
	ErrInvalidFragment       = Error(newErr("invalid fragment in URI"))
	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)"))
)

Validation errors.

var UsesDNSHostValidation = func(scheme string) bool {
	switch scheme {
	case "dns":
		return true
	case "dntp":
		return true
	case "finger":
		return true
	case "ftp":
		return true
	case "git":
		return true
	case "http":
		return true
	case "https":
		return true
	case "imap":
		return true
	case "irc":
		return true
	case "jms":
		return true
	case "mailto":
		return true
	case "nfs":
		return true
	case "nntp":
		return true
	case "ntp":
		return true
	case "postgres":
		return true
	case "redis":
		return true
	case "rmi":
		return true
	case "rtsp":
		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

func IsURI(raw string) bool

IsURI tells if a URI is valid according to RFC3986/RFC397.

Example

Code:play 

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

func IsURIReference(raw string) bool

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

Code:play 

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
}

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

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
}

URI represents a general RFC3986 URI.

func Parse

func Parse(raw string) (URI, error)

Parse attempts to parse a URI. It returns an error if the URI is not RFC3986-compliant.

Example

Code:play 

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

func ParseReference(raw string) (URI, error)

ParseReference attempts to parse a URI relative reference.

It returns an error if the URI is not RFC3986-compliant.

Example

Code:play 

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

Source Files

builder.go dns.go errors.go post_go20.go uri.go

Version
v1.1.0 (latest)
Published
Sep 23, 2023
Platform
windows/amd64
Imports
7 packages
Last checked
now

Tools for package owners.