diff --git a/magnet.go b/magnet.go index 848e3de3..4c3e137d 100644 --- a/magnet.go +++ b/magnet.go @@ -16,6 +16,20 @@ type Magnet struct { const xtPrefix = "urn:btih:" +func (m *Magnet) String() (ret string) { + // net.URL likes to assume //, and encodes ':' on us, so we do most of + // this manually. + ret = "magnet:?xt=" + ret += xtPrefix + hex.EncodeToString(m.InfoHash[:]) + if m.DisplayName != "" { + ret += "&dn=" + url.QueryEscape(m.DisplayName) + } + for _, tr := range m.Trackers { + ret += "&tr=" + url.QueryEscape(tr) + } + return +} + func ParseMagnetURI(uri string) (m Magnet, err error) { u, err := url.Parse(uri) if err != nil { diff --git a/magnet_test.go b/magnet_test.go new file mode 100644 index 00000000..49b586ee --- /dev/null +++ b/magnet_test.go @@ -0,0 +1,23 @@ +package torrent + +import ( + "encoding/hex" + "testing" +) + +// Converting from our Magnet type to URL string. +func TestMagnetString(t *testing.T) { + m := Magnet{ + DisplayName: "Shit Movie (1985) 1337p - Eru", + Trackers: []string{ + "http://http.was.great!", + "udp://anti.piracy.honeypot:6969", + }, + } + hex.Decode(m.InfoHash[:], []byte("51340689c960f0778a4387aef9b4b52fd08390cd")) + s := m.String() + const e = `magnet:?xt=urn:btih:51340689c960f0778a4387aef9b4b52fd08390cd&dn=Shit+Movie+%281985%29+1337p+-+Eru&tr=http%3A%2F%2Fhttp.was.great%21&tr=udp%3A%2F%2Fanti.piracy.honeypot%3A6969` + if s != e { + t.Fatalf("\nexpected:\n\t%q\nactual\n\t%q", e, s) + } +}