LoginSignup
3
3

More than 5 years have passed since last update.

Golang の net/url で # を含む文字列を Parse() する

Last updated at Posted at 2015-06-30

net/url の Parse()# を含む文字列を渡す時は以下の点に注意する。

  • # 以降は削除される。 (フラグメント識別子と見なされる)
  • # を文字列に含めたい場合は %23 で記述する。 (エスケープシーケンス)

以下はこの記事を書くに至った経緯なので、多くの方にとって有用な情報はないと思います。

発端

Go で PostgreSQL に繋いでみようと思い、以下のようなコードを書いていた。

package main

import (
        "database/sql"
        "fmt"
        _ "github.com/lib/pq"
)

func main() {
        db, err := sql.Open("postgres", "postgres://user1:@localhost:5432/postgres?sslmode=disable&password=asdf#1234")
        if err != nil {
                panic(err)
        }
        fmt.Println(db)

        rows, err := db.Query("SELECT * FROM table1")
        if err != nil {
                panic(err)
        }
        fmt.Println(rows)
}

実行してみると...

panic: pq: password authentication failed for user "user1"

認証に失敗してしまった。

調査

panic が起きた db.Query から辿って行くと、 lib/pq が DSN をパースする際に net/urlParse() を呼んでいた。

  • # 以降の削除
  • RFC 2396 に基づいた URL 文字列のアンエスケープ

Parse() では上記 2 点の処理がされている。

修正

# をエスケープシーケンスに置き換えた。

db, err := sql.Open("postgres", "postgres://user1:@localhost:5432/postgres?sslmode=disable&password=asdf#zxcv")

これを

db, err := sql.Open("postgres", "postgres://user1:@localhost:5432/postgres?sslmode=disable&password=asdf%23zxcv")

こうすることで無事に動きました。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3