Skip to content

Instantly share code, notes, and snippets.

@wthorp
Created April 3, 2022 22:47
Show Gist options
  • Save wthorp/c82c970edd9147196297969b139bc214 to your computer and use it in GitHub Desktop.
Save wthorp/c82c970edd9147196297969b139bc214 to your computer and use it in GitHub Desktop.
Turn any HTTP file into a torrent
package main
import (
"crypto/sha1"
"fmt"
"io"
"net/http"
"os"
"strings"
"github.com/marksamman/bencode"
)
const file = "http://link.us1.storjshare.io/s/jwqpp4kdw2nhm4ep2lkrxmmhw6oa/billtest/bunny.mp4?download=1"
const pieceLength = 2621440
func main() {
size, hashes, err := GenerateHashes(file)
if err != nil {
fmt.Printf("error: %+v", err)
return
}
fmt.Printf("%d %d %f\n", size, len(hashes)/40, float64(size)/float64(pieceLength))
dict := make(map[string]interface{})
dict["announce"] = "udp://tracker.torrent.eu.org:451"
dict["comment"] = "Testing torrents"
dict["creation date"] = 1391870037
// This is how the original spec HTTP seeding would work (see http://www.bittorrent.org/beps/bep_0019.html)
// dict["httpseeds"] = []interface{}{file}
// This is "get-right" style HTTP seeding. Most clients lack HTTPS support. (https://www.getright.com/seedtorrent.html)
dict["url-list"] = []interface{}{file}
infoDict := make(map[string]interface{})
infoDict["length"] = size
infoDict["name"] = "bunny.mp4"
infoDict["piece length"] = pieceLength
infoDict["pieces"] = hashes
dict["info"] = infoDict
os.WriteFile("file.torrent", bencode.Encode(dict), 0644)
}
func GenerateHashes(url string) (int, string, error) {
size := 0
var sb strings.Builder
resp, err := http.Get(url)
if err != nil {
return 0, "", err
}
defer resp.Body.Close()
for {
buf := make([]byte, pieceLength)
n := 0
for n < pieceLength && err == nil {
var nn int
nn, err = resp.Body.Read(buf[n:])
n += nn
}
if n > 0 {
size += n
h := sha1.New()
h.Write(buf[:n])
sb.WriteString(string(h.Sum(nil)))
}
if err != nil {
if err == io.EOF {
err = nil
}
break
}
}
return size, sb.String(), err
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment