urlutil

package
v0.0.0-...-c53bedf Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 10, 2025 License: Unlicense Imports: 8 Imported by: 0

Documentation

Overview

Package urlutil contains types and utilities for dealing with URLs.

Index

Examples

Constants

View Source
const (
	SchemeFile  = "file"
	SchemeGRPC  = "grpc"
	SchemeGRPCS = "grpcs"
	SchemeHTTP  = "http"
	SchemeHTTPS = "https"
)

Known scheme constants.

View Source
const ErrEmpty errors.Error = "empty url"

ErrEmpty is returned from Parse and URL.UnmarshalText when the input is empty.

Variables

This section is empty.

Functions

func IsValidGRPCURLScheme

func IsValidGRPCURLScheme(s string) (ok bool)

IsValidGRPCURLScheme returns true if s is a valid gRPC(S) URL scheme. That is, SchemeGRPC or SchemeGRPCS

func IsValidHTTPURLScheme

func IsValidHTTPURLScheme(s string) (ok bool)

IsValidHTTPURLScheme returns true if s is a valid HTTP(S) URL scheme. That is, SchemeHTTP or SchemeHTTPS

func RedactUserinfo

func RedactUserinfo(u *url.URL) (redacted *url.URL)

RedactUserinfo returns u if the URL does not contain any userinfo data. Otherwise, it returns a deep clone with both username and password redacted. u must not be nil.

func RedactUserinfoInURLError

func RedactUserinfoInURLError(u *url.URL, err error)

RedactUserinfoInURLError checks if err is a *url.Error and, if it is, replaces the underlying URL string with a redacted version of u. u must not be nil.

Example
package main

import (
	"context"
	"fmt"
	"net"
	"net/http"
	"net/url"
	"time"

	"github.com/dimwittedpa/golibs/errors"
	"github.com/dimwittedpa/golibs/netutil/urlutil"
)

func main() {
	c := &http.Client{
		Timeout: 1 * time.Second,
		Transport: &http.Transport{
			DialContext: func(ctx context.Context, network, addr string) (conn net.Conn, err error) {
				return nil, errors.Error("test error")
			},
		},
	}

	u := &url.URL{
		Scheme: urlutil.SchemeHTTP,
		Host:   "does-not-exist.example",
		User:   url.UserPassword("secretUser", "secretPassword"),
	}

	_, err := c.Get(u.String())
	urlutil.RedactUserinfoInURLError(u, err)

	fmt.Printf("got error: %s", err)

}
Output:

got error: Get "http://xxxxx:xxxxx@does-not-exist.example": test error

func ValidateFileURL

func ValidateFileURL(u *url.URL) (err error)

ValidateFileURL returns nil if u is a valid file URL.

TODO(a.garipov): Make the validations stricter.

func ValidateGRPCURL

func ValidateGRPCURL(u *url.URL) (err error)

ValidateGRPCURL returns nil if u is a valid gRPC(S) URL.

TODO(a.garipov): Make the validations stricter.

func ValidateHTTPURL

func ValidateHTTPURL(u *url.URL) (err error)

ValidateHTTPURL returns nil if u is a valid HTTP(S) URL.

TODO(a.garipov): Make the validations stricter.

Example
package main

import (
	"fmt"
	"net/url"

	"github.com/dimwittedpa/golibs/netutil/urlutil"
)

func main() {
	fmt.Println(urlutil.ValidateHTTPURL(nil))

	fmt.Println(urlutil.ValidateHTTPURL(&url.URL{
		Scheme: urlutil.SchemeGRPC,
		Host:   "host.example",
	}))

	fmt.Println(urlutil.ValidateHTTPURL(&url.URL{
		Scheme: urlutil.SchemeHTTP,
		Host:   "host.example",
	}))

	fmt.Println(urlutil.ValidateHTTPURL(&url.URL{
		Scheme: "HTTP",
		Host:   "HOST.EXAMPLE",
	}))

}
Output:

bad http(s) url: no value
bad http(s) url "grpc://host.example": scheme: bad enum value: "grpc"; want "http" or "https"
<nil>
<nil>

Types

type URL

type URL struct {
	url.URL
}

URL is a wrapper around url.URL that can marshal and unmarshal itself from text form more easily.

Example
package main

import (
	"encoding/json"
	"fmt"
	"net/url"

	"github.com/dimwittedpa/golibs/netutil/urlutil"
)

// check is an error-checking helper for examples.
func check(err error) {
	if err != nil {
		panic(err)
	}
}

func main() {
	type jsonStruct struct {
		Stdlib *url.URL
		Util   *urlutil.URL
	}

	const rawURL = "https://host.example:1234/path?query=1#fragment"

	stdlibURL, err := url.Parse(rawURL)
	check(err)

	utilURL, err := urlutil.Parse(rawURL)
	check(err)

	v := &jsonStruct{
		Stdlib: stdlibURL,
		Util:   utilURL,
	}

	data, err := json.MarshalIndent(v, "", "  ")
	check(err)

	fmt.Printf("%s\n", data)

	v = &jsonStruct{}
	data = []byte(`{"Util":"` + rawURL + `"}`)
	err = json.Unmarshal(data, v)
	check(err)

	fmt.Printf("%q\n", v.Util)

}
Output:

{
  "Stdlib": {
    "Scheme": "https",
    "Opaque": "",
    "User": null,
    "Host": "host.example:1234",
    "Path": "/path",
    "RawPath": "",
    "OmitHost": false,
    "ForceQuery": false,
    "RawQuery": "query=1",
    "Fragment": "fragment",
    "RawFragment": ""
  },
  "Util": "https://host.example:1234/path?query=1#fragment"
}
"https://host.example:1234/path?query=1#fragment"

func Parse

func Parse(rawURL string) (u *URL, err error)

Parse is a wrapper around url.Parse that returns *URL. Unlike url.Parse, it does not consider empty string a valid URL and returns ErrEmpty.

func (*URL) MarshalText

func (u *URL) MarshalText() (b []byte, err error)

MarshalText implements the encoding.TextMarshaler interface for *URL.

TODO(e.burkov): Consider declaring it on a non-pointer receiver.

func (*URL) UnmarshalJSON

func (u *URL) UnmarshalJSON(b []byte) (err error)

UnmarshalJSON implements the json.Unmarshaler interface for *URL.

func (*URL) UnmarshalText

func (u *URL) UnmarshalText(b []byte) (err error)

UnmarshalText implements the encoding.TextUnmarshaler interface for *URL.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL