switch to using config file, no flags. remove fwd port

Signed-off-by: kim (grufwub) <grufwub@gmail.com>
development
kim (grufwub) 4 years ago
parent 5d4b97c607
commit 1cce82a480

@ -15,7 +15,7 @@ func setupInitialCGIEnv(safePath string) []string {
env = append(env, "SERVER_SOFTWARE=Gophi "+Version)
env = append(env, "SERVER_PROTOCOL="+protocol)
env = append(env, "SERVER_NAME="+Hostname)
env = append(env, "SERVER_PORT="+FwdPort)
env = append(env, "SERVER_PORT="+Port)
env = append(env, "DOCUMENT_ROOT="+Root)
env = append(env, "GATEWAY_INTERFACE=CGI/1.1")
env = append(env, "PATH="+safePath)

@ -1,7 +1,6 @@
package core
import (
"flag"
"fmt"
"log"
"os"
@ -11,51 +10,78 @@ import (
"time"
"github.com/grufwub/go-bufpools"
"github.com/grufwub/go-config"
"github.com/grufwub/go-errors"
"github.com/grufwub/go-filecache"
"github.com/grufwub/go-logger"
)
// ParseFlagsAndSetup parses necessary core server flags, and sets up the core ready for Start() to be called
func ParseFlagsAndSetup(proto string, defaultPort uint, newListener func() (*Listener, *errors.Error), fileContent func(*Path) FileContent, dirHandler func(*Client, *os.File, *Path) *errors.Error, largeHandler func(*Client, *os.File, *Path) *errors.Error) {
// Setup numerous temporary flag variables, and store the rest
// directly in their final operating location. Strings are stored
// in `string_constants.go` to allow for later localization
sysLog := flag.String(sysLogFlagStr, "stdout", sysLogDescStr)
accLog := flag.String(accLogFlagStr, "stdout", accLogDescStr)
flag.StringVar(&Root, rootFlagStr, "/var/"+proto, rootDescStr)
flag.StringVar(&Bind, bindFlagStr, "", bindDescStr)
flag.StringVar(&Hostname, hostnameFlagStr, "localhost", hostnameDescStr)
port := flag.Uint(portFlagStr, defaultPort, portDescStr)
fwdPort := flag.Uint(fwdPortFlagStr, 0, fwdPortDescStr)
flag.DurationVar(&connReadDeadline, connReadTimeoutFlagStr, time.Duration(time.Second*5), connReadTimeoutDescStr)
flag.DurationVar(&connWriteDeadline, connWriteTimeoutFlagStr, time.Duration(time.Second*15), connWriteTimeoutDescStr)
cReadBuf := flag.Uint(connReadBufFlagStr, 1024, connReadBufDescStr)
cWriteBuf := flag.Uint(connWriteBufFlagStr, 1024, connWriteBufDescStr)
cReadMax := flag.Uint(connReadMaxFlagStr, 4096, connReadMaxDescStr)
fReadBuf := flag.Uint(fileReadBufFlagStr, 1024, fileReadBufDescStr)
flag.DurationVar(&monitorSleepTime, monitorSleepTimeFlagStr, time.Duration(time.Second*1), monitorSleepTimeDescStr)
cacheMax := flag.Float64(cacheFileMaxFlagStr, 1.0, cacheFileMaxDescStr)
cacheSize := flag.Uint(cacheSizeFlagStr, 100, cacheSizeDescStr)
cacheAgeMax := flag.Duration(cacheAgeMaxFlagStr, time.Minute*5, cacheAgeMaxDescStr)
restrictedPathsList := flag.String(restrictPathsFlagStr, "", restrictPathsDescStr)
hiddenPathsList := flag.String(hiddenPathsFlagStr, "", hiddenPathsDescStr)
remapRequestsList := flag.String(remapRequestsFlagStr, "", remapRequestsDescStr)
cgiDir := flag.String(cgiDirFlagStr, "", cgiDirDescStr)
flag.DurationVar(&maxCGIRunTime, maxCGITimeFlagStr, time.Duration(time.Second*3), maxCGITimeDescStr)
safePath := flag.String(safePathFlagStr, "/bin:/usr/bin", safePathDescStr)
userSpacesEnabled := flag.Bool(userSpacesFlagStr, false, userSpacesDescStr)
printVersion := flag.Bool(versionFlagStr, false, versionDescStr)
// Parse flags! (including any set by outer calling function)
flag.Parse()
// If version print requested, do so!
if *printVersion {
fmt.Println("Gophi " + Version)
os.Exit(0)
func usage(code int) {
fmt.Printf("Usage: %s [-v|--version] [-c|--config $file]\n", os.Args[0])
os.Exit(code)
}
// ParseConfigAndSetup parses necessary core server config from file (and any others defined), and sets up the core ready for Start() to be called
func ParseConfigAndSetup(tree config.Tree, proto string, defaultPort uint, newListener func() (*Listener, *errors.Error), fileContent func(*Path) FileContent, dirHandler func(*Client, *os.File, *Path) *errors.Error, largeHandler func(*Client, *os.File, *Path) *errors.Error) {
// Default configuration file location
configFile := "/etc/gophi." + proto + ".conf"
// If we have arguments to handle, do so!
if len(os.Args) > 1 {
switch os.Args[1] {
case "-c", "--config":
if len(os.Args) != 3 {
usage(1)
}
configFile = os.Args[2]
case "-v", "--version":
fmt.Println("Gophi " + Version)
os.Exit(0)
default:
usage(1)
}
}
// Core configuration
tree.StringVar(&Root, "root", "/var/"+proto)
tree.StringVar(&Bind, "listen", "")
tree.StringVar(&Hostname, "hostname", "")
port := tree.Uint64("port", uint64(defaultPort))
// Filesystem configuration
fReadBuf := tree.Uint64("filesystem.read-buf", 1024)
tree.DurationVar(&monitorSleepTime, "filesystem.cache.monitor-freq", time.Second*60)
cacheMax := tree.Float64("filesystem.cache.file-max", 1.0)
cacheSize := tree.Uint64("filesystem.cache.size", 100)
cacheAgeMax := tree.Duration("filesystem.cache.age-max", time.Minute*5)
// Request mapping, hiding, restricting
restrictedPathsList := tree.StringArray("requests.restrict", []string{})
hiddenPathsList := tree.StringArray("requests.hidden", []string{})
remapRequestsList := tree.StringArray("requests.remap", []string{})
// Logging configuration
sysLog := tree.String("log.system", "stdout")
accLog := tree.String("log.access", "stdout")
// Connection configuration
tree.DurationVar(&connReadDeadline, "connection.read-timeout", time.Second*5)
tree.DurationVar(&connWriteDeadline, "connection.write-timeout", time.Second*15)
cReadBuf := tree.Uint64("connection.read-buf", 1024)
cWriteBuf := tree.Uint64("connection.write-buf", 1024)
cReadMax := tree.Uint64("connection.read-max", 4096)
// CGI configuration
cgiDir := tree.String("cgi.directory", "")
safePath := tree.String("cgi.safe-path", "/bin:/usr/bin")
tree.DurationVar(&maxCGIRunTime, "cgi.max-time", time.Duration(time.Second*3))
// User space configuration
userSpacesEnabled := tree.Bool("user-spaces", false)
// Parse provided config file
_ = tree.ParseDefined(configFile)
// Setup loggers
SystemLog = setupLogger(*sysLog)
if *sysLog == *accLog {
@ -79,11 +105,7 @@ func ParseFlagsAndSetup(proto string, defaultPort uint, newListener func() (*Lis
SystemLog.Infof(chDirStr, Root)
// Set port info
if *fwdPort == 0 {
fwdPort = port
}
Port = strconv.Itoa(int(*port))
FwdPort = strconv.Itoa(int(*fwdPort))
// Set protocol string (only really used by CGI and one call to SystemLog)
protocol = proto
@ -92,7 +114,7 @@ func ParseFlagsAndSetup(proto string, defaultPort uint, newListener func() (*Lis
var err *errors.Error
serverListener, err = newListener()
if err != nil {
SystemLog.Fatalf(listenerBeginFailStr, protocol, Hostname, FwdPort, Bind, Port, err.Error())
SystemLog.Fatalf(listenerBeginFailStr, protocol, Hostname, Port, Bind, Port, err.Error())
}
// Setup the sync pools
@ -109,7 +131,7 @@ func ParseFlagsAndSetup(proto string, defaultPort uint, newListener func() (*Lis
FileCache = filecache.NewFileCache(int(*cacheSize), *cacheAgeMax)
// If no restricted paths provided, set to the disabled function. Else, compile and enable
if *restrictedPathsList == "" {
if *restrictedPathsList == nil {
SystemLog.Info(pathRestrictionsDisabledStr)
IsRestrictedPath = isRestrictedPathDisabled
} else {
@ -119,7 +141,7 @@ func ParseFlagsAndSetup(proto string, defaultPort uint, newListener func() (*Lis
}
// If no hidden paths provided, set to the disabled function. Else, compile and enable
if *hiddenPathsList == "" {
if *hiddenPathsList == nil {
SystemLog.Info(pathHidingDisableStr)
IsHiddenPath = isHiddenPathDisabled
} else {
@ -129,7 +151,7 @@ func ParseFlagsAndSetup(proto string, defaultPort uint, newListener func() (*Lis
}
// If no remapped paths provided, set to the disabled function. Else, compile and enable
if *remapRequestsList == "" {
if *remapRequestsList == nil {
SystemLog.Info(requestRemapDisabledStr)
RemapRequest = remapRequestDisabled
} else {

@ -13,22 +13,6 @@ type FileContent interface {
Clear()
}
// generatedFileContents is a simple FileContent implementation for holding onto a generated (virtual) file contents
type generatedFileContent struct {
content []byte
}
// ReadAllFrom does nothing for generated content
func (fc *generatedFileContent) Load(p *Path, file *os.File) *errors.Error { return nil }
// WriteAllTo writes the generated FileContent to client
func (fc *generatedFileContent) WriteToClient(client *Client, p *Path) *errors.Error {
return client.Conn().Write(fc.content)
}
// Clear does nothing
func (fc *generatedFileContent) Clear() {}
// RegularFileContent is the simplest implementation of core.FileContents for regular files
type RegularFileContent struct {
content []byte

@ -6,7 +6,6 @@ import (
"sort"
"github.com/grufwub/go-errors"
"github.com/grufwub/go-filecache"
)
// OpenFile opens a file for reading (read-only, world-readable)
@ -119,16 +118,3 @@ func ScanDirectory(dir *os.File, p *Path, iterator func(os.FileInfo, *Path)) *er
return nil
}
// AddGeneratedFile adds a generated file content byte slice to the file cache, with supplied path as the key
func AddGeneratedFile(p *Path, b []byte) {
// Get write lock, defer unlock
FileCache.Lock()
defer FileCache.Unlock()
// Wrap contents in File
file := filecache.NewFile(p.Absolute(), false, &generatedFileContent{b})
// Add to cache!
FileCache.Put(file)
}

@ -29,11 +29,11 @@ func compileCGIRegex(cgiDir string) *regexp.Regexp {
}
// compileRestrictedPathsRegex turns a string of restricted paths into a slice of compiled regular expressions
func compileRestrictedPathsRegex(restrictions string) []*regexp.Regexp {
func compileRestrictedPathsRegex(restrictions []string) []*regexp.Regexp {
regexes := make([]*regexp.Regexp, 0)
// Split restrictions string by new lines
for _, expr := range strings.Split(restrictions, "\n") {
for _, expr := range restrictions {
// Skip empty expressions
if len(expr) == 0 {
continue
@ -54,11 +54,11 @@ func compileRestrictedPathsRegex(restrictions string) []*regexp.Regexp {
}
// compileRestrictedPathsRegex turns a string of hidden paths into a slice of compiled regular expressions
func compileHiddenPathsRegex(hidden string) []*regexp.Regexp {
func compileHiddenPathsRegex(hidden []string) []*regexp.Regexp {
regexes := make([]*regexp.Regexp, 0)
// Split restrictions string by new lines
for _, expr := range strings.Split(hidden, "\n") {
for _, expr := range hidden {
// Skip empty expressions
if len(expr) == 0 {
continue
@ -79,11 +79,11 @@ func compileHiddenPathsRegex(hidden string) []*regexp.Regexp {
}
// compileRequestRemapRegex turns a string of remapped paths into a slice of compiled RequestRemap structures
func compileRequestRemapRegex(remaps string) []*RequestRemap {
func compileRequestRemapRegex(remaps []string) []*RequestRemap {
requestRemaps := make([]*RequestRemap, 0)
// Split remaps string by new lines
for _, expr := range strings.Split(remaps, "\n") {
for _, expr := range remaps {
// Skip empty expressions
if len(expr) == 0 {
continue

@ -29,9 +29,6 @@ var (
// Port stores the internal port the host is binded to
Port string
// FwdPort stores the host's outward port number
FwdPort string
// AccessLog is the global Access SLogger
AccessLog *logger.SLogger
@ -104,7 +101,7 @@ func Start(serve func(*Client)) {
go FileCache.StartMonitor(monitorSleepTime)
// Start the listener
SystemLog.Infof(listeningOnStr, protocol, Hostname, FwdPort, Bind, Port)
SystemLog.Infof(listeningOnStr, protocol, Hostname, Port, Bind, Port)
go func() {
for {
client, err := serverListener.Accept()

@ -1,83 +1,5 @@
package core
// Core flag string constants
const (
sysLogFlagStr = "sys-log"
sysLogDescStr = "System log output location ['stdout', 'stderr', 'null', $filename]"
accLogFlagStr = "acc-log"
accLogDescStr = "Access log output location ['stdout', 'stderr', 'null', $filename]"
rootFlagStr = "root"
rootDescStr = "Server root directory"
bindFlagStr = "bind-addr"
bindDescStr = "IP address to bind to"
hostnameFlagStr = "hostname"
hostnameDescStr = "Server hostname (FQDN)"
portFlagStr = "port"
portDescStr = "Port to listen on"
fwdPortFlagStr = "fwd-port"
fwdPortDescStr = "Outward-facing port"
connReadTimeoutFlagStr = "conn-read-timeout"
connReadTimeoutDescStr = "Client connection read timeout"
connWriteTimeoutFlagStr = "conn-write-timeout"
connWriteTimeoutDescStr = "Client connection write timeout"
connReadBufFlagStr = "conn-read-buf"
connReadBufDescStr = "Connection read buffer size (bytes)"
connWriteBufFlagStr = "conn-write-buf"
connWriteBufDescStr = "Connection write buffer size (bytes)"
connReadMaxFlagStr = "conn-read-max"
connReadMaxDescStr = "Connection read max (bytes)"
fileReadBufFlagStr = "file-read-buf"
fileReadBufDescStr = "File read buffer size (bytes)"
monitorSleepTimeFlagStr = "cache-monitor-freq"
monitorSleepTimeDescStr = "File cache freshness monitor frequency"
cacheFileMaxFlagStr = "cache-file-max"
cacheFileMaxDescStr = "Max cached file size (megabytes)"
cacheSizeFlagStr = "cache-size"
cacheSizeDescStr = "File cache size"
cacheAgeMaxFlagStr = "cache-age-max"
cacheAgeMaxDescStr = "Maximum cached file age before purge"
restrictPathsFlagStr = "restrict-paths"
restrictPathsDescStr = "Restrict paths as new-line separated list of regex statements (see documenation)"
hiddenPathsFlagStr = "hidden-paths"
hiddenPathsDescStr = "Hidden paths as new-line separated list of regex statements (see documentation)"
remapRequestsFlagStr = "remap-requests"
remapRequestsDescStr = "Remap requests as new-line separated list of remap statements (see documenation)"
cgiDirFlagStr = "cgi-dir"
cgiDirDescStr = "CGI scripts directory (empty to disable)"
maxCGITimeFlagStr = "max-cgi-time"
maxCGITimeDescStr = "Maximum CGI script execution time"
safePathFlagStr = "safe-path"
safePathDescStr = "CGI environment safe PATH variable"
userSpacesFlagStr = "user-spaces"
userSpacesDescStr = "Enable user sub-dirs for personal server space"
versionFlagStr = "version"
versionDescStr = "Print version string"
)
// Log string constants
const (
hostnameBindEmptyStr = "At least one of hostname or bind-addr must be non-empty!"

@ -0,0 +1,109 @@
# NOTE: due to how TOML is parsed, you will
# need to escape forward slashes in regex
# statements and anywhere else you may
# need them
root = "/home/grufwub/gopher_space"
listen = "127.0.0.1"
hostname = "localhost"
port = 1024
#fwd-port = 70
[connection]
# Connection read timeout
read-timeout = "5s"
# Connection write timeout
write-timeout = "15s"
# Connection read buffer size (in bytes)
read-buf = 1024
# Connection write buffer size (in bytes)
write-buf = 1024
# Connection read max (in bytes)
read-max = 4096
[filesystem]
# File read buffer size (in bytes)
read-buf = 1024
[filesystem.cache]
# Filesystem monitor check freq.
monitor-freq = "60s"
# Maximum cached file size (in MB)
file-max = 1.0
# Maximum file age before mark
# as stale, i.e. safe to be
# removed on next monitor sweep
age-max = "5m"
# Cache size count
size = 100
[requests]
# String array of filesystem path
# regex statements to restrict.
restrict = [
"(.+/)?\\.\\w",
]
# String array of filesystem path
# regex statements to hide from dir
# listings
hidden = [
"",
]
# String array of request remapping
# regex statements
remap = [
"",
]
[log]
# Log output locations, options:
# - stdout -> /dev/stdout
# - stderr -> /dev/stderr
# - null -> /dev/null
# - $file -> $file
system = "stdout"
access = "stdout"
[cgi]
# Relative CGI scripts directory
# path within server root
directory = "cgi-bin"
# CGI environment $PATH
safe-path = "/bin:/usr/bin"
# Maximum CGI script runtime
max-time = "3s"
# Gopher specific configuration, uncomment
# if you have built gophi as a gopher server
#[gopher]
# # Page width before line truncation
# page-width = 80
#
# # Footer text included below gophermaps
# footer = ""
#
# # Subgophermap size max (in megabytes)
# subgopher-max = 1.0
#
# # Information included in caps.txt
# # policy file
# admin-email = ""
# description = ""
# geolocation = ""
# Gemini specific configuration, uncomment
# if you have built gophi as a gemini server
#[gemini]
# tls-cert = ""
# tls-key = ""

@ -3,10 +3,10 @@ package gemini
import (
"crypto/rand"
"crypto/tls"
"flag"
"gophi/core"
"io"
"github.com/grufwub/go-config"
"github.com/grufwub/go-errors"
"github.com/grufwub/go-logger"
)
@ -22,10 +22,14 @@ func init() {
// Run does as says :)
func Run() {
// Create new TOML config parser
tree := make(config.Tree)
// Parse gemini specific flags, then all
certFile := flag.String(certFileFlagStr, "", certFileDescStr)
keyFile := flag.String(keyFileFlagStr, "", keyFileDescStr)
core.ParseFlagsAndSetup(
certFile := tree.String("tls-cert", "")
keyFile := tree.String("tls-key", "")
core.ParseConfigAndSetup(
tree,
"gemini",
1965,
func() (*core.Listener, *errors.Error) {

@ -28,15 +28,6 @@ const (
invalidHostPortErrStr = "Invalid host:port pair (not equal to runtime values)"
)
// Gemini flag string constants
const (
certFileFlagStr = "tls-cert"
certFileDescStr = "TLS certificate file (REQUIRED)"
keyFileFlagStr = "tls-key"
keyFileDescStr = "TLS certificate file (REQUIRED)"
)
// Log string constants
const (
entropyAssertFailStr = "Failed to assert safe source of system entropy exists!"

@ -4,6 +4,7 @@ go 1.15
require (
github.com/grufwub/go-bufpools v0.0.0-20201026084325-a3a938b7d6d8
github.com/grufwub/go-config v0.0.8
github.com/grufwub/go-errors v0.0.0-20201109215724-b43fef6af3e8
github.com/grufwub/go-filecache v0.0.0-20201109234016-53d503bf2622
github.com/grufwub/go-logger v0.0.0-20201101130825-423526bd353f

@ -1,14 +1,34 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/grufwub/go-bufpools v0.0.0-20201026084325-a3a938b7d6d8 h1:NFJnr99JkUeqZcTCf0uwMX3EG7YpwLrQ3j9gGlkd5tg=
github.com/grufwub/go-bufpools v0.0.0-20201026084325-a3a938b7d6d8/go.mod h1:ITqLRtG+W1bZHGdkWewV7inb+GcWfq2Jcjqx4AZ7aBY=
github.com/grufwub/go-config v0.0.0-20201124172124-ab889252a803 h1:2iPyExiV1bZvk9mIGNqUHNa+eumkHxsboOJ4v9kXbY4=
github.com/grufwub/go-config v0.0.0-20201124172124-ab889252a803/go.mod h1:0U5Y0EkNeL09YkY70fNZv4Kelfayp/VroEs2UzmUG04=
github.com/grufwub/go-config v0.0.0-20201124181629-6b32a4ba72aa h1:YpJ096JOYkatWvGMXyCgrKeH8MFfEDiDpPxehb3hPWo=
github.com/grufwub/go-config v0.0.0-20201124181629-6b32a4ba72aa/go.mod h1:0U5Y0EkNeL09YkY70fNZv4Kelfayp/VroEs2UzmUG04=
github.com/grufwub/go-config v0.0.1 h1:YRdGk6+bmJA5WrauQ/lxVIXeUFJunJZ1uMrD3DJYix0=
github.com/grufwub/go-config v0.0.1/go.mod h1:0U5Y0EkNeL09YkY70fNZv4Kelfayp/VroEs2UzmUG04=
github.com/grufwub/go-config v0.0.2 h1:5jmpqlJuX3+xJL2klggIzMpbfrRldzjpSimaAPfa9kA=
github.com/grufwub/go-config v0.0.2/go.mod h1:0U5Y0EkNeL09YkY70fNZv4Kelfayp/VroEs2UzmUG04=
github.com/grufwub/go-config v0.0.3 h1:ifJKvpA/XDTU/OXggjcRtWVaQmBHd338kIe18zE8cHo=
github.com/grufwub/go-config v0.0.3/go.mod h1:0U5Y0EkNeL09YkY70fNZv4Kelfayp/VroEs2UzmUG04=
github.com/grufwub/go-config v0.0.4 h1:soVvy6XPet6uaf2uENPCXAgXVJBXbxT/vW6/FAhiTx0=
github.com/grufwub/go-config v0.0.4/go.mod h1:0U5Y0EkNeL09YkY70fNZv4Kelfayp/VroEs2UzmUG04=
github.com/grufwub/go-config v0.0.5 h1:9eU1+tNHKBDvyj14qhFVMaP4iwaQo1ywojXrPjDR/uE=
github.com/grufwub/go-config v0.0.5/go.mod h1:0U5Y0EkNeL09YkY70fNZv4Kelfayp/VroEs2UzmUG04=
github.com/grufwub/go-config v0.0.6 h1:VPhbGhbQh5goCFyIEnA2zJqcDLgxpm9nXpAjUH+YONo=
github.com/grufwub/go-config v0.0.6/go.mod h1:0U5Y0EkNeL09YkY70fNZv4Kelfayp/VroEs2UzmUG04=
github.com/grufwub/go-config v0.0.7 h1:h37CmDYxYl9B4zf9SjjZNdW2i14rII36a0vbnQ0+7lQ=
github.com/grufwub/go-config v0.0.7/go.mod h1:0U5Y0EkNeL09YkY70fNZv4Kelfayp/VroEs2UzmUG04=
github.com/grufwub/go-config v0.0.8 h1:4wM4ua+JnQz/QnD3qD1NMrJlTHgwMStoii6mmOxcH7U=
github.com/grufwub/go-config v0.0.8/go.mod h1:0U5Y0EkNeL09YkY70fNZv4Kelfayp/VroEs2UzmUG04=
github.com/grufwub/go-errors v0.0.0-20201109215724-b43fef6af3e8 h1:RZ1QpN8yD2+4cFNnC5Oj7HUmYKK3Tg42Us6ENquSoj8=
github.com/grufwub/go-errors v0.0.0-20201109215724-b43fef6af3e8/go.mod h1:AXGtU2fWv8ejaUUT0+9wTOlWqcxYDo8wuYnhrYtoBKM=
github.com/grufwub/go-filecache v0.0.0-20201109171316-e186294c25c3 h1:sKi/LgWR7E8VS3fOz0QFWqTl8mhcSiosYPXlT+hxdUU=
github.com/grufwub/go-filecache v0.0.0-20201109171316-e186294c25c3/go.mod h1:FAUdzHGs72ulYZCh9xPJWJosuInjppjBOw/bKJYS+R8=
github.com/grufwub/go-filecache v0.0.0-20201109230405-fc17bb15911c h1:7wPLhDm60uI8f5pU5wlkVtrAV+ej5uNZQ0BbXq85enk=
github.com/grufwub/go-filecache v0.0.0-20201109230405-fc17bb15911c/go.mod h1:FAUdzHGs72ulYZCh9xPJWJosuInjppjBOw/bKJYS+R8=
github.com/grufwub/go-filecache v0.0.0-20201109234016-53d503bf2622 h1:5KP/W4Usq09XBySqmPVuYDcPAGI4Z86bTN4k1yKapmI=
github.com/grufwub/go-filecache v0.0.0-20201109234016-53d503bf2622/go.mod h1:FAUdzHGs72ulYZCh9xPJWJosuInjppjBOw/bKJYS+R8=
github.com/grufwub/go-logger v0.0.0-20201101130825-423526bd353f h1:dLs3F/sxDeP9EOF+9oUVoCucDoPBvmRCGKQnbrTgZsg=
github.com/grufwub/go-logger v0.0.0-20201101130825-423526bd353f/go.mod h1:pZny1PMTpy9FAKMbaDYbPJbthl0wrSpVoIcnEjkRZaQ=
github.com/grufwub/go-upmutex v0.0.0-20201106234426-e4de73a0e690 h1:o2aGDpfO5v3qAVlvwLzQMM549fzMPi5NaT44YVdIprk=
github.com/grufwub/go-upmutex v0.0.0-20201106234426-e4de73a0e690/go.mod h1:Eb/BM4cKjBdmbwJ0XJ4GxIeSFCBOIWzIUx7RN/VKHNs=
github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=

@ -7,7 +7,23 @@ import (
"github.com/grufwub/go-errors"
)
// gophermapContents is an implementation of core.FileContents that holds individually renderable sections of a gophermap
// generatedFileContents is a simple core.FileContent implementation for holding onto a generated (virtual) file contents
type generatedFileContent struct {
content []byte
}
// ReadAllFrom does nothing for generated content
func (fc *generatedFileContent) Load(p *core.Path, file *os.File) *errors.Error { return nil }
// WriteAllTo writes the generated FileContent to client
func (fc *generatedFileContent) WriteToClient(client *core.Client, p *core.Path) *errors.Error {
return client.Conn().Write(fc.content)
}
// Clear does nothing
func (fc *generatedFileContent) Clear() {}
// gophermapContents is an implementation of core.FileContent that holds individually renderable sections of a gophermap
type gophermapContent struct {
sections []gophermapSection
}

@ -43,7 +43,7 @@ func replacePlacementStrs(line string) string {
return split[0] + "\t" +
split[1] + "\t" +
strings.Replace(split[2], "$host", core.Hostname, 1) + "\t" +
strings.Replace(split[3], "$port", core.FwdPort, 1)
strings.Replace(split[3], "$port", core.Port, 1)
}
// buildLine builds a gopher line string
@ -65,10 +65,10 @@ func buildErrorLine(selector string) []byte {
func appendFileListing(b []byte, file os.FileInfo, p *core.Path) []byte {
switch {
case file.Mode().IsDir():
return append(b, buildLine(typeDirectory, file.Name(), p.Selector(), core.Hostname, core.FwdPort)...)
return append(b, buildLine(typeDirectory, file.Name(), p.Selector(), core.Hostname, core.Port)...)
case file.Mode().IsRegular():
t := getItemType(file.Name())
return append(b, buildLine(t, file.Name(), p.Selector(), core.Hostname, core.FwdPort)...)
return append(b, buildLine(t, file.Name(), p.Selector(), core.Hostname, core.Port)...)
default:
return b
}

@ -1,23 +1,28 @@
package gopher
import (
"flag"
"gophi/core"
"net"
"github.com/grufwub/go-config"
"github.com/grufwub/go-errors"
"github.com/grufwub/go-filecache"
)
// Run does as says :)
func Run() {
// Create new TOML config parser
tree := make(config.Tree)
// Parse gopher specific flags, then all
pWidth := flag.Uint(pageWidthFlagStr, 80, pageWidthDescStr)
footerText := flag.String(footerTextFlagStr, "Gophi, a Gopher server in Go!", footerTextDescStr)
subgopherSizeMax := flag.Float64(subgopherSizeMaxFlagStr, 1.0, subgopherSizeMaxDescStr)
admin := flag.String(adminFlagStr, "", adminDescStr)
desc := flag.String(descFlagStr, "", descDescStr)
geo := flag.String(geoFlagStr, "", geoDescStr)
core.ParseFlagsAndSetup(
pWidth := tree.Uint64("gopher.page-width", 80)
footerText := tree.String("gopher.footer", "")
subgopherSizeMax := tree.Float64("gopher.subgopher-max", 1.0)
admin := tree.String("gopher.admin-email", "")
desc := tree.String("gopher.description", "")
geo := tree.String("gopher.geolocation", "")
core.ParseConfigAndSetup(
tree,
"gopher",
70,
func() (*core.Listener, *errors.Error) {
@ -40,7 +45,13 @@ func Run() {
// Add generated policy file to cache
p := core.NewPath(core.Root, "caps.txt")
core.SystemLog.Infof("Generating policy file %s...", p.Absolute())
core.AddGeneratedFile(p, generateCapsTxt(*desc, *admin, *geo))
core.FileCache.Put(filecache.NewFile(p.Absolute(), false, &generatedFileContent{generateCapsTxt(*desc, *admin, *geo)}))
// Remove things we don't need hanging around
desc = nil
admin = nil
geo = nil
tree = nil
// Start!
core.Start(serve)

@ -13,27 +13,6 @@ const (
errorResponse503 = "503 Service Unavailable"
)
// Gopher flag string constants
const (
pageWidthFlagStr = "page-width"
pageWidthDescStr = "Gopher page width"
footerTextFlagStr = "footer-text"
footerTextDescStr = "Footer text (empty to disable)"
subgopherSizeMaxFlagStr = "subgopher-size-max"
subgopherSizeMaxDescStr = "Subgophermap size max (megabytes)"
adminFlagStr = "admin"
adminDescStr = "Generated policy file admin email"
descFlagStr = "description"
descDescStr = "Generated policy file server description"
geoFlagStr = "geolocation"
geoDescStr = "Generated policy file server geolocation"
)
// Log string constants
const (
clientReadFailStr = "Failed to read"

Loading…
Cancel
Save