Search code examples
urlgobuild

Go url.Parse(string) fails with certain user names or passwords


Using a URL that has worked in the past, I know receive a parsing error from net/url. What's wrong with it?

parse postgres://user:abc{[email protected]:5432/db?sslmode=require: net/url: invalid userinfo

Sample application

See https://play.golang.com/p/mQZaN5JN3_q to run.

package main

import (
    "fmt"
    "net/url"
)

func main() {
    dsn := "postgres://user:abc{[email protected]:5432/db?sslmode=require"

    u, err := url.Parse(dsn)
    fmt.Println(u, err)
}

Solution

  • It turns out up until Go v1.9.3 net/url didn't validate the user info when parsing a url. This may break existing applications when compiled using v1.9.4 if the username or password contain special characters.

    It now expects the user info to be percent encoded string in order to handle special characters. The new behaviour got introduced in ba1018b.

    Fixed sample application

    package main
    
    import (
        "fmt"
        "net/url"
    )
    
    func main() {
        dsn1 := "postgres://user:abc{[email protected]:5432/db?sslmode=require" // this works up until 1.9.3 but no longer in 1.9.4
        dsn2 := "postgres://user:abc%[email protected]:5432/db?sslmode=require" // this works everywhere, note { is now %7B
    
        u, err := url.Parse(dsn1)
        fmt.Println("1st url:\t", u, err)
    
        u, err = url.Parse(dsn2)
        fmt.Println("2nd url:\t", u, err)
    }
    

    Run the code on https://play.golang.com/p/jGIQgbiKZwz.