func main() { flag.Usage = usage flag.Parse() if *createTorrent != "" { err := torrent.WriteMetaInfoBytes(*createTorrent, os.Stdout) if err != nil { log.Fatal("Could not create torrent file:", err) } return } if *createTracker != "" { err := startTracker(*createTracker, flag.Args()) if err != nil { log.Fatal("Tracker returned error:", err) } return } args := flag.Args() narg := flag.NArg() if narg != 1 { if narg < 1 { log.Println("Too few arguments. Torrent file or torrent URL required.") } else { log.Printf("Too many arguments. (Expected 1): %v", args) } usage() } torrentFlags := parseTorrentFlags() if *cpuprofile != "" { cpuf, err := os.Create(*cpuprofile) if err != nil { log.Fatal(err) } pprof.StartCPUProfile(cpuf) defer pprof.StopCPUProfile() } if *memprofile != "" { defer func(file string) { memf, err := os.Create(file) if err != nil { log.Fatal(err) } pprof.WriteHeapProfile(memf) }(*memprofile) } log.Println("Starting.") err := torrent.RunTorrents(torrentFlags, args) if err != nil { log.Fatal("Could not run torrents", args, err) } }
func testHelperProcessImp(args []string) (err error) { for len(args) > 0 { if args[0] == "--" { args = args[1:] break } args = args[1:] } if len(args) == 0 { err = fmt.Errorf("No commands\n") return } cmd, args := args[0], args[1:] switch cmd { case "tracker": if len(args) < 2 { err = fmt.Errorf("tracker expected 2 or more args\n") return } addr, torrentFiles := args[0], args[1:] err = StartTracker(addr, torrentFiles) if err != nil { return } case "client": if len(args) < 4 { err = fmt.Errorf("client expected 4 or more args\n") return } portStr, fileDir, seedRatioStr, torrentFiles := args[0], args[1], args[2], args[3:] var port uint64 port, err = strconv.ParseUint(portStr, 10, 16) if err != nil { return } var seedRatio float64 seedRatio, err = strconv.ParseFloat(seedRatioStr, 64) torrentFlags := torrent.TorrentFlags{ Port: int(port), FileDir: fileDir, SeedRatio: seedRatio, } err = torrent.RunTorrents(&torrentFlags, torrentFiles) if err != nil { return } default: err = fmt.Errorf("Unknown command %q\n", cmd) return } return }
func main() { tracker := flag.String("tracker", "", "tracker url: http://host:port/") listen := flag.String("listen", "0.0.0.0:8888", "bind location") root := flag.String("root", "", "root dir to keep working files") flag.Parse() if *tracker == "" || *root == "" { flag.PrintDefaults() return } tu, err := url.Parse(*tracker) if err != nil { log.Fatal(err) } mux := http.NewServeMux() mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { u := *req.URL u.Host = strings.TrimPrefix(req.Host, "p2p-") if req.TLS != nil { u.Scheme = "https" } else { u.Scheme = "http" } log.Println("got request:", req.Method, u.String()) if req.Method == "PUT" || !strings.HasPrefix(u.Path, "/v1/images/") || !strings.HasSuffix(u.Path, "/layer") { pu := u pu.Path = "/" proxy := httputil.NewSingleHostReverseProxy(&pu) proxy.ServeHTTP(w, req) return } tu := *tu q := tu.Query() q.Set("url", u.String()) log.Println(tu.String() + "?" + q.Encode()) resp, err := http.Get(tu.String() + "?" + q.Encode()) if err != nil { http.Error(w, "getting torrent failed", http.StatusInternalServerError) return } defer resp.Body.Close() f, err := ioutil.TempFile(*root, "image-torrent-") if err != nil { http.Error(w, "torrent file creation failed", http.StatusInternalServerError) return } defer func() { f.Close() os.Remove(f.Name()) }() _, err = io.Copy(f, resp.Body) if err != nil { http.Error(w, "reading torrent contents failed", http.StatusInternalServerError) return } m, err := torrent.GetMetaInfo(nil, f.Name()) if err != nil { http.Error(w, "reading torrent failed", http.StatusInternalServerError) return } err = torrent.RunTorrents(&torrent.TorrentFlags{ FileDir: *root, SeedRatio: 0, }, []string{f.Name()}) lf := path.Join(*root, m.Info.Name) defer os.Remove(lf) // TODO: start another RunTorrents for configured interval // TODO: and remove data after that // TODO: or to hell with it if err != nil { http.Error(w, "downloading torrent failed", http.StatusInternalServerError) return } l, err := os.Open(lf) if err != nil { http.Error(w, "layer file open failed", http.StatusInternalServerError) return } defer l.Close() io.Copy(w, l) }) err = http.ListenAndServe(*listen, mux) if err != nil { log.Fatal(err) } }
func main() { flag.Usage = usage flag.Parse() if *createTorrent != "" { err := torrent.WriteMetaInfoBytes(*createTorrent, *createTracker, os.Stdout) if err != nil { log.Fatal("Could not create torrent file:", err) } return } if *createTracker != "" { err := startTracker(*createTracker, flag.Args()) if err != nil { log.Fatal("Tracker returned error:", err) } return } args := flag.Args() narg := flag.NArg() if narg < 1 { log.Println("Too few arguments. Torrent file or torrent URL required.") usage() } torrentFlags, err := parseTorrentFlags() if err != nil { log.Fatal("Could not parse flags:", err) } if *cpuprofile != "" { cpuf, err := os.Create(*cpuprofile) if err != nil { log.Fatal(err) } pprof.StartCPUProfile(cpuf) defer pprof.StopCPUProfile() } if *memprofile != "" { defer func(file string) { memf, err := os.Create(file) if err != nil { log.Fatal(err) } pprof.WriteHeapProfile(memf) }(*memprofile) } if (*memoryPerTorrent) >= 0 { //User is worried about memory use. debug.SetGCPercent(20) //Set the GC to clear memory more often. } log.Println("Starting.") err = torrent.RunTorrents(torrentFlags, args) if err != nil { log.Fatal("Could not run torrents", args, err) } }
func main() { tracker := flag.String("tracker", "", "tracker url: http://host:port/") listen := flag.String("listen", "0.0.0.0:8888", "bind location") root := flag.String("root", "", "root dir to keep working files") flag.Parse() if *tracker == "" || *root == "" { flag.PrintDefaults() return } tu, err := url.Parse(*tracker) if err != nil { log.Fatal(err) } mux := http.NewServeMux() mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { u := *req.URL u.Host = strings.TrimPrefix(req.Host, "p2p-") if req.TLS != nil { u.Scheme = "https" } else { u.Scheme = "http" } log.Println("got request:", req.Method, u.String()) // should be support V2 registry api if req.Method == "PUT" || strings.HasPrefix(u.Path, "/v2/") || strings.Contains(u.Path, "ping") { pu := u pu.Path = "/" proxy := httputil.NewSingleHostReverseProxy(&pu) proxy.ServeHTTP(w, req) return } tu := *tu q := tu.Query() q.Set("url", u.String()) log.Println(tu.String() + "?" + q.Encode()) resp, err := http.Get(tu.String() + "?" + q.Encode()) if err != nil { http.Error(w, "getting torrent failed", http.StatusInternalServerError) return } defer resp.Body.Close() f, err := ioutil.TempFile(*root, "image-torrent-") if err != nil { http.Error(w, "torrent file creation failed", http.StatusInternalServerError) return } defer func() { f.Close() os.Remove(f.Name()) }() _, err = io.Copy(f, resp.Body) if err != nil { http.Error(w, "reading torrent contents failed", http.StatusInternalServerError) return } m, err := torrent.GetMetaInfo(nil, f.Name()) if err != nil { http.Error(w, "reading torrent failed", http.StatusInternalServerError) return } log.Printf("============> get metainfo %p", m) err = torrent.RunTorrents(&torrent.TorrentFlags{ FileDir: *root, SeedRatio: math.Inf(0), FileSystemProvider: torrent.OsFsProvider{}, InitialCheck: true, MaxActive: 1, ExecOnSeeding: "", Cacher: torrent.NewRamCacheProvider(1), }, []string{f.Name()}) lf := path.Join(*root, m.Info.Name) log.Println("==============>ls path:", lf) defer os.Remove(lf) // TODO: start another RunTorrents for configured interval // TODO: and remove data after that // TODO: or to hell with it if err != nil { http.Error(w, "downloading torrent failed", http.StatusInternalServerError) return } l, err := os.Open(lf) if err != nil { http.Error(w, "layer file open failed", http.StatusInternalServerError) return } defer l.Close() io.Copy(w, l) }) cert := "cert.pem" key := "key.pem" err = http.ListenAndServeTLS(*listen, cert, key, mux) if err != nil { log.Fatal("ListenAndServe: ", err) } }