Skip to content

Commit

Permalink
Make it possible to bind on multiple addresses
Browse files Browse the repository at this point in the history
  • Loading branch information
gvalkov committed Oct 14, 2018
1 parent 2c0fb4e commit f2b575a
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 19 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ If a directory is given, all files under it are served recursively.
Example usage:
tailon file1.txt file2.txt file3.txt
tailon alias=messages,/var/log/messages "/var/log/*.log"
tailon -b localhost:8080 -c config.toml
tailon -b localhost:8080,localhost:8081 -c config.toml
For information on usage through the configuration file, please refer to the
'--help-config' option.
Expand Down
50 changes: 34 additions & 16 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ package main

import (
"fmt"
"io/ioutil"
"github.com/mitchellh/mapstructure"
"github.com/pelletier/go-toml"
flag "github.com/spf13/pflag"
"io/ioutil"
"log"
"net"
"os"
"strings"
"sync"
)

const scriptDescription = `
Expand Down Expand Up @@ -50,7 +51,7 @@ If a directory is given, all files under it are served recursively.
Example usage:
tailon file1.txt file2.txt file3.txt
tailon alias=messages,/var/log/messages "/var/log/*.log"
tailon -b localhost:8080 -c config.toml
tailon -b localhost:8080,localhost:8081 -c config.toml
For information on usage through the configuration file, please refer to the
'--help-config' option.
Expand All @@ -66,8 +67,8 @@ more configurability than the command-line interface.
# The root of the web application.
relative-root = "/"
# The address to listen on. Can be an address:port combination or an unix socket.
listen-addr = ":8080"
# The addresses to listen on. Can be an address:port combination or an unix socket.
listen-addr = [":8080"]
# Allow download of know files (only those matched by a filespec).
allow-download = true
Expand All @@ -86,7 +87,7 @@ At startup, tailon loads a default config file. The contents of that file are:
const defaultTomlConfig = `
title = "Tailon file viewer"
relative-root = "/"
listen-addr = ":8080"
listen-addr = [":8080"]
allow-download = true
allow-commands = ["tail", "grep", "sed", "awk"]
Expand Down Expand Up @@ -197,7 +198,7 @@ func parseFileSpec(spec string) (FileSpec, error) {
// Config contains all backend and frontend configuration options and relevant state.
type Config struct {
RelativeRoot string
BindAddr string
BindAddr []string
ConfigPath string
WrapLinesInitial bool
TailLinesInitial int
Expand All @@ -223,8 +224,15 @@ func makeConfig() *Config {

defaults, commandSpecs := parseTomlConfig(configContent)

// Convert the list of bind addresses from []interface{} to []string.
addrsA := defaults.Get("listen-addr").([]interface{})
addrsB := make([]string, len(addrsA))
for i := range addrsA {
addrsB[i] = addrsA[i].(string)
}

config := Config{
BindAddr: defaults.Get("listen-addr").(string),
BindAddr: addrsB,
RelativeRoot: defaults.Get("relative-root").(string),
AllowDownload: defaults.Get("allow-download").(bool),
CommandSpecs: commandSpecs,
Expand All @@ -237,17 +245,15 @@ func makeConfig() *Config {
var config = &Config{}

func main() {
flag.StringVarP(&config.ConfigPath, "config", "c", "", "")
flag.Parse()

config = makeConfig()

printHelp := flag.BoolP("help", "h", false, "Show this help message and exit")
printConfigHelp := flag.BoolP("help-config", "e", false, "Show configuration file help and exit")
bindAddr := flag.StringP("bind", "b", strings.Join(config.BindAddr, ","), "Listen on the specified address and port")

flag.StringVarP(&config.BindAddr, "bind", "b", config.BindAddr, "Listen on the specified address and port")
flag.StringVarP(&config.RelativeRoot, "relative-root", "r", config.RelativeRoot, "webapp relative root")
flag.BoolVarP(&config.AllowDownload, "allow-download", "a", config.AllowDownload, "allow file downloads")
flag.StringVarP(&config.ConfigPath, "config", "c", "", "")
flag.Parse()

flag.Usage = func() {
Expand All @@ -267,6 +273,8 @@ func main() {
os.Exit(0)
}

config.BindAddr = strings.Split(*bindAddr, ",")

// Ensure that relative root is always '/' or '/$arg/'.
config.RelativeRoot = "/" + strings.TrimLeft(config.RelativeRoot, "/")
config.RelativeRoot = strings.TrimRight(config.RelativeRoot, "/") + "/"
Expand Down Expand Up @@ -296,17 +304,27 @@ func main() {
log.Print("Generate initial file listing")
createListing(config.FileSpecs)

var wg sync.WaitGroup
for _, addr := range config.BindAddr {
wg.Add(1)
go startServer(config, addr)
}
wg.Wait()

}

func startServer(config *Config, bindAddr string) {
loggerHTML := log.New(os.Stdout, "", log.LstdFlags)
loggerHTML.Printf("Server start, relative-root: %s, bind-addr: %s\n", config.RelativeRoot, config.BindAddr)
loggerHTML.Printf("Server start, relative-root: %s, bind-addr: %s\n", config.RelativeRoot, bindAddr)

server := setupServer(config, loggerHTML)
server := setupServer(config, bindAddr, loggerHTML)

if strings.Contains(config.BindAddr, ":") {
if strings.Contains(bindAddr, ":") {
server.ListenAndServe()
} else {
os.Remove(config.BindAddr)
os.Remove(bindAddr)

unixAddr, _ := net.ResolveUnixAddr("unix", config.BindAddr)
unixAddr, _ := net.ResolveUnixAddr("unix", bindAddr)
unixListener, err := net.ListenUnix("unix", unixAddr)
unixListener.SetUnlinkOnClose(true)

Expand Down
4 changes: 2 additions & 2 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ func setupRoutes(relativeroot string) *http.ServeMux {
return router
}

func setupServer(config *Config, logger *log.Logger) *http.Server {
func setupServer(config *Config, addr string, logger *log.Logger) *http.Server {
router := setupRoutes(config.RelativeRoot)
loggingRouter := handlers.LoggingHandler(os.Stderr, router)

server := http.Server{
Addr: config.BindAddr,
Addr: addr,
Handler: loggingRouter,
ErrorLog: logger,
ReadTimeout: 5 * time.Second,
Expand Down

0 comments on commit f2b575a

Please sign in to comment.