Encode URLs in Go

The net/url package is a useful package for dealing with URLs, paths and parameters in Go. You can have parameters encoded in a URL or automatically convert special characters.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package main

import (
	"fmt"
	"log"
	"net/url"
)

func main() {
	//set the URL
	baseUrl, err := url.Parse("https://www.google.com/search")
	if err != nil {
		log.Fatalln(err)
	}
	fmt.Printf("URL: %s\n", baseUrl)
	fmt.Println(baseUrl.Host)
	fmt.Println(baseUrl.Path)
}

Try it

As you can see url.Parse splits the URL into its components and saves it to a structure. In addition to the fields above, there are also others (from the documentation):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
type URL struct {
    Scheme     string
    Opaque     string    // encoded opaque data
    User       Userinfo // username and password information
    Host       string    // host or host:port
    Path       string    // path (relative paths may omit leading slash)
    RawPath    string    // encoded path hint (see EscapedPath method); added in Go 1.5
    ForceQuery bool      // append a query ('?') even if RawQuery is empty; added in Go 1.7
    RawQuery   string    // encoded query values, without '?'
    Fragment   string    // fragment for references, without '#'
}

Working with URLs

Net/url defines a type Values as a key-value pair and offers some methods to work with it.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package main

import (
	"fmt"
	"log"
	"net/url"
)

func main() {
	//parameters
	p := url.Values{}
	p.Add("q", "cat")
	p.Add("s", "something else")

	fmt.Println(p)
	fmt.Println(p.Encode())

	//this also works backwards
	q, err := url.ParseQuery("q=cat&s=something+else")

	if err != nil {
		log.Fatalln(err)
	}

	fmt.Println(q)

	//delete a key
	p.Del("q")
	fmt.Println(p)

}

Try it

Encode URL paths with special characters

When creating the URL with the parse method, an encoded version of the URL path is also created, so that special characters are not a problem:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package main

import (
	"fmt"
	"log"
	"net/url"
)

func main() {
	//set the URL
	baseUrl, err := url.Parse("https://www.google.com/search")
	if err != nil {
		log.Fatalln(err)
	}

	//path encoding
	baseUrl.Path += "/a path with spaces and special chars!ü@"
	fmt.Printf("URL: %s\n", baseUrl)

	fmt.Println(baseUrl.Host)
	fmt.Println(baseUrl.Path)
	fmt.Println(baseUrl.EscapedPath())

	//lets try this backwards
	newUrl, err := url.ParseRequestURI("https://www.google.com/search/a%20path%20with%20spaces%20and%20special%20chars%21%C3%BC@")
	if err != nil {
		log.Fatalln(err)
	}
	fmt.Println(newUrl.Host)
	fmt.Println(newUrl.Path)
	fmt.Println(baseUrl.EscapedPath())
}

The package contains even more practical functionality. You can find the documentary at: https://golang.org/pkg/net/

0%