Overhaul.

This commit is contained in:
kayos@tcp.direct 2022-07-08 13:23:20 -07:00
parent 44aede482b
commit 235e9bb643
Signed by: kayos
GPG Key ID: 4B841471B4BEE979
11 changed files with 221 additions and 231 deletions

View File

@ -5,6 +5,8 @@ import (
"github.com/gin-gonic/gin"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"git.tcp.direct/tcp.direct/tcp.ac/config"
)
type EntryType uint8
@ -75,7 +77,7 @@ func (p *Post) Log(l zerolog.Logger) *zerolog.Logger {
func validateKey(rKey string) bool {
// if it doesn't match the key size or it isn't alphanumeric - throw it out
if len(rKey) != keySize || !valid.IsAlphanumeric(rKey) {
if len(rKey) != config.DeleteKeySize || !valid.IsAlphanumeric(rKey) {
log.Warn().Str("rKey", rKey).
Msg("delete request failed sanity check!")
return false
@ -85,9 +87,9 @@ func validateKey(rKey string) bool {
func (p *Post) URLString() string {
var keyurl string = ""
url := baseURL + p.TypeCode() + "/" + string(p.UID())
url := config.BaseURL + p.TypeCode() + "/" + string(p.UID())
if p.DelKey() != "" {
keyurl = baseURL + "d/" + p.TypeCode() + "/" + p.DelKey()
keyurl = config.BaseURL + "d/" + p.TypeCode() + "/" + p.DelKey()
}
p.Log(log.Logger).Info().Msg("success")
@ -100,9 +102,9 @@ func (p *Post) URLString() string {
func (p *Post) Serve(c *gin.Context) {
var keyurl string = ""
url := baseURL + p.TypeCode() + "/" + string(p.UID())
url := config.BaseURL + p.TypeCode() + "/" + string(p.UID())
if p.DelKey() != "" {
keyurl = baseURL + "d/" + p.TypeCode() + "/" + p.DelKey()
keyurl = config.BaseURL + "d/" + p.TypeCode() + "/" + p.DelKey()
}
log.Info().

View File

@ -1,74 +0,0 @@
package main
import (
"fmt"
"os"
"strconv"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
)
// //////////// global declarations
var (
// config directives
debugBool bool
baseURL string
webPort string
webIP string
dbDir string
logDir string
uidSize int
keySize int
txtPort string
maxSize int
// utilitarian globals
err error
fn string
s string
i int
f *os.File
)
func configRead() {
// name of the file
// and the extension
viper.SetConfigName("config")
viper.SetConfigType("toml")
// potential config paths
viper.AddConfigPath("/etc/tcpac/")
viper.AddConfigPath("../")
viper.AddConfigPath("./")
// this should be replaced with more intelligent handling
err = viper.ReadInConfig()
if err != nil {
panic(fmt.Errorf("Fatal error reading config file: %s \n", err))
}
// read config
debugBool = viper.GetBool("global.debug") // we need to load the debug boolean first
if debugBool {
zerolog.SetGlobalLevel(zerolog.DebugLevel)
log.Debug().Msg("Debug mode enabled")
} else {
zerolog.SetGlobalLevel(zerolog.InfoLevel)
}
baseURL = viper.GetString("http.baseurl")
i := viper.GetInt("http.port")
webPort = strconv.Itoa(i)
webIP = viper.GetString("http.bindip")
dbDir = viper.GetString("files.data")
logDir = viper.GetString("files.logs")
uidSize = viper.GetInt("global.uidsize")
keySize = viper.GetInt("global.delkeysize")
txtPort = viper.GetString("txt.port")
maxSize = viper.GetInt("files.maxuploadsize")
//
}

View File

@ -1,20 +1,24 @@
title = "tcp.ac config"
[global]
debug = true
uidsize = 5
delkeysize = 12
[data]
directory = '.data'
max_key_size_mb = 10
max_value_size_mb = 20
[http]
baseurl = "http://127.0.0.1:8080/"
bindip = "127.0.0.1"
port = 8080
bind_addr = '127.0.0.1'
bind_port = '8080'
unix_socket_path = '/var/run/tcp.ac'
unix_socket_permissions = 420
use_unix_socket = false
[txt]
# string: port to listen on for termbin clone
port = "9988"
[logger]
debug = true
directory = '.logs'
nocolor = false
trace = false
use_date_filename = true
[other]
delete_key_size = 12
termbin_listen = '127.0.0.1:9999'
uid_size = 5
[files]
data = "./data/"
logs = "./logs/"
sizelimit = 48

View File

@ -7,7 +7,6 @@ import (
"os"
"path/filepath"
"runtime"
"strconv"
"github.com/rs/zerolog"
"github.com/spf13/viper"
@ -20,20 +19,24 @@ const (
var (
// Version roughly represents the applications current version.
Version = runtime.
Version = "asdf"
)
var (
BaseURL, WebPort, WebIP, DBDir, LogDir, TxtPort string
UIDSize, KeySize, MaxSize int
BaseURL, HTTPPort, HTTPBind, DBDir, LogDir,
TermbinListen, UnixSocketPath string
UIDSize, DeleteKeySize, KVMaxKeySizeMB,
KVMaxValueSizeMB int
UnixSocketPermissions uint32
UseUnixSocket bool
)
var usage = []string{
"\n" + Title + " v" + Version + " Usage\n",
"-c <config.toml> - Specify config file",
"-c <toml> - Specify config file",
"--nocolor - disable color and banner ",
"--banner - show banner + version and exit",
"--genconfig - write default config to 'config.toml' then exit",
"--genconfig - write default config to 'toml' then exit",
}
func printUsage() {
@ -42,8 +45,14 @@ func printUsage() {
}
var (
forceDebug = false
forceTrace = false
forceDebug = false
forceTrace = false
genConfig = false
noColorForce = false
customconfig = false
home string
prefConfigLocation string
snek *viper.Viper
)
// TODO: should probably just make a proper CLI with flags or something
@ -53,35 +62,23 @@ func argParse() {
case "-h":
printUsage()
case "--genconfig":
GenConfig = true
genConfig = true
case "--debug", "-v":
forceDebug = true
case "--trace", "-vv":
forceTrace = true
case "--nocolor":
noColorForce = true
case "--banner":
BannerOnly = true
case "-c", "--config":
if len(os.Args) <= i-1 {
panic("syntax error! expected file after -c")
}
loadCustomConfig(os.Args[i+1])
default:
continue
}
}
}
// generic vars
var (
noColorForce = false
customconfig = false
home string
prefConfigLocation string
snek *viper.Viper
)
// exported generic vars
var (
// Trace is the value of our trace (extra verbose) on/off toggle as per the current configuration.
@ -92,11 +89,6 @@ var (
Filename string
)
func init() {
prefConfigLocation = home + "/.config/" + Title
snek = viper.New()
}
func writeConfig() {
var err error
//goland:noinspection GoBoolExpressions
@ -119,7 +111,7 @@ func writeConfig() {
}
}
newconfig := prefConfigLocation + "/" + "config.toml"
newconfig := prefConfigLocation + "/" + "toml"
if err = snek.SafeWriteConfigAs(newconfig); err != nil {
fmt.Println("Failed to write new configuration file: " + err.Error())
os.Exit(1)
@ -130,11 +122,19 @@ func writeConfig() {
// Init will initialize our toml configuration engine and define our default configuration values which can be written to a new configuration file if desired
func Init() {
argParse()
prefConfigLocation = home + "/.config/" + Title
snek = viper.New()
if genConfig {
setDefaults()
println("config file generated at: " + Filename)
os.Exit(0)
}
snek.SetConfigType("toml")
snek.SetConfigName("config")
argParse()
if customconfig {
associateExportedVariables()
return
@ -146,7 +146,7 @@ func Init() {
snek.AddConfigPath(loc)
}
if err = snek.MergeInConfig(); err != nil {
if err := snek.MergeInConfig(); err != nil {
println("Error reading configuration file: " + err.Error())
println("Writing new configuration file...")
writeConfig()
@ -171,7 +171,8 @@ func getConfigPaths() (paths []string) {
func loadCustomConfig(path string) {
/* #nosec */
if f, err = os.Open(path); err != nil {
f, err := os.Open(path)
if err != nil {
println("Error opening specified config file: " + path)
println(err.Error())
os.Exit(1)
@ -212,59 +213,47 @@ func processOpts() {
stringOpt := map[string]*string{
"http.bind_addr": &HTTPBind,
"http.bind_port": &HTTPPort,
"http.unix_socket_path": &UnixSocketPath,
"logger.directory": &LogDir,
"deception.server_name": &FakeServerName,
}
// string slice options and their exported variables
strSliceOpt := map[string]*[]string{
"http.router.paths": &Paths,
"other.termbin_listen": &TermbinListen,
}
// bool options and their exported variables
boolOpt := map[string]*bool{
"performance.restrict_concurrency": &RestrictConcurrency,
"http.use_unix_socket": &UseUnixSocket,
"logger.debug": &Debug,
"logger.trace": &Trace,
"logger.nocolor": &NoColor,
"http.router.makerobots": &MakeRobots,
"http.router.catchall": &CatchAll,
"http.use_unix_socket": &UseUnixSocket,
"logger.debug": &Debug,
"logger.trace": &Trace,
"logger.nocolor": &noColorForce,
}
// integer options and their exported variables
intOpt := map[string]*int{
"performance.max_workers": &MaxWorkers,
"data.max_key_size": &KVMaxKeySizeMB,
"data.max_value_size": &KVMaxValueSizeMB,
"other.uid_size": &UIDSize,
}
uint32Opt := map[string]*uint32{
"http.unix_socket_permissions": &UnixSocketPermissions,
}
for key, opt := range stringOpt {
*opt = snek.GetString(key)
}
for key, opt := range strSliceOpt {
*opt = snek.GetStringSlice(key)
}
for key, opt := range boolOpt {
*opt = snek.GetBool(key)
}
for key, opt := range intOpt {
*opt = snek.GetInt(key)
}
for key, opt := range uint32Opt {
*opt = snek.GetUint32(key)
}
}
func associateExportedVariables() {
processOpts()
if noColorForce {
NoColor = true
}
if UseUnixSocket {
UnixSocketPath = snek.GetString("http.unix_socket_path")
parsedPermissions, err := strconv.ParseUint(snek.GetString("http.unix_socket_permissions"), 8, 32)
if err == nil {
UnixSocketPermissions = uint32(parsedPermissions)
}
}
// We set exported variables here so that it tracks when accessed from other packages.
if Debug || forceDebug {
zerolog.SetGlobalLevel(zerolog.DebugLevel)
Debug = true

60
config/defaults.go Normal file
View File

@ -0,0 +1,60 @@
package config
import (
"fmt"
"os"
"runtime"
)
var (
configSections = []string{"logger", "http", "data", "other"}
defNoColor = false
)
var defOpts = map[string]map[string]interface{}{
"logger": {
"directory": ".logs",
"debug": true,
"trace": false,
"nocolor": defNoColor,
"use_date_filename": true,
},
"http": {
"use_unix_socket": false,
"unix_socket_path": "/var/run/tcp.ac",
"unix_socket_permissions": uint32(0644),
"bind_addr": "127.0.0.1",
"bind_port": "8080",
},
"data": {
"directory": ".data",
"max_key_size_mb": 10,
"max_value_size_mb": 20,
},
"other": {
"uid_size": 5,
"delete_key_size": 12,
"termbin_listen": "127.0.0.1:9999",
},
}
func setDefaults() {
//goland:noinspection GoBoolExpressions
if runtime.GOOS == "windows" {
snek.SetDefault("logger.directory", "./logs/")
defNoColor = true
}
for _, def := range configSections {
snek.SetDefault(def, defOpts[def])
}
if genConfig {
if err := snek.SafeWriteConfigAs("./config.toml"); err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
os.Exit(0)
}
}

14
db.go
View File

@ -1,8 +1,9 @@
package main
import (
prologic "git.tcp.direct/Mirrors/bitcask-mirror"
"git.tcp.direct/tcp.direct/database/bitcask"
"git.tcp.direct/tcp.direct/tcp.ac/config"
)
var stores = []string{"hsh", "key", "img", "txt", "url"}
@ -10,11 +11,16 @@ var megabyte = float64(1024 * 1024)
var db *bitcask.DB
func init() {
bitcask.SetDefaultBitcaskOptions(
bitcask.WithMaxKeySize(uint32(config.KVMaxKeySizeMB*int(megabyte))),
bitcask.WithMaxValueSize(uint64(config.KVMaxValueSizeMB*int(megabyte))),
)
}
func dbInit() error {
db = bitcask.OpenDB(dbDir)
var bitcaskopts = []prologic.Option{prologic.WithMaxValueSize(uint64(maxSize) * uint64(megabyte))}
db = bitcask.OpenDB(config.DBDir)
for _, st := range stores {
if err := db.Init(st, bitcaskopts...); err != nil {
if err := db.Init(st); err != nil {
return err
}
}

2
go.mod
View File

@ -3,7 +3,6 @@ module git.tcp.direct/tcp.direct/tcp.ac
go 1.18
require (
git.tcp.direct/Mirrors/bitcask-mirror v0.0.0-20220228092422-1ec4297c7e34
git.tcp.direct/kayos/putxt v0.0.0-20220707194005-5bc828145cc4
git.tcp.direct/tcp.direct/database v0.0.0-20220610180603-058d36edd7f0
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
@ -19,6 +18,7 @@ require (
)
require (
git.tcp.direct/Mirrors/bitcask-mirror v0.0.0-20220228092422-1ec4297c7e34 // indirect
github.com/abcum/lcp v0.0.0-20201209214815-7a3f3840be81 // indirect
github.com/dsoprea/go-exif v0.0.0-20190901173045-3ce78807c90f // indirect
github.com/dsoprea/go-jpeg-image-structure v0.0.0-20190422055009-d6f9ba25cf48 // indirect

12
img.go
View File

@ -17,6 +17,8 @@ import (
exifremove "github.com/scottleedavis/go-exif-remove"
"github.com/twharmon/gouid"
"golang.org/x/crypto/blake2b"
"git.tcp.direct/tcp.direct/tcp.ac/config"
)
var fExt string
@ -89,7 +91,7 @@ func imgView(c *gin.Context) {
}
// if it doesn't match the key size or it isn't alphanumeric - throw it out
if !valid.IsAlphanumeric(rUid) || len(rUid) != uidSize {
if !valid.IsAlphanumeric(rUid) || len(rUid) != config.UIDSize {
slog.Warn().
Str("remoteaddr", c.ClientIP()).
Msg("request discarded as invalid")
@ -135,17 +137,17 @@ func imgView(c *gin.Context) {
func newUIDandKey() (uid string, key string) {
slog := log.With().Str("caller", "newUIDandKey").Logger()
// generate new uid and delete key
uid = gouid.String(uidSize, gouid.MixedCaseAlphaNum)
key = gouid.String(keySize, gouid.MixedCaseAlphaNum)
uid = gouid.String(config.UIDSize, gouid.MixedCaseAlphaNum)
key = gouid.String(config.DeleteKeySize, gouid.MixedCaseAlphaNum)
// lets make sure that we don't clash even though its highly unlikely
for db.With("img").Has([]byte(uid)) {
slog.Warn().Msg(" uid already exists! generating new...")
uid = gouid.String(uidSize, gouid.MixedCaseAlphaNum)
uid = gouid.String(config.UIDSize, gouid.MixedCaseAlphaNum)
}
for db.With("key").Has([]byte(key)) {
slog.Warn().Msg(" delete key already exists! generating new...")
key = gouid.String(keySize, gouid.MixedCaseAlphaNum)
key = gouid.String(config.DeleteKeySize, gouid.MixedCaseAlphaNum)
}
return
}

94
main.go
View File

@ -6,64 +6,40 @@ import (
"os/signal"
"syscall"
"github.com/gin-gonic/gin"
"github.com/muesli/termenv"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"git.tcp.direct/tcp.direct/tcp.ac/config"
)
var Banner string = "CiAgLGQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogIDg4ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKTU04OE1NTSAsYWRQUFliYSwgOGIsZFBQWWJhLCAgICAgICxhZFBQWVliYSwgICxhZFBQWWJhLCAgCiAgODggICBhOCIgICAgICIiIDg4UCcgICAgIjhhICAgICAiIiAgICAgYFk4IGE4IiAgICAgIiIgIAogIDg4ICAgOGIgICAgICAgICA4OCAgICAgICBkOCAgICAgLGFkUFBQUFA4OCA4YiAgICAgICAgICAKICA4OCwgICI4YSwgICAsYWEgODhiLCAgICxhOCIgODg4IDg4LCAgICAsODggIjhhLCAgICxhYSAgCiAgIlk4ODggYCJZYmJkOCInIDg4YFliYmRQIicgIDg4OCBgIjhiYmRQIlk4ICBgIlliYmQ4IicgIAogICAgICAgICAgICAgICAgICA4OCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgODggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCg=="
func init() {
func makeDirectories() {
log.Trace().Msgf("establishing log directory presence at %s...", config.LogDir)
err := os.MkdirAll(config.LogDir, 0o644)
if err != nil {
log.Fatal().
Str("directory", config.LogDir).
Err(err).Msg("failed to open log directory")
return
}
log.Trace().Msgf("establishing data directory presence at %s...", config.DBDir)
err = os.MkdirAll(config.DBDir, 0o644)
if err != nil {
log.Fatal().
Str("directory", config.DBDir).
Err(err).Msg("failed to open directory")
return
}
}
func printBanner() {
out := termenv.String(b64d(Banner))
p := termenv.ColorProfile()
out = out.Foreground(p.Color("#948DB8"))
fmt.Println(out)
// initialize the logger before the config: that way we can output debug lines
// pertaining to the parsing of the configuration init
// ////////// init logging ////////////
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
consoleWriter := zerolog.ConsoleWriter{Out: os.Stdout}
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
log.Info().Msg("Initializing...")
// see config.go
configRead()
if !debugBool {
gin.SetMode(gin.ReleaseMode)
}
// now that we know where to put the log file, we can start output (replace logger)
err := os.MkdirAll(logDir, 0o755)
if err != nil {
log.Fatal().Str("directory", logDir).Str("intent", "logDir").Err(err).Msg("failed to open directory")
return
}
err = os.MkdirAll(dbDir, 0o755)
if err != nil {
log.Fatal().Str("directory", dbDir).Str("intent", "dbDir").Err(err).Msg("failed to open directory")
return
}
lf, err := os.OpenFile(logDir+"tcpac.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0o666)
if err != nil {
log.Fatal().Str("logDir", logDir).Err(err).Msg("Error opening log file!")
}
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
multi := zerolog.MultiLevelWriter(consoleWriter, lf)
log.Logger = zerolog.New(multi).With().Timestamp().Logger()
err = dbInit()
if err != nil {
log.Fatal().Err(err).Msg("bitcask failure")
}
}
func catchSignal() {
@ -83,9 +59,27 @@ func catchSignal() {
}
func main() {
printBanner()
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
consoleWriter := zerolog.ConsoleWriter{Out: os.Stdout}
log.Logger = log.Output(consoleWriter).With().Timestamp().Logger()
log.Info().Msg("Initializing...")
config.Init()
makeDirectories()
log.Debug().Msg("debug enabled")
log.Trace().Msg("trace enabled")
lf, err := os.OpenFile(config.LogDir+"tcpac.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0o666)
if err != nil {
log.Fatal().Str("config.LogDir", config.LogDir).Err(err).Msg("Error opening log file!")
}
multi := zerolog.MultiLevelWriter(consoleWriter, lf)
log.Logger = zerolog.New(multi).With().Timestamp().Logger()
err = dbInit()
if err != nil {
log.Fatal().Err(err).Msg("bitcask failure")
}
defer db.SyncAndCloseAll()
go catchSignal()
go serveTermbin()
// see router.go
httpRouter()
go httpRouter()
catchSignal()
}

View File

@ -10,6 +10,8 @@ import (
"github.com/gin-gonic/gin"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"git.tcp.direct/tcp.direct/tcp.ac/config"
)
var favicon string = "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"
@ -30,7 +32,7 @@ func urlPost(c *gin.Context) {
}
func httpRouter() {
if !debugBool {
if !config.Debug {
gin.SetMode(gin.ReleaseMode)
}
@ -79,6 +81,8 @@ func httpRouter() {
delR.GET("/i/:key", imgDel)
delR.GET("/t/:key", txtDel)
log.Info().Str("webIP", webIP).Str("webPort", webPort).Msg("done; tcp.ac is live.")
router.Run(webIP + ":" + webPort)
log.Info().Str("Host", config.HTTPBind).
Str("Port", config.HTTPPort).
Msg("done; tcp.ac is live.")
router.Run(config.HTTPBind + ":" + config.HTTPPort)
}

27
txt.go
View File

@ -2,6 +2,7 @@ package main
import (
"errors"
"net"
"strings"
valid "github.com/asaskevich/govalidator"
@ -11,6 +12,8 @@ import (
"golang.org/x/crypto/blake2b"
termbin "git.tcp.direct/kayos/putxt"
"git.tcp.direct/tcp.direct/tcp.ac/config"
)
func init() {
@ -19,7 +22,6 @@ func init() {
func incoming() {
var msg termbin.Message
select {
case msg = <-termbin.Msg:
switch msg.Type {
@ -74,31 +76,31 @@ func termPost(b []byte) {
}
// generate new uid and delete key
uid := gouid.String(uidSize, gouid.MixedCaseAlphaNum)
key := gouid.String(keySize, gouid.MixedCaseAlphaNum)
uid := gouid.String(config.UIDSize, gouid.MixedCaseAlphaNum)
key := gouid.String(config.DeleteKeySize, gouid.MixedCaseAlphaNum)
// lets make sure that we don't clash even though its highly unlikely
for uidRef, _ := db.With("txt").Get([]byte(uid)); uidRef != nil; {
slog.Info().Msg(" uid already exists! generating new...")
uid = gouid.String(uidSize, gouid.MixedCaseAlphaNum)
uid = gouid.String(config.UIDSize, gouid.MixedCaseAlphaNum)
}
for keyRef, _ := db.With("key").Get([]byte(key)); keyRef != nil; {
slog.Info().Msg(" delete key already exists! generating new...")
key = gouid.String(keySize, gouid.MixedCaseAlphaNum)
key = gouid.String(config.DeleteKeySize, gouid.MixedCaseAlphaNum)
}
db.With("hsh").Put(hash, []byte(uid))
uid = gouid.String(uidSize, gouid.MixedCaseAlphaNum)
key = gouid.String(keySize, gouid.MixedCaseAlphaNum)
uid = gouid.String(config.UIDSize, gouid.MixedCaseAlphaNum)
key = gouid.String(config.DeleteKeySize, gouid.MixedCaseAlphaNum)
for uidRef, _ := db.With("txt").Get([]byte(uid)); uidRef != nil; {
slog.Info().Msg(" uid already exists! generating new...")
uid = gouid.String(uidSize, gouid.MixedCaseAlphaNum)
uid = gouid.String(config.UIDSize, gouid.MixedCaseAlphaNum)
}
for keyRef, _ := db.With("key").Get([]byte(key)); keyRef != nil; {
slog.Info().Msg(" delete key already exists! generating new...")
key = gouid.String(keySize, gouid.MixedCaseAlphaNum)
key = gouid.String(config.DeleteKeySize, gouid.MixedCaseAlphaNum)
}
db.With("hsh").Put([]byte(hash), []byte(uid))
@ -129,7 +131,7 @@ func termPost(b []byte) {
}
func txtView(c *gin.Context) {
raddr, _ := c.RemoteIP()
raddr := net.ParseIP(c.RemoteIP())
if termbin.Rater.Check(&termbin.Identity{Actual: raddr}) {
errThrow(c, 429, errors.New("ratelimitted"), "too many requests")
return
@ -148,7 +150,7 @@ func txtView(c *gin.Context) {
}
// if it doesn't match the key size or it isn't alphanumeric - throw it out
if !valid.IsAlphanumeric(rUid) || len(rUid) != uidSize {
if !valid.IsAlphanumeric(rUid) || len(rUid) != config.UIDSize {
errThrow(c, 400, errors.New("request discarded as invalid"), "400")
return
}
@ -218,7 +220,8 @@ func serveTermbin() {
incoming()
}
}()
err := termbin.Listen("", txtPort)
split := strings.Split(config.TermbinListen, ":")
err := termbin.Listen(split[0], split[1])
if err != nil {
println(err.Error())
return