func New(c Config) http.Handler { e := &echoHandler{ config: c, cache: filecache.New(250 * 1000 * 1000), //250Mb stats: echoStats{ Uptime: time.Now(), }, requests: nil, } e.ws = websocket.Handler(e.serveWS) var h http.Handler = e if c.Log { h = requestlog.Wrap(h) } return h }
func (s *Server) Run(version string) error { s.state.Stats.Version = version s.state.Stats.Runtime = strings.TrimPrefix(runtime.Version(), "go") s.state.Stats.Uptime = time.Now() if err := s.init(); err != nil { return err } // TODO if Open { // cross platform open - https://github.com/skratchdot/open-golang // } h := http.Handler(http.HandlerFunc(s.handle)) if s.Log { h = requestlog.Wrap(h) } log.Printf("Listening on %d...", s.Port) return http.ListenAndServe(s.Host+":"+strconv.Itoa(s.Port), h) }
func NewHandler(c Config) (http.Handler, error) { p := &podslingHandler{ files: static.FileSystemHandler(), } if c.DatabaseURL == "" { return nil, fmt.Errorf("Missing Database URL") } else if info, err := pq.ParseURL(c.DatabaseURL); err != nil { return nil, fmt.Errorf("Invalid Database URL: %s", err) } else if db, err := sql.Open("postgres", info); err != nil { return nil, fmt.Errorf("Failed to open Database: %s", err) } else if err := p.initDB(db); err != nil { return nil, fmt.Errorf("Failed to setup Database: %s", err) } h := http.Handler(p) if c.Log { h = requestlog.Wrap(h) } return h, nil }
func (s *Server) Run(version string) error { tls := s.CertPath != "" || s.KeyPath != "" //poor man's XOR if tls && (s.CertPath == "" || s.KeyPath == "") { return fmt.Errorf("You must provide both key and cert paths") } s.state.Stats.Title = s.Title s.state.Stats.Version = version s.state.Stats.Runtime = strings.TrimPrefix(runtime.Version(), "go") s.state.Stats.Uptime = time.Now() //init maps s.state.Users = map[string]*realtime.User{} //will use a the local embed/ dir if it exists, otherwise will use the hardcoded embedded binaries s.files = http.HandlerFunc(s.serveFiles) s.static = ctstatic.FileSystemHandler() s.scraper = &scraper.Handler{Log: false} if err := s.scraper.LoadConfig(defaultSearchConfig); err != nil { log.Fatal(err) } s.state.SearchProviders = s.scraper.Config //share scraper config s.scraperh = http.StripPrefix("/search", s.scraper) s.engine = engine.New() //realtime s.rt = realtime.NewHandler() if err := s.rt.Add("state", &s.state); err != nil { log.Fatalf("State object not syncable: %s", err) } //realtime user events go func() { for user := range s.rt.UserEvents() { if user.Connected { s.state.Users[user.ID] = user } else { delete(s.state.Users, user.ID) } s.state.Update() } }() //configure engine c := engine.Config{ DownloadDirectory: "./downloads", EnableUpload: true, AutoStart: true, } if _, err := os.Stat(s.ConfigPath); err == nil { if b, err := ioutil.ReadFile(s.ConfigPath); err != nil { return fmt.Errorf("Read configuration error: %s", err) } else if len(b) == 0 { //ignore empty file } else if err := json.Unmarshal(b, &c); err != nil { return fmt.Errorf("Malformed configuration: %s", err) } } if c.IncomingPort <= 0 || c.IncomingPort >= 65535 { c.IncomingPort = 50007 } if err := s.reconfigure(c); err != nil { return fmt.Errorf("initial configure failed: %s", err) } //poll torrents and files go func() { for { s.state.Lock() s.state.Torrents = s.engine.GetTorrents() s.state.Downloads = s.listFiles() // log.Printf("torrents #%d files #%d", len(s.state.Torrents), len(s.state.Downloads.Children)) s.state.Unlock() s.state.Update() time.Sleep(1 * time.Second) } }() host := s.Host if host == "" { host = "0.0.0.0" } addr := fmt.Sprintf("%s:%d", host, s.Port) proto := "http" if tls { proto += "s" } log.Printf("Listening at %s://%s", proto, addr) if s.Open { openhost := host if openhost == "0.0.0.0" { openhost = "localhost" } go func() { time.Sleep(1 * time.Second) open.Run(fmt.Sprintf("%s://%s:%d", proto, openhost, s.Port)) }() } h := http.Handler(http.HandlerFunc(s.handle)) if s.Log { h = requestlog.Wrap(h) } if tls { return http.ListenAndServeTLS(addr, s.CertPath, s.KeyPath, h) } else { return http.ListenAndServe(addr, h) } }