Pass in config struct
This commit is contained in:
parent
8f1105bc59
commit
71f79fd84e
|
@ -5,10 +5,9 @@ import (
|
|||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/khlieng/dispatch/assets"
|
||||
"github.com/khlieng/dispatch/config"
|
||||
"github.com/khlieng/dispatch/server"
|
||||
"github.com/khlieng/dispatch/storage"
|
||||
"github.com/khlieng/dispatch/storage/bleve"
|
||||
|
@ -36,34 +35,18 @@ var rootCmd = &cobra.Command{
|
|||
Use: "dispatch",
|
||||
Short: "Web-based IRC client in Go.",
|
||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
if v, _ := cmd.Flags().GetBool("version"); v {
|
||||
if viper.GetBool("version") {
|
||||
printVersion()
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
if cmd.Use == "dispatch" {
|
||||
if cmd == cmd.Root() {
|
||||
fmt.Printf(logo, version.Tag, version.Commit, version.Date)
|
||||
}
|
||||
|
||||
storage.Initialize(viper.GetString("dir"))
|
||||
|
||||
initConfig(storage.Path.Config(), viper.GetBool("reset_config"))
|
||||
|
||||
viper.SetConfigName("config")
|
||||
viper.AddConfigPath(storage.Path.Root())
|
||||
viper.ReadInConfig()
|
||||
|
||||
viper.WatchConfig()
|
||||
|
||||
prev := time.Now()
|
||||
viper.OnConfigChange(func(e fsnotify.Event) {
|
||||
now := time.Now()
|
||||
// fsnotify sometimes fires twice
|
||||
if now.Sub(prev) > time.Second {
|
||||
log.Println("New config loaded")
|
||||
prev = now
|
||||
}
|
||||
})
|
||||
initConfig(storage.Path.Config(), viper.GetBool("reset-config"))
|
||||
},
|
||||
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
@ -78,19 +61,28 @@ var rootCmd = &cobra.Command{
|
|||
}
|
||||
defer db.Close()
|
||||
|
||||
srv := server.Dispatch{
|
||||
Store: db,
|
||||
SessionStore: db,
|
||||
cfg, cfgUpdated := config.LoadConfig()
|
||||
dispatch := server.New(cfg)
|
||||
|
||||
GetMessageStore: func(user *storage.User) (storage.MessageStore, error) {
|
||||
return boltdb.New(storage.Path.Log(user.Username))
|
||||
},
|
||||
GetMessageSearchProvider: func(user *storage.User) (storage.MessageSearchProvider, error) {
|
||||
return bleve.New(storage.Path.Index(user.Username))
|
||||
},
|
||||
go func() {
|
||||
for {
|
||||
dispatch.SetConfig(<-cfgUpdated)
|
||||
log.Println("New config loaded")
|
||||
}
|
||||
}()
|
||||
|
||||
dispatch.Store = db
|
||||
dispatch.SessionStore = db
|
||||
|
||||
dispatch.GetMessageStore = func(user *storage.User) (storage.MessageStore, error) {
|
||||
return boltdb.New(storage.Path.Log(user.Username))
|
||||
}
|
||||
|
||||
srv.Run()
|
||||
dispatch.GetMessageSearchProvider = func(user *storage.User) (storage.MessageSearchProvider, error) {
|
||||
return bleve.New(storage.Path.Index(user.Username))
|
||||
}
|
||||
|
||||
dispatch.Run()
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -110,14 +102,11 @@ func init() {
|
|||
rootCmd.Flags().Bool("dev", false, "development mode")
|
||||
rootCmd.Flags().BoolP("version", "v", false, "show version")
|
||||
|
||||
viper.BindPFlag("dir", rootCmd.PersistentFlags().Lookup("dir"))
|
||||
viper.BindPFlag("reset_config", rootCmd.PersistentFlags().Lookup("reset-config"))
|
||||
viper.BindPFlag("address", rootCmd.Flags().Lookup("address"))
|
||||
viper.BindPFlag("port", rootCmd.Flags().Lookup("port"))
|
||||
viper.BindPFlag("dev", rootCmd.Flags().Lookup("dev"))
|
||||
viper.BindPFlags(rootCmd.PersistentFlags())
|
||||
viper.BindPFlags(rootCmd.Flags())
|
||||
|
||||
viper.SetDefault("hexIP", false)
|
||||
viper.SetDefault("verify_client_certificates", true)
|
||||
viper.SetDefault("verify_certificates", true)
|
||||
}
|
||||
|
||||
func initConfig(configPath string, overwrite bool) {
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/khlieng/dispatch/storage"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Address string
|
||||
Port string
|
||||
Dev bool
|
||||
HexIP bool
|
||||
VerifyCertificates bool `mapstructure:"verify_certificates"`
|
||||
Defaults *Defaults
|
||||
HTTPS *HTTPS
|
||||
LetsEncrypt *LetsEncrypt
|
||||
}
|
||||
|
||||
type Defaults struct {
|
||||
Name string
|
||||
Host string
|
||||
Port int
|
||||
Channels []string
|
||||
Password string
|
||||
SSL bool
|
||||
ReadOnly bool
|
||||
ShowDetails bool `mapstructure:"show_details"`
|
||||
}
|
||||
|
||||
type HTTPS struct {
|
||||
Enabled bool
|
||||
Port string
|
||||
Redirect bool
|
||||
Cert string
|
||||
Key string
|
||||
HSTS *HSTS
|
||||
}
|
||||
|
||||
type HSTS struct {
|
||||
Enabled bool
|
||||
MaxAge string `mapstructure:"max_age"`
|
||||
IncludeSubdomains bool `mapstructure:"include_subdomains"`
|
||||
Preload bool
|
||||
}
|
||||
|
||||
type LetsEncrypt struct {
|
||||
Domain string
|
||||
Email string
|
||||
Port string
|
||||
Proxy bool
|
||||
}
|
||||
|
||||
func LoadConfig() (*Config, chan *Config) {
|
||||
viper.SetConfigName("config")
|
||||
viper.AddConfigPath(storage.Path.Root())
|
||||
viper.ReadInConfig()
|
||||
|
||||
config := &Config{}
|
||||
viper.Unmarshal(config)
|
||||
|
||||
viper.WatchConfig()
|
||||
|
||||
configCh := make(chan *Config, 1)
|
||||
|
||||
prev := time.Now()
|
||||
viper.OnConfigChange(func(e fsnotify.Event) {
|
||||
now := time.Now()
|
||||
// fsnotify sometimes fires twice
|
||||
if now.Sub(prev) > time.Second {
|
||||
config := &Config{}
|
||||
err := viper.Unmarshal(config)
|
||||
if err == nil {
|
||||
configCh <- config
|
||||
}
|
||||
|
||||
prev = now
|
||||
}
|
||||
})
|
||||
|
||||
return config, configCh
|
||||
}
|
|
@ -5,9 +5,9 @@ import (
|
|||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/khlieng/dispatch/config"
|
||||
"github.com/khlieng/dispatch/storage"
|
||||
"github.com/khlieng/dispatch/version"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
type connectDefaults struct {
|
||||
|
@ -28,7 +28,7 @@ type dispatchVersion struct {
|
|||
}
|
||||
|
||||
type indexData struct {
|
||||
Defaults connectDefaults
|
||||
Defaults *config.Defaults
|
||||
Servers []Server
|
||||
Channels []*storage.Channel
|
||||
HexIP bool
|
||||
|
@ -43,9 +43,12 @@ type indexData struct {
|
|||
Messages *Messages
|
||||
}
|
||||
|
||||
func getIndexData(r *http.Request, path string, state *State) *indexData {
|
||||
func (d *Dispatch) getIndexData(r *http.Request, path string, state *State) *indexData {
|
||||
cfg := d.Config()
|
||||
|
||||
data := indexData{
|
||||
HexIP: viper.GetBool("hexIP"),
|
||||
Defaults: cfg.Defaults,
|
||||
HexIP: cfg.HexIP,
|
||||
Version: dispatchVersion{
|
||||
Tag: version.Tag,
|
||||
Commit: version.Commit,
|
||||
|
@ -53,15 +56,8 @@ func getIndexData(r *http.Request, path string, state *State) *indexData {
|
|||
},
|
||||
}
|
||||
|
||||
data.Defaults = connectDefaults{
|
||||
Name: viper.GetString("defaults.name"),
|
||||
Host: viper.GetString("defaults.host"),
|
||||
Port: viper.GetInt("defaults.port"),
|
||||
Channels: viper.GetStringSlice("defaults.channels"),
|
||||
Password: viper.GetString("defaults.password") != "",
|
||||
SSL: viper.GetBool("defaults.ssl"),
|
||||
ReadOnly: viper.GetBool("defaults.readonly"),
|
||||
ShowDetails: viper.GetBool("defaults.show_details"),
|
||||
if data.Defaults.Password != "" {
|
||||
data.Defaults.Password = "******"
|
||||
}
|
||||
|
||||
if state == nil {
|
||||
|
|
|
@ -4,6 +4,7 @@ package server
|
|||
|
||||
import (
|
||||
json "encoding/json"
|
||||
config "github.com/khlieng/dispatch/config"
|
||||
storage "github.com/khlieng/dispatch/storage"
|
||||
easyjson "github.com/mailru/easyjson"
|
||||
jlexer "github.com/mailru/easyjson/jlexer"
|
||||
|
@ -38,8 +39,14 @@ func easyjson7e607aefDecodeGithubComKhliengDispatchServer(in *jlexer.Lexer, out
|
|||
}
|
||||
switch key {
|
||||
case "defaults":
|
||||
if data := in.Raw(); in.Ok() {
|
||||
in.AddError((out.Defaults).UnmarshalJSON(data))
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
out.Defaults = nil
|
||||
} else {
|
||||
if out.Defaults == nil {
|
||||
out.Defaults = new(config.Defaults)
|
||||
}
|
||||
easyjson7e607aefDecodeGithubComKhliengDispatchConfig(in, &*out.Defaults)
|
||||
}
|
||||
case "servers":
|
||||
if in.IsNull() {
|
||||
|
@ -153,7 +160,7 @@ func easyjson7e607aefEncodeGithubComKhliengDispatchServer(out *jwriter.Writer, i
|
|||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
if true {
|
||||
if in.Defaults != nil {
|
||||
const prefix string = ",\"defaults\":"
|
||||
if first {
|
||||
first = false
|
||||
|
@ -161,7 +168,7 @@ func easyjson7e607aefEncodeGithubComKhliengDispatchServer(out *jwriter.Writer, i
|
|||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.Raw((in.Defaults).MarshalJSON())
|
||||
easyjson7e607aefEncodeGithubComKhliengDispatchConfig(out, *in.Defaults)
|
||||
}
|
||||
if len(in.Servers) != 0 {
|
||||
const prefix string = ",\"servers\":"
|
||||
|
@ -352,6 +359,167 @@ func easyjson7e607aefEncodeGithubComKhliengDispatchStorage(out *jwriter.Writer,
|
|||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
func easyjson7e607aefDecodeGithubComKhliengDispatchConfig(in *jlexer.Lexer, out *config.Defaults) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
in.Skip()
|
||||
return
|
||||
}
|
||||
in.Delim('{')
|
||||
for !in.IsDelim('}') {
|
||||
key := in.UnsafeString()
|
||||
in.WantColon()
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
in.WantComma()
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "name":
|
||||
out.Name = string(in.String())
|
||||
case "host":
|
||||
out.Host = string(in.String())
|
||||
case "port":
|
||||
out.Port = int(in.Int())
|
||||
case "channels":
|
||||
if in.IsNull() {
|
||||
in.Skip()
|
||||
out.Channels = nil
|
||||
} else {
|
||||
in.Delim('[')
|
||||
if out.Channels == nil {
|
||||
if !in.IsDelim(']') {
|
||||
out.Channels = make([]string, 0, 4)
|
||||
} else {
|
||||
out.Channels = []string{}
|
||||
}
|
||||
} else {
|
||||
out.Channels = (out.Channels)[:0]
|
||||
}
|
||||
for !in.IsDelim(']') {
|
||||
var v7 string
|
||||
v7 = string(in.String())
|
||||
out.Channels = append(out.Channels, v7)
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim(']')
|
||||
}
|
||||
case "password":
|
||||
out.Password = string(in.String())
|
||||
case "ssl":
|
||||
out.SSL = bool(in.Bool())
|
||||
case "readOnly":
|
||||
out.ReadOnly = bool(in.Bool())
|
||||
case "showDetails":
|
||||
out.ShowDetails = bool(in.Bool())
|
||||
default:
|
||||
in.SkipRecursive()
|
||||
}
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim('}')
|
||||
if isTopLevel {
|
||||
in.Consumed()
|
||||
}
|
||||
}
|
||||
func easyjson7e607aefEncodeGithubComKhliengDispatchConfig(out *jwriter.Writer, in config.Defaults) {
|
||||
out.RawByte('{')
|
||||
first := true
|
||||
_ = first
|
||||
if in.Name != "" {
|
||||
const prefix string = ",\"name\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.String(string(in.Name))
|
||||
}
|
||||
if in.Host != "" {
|
||||
const prefix string = ",\"host\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.String(string(in.Host))
|
||||
}
|
||||
if in.Port != 0 {
|
||||
const prefix string = ",\"port\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.Int(int(in.Port))
|
||||
}
|
||||
if len(in.Channels) != 0 {
|
||||
const prefix string = ",\"channels\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
{
|
||||
out.RawByte('[')
|
||||
for v8, v9 := range in.Channels {
|
||||
if v8 > 0 {
|
||||
out.RawByte(',')
|
||||
}
|
||||
out.String(string(v9))
|
||||
}
|
||||
out.RawByte(']')
|
||||
}
|
||||
}
|
||||
if in.Password != "" {
|
||||
const prefix string = ",\"password\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.String(string(in.Password))
|
||||
}
|
||||
if in.SSL {
|
||||
const prefix string = ",\"ssl\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.Bool(bool(in.SSL))
|
||||
}
|
||||
if in.ReadOnly {
|
||||
const prefix string = ",\"readOnly\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.Bool(bool(in.ReadOnly))
|
||||
}
|
||||
if in.ShowDetails {
|
||||
const prefix string = ",\"showDetails\":"
|
||||
if first {
|
||||
first = false
|
||||
out.RawString(prefix[1:])
|
||||
} else {
|
||||
out.RawString(prefix)
|
||||
}
|
||||
out.Bool(bool(in.ShowDetails))
|
||||
}
|
||||
out.RawByte('}')
|
||||
}
|
||||
func easyjson7e607aefDecodeGithubComKhliengDispatchServer1(in *jlexer.Lexer, out *dispatchVersion) {
|
||||
isTopLevel := in.IsStart()
|
||||
if in.IsNull() {
|
||||
|
@ -488,9 +656,9 @@ func easyjson7e607aefDecodeGithubComKhliengDispatchServer2(in *jlexer.Lexer, out
|
|||
out.Channels = (out.Channels)[:0]
|
||||
}
|
||||
for !in.IsDelim(']') {
|
||||
var v7 string
|
||||
v7 = string(in.String())
|
||||
out.Channels = append(out.Channels, v7)
|
||||
var v10 string
|
||||
v10 = string(in.String())
|
||||
out.Channels = append(out.Channels, v10)
|
||||
in.WantComma()
|
||||
}
|
||||
in.Delim(']')
|
||||
|
@ -557,11 +725,11 @@ func easyjson7e607aefEncodeGithubComKhliengDispatchServer2(out *jwriter.Writer,
|
|||
}
|
||||
{
|
||||
out.RawByte('[')
|
||||
for v8, v9 := range in.Channels {
|
||||
if v8 > 0 {
|
||||
for v11, v12 := range in.Channels {
|
||||
if v11 > 0 {
|
||||
out.RawByte(',')
|
||||
}
|
||||
out.String(string(v9))
|
||||
out.String(string(v12))
|
||||
}
|
||||
out.RawByte(']')
|
||||
}
|
||||
|
|
|
@ -5,8 +5,6 @@ import (
|
|||
"encoding/hex"
|
||||
"net"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/khlieng/dispatch/pkg/irc"
|
||||
"github.com/khlieng/dispatch/storage"
|
||||
)
|
||||
|
@ -38,7 +36,9 @@ func connectIRC(server *storage.Server, state *State, srcIP []byte) *irc.Client
|
|||
address = net.JoinHostPort(server.Host, server.Port)
|
||||
}
|
||||
|
||||
if viper.GetBool("hexIP") {
|
||||
cfg := state.srv.Config()
|
||||
|
||||
if cfg.HexIP {
|
||||
i.Username = hex.EncodeToString(srcIP)
|
||||
} else if i.Username == "" {
|
||||
i.Username = server.Nick
|
||||
|
@ -49,16 +49,16 @@ func connectIRC(server *storage.Server, state *State, srcIP []byte) *irc.Client
|
|||
}
|
||||
|
||||
if server.Password == "" &&
|
||||
viper.GetString("defaults.password") != "" &&
|
||||
address == viper.GetString("defaults.host") {
|
||||
i.Password = viper.GetString("defaults.password")
|
||||
cfg.Defaults.Password != "" &&
|
||||
address == cfg.Defaults.Host {
|
||||
i.Password = cfg.Defaults.Password
|
||||
} else {
|
||||
i.Password = server.Password
|
||||
}
|
||||
|
||||
if i.TLS {
|
||||
i.TLSConfig = &tls.Config{
|
||||
InsecureSkipVerify: !viper.GetBool("verify_certificates"),
|
||||
InsecureSkipVerify: !cfg.VerifyCertificates,
|
||||
}
|
||||
|
||||
if cert := state.user.GetCertificate(); cert != nil {
|
||||
|
|
|
@ -16,7 +16,6 @@ import (
|
|||
|
||||
"github.com/dsnet/compress/brotli"
|
||||
"github.com/khlieng/dispatch/assets"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
const longCacheControl = "public, max-age=31536000, immutable"
|
||||
|
@ -73,7 +72,9 @@ var (
|
|||
)
|
||||
|
||||
func (d *Dispatch) initFileServer() {
|
||||
if viper.GetBool("dev") {
|
||||
cfg := d.Config()
|
||||
|
||||
if cfg.Dev {
|
||||
indexScripts = []string{"boot.js", "main.js"}
|
||||
} else {
|
||||
bootloader := decompressedAsset(findAssetName("boot*.js"))
|
||||
|
@ -149,13 +150,13 @@ workbox.precaching.precacheAndRoute([{
|
|||
}]);
|
||||
workbox.routing.registerNavigationRoute('/');`)...)
|
||||
|
||||
if viper.GetBool("https.hsts.enabled") && viper.GetBool("https.enabled") {
|
||||
hstsHeader = "max-age=" + viper.GetString("https.hsts.max_age")
|
||||
if cfg.HTTPS.HSTS.Enabled && cfg.HTTPS.Enabled {
|
||||
hstsHeader = "max-age=" + cfg.HTTPS.HSTS.MaxAge
|
||||
|
||||
if viper.GetBool("https.hsts.include_subdomains") {
|
||||
if cfg.HTTPS.HSTS.IncludeSubdomains {
|
||||
hstsHeader += "; includeSubDomains"
|
||||
}
|
||||
if viper.GetBool("https.hsts.preload") {
|
||||
if cfg.HTTPS.HSTS.Preload {
|
||||
hstsHeader += "; preload"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,12 +8,13 @@ import (
|
|||
"net/http/httputil"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/khlieng/dispatch/config"
|
||||
"github.com/khlieng/dispatch/pkg/letsencrypt"
|
||||
"github.com/khlieng/dispatch/pkg/session"
|
||||
"github.com/khlieng/dispatch/storage"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
var channelStore = storage.NewChannelStore()
|
||||
|
@ -25,8 +26,29 @@ type Dispatch struct {
|
|||
GetMessageStore func(*storage.User) (storage.MessageStore, error)
|
||||
GetMessageSearchProvider func(*storage.User) (storage.MessageSearchProvider, error)
|
||||
|
||||
cfg *config.Config
|
||||
upgrader websocket.Upgrader
|
||||
states *stateStore
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
func New(cfg *config.Config) *Dispatch {
|
||||
return &Dispatch{
|
||||
cfg: cfg,
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Dispatch) Config() *config.Config {
|
||||
d.lock.Lock()
|
||||
cfg := d.cfg
|
||||
d.lock.Unlock()
|
||||
return cfg
|
||||
}
|
||||
|
||||
func (d *Dispatch) SetConfig(cfg *config.Config) {
|
||||
d.lock.Lock()
|
||||
d.cfg = cfg
|
||||
d.lock.Unlock()
|
||||
}
|
||||
|
||||
func (d *Dispatch) Run() {
|
||||
|
@ -35,7 +57,7 @@ func (d *Dispatch) Run() {
|
|||
WriteBufferSize: 1024,
|
||||
}
|
||||
|
||||
if viper.GetBool("dev") {
|
||||
if d.Config().Dev {
|
||||
d.upgrader.CheckOrigin = func(r *http.Request) bool {
|
||||
return true
|
||||
}
|
||||
|
@ -105,16 +127,17 @@ func (d *Dispatch) loadUser(user *storage.User) {
|
|||
}
|
||||
|
||||
func (d *Dispatch) startHTTP() {
|
||||
addr := viper.GetString("address")
|
||||
port := viper.GetString("port")
|
||||
cfg := d.Config()
|
||||
addr := cfg.Address
|
||||
port := cfg.Port
|
||||
|
||||
if viper.GetBool("https.enabled") {
|
||||
portHTTPS := viper.GetString("https.port")
|
||||
redirect := viper.GetBool("https.redirect")
|
||||
if cfg.HTTPS.Enabled {
|
||||
portHTTPS := cfg.HTTPS.Port
|
||||
redirect := cfg.HTTPS.Redirect
|
||||
|
||||
if redirect {
|
||||
log.Println("[HTTP] Listening on port", port, "(HTTPS Redirect)")
|
||||
go http.ListenAndServe(net.JoinHostPort(addr, port), createHTTPSRedirect(portHTTPS))
|
||||
go http.ListenAndServe(net.JoinHostPort(addr, port), d.createHTTPSRedirect(portHTTPS))
|
||||
}
|
||||
|
||||
server := &http.Server{
|
||||
|
@ -122,17 +145,17 @@ func (d *Dispatch) startHTTP() {
|
|||
Handler: d,
|
||||
}
|
||||
|
||||
if certExists() {
|
||||
if d.certExists() {
|
||||
log.Println("[HTTPS] Listening on port", portHTTPS)
|
||||
server.ListenAndServeTLS(viper.GetString("https.cert"), viper.GetString("https.key"))
|
||||
} else if domain := viper.GetString("letsencrypt.domain"); domain != "" {
|
||||
server.ListenAndServeTLS(cfg.HTTPS.Cert, cfg.HTTPS.Key)
|
||||
} else if domain := cfg.LetsEncrypt.Domain; domain != "" {
|
||||
dir := storage.Path.LetsEncrypt()
|
||||
email := viper.GetString("letsencrypt.email")
|
||||
lePort := viper.GetString("letsencrypt.port")
|
||||
email := cfg.LetsEncrypt.Email
|
||||
lePort := cfg.LetsEncrypt.Port
|
||||
|
||||
if viper.GetBool("letsencrypt.proxy") && lePort != "" && (port != "80" || !redirect) {
|
||||
if cfg.LetsEncrypt.Proxy && lePort != "" && (port != "80" || !redirect) {
|
||||
log.Println("[HTTP] Listening on port 80 (Let's Encrypt Proxy))")
|
||||
go http.ListenAndServe(net.JoinHostPort(addr, "80"), http.HandlerFunc(letsEncryptProxy))
|
||||
go http.ListenAndServe(net.JoinHostPort(addr, "80"), http.HandlerFunc(d.letsEncryptProxy))
|
||||
}
|
||||
|
||||
le, err := letsencrypt.Run(dir, domain, email, ":"+lePort)
|
||||
|
@ -150,7 +173,7 @@ func (d *Dispatch) startHTTP() {
|
|||
log.Fatal("Could not locate SSL certificate or private key")
|
||||
}
|
||||
} else {
|
||||
if viper.GetBool("dev") {
|
||||
if cfg.Dev {
|
||||
// The node dev server will proxy index page requests and
|
||||
// websocket connections to this port
|
||||
port = "1337"
|
||||
|
@ -174,10 +197,9 @@ func (d *Dispatch) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
state := d.handleAuth(w, r, true, true)
|
||||
data := getIndexData(r, referer.EscapedPath(), state)
|
||||
data := d.getIndexData(r, referer.EscapedPath(), state)
|
||||
|
||||
writeJSON(w, r, data)
|
||||
|
||||
} else if strings.HasPrefix(r.URL.Path, "/ws") {
|
||||
if !websocket.IsWebSocketUpgrade(r) {
|
||||
fail(w, http.StatusBadRequest)
|
||||
|
@ -207,10 +229,10 @@ func (d *Dispatch) upgradeWS(w http.ResponseWriter, r *http.Request, state *Stat
|
|||
newWSHandler(conn, state, r).run()
|
||||
}
|
||||
|
||||
func createHTTPSRedirect(portHTTPS string) http.HandlerFunc {
|
||||
func (d *Dispatch) createHTTPSRedirect(portHTTPS string) http.HandlerFunc {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if strings.HasPrefix(r.URL.Path, "/.well-known/acme-challenge") {
|
||||
letsEncryptProxy(w, r)
|
||||
d.letsEncryptProxy(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -230,7 +252,7 @@ func createHTTPSRedirect(portHTTPS string) http.HandlerFunc {
|
|||
})
|
||||
}
|
||||
|
||||
func letsEncryptProxy(w http.ResponseWriter, r *http.Request) {
|
||||
func (d *Dispatch) letsEncryptProxy(w http.ResponseWriter, r *http.Request) {
|
||||
host, _, err := net.SplitHostPort(r.Host)
|
||||
if err != nil {
|
||||
host = r.Host
|
||||
|
@ -238,7 +260,7 @@ func letsEncryptProxy(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
upstream := &url.URL{
|
||||
Scheme: "http",
|
||||
Host: net.JoinHostPort(host, viper.GetString("letsencrypt.port")),
|
||||
Host: net.JoinHostPort(host, d.Config().LetsEncrypt.Port),
|
||||
}
|
||||
|
||||
httputil.NewSingleHostReverseProxy(upstream).ServeHTTP(w, r)
|
||||
|
|
|
@ -2,22 +2,19 @@ package server
|
|||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func certExists() bool {
|
||||
cert := viper.GetString("https.cert")
|
||||
key := viper.GetString("https.key")
|
||||
func (d *Dispatch) certExists() bool {
|
||||
cfg := d.Config().HTTPS
|
||||
|
||||
if cert == "" || key == "" {
|
||||
if cfg.Cert == "" || cfg.Key == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
if _, err := os.Stat(cert); err != nil {
|
||||
if _, err := os.Stat(cfg.Cert); err != nil {
|
||||
return false
|
||||
}
|
||||
if _, err := os.Stat(key); err != nil {
|
||||
if _, err := os.Stat(cfg.Key); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue