Skip to content

Instantly share code, notes, and snippets.

@steeve
Last active December 24, 2015 23:49
Show Gist options
  • Save steeve/6882818 to your computer and use it in GitHub Desktop.
Save steeve/6882818 to your computer and use it in GitHub Desktop.
void
_wrap_add_torrent_params_name_get(void *swig_v)
{
libtorrent::add_torrent_params *arg1 = (libtorrent::add_torrent_params *) 0 ;
std::string *result = 0 ;
struct swigargs {
libtorrent::add_torrent_params *arg1;
long : 0;
_gostring_ result;
} *swig_a = (struct swigargs *) swig_v;
arg1 = *(libtorrent::add_torrent_params **)&swig_a->arg1;
result = (std::string *) & ((arg1)->name);
swig_a->result = _swig_makegostring((*result).data(), (*result).length());
}
func _swig_wrap_add_torrent_params_name_get(SwigcptrAdd_torrent_params) string
func (arg1 SwigcptrAdd_torrent_params) GetName() string {
return _swig_wrap_add_torrent_params_name_get(arg1)
}
type Add_torrent_params interface {
Swigcptr() uintptr
SwigIsAdd_torrent_params()
...
GetName() string
...
}
func _swig_wrap_add_torrent_params_name_get(SwigcptrAdd_torrent_params) string
func (arg1 SwigcptrAdd_torrent_params) GetName() string {
return _swig_wrap_add_torrent_params_name_get(arg1)
}
type Add_torrent_params interface {
Swigcptr() uintptr
SwigIsAdd_torrent_params()
...
GetName() string
...
}
Raspberry Pi Rev 1.0 with 256mb RAM
root@raspberrypi:~# uname -a
Linux raspberrypi 3.6.11+ #474 PREEMPT Thu Jun 13 17:14:42 BST 2013 armv6l GNU/Linux
root@raspberrypi:~# lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 7.1 (n/a)
Release: 7.1
Codename: n/a
root@raspberrypi:~# free -m
total used free shared buffers cached
Mem: 232 58 173 0 6 33
-/+ buffers/cache: 18 213
Swap: 0 0 0
root@raspberrypi:~# cat /boot/config.txt
gpu_mem=16
runtime: newstack framesize=0x10 argsize=0x8 sp=0x84c7dce4 stack=[0x86580000, 0x86580fcc]
morebuf={pc:0x1cae8c sp:0x84c7dce4 lr:0x0}
sched={pc:0x1cad74 sp:0x84c7dce4 lr:0x1cae8c ctxt:0xf0}
runtime: split stack overflow: 0x84c7dce4 < 0x86580000
fatal error: runtime: split stack overflow
runtime stack:
runtime.throw(0x6af831)
/usr/local/go/src/pkg/runtime/panic.c:464 +0x5c
runtime.newstack()
/usr/local/go/src/pkg/runtime/stack.c:247 +0x1b8
runtime.morestack()
/usr/local/go/src/pkg/runtime/asm_arm.s:212 +0x44
goroutine 1 [stack split]:
_cgo_allocate(0x0, 0x967a1a00)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0x84c7dce4
runtime: unexpected return pc for crosscall2 called from 0x84c7dd00
crosscall2()
/usr/local/go/src/pkg/runtime/cgo/asm_arm.s:23 +0x10 fp=0x84c7dce4
goroutine 3 [syscall]:
runtime.goexit()
/usr/local/go/src/pkg/runtime/proc.c:1389
goroutine 4 [syscall]:
os/signal.loop()
/usr/local/go/src/pkg/os/signal/signal_unix.go:21 +0x24
created by os/signal.init·1
/usr/local/go/src/pkg/os/signal/signal_unix.go:27 +0x48
fatal error: runtime: stack split during syscall
runtime stack:
runtime.throw(0x6b08cc)
/usr/local/go/src/pkg/runtime/panic.c:464 +0x5c
runtime.newstack()
/usr/local/go/src/pkg/runtime/stack.c:261 +0x5bc
runtime.morestack()
/usr/local/go/src/pkg/runtime/asm_arm.s:212 +0x44
goroutine 1 [stack split]:
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
crosscall2()
/usr/local/go/src/pkg/runtime/cgo/asm_arm.s:23 +0x10 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
_cgo_allocate(0xbefe9b68, 0x8)
/usr/local/go/src/pkg/runtime/cgo/callbacks.c:51 fp=0xbefe9b34
goroutine 3 [syscall]:
runtime.goexit()
/usr/local/go/src/pkg/runtime/proc.c:1396
goroutine 4 [syscall]:
os/signal.loop()
/usr/local/go/src/pkg/os/signal/signal_unix.go:21 +0x24
created by os/signal.init·1
/usr/local/go/src/pkg/os/signal/signal_unix.go:27 +0x48
package main
import (
"fmt"
"io"
"net/http"
"time"
"path"
"os"
"os/signal"
"syscall"
"log"
"flag"
"math"
"encoding/json"
"./libtorrent-go"
)
type JSONStruct map[string]interface{}
func (r JSONStruct) String() (s string) {
b, err := json.Marshal(r)
if err != nil {
s = ""
return
}
s = string(b)
return
}
var session libtorrent.Session
var torrentHandle libtorrent.Torrent_handle
var magnetUri string
var bindAddress string
func getOffset(f libtorrent.File_entry) int64 {
var ret int64
f.Get_offset2(&ret)
return ret
}
func getSize(f libtorrent.File_entry) int64 {
var ret int64
f.Get_size2(&ret)
return ret
}
func getPiecesForFile(f libtorrent.File_entry, pieceLength int) (int, int) {
startPiece := int(getOffset(f)) / pieceLength
totalPieces := int(math.Ceil(float64(getSize(f)) / float64(pieceLength)))
return startPiece, startPiece + totalPieces
}
func getMaxPiece(pieces libtorrent.Bitfield, startPiece int, endPiece int) int {
for i := startPiece; i <= endPiece; i++ {
if pieces.Get_bit(i) == false {
return i
}
}
return int(pieces.Size())
}
func getBiggestFile(info libtorrent.Torrent_info) (int, libtorrent.File_entry) {
idx := 0
retFile := info.File_at(0)
for i := 1; i < info.Num_files(); i++ {
if getSize(info.File_at(i)) > getSize(retFile) {
idx = i
retFile = info.File_at(i)
}
}
return idx, retFile
}
func statusHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
if torrentHandle == nil {
fmt.Fprint(w, JSONStruct{"state": -1})
return
}
status := torrentHandle.Status()
maxPiece := 0
totalPieces := 0
if (status.GetHas_metadata()) {
torrentInfo := torrentHandle.Get_torrent_info()
_, servedFile := getBiggestFile(torrentInfo)
startPiece, endPiece := getPiecesForFile(servedFile, torrentInfo.Piece_length())
maxPiece = getMaxPiece(status.GetPieces(), startPiece, endPiece)
totalPieces = endPiece - startPiece
}
fmt.Fprint(w, JSONStruct{
"state": status.GetState(),
"progress": status.GetProgress(),
"download_rate": float32(status.GetDownload_rate()) / 1000,
"upload_rate": float32(status.GetUpload_rate()) / 1000,
"num_peers": status.GetNum_peers(),
"num_seeds": status.GetNum_seeds(),
"max_piece": maxPiece,
"total_pieces": totalPieces,
})
}
func fileStreamHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
return
}
// Make sure we first have metadata
for torrentHandle.Status().GetHas_metadata() == false {
time.Sleep(100 * time.Millisecond)
}
torrentInfo := torrentHandle.Get_torrent_info()
log.Println(torrentInfo)
servedFileIdx, servedFile := getBiggestFile(torrentInfo)
// servedFileIdx, servedFile := findFileEntry(r.URL.Path)
startPiece, endPiece := getPiecesForFile(servedFile, torrentInfo.Piece_length())
torrentHandle.Piece_priority(servedFileIdx, 6)
for i := 0; i < torrentInfo.Num_files(); i++ {
if i == servedFileIdx {
torrentHandle.File_priority(i, 6)
} else {
torrentHandle.File_priority(i, 0)
}
}
fp, _ := os.Open(path.Join(torrentHandle.Save_path(), servedFile.GetPath()))
defer fp.Close()
currentPiece := 0
lastPiece := 0
pieceLength := torrentInfo.Piece_length()
for {
s := torrentHandle.Status()
maxPiece := getMaxPiece(s.GetPieces(), startPiece, endPiece)
for currentPiece = lastPiece; currentPiece < maxPiece; currentPiece++ {
fp.Seek(int64(currentPiece * pieceLength), 0)
_, err := io.CopyN(w, fp, int64(pieceLength))
if err != nil {
log.Printf("Client disconnected from %s\n", r.URL.Path)
return
}
}
if maxPiece == endPiece {
return
}
lastPiece = maxPiece
time.Sleep(10 * time.Millisecond)
}
}
func startServices() {
log.Println("Starting DHT...")
session.Start_dht()
log.Println("Starting LSD...")
session.Start_lsd()
log.Println("Starting UPNP...")
session.Start_upnp()
log.Println("Starting NATPMP...")
session.Start_natpmp()
}
func stopServices() {
log.Println("Stopping DHT...")
session.Stop_dht()
log.Println("Stopping LSD...")
session.Stop_lsd()
log.Println("Stopping UPNP...")
session.Stop_upnp()
log.Println("Stopping NATPMP...")
session.Stop_natpmp()
}
func removeFiles() {
if torrentHandle.Status().GetHas_metadata() == false {
return
}
torrentInfo := torrentHandle.Get_torrent_info()
for i := 0; i < torrentInfo.Num_files(); i++ {
os.RemoveAll(path.Join(torrentHandle.Save_path(), torrentInfo.File_at(i).GetPath()))
}
}
func cleanup() {
stopServices()
log.Println("Removing torrent...")
session.Set_alert_mask(libtorrent.AlertStorage_notification)
// Just in case
defer removeFiles()
session.Remove_torrent(torrentHandle, 1);
log.Println("Waiting for files to be removed...")
// for {
// if session.Wait_for_alert(libtorrent.Seconds(30)).Swigcptr() == 0 {
// return
// }
// if session.Pop_alert2().What() == "cache_flushed_alert" {
// return
// }
// }
}
func parseFlags() {
flag.StringVar(&magnetUri, "magnet", "", "Magnet URI of Torrent")
flag.StringVar(&bindAddress, "bind", ":5001", "Bind address of torrent2http2")
flag.Parse()
if magnetUri == "" {
flag.Usage();
os.Exit(1)
}
}
func main() {
parseFlags()
log.Println("Starting BT engine...")
session = libtorrent.NewSession()
session.Listen_on(libtorrent.NewPair_int_int(6881, 6891))
log.Println("Setting Session settings...")
sessionSettings := session.Settings()
sessionSettings.SetConnection_speed(1000)
sessionSettings.SetRequest_timeout(1)
sessionSettings.SetPeer_connect_timeout(1)
session.Set_settings(sessionSettings)
fmt.Println("1")
startServices()
fmt.Println("2")
torrentParams := libtorrent.Parse_magnet_uri2(magnetUri)
fmt.Println("4")
torrentHandle = session.Add_torrent(torrentParams)
fmt.Println("5")
torrentHandle.Set_sequential_download(true)
fmt.Println("6")
log.Printf("Downloading: %s\n", torrentParams.GetName())
go func() {
for torrentHandle.Status().GetHas_metadata() == false {
time.Sleep(100 * time.Millisecond)
}
torrentInfo := torrentHandle.Get_torrent_info()
servedFileIdx, servedFile := getBiggestFile(torrentInfo)
startPiece, _ := getPiecesForFile(servedFile, torrentInfo.Piece_length())
log.Printf("Setting priority 7 for piece %d\n", startPiece)
torrentHandle.Piece_priority(startPiece, 7)
for i := 0; i < torrentInfo.Num_files(); i++ {
if i == servedFileIdx {
torrentHandle.File_priority(i, 6)
} else {
torrentHandle.File_priority(i, 0)
}
}
}()
log.Println("Registering HTTP endpoints...")
http.HandleFunc("/status", statusHandler)
http.HandleFunc("/file", fileStreamHandler)
// Shutdown procedures
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
// Allow shutdown via HTTP
http.HandleFunc("/shutdown", func (w http.ResponseWriter, r *http.Request) {
c <- os.Interrupt
})
go func(){
<-c
log.Println("Stopping torrent2http...")
cleanup()
log.Println("Bye bye")
os.Exit(0)
}()
log.Printf("Listening HTTP on %s...\n", bindAddress)
http.ListenAndServe(bindAddress, nil)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment