Merge pull request #414 from chihaya/http-and-https
Add https_addr config, required to run HTTPS
This commit is contained in:
commit
862b452cef
2 changed files with 78 additions and 24 deletions
|
@ -25,9 +25,13 @@ chihaya:
|
||||||
# If you do not wish to run this, delete this section.
|
# If you do not wish to run this, delete this section.
|
||||||
http:
|
http:
|
||||||
# The network interface that will bind to an HTTP server for serving
|
# The network interface that will bind to an HTTP server for serving
|
||||||
# BitTorrent traffic.
|
# BitTorrent traffic. Remove this to disable the non-TLS listener.
|
||||||
addr: "0.0.0.0:6969"
|
addr: "0.0.0.0:6969"
|
||||||
|
|
||||||
|
# The network interface that will bind to an HTTPS server for serving
|
||||||
|
# BitTorrent traffic. If set, tls_cert_path and tls_key_path are required.
|
||||||
|
https_addr: ""
|
||||||
|
|
||||||
# The path to the required files to listen via HTTPS.
|
# The path to the required files to listen via HTTPS.
|
||||||
tls_cert_path: ""
|
tls_cert_path: ""
|
||||||
tls_key_path: ""
|
tls_key_path: ""
|
||||||
|
|
|
@ -5,6 +5,7 @@ package http
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"errors"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
@ -21,6 +22,7 @@ import (
|
||||||
// Frontend.
|
// Frontend.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Addr string `yaml:"addr"`
|
Addr string `yaml:"addr"`
|
||||||
|
HTTPSAddr string `yaml:"https_addr"`
|
||||||
ReadTimeout time.Duration `yaml:"read_timeout"`
|
ReadTimeout time.Duration `yaml:"read_timeout"`
|
||||||
WriteTimeout time.Duration `yaml:"write_timeout"`
|
WriteTimeout time.Duration `yaml:"write_timeout"`
|
||||||
IdleTimeout time.Duration `yaml:"idle_timeout"`
|
IdleTimeout time.Duration `yaml:"idle_timeout"`
|
||||||
|
@ -36,6 +38,7 @@ type Config struct {
|
||||||
func (cfg Config) LogFields() log.Fields {
|
func (cfg Config) LogFields() log.Fields {
|
||||||
return log.Fields{
|
return log.Fields{
|
||||||
"addr": cfg.Addr,
|
"addr": cfg.Addr,
|
||||||
|
"httpsAddr": cfg.HTTPSAddr,
|
||||||
"readTimeout": cfg.ReadTimeout,
|
"readTimeout": cfg.ReadTimeout,
|
||||||
"writeTimeout": cfg.WriteTimeout,
|
"writeTimeout": cfg.WriteTimeout,
|
||||||
"idleTimeout": cfg.IdleTimeout,
|
"idleTimeout": cfg.IdleTimeout,
|
||||||
|
@ -103,6 +106,7 @@ func (cfg Config) Validate() Config {
|
||||||
// Frontend represents the state of an HTTP BitTorrent Frontend.
|
// Frontend represents the state of an HTTP BitTorrent Frontend.
|
||||||
type Frontend struct {
|
type Frontend struct {
|
||||||
srv *http.Server
|
srv *http.Server
|
||||||
|
tlsSrv *http.Server
|
||||||
tlsCfg *tls.Config
|
tlsCfg *tls.Config
|
||||||
|
|
||||||
logic frontend.TrackerLogic
|
logic frontend.TrackerLogic
|
||||||
|
@ -119,6 +123,10 @@ func NewFrontend(logic frontend.TrackerLogic, provided Config) (*Frontend, error
|
||||||
Config: cfg,
|
Config: cfg,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cfg.Addr == "" && cfg.HTTPSAddr == "" {
|
||||||
|
return nil, errors.New("must specify addr or https_addr or both")
|
||||||
|
}
|
||||||
|
|
||||||
// If TLS is enabled, create a key pair.
|
// If TLS is enabled, create a key pair.
|
||||||
if cfg.TLSCertPath != "" && cfg.TLSKeyPath != "" {
|
if cfg.TLSCertPath != "" && cfg.TLSKeyPath != "" {
|
||||||
var err error
|
var err error
|
||||||
|
@ -131,23 +139,54 @@ func NewFrontend(logic frontend.TrackerLogic, provided Config) (*Frontend, error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
if cfg.HTTPSAddr != "" && f.tlsCfg == nil {
|
||||||
if err := f.listenAndServe(); err != nil {
|
return nil, errors.New("must specify tls_cert_path and tls_key_path when using https_addr")
|
||||||
log.Fatal("failed while serving http", log.Err(err))
|
}
|
||||||
}
|
if cfg.HTTPSAddr == "" && f.tlsCfg != nil {
|
||||||
}()
|
return nil, errors.New("must specify https_addr when using tls_cert_path and tls_key_path")
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg.Addr != "" {
|
||||||
|
go func() {
|
||||||
|
if err := f.listenAndServe(); err != nil {
|
||||||
|
log.Fatal("failed while serving http", log.Err(err))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg.HTTPSAddr != "" {
|
||||||
|
go func() {
|
||||||
|
if err := f.listenAndServeTLS(); err != nil {
|
||||||
|
log.Fatal("failed while serving https", log.Err(err))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
return f, nil
|
return f, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop provides a thread-safe way to shutdown a currently running Frontend.
|
// Stop provides a thread-safe way to shutdown a currently running Frontend.
|
||||||
func (f *Frontend) Stop() stop.Result {
|
func (f *Frontend) Stop() stop.Result {
|
||||||
c := make(stop.Channel)
|
stopGroup := stop.NewGroup()
|
||||||
go func() {
|
|
||||||
c.Done(f.srv.Shutdown(context.Background()))
|
|
||||||
}()
|
|
||||||
|
|
||||||
return c.Result()
|
if f.srv != nil {
|
||||||
|
stopGroup.AddFunc(f.makeStopFunc(f.srv))
|
||||||
|
}
|
||||||
|
if f.tlsSrv != nil {
|
||||||
|
stopGroup.AddFunc(f.makeStopFunc(f.tlsSrv))
|
||||||
|
}
|
||||||
|
|
||||||
|
return stopGroup.Stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) makeStopFunc(stopSrv *http.Server) stop.Func {
|
||||||
|
return func() stop.Result {
|
||||||
|
c := make(stop.Channel)
|
||||||
|
go func() {
|
||||||
|
c.Done(stopSrv.Shutdown(context.Background()))
|
||||||
|
}()
|
||||||
|
return c.Result()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Frontend) handler() http.Handler {
|
func (f *Frontend) handler() http.Handler {
|
||||||
|
@ -164,12 +203,11 @@ func (f *Frontend) handler() http.Handler {
|
||||||
return router
|
return router
|
||||||
}
|
}
|
||||||
|
|
||||||
// listenAndServe blocks while listening and serving HTTP BitTorrent requests
|
// listenAndServe blocks while listening and serving non-TLS HTTP BitTorrent
|
||||||
// until Stop() is called or an error is returned.
|
// requests until Stop() is called or an error is returned.
|
||||||
func (f *Frontend) listenAndServe() error {
|
func (f *Frontend) listenAndServe() error {
|
||||||
f.srv = &http.Server{
|
f.srv = &http.Server{
|
||||||
Addr: f.Addr,
|
Addr: f.Addr,
|
||||||
TLSConfig: f.tlsCfg,
|
|
||||||
Handler: f.handler(),
|
Handler: f.handler(),
|
||||||
ReadTimeout: f.ReadTimeout,
|
ReadTimeout: f.ReadTimeout,
|
||||||
WriteTimeout: f.WriteTimeout,
|
WriteTimeout: f.WriteTimeout,
|
||||||
|
@ -179,18 +217,30 @@ func (f *Frontend) listenAndServe() error {
|
||||||
f.srv.SetKeepAlivesEnabled(f.EnableKeepAlive)
|
f.srv.SetKeepAlivesEnabled(f.EnableKeepAlive)
|
||||||
|
|
||||||
// Start the HTTP server.
|
// Start the HTTP server.
|
||||||
if f.tlsCfg != nil {
|
if err := f.srv.ListenAndServe(); err != http.ErrServerClosed {
|
||||||
// ... using TLS.
|
return err
|
||||||
if err := f.srv.ListenAndServeTLS("", ""); err != http.ErrServerClosed {
|
}
|
||||||
return err
|
return nil
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// ... using plain TCP.
|
// listenAndServeTLS blocks while listening and serving TLS HTTP BitTorrent
|
||||||
if err := f.srv.ListenAndServe(); err != http.ErrServerClosed {
|
// requests until Stop() is called or an error is returned.
|
||||||
return err
|
func (f *Frontend) listenAndServeTLS() error {
|
||||||
}
|
f.tlsSrv = &http.Server{
|
||||||
|
Addr: f.HTTPSAddr,
|
||||||
|
TLSConfig: f.tlsCfg,
|
||||||
|
Handler: f.handler(),
|
||||||
|
ReadTimeout: f.ReadTimeout,
|
||||||
|
WriteTimeout: f.WriteTimeout,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Disable KeepAlives.
|
||||||
|
f.tlsSrv.SetKeepAlivesEnabled(f.EnableKeepAlive)
|
||||||
|
|
||||||
|
// Start the HTTP server.
|
||||||
|
if err := f.tlsSrv.ListenAndServeTLS("", ""); err != http.ErrServerClosed {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue