11 // Magnet link components.
18 const xtPrefix = "urn:btih:"
20 func (m Magnet) String() string {
21 // net.URL likes to assume //, and encodes ':' on us, so we do most of
24 ret += xtPrefix + hex.EncodeToString(m.InfoHash[:])
25 if m.DisplayName != "" {
26 ret += "&dn=" + url.QueryEscape(m.DisplayName)
28 for _, tr := range m.Trackers {
29 ret += "&tr=" + url.QueryEscape(tr)
34 // ParseMagnetURI parses Magnet-formatted URIs into a Magnet instance
35 func ParseMagnetURI(uri string) (m Magnet, err error) {
36 u, err := url.Parse(uri)
38 err = fmt.Errorf("error parsing uri: %s", err)
41 if u.Scheme != "magnet" {
42 err = fmt.Errorf("unexpected scheme: %q", u.Scheme)
45 xt := u.Query().Get("xt")
46 if !strings.HasPrefix(xt, xtPrefix) {
47 err = fmt.Errorf("bad xt parameter")
50 infoHash := xt[len(xtPrefix):]
52 // BTIH hash can be in HEX or BASE32 encoding
53 // will assign appropriate func judging from symbol length
54 var decode func(dst, src []byte) (int, error)
55 switch len(infoHash) {
59 decode = base32.StdEncoding.Decode
63 err = fmt.Errorf("unhandled xt parameter encoding: encoded length %d", len(infoHash))
66 n, err := decode(m.InfoHash[:], []byte(infoHash))
68 err = fmt.Errorf("error decoding xt: %s", err)
74 m.DisplayName = u.Query().Get("dn")
75 m.Trackers = u.Query()["tr"]