Skip to content

Commit 3d0364d

Browse files
committed
allow accessing data by paths
1 parent 95280b3 commit 3d0364d

File tree

4 files changed

+42
-17
lines changed

4 files changed

+42
-17
lines changed

README.md

+11-7
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,17 @@ Routes
5656

5757
There are several routes to interact with torrents:
5858

59-
- `GET /data?ih=<infohash in hex>&path=<display path of file declared in torrent info>&filename=<file name of the data, optional>`. Note that this handler supports HTTP range requests for bytes. Response will block until the data is available.
60-
- `GET /status`. This fetches the textual status info page per anacrolix/torrent.Client.WriteStatus. Very useful for debugging.
61-
- `GET /info?ih=<infohash in hex>`. This returns the info bytes for the matching torrent. It's useful if the caller needs to know about the torrent, such as what files it contains. It will block until the info is available. The response is the full bencoded info dictionary per [BEP 3](http://www.bittorrent.org/beps/bep_0003.html).
62-
- `/events?ih=<infohash in hex>`. This is a websocket that emits frames with [confluence.Event] encoded as JSON for the torrent. The PieceChanged field for instance is set if the given piece changed [state](https://godoc.org/github.com/anacrolix/torrent#PieceState) within the torrent.
63-
- `GET /fileState?ih=<infohash in hex>&path=<display path of file declared in torrent info>`. Returns [file state](https://godoc.org/github.com/anacrolix/torrent#File.State) encoded as JSON.
64-
- `POST /metainfo?ih=<infohash in hex>`. The request body is a bencoded metainfo, as typically appears in a `.torrent` file. The trackers and info bytes are applied to the torrent matching the info hash provided in the query. No fields in the metainfo are mandatory.
65-
- `GET /metainfo?ih=<infohash in hex>`. returns a .torrent file containing the hash info.
59+
- `GET /data/infohash/<infohash in hex>/<display path of file declared in torrent info>`
60+
61+
`GET /data/magnet/<URI-encoded magnet link>/<display path of file declared in torrent info>`
62+
63+
`GET /data?ih=<infohash in hex>&path=<display path of file declared in torrent info>&filename=<file name of the data, optional>`. Note that this handler supports HTTP range requests for bytes. Response will block until the data is available.
64+
- `GET /status`. This fetches the textual status info page per anacrolix/torrent.Client.WriteStatus. Very useful for debugging.
65+
- `GET /info?ih=<infohash in hex>`. This returns the info bytes for the matching torrent. It's useful if the caller needs to know about the torrent, such as what files it contains. It will block until the info is available. The response is the full bencoded info dictionary per [BEP 3](http://www.bittorrent.org/beps/bep_0003.html).
66+
- `/events?ih=<infohash in hex>`. This is a websocket that emits frames with [confluence.Event] encoded as JSON for the torrent. The PieceChanged field for instance is set if the given piece changed [state](https://godoc.org/github.com/anacrolix/torrent#PieceState) within the torrent.
67+
- `GET /fileState?ih=<infohash in hex>&path=<display path of file declared in torrent info>`. Returns [file state](https://godoc.org/github.com/anacrolix/torrent#File.State) encoded as JSON.
68+
- `POST /metainfo?ih=<infohash in hex>`. The request body is a bencoded metainfo, as typically appears in a `.torrent` file. The trackers and info bytes are applied to the torrent matching the info hash provided in the query. No fields in the metainfo are mandatory.
69+
- `GET /metainfo?ih=<infohash in hex>`. returns a .torrent file containing the hash info.
6670

6771
Wherever a `?ih=<infohash>` query parameter is expected, it can also be substituted by a `?magnet=<magnet URI>` parameter instead.
6872

confluence/handlers.go

+11-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"path"
1010
"strconv"
1111
"sync"
12+
"strings"
1213

1314
"github.com/anacrolix/dht/v2/bep44"
1415
"github.com/anacrolix/dht/v2/exts/getput"
@@ -26,15 +27,22 @@ func dataHandler(w http.ResponseWriter, r *request) {
2627
"Content-Disposition", "filename="+strconv.Quote(q.Get("filename")),
2728
)
2829
}
29-
if len(q["path"]) == 0 {
30+
filepath := q.Get("path")
31+
if filepath == "" {
32+
parts := strings.SplitN(r.URL.Path, "/", 5)
33+
if len(parts) == 5 {
34+
filepath = parts[4]
35+
}
36+
}
37+
if filepath == "" {
3038
ServeTorrent(w, r.Request, t)
3139
} else {
3240
if !q.Has("filename") {
3341
w.Header().Set(
34-
"Content-Disposition", "filename="+strconv.Quote(path.Base(q.Get("path"))),
42+
"Content-Disposition", "filename="+strconv.Quote(path.Base(filepath)),
3543
)
3644
}
37-
ServeFile(w, r.Request, t, q.Get("path"))
45+
ServeFile(w, r.Request, t, filepath)
3846
}
3947
}
4048

confluence/middlewares.go

+15-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import (
1111
"path"
1212
"path/filepath"
1313
"time"
14+
"strings"
15+
"net/url"
1416

1517
"github.com/anacrolix/squirrel"
1618
"github.com/anacrolix/torrent"
@@ -50,6 +52,13 @@ func (me *Handler) withTorrentContext(h func(w http.ResponseWriter, r *request))
5052
ih, err, afterAdd := func() (ih metainfo.Hash, err error, afterAdd func(t *torrent.Torrent)) {
5153
q := r.URL.Query()
5254
ms := q.Get("magnet")
55+
parts := strings.SplitN(r.URL.Path, "/", 5)
56+
// /<handler>/magnet|infohash/<magnet or infohash>/...
57+
//[0] [1] [2] [3] [4]
58+
if ms == "" && len(parts) >= 4 && parts[2] == "magnet" {
59+
ms, err = url.PathUnescape(parts[3])
60+
}
61+
5362
if ms != "" {
5463
m, err := metainfo.ParseMagnetUri(ms)
5564
if err != nil {
@@ -61,8 +70,12 @@ func (me *Handler) withTorrentContext(h func(w http.ResponseWriter, r *request))
6170
t.AddTrackers(ts)
6271
}
6372
}
64-
if ihqv := q.Get(infohashQueryKey); ihqv != "" {
65-
err = ih.FromHexString(q.Get(infohashQueryKey))
73+
ihhex := q.Get(infohashQueryKey)
74+
if ihhex == "" && len(parts) >= 4 && parts[2] == "infohash" {
75+
ihhex = parts[3]
76+
}
77+
if ihhex != "" {
78+
err = ih.FromHexString(ihhex)
6679
return
6780
}
6881
err = fmt.Errorf("expected nonempty query parameter %q or %q", magnetQueryKey, infohashQueryKey)

confluence/mux.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,17 @@ import (
99
func (h *Handler) initMux() {
1010
h.initMuxOnce.Do(func() {
1111
mux := &h.mux
12-
mux.Handle("/data", h.withTorrentContext(dataHandler))
12+
mux.Handle("/data/", h.withTorrentContext(dataHandler))
1313
mux.HandleFunc("/status", h.statusHandler)
14-
mux.Handle("/info", h.withTorrentContext(infoHandler))
15-
mux.Handle("/events", h.withTorrentContext(eventHandler))
16-
mux.Handle("/fileState", h.withTorrentContext(func(w http.ResponseWriter, r *request) {
14+
mux.Handle("/info/", h.withTorrentContext(infoHandler))
15+
mux.Handle("/events/", h.withTorrentContext(eventHandler))
16+
mux.Handle("/fileState/", h.withTorrentContext(func(w http.ResponseWriter, r *request) {
1717
httptoo.GzipHandler(http.HandlerFunc(func(w http.ResponseWriter, hr *http.Request) {
1818
r.Request = hr
1919
fileStateHandler(w, r)
2020
})).ServeHTTP(w, r.Request)
2121
}))
22-
mux.Handle("/metainfo", h.withTorrentContext(h.metainfoHandler))
22+
mux.Handle("/metainfo/", h.withTorrentContext(h.metainfoHandler))
2323
mux.HandleFunc("/bep44", h.handleBep44)
2424
})
2525
}

0 commit comments

Comments
 (0)