2021-11-10 19:06:12 +00:00
package setting
import (
2021-11-29 17:16:27 +00:00
"bytes"
"errors"
2021-11-10 19:06:12 +00:00
"flag"
"fmt"
"os"
"time"
"github.com/dcarrillo/whatismyip/internal/core"
)
type geodbPath struct {
City string
ASN string
}
type serverSettings struct {
ReadTimeout time . Duration
WriteTimeout time . Duration
}
type settings struct {
2022-04-02 16:10:48 +00:00
GeodbPath geodbPath
TemplatePath string
BindAddress string
TLSAddress string
TLSCrtPath string
TLSKeyPath string
TrustedHeader string
2022-05-01 17:47:27 +00:00
TrustedPortHeader string
2022-04-02 16:10:48 +00:00
EnableSecureHeaders bool
2023-03-18 19:38:18 +00:00
EnableHTTP3 bool
2022-04-02 16:10:48 +00:00
Server serverSettings
version bool
2021-11-10 19:06:12 +00:00
}
const defaultAddress = ":8080"
2021-11-30 16:21:01 +00:00
// ErrVersion is the custom error triggered when -version flag is passed
2021-11-29 17:16:27 +00:00
var ErrVersion = errors . New ( "setting: version requested" )
2021-11-30 16:21:01 +00:00
// App is the var with the parsed settings
2021-11-29 17:16:27 +00:00
var App = settings {
// hard-coded for the time being
Server : serverSettings {
ReadTimeout : 10 * time . Second ,
WriteTimeout : 10 * time . Second ,
} ,
}
2021-11-30 16:21:01 +00:00
// Setup initializes the App object parsing the flags
2021-11-29 17:16:27 +00:00
func Setup ( args [ ] string ) ( output string , err error ) {
flags := flag . NewFlagSet ( "whatismyip" , flag . ContinueOnError )
var buf bytes . Buffer
flags . SetOutput ( & buf )
2021-11-10 19:06:12 +00:00
2021-11-29 17:16:27 +00:00
flags . StringVar ( & App . GeodbPath . City , "geoip2-city" , "" , "Path to GeoIP2 city database" )
flags . StringVar ( & App . GeodbPath . ASN , "geoip2-asn" , "" , "Path to GeoIP2 ASN database" )
flags . StringVar ( & App . TemplatePath , "template" , "" , "Path to template file" )
flags . StringVar (
& App . BindAddress ,
2021-11-18 18:26:53 +00:00
"bind" ,
defaultAddress ,
"Listening address (see https://pkg.go.dev/net?#Listen)" ,
)
2021-11-29 17:16:27 +00:00
flags . StringVar (
& App . TLSAddress ,
2021-11-18 18:26:53 +00:00
"tls-bind" ,
"" ,
"Listening address for TLS (see https://pkg.go.dev/net?#Listen)" ,
)
2021-11-29 17:16:27 +00:00
flags . StringVar ( & App . TLSCrtPath , "tls-crt" , "" , "When using TLS, path to certificate file" )
flags . StringVar ( & App . TLSKeyPath , "tls-key" , "" , "When using TLS, path to private key file" )
2022-05-02 16:00:36 +00:00
flags . StringVar (
& App . TrustedHeader ,
2021-11-18 18:26:53 +00:00
"trusted-header" ,
"" ,
2022-05-02 16:00:36 +00:00
"Trusted request header for remote IP (e.g. X-Real-IP). When using this feature if -trusted-port-header is not set the client port is shown as 'unknown'" ,
2021-11-18 18:26:53 +00:00
)
2022-05-02 16:00:36 +00:00
flags . StringVar (
& App . TrustedPortHeader ,
2022-05-01 17:47:27 +00:00
"trusted-port-header" ,
"" ,
2022-05-02 16:00:36 +00:00
"Trusted request header for remote client port (e.g. X-Real-Port). When this parameter is set -trusted-header becomes mandatory" ,
2022-05-01 17:47:27 +00:00
)
2021-11-29 17:16:27 +00:00
flags . BoolVar ( & App . version , "version" , false , "Output version information and exit" )
2022-04-02 16:10:48 +00:00
flags . BoolVar (
& App . EnableSecureHeaders ,
"enable-secure-headers" ,
false ,
"Add sane security-related headers to every response" ,
)
2023-03-18 19:38:18 +00:00
flags . BoolVar (
& App . EnableHTTP3 ,
"enable-http3" ,
false ,
"Enable HTTP/3 protocol. HTTP/3 requires --tls-bind set, as HTTP/3 starts as a TLS connection that then gets upgraded to UDP. The UDP port is the same as the one used for the TLS server." ,
)
2021-11-10 19:06:12 +00:00
2021-11-29 17:16:27 +00:00
err = flags . Parse ( args )
if err != nil {
return buf . String ( ) , err
2021-11-10 19:06:12 +00:00
}
2021-11-29 17:16:27 +00:00
if App . version {
return fmt . Sprintf ( "whatismyip version %s" , core . Version ) , ErrVersion
2021-11-10 19:06:12 +00:00
}
2022-05-01 17:47:27 +00:00
if App . TrustedPortHeader != "" && App . TrustedHeader == "" {
2023-03-16 18:59:04 +00:00
return "" , fmt . Errorf ( "truster-header is mandatory when truster-port-header is set" )
2022-05-01 17:47:27 +00:00
}
2021-11-29 17:16:27 +00:00
if App . GeodbPath . City == "" || App . GeodbPath . ASN == "" {
2023-03-16 18:59:04 +00:00
return "" , fmt . Errorf ( "geoip2-city and geoip2-asn parameters are mandatory" )
2021-11-10 19:06:12 +00:00
}
2021-11-29 17:16:27 +00:00
if ( App . TLSAddress != "" ) && ( App . TLSCrtPath == "" || App . TLSKeyPath == "" ) {
2023-03-16 18:59:04 +00:00
return "" , fmt . Errorf ( "in order to use TLS, the -tls-crt and -tls-key flags are mandatory" )
2021-11-10 19:06:12 +00:00
}
2023-03-18 19:38:18 +00:00
if App . EnableHTTP3 && App . TLSAddress == "" {
return "" , fmt . Errorf ( "in order to use HTTP3, the -tls-bind is mandatory" )
}
2021-11-29 17:16:27 +00:00
if App . TemplatePath != "" {
info , err := os . Stat ( App . TemplatePath )
if os . IsNotExist ( err ) {
2023-03-16 18:59:04 +00:00
return "" , fmt . Errorf ( "%s no such file or directory" , App . TemplatePath )
2021-11-29 17:16:27 +00:00
}
if info . IsDir ( ) {
2023-03-16 18:59:04 +00:00
return "" , fmt . Errorf ( "%s must be a file" , App . TemplatePath )
2021-11-29 17:16:27 +00:00
}
2021-11-10 19:06:12 +00:00
}
2021-11-29 17:16:27 +00:00
return buf . String ( ) , nil
2021-11-10 19:06:12 +00:00
}