mirror of
https://github.com/1f349/violet.git
synced 2024-11-24 04:11:32 +00:00
Transition to new logger
This commit is contained in:
parent
a8db73d957
commit
1f4f4414d5
@ -4,11 +4,11 @@ import (
|
|||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509/pkix"
|
"crypto/x509/pkix"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/1f349/violet/logger"
|
||||||
"github.com/1f349/violet/utils"
|
"github.com/1f349/violet/utils"
|
||||||
"github.com/mrmelon54/certgen"
|
"github.com/mrmelon54/certgen"
|
||||||
"github.com/mrmelon54/rescheduler"
|
"github.com/mrmelon54/rescheduler"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"log"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
@ -17,6 +17,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var Logger = logger.Logger.WithPrefix("Violet Certs")
|
||||||
|
|
||||||
// Certs is the certificate loader and management system.
|
// Certs is the certificate loader and management system.
|
||||||
type Certs struct {
|
type Certs struct {
|
||||||
cDir fs.FS
|
cDir fs.FS
|
||||||
@ -69,7 +71,7 @@ func New(certDir fs.FS, keyDir fs.FS, selfCert bool) *Certs {
|
|||||||
return now.AddDate(10, 0, 0)
|
return now.AddDate(10, 0, 0)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln("Failed to generate CA cert for self-signed mode:", err)
|
logger.Logger.Fatal("Failed to generate CA cert for self-signed mode", "err", err)
|
||||||
}
|
}
|
||||||
c.ca = ca
|
c.ca = ca
|
||||||
}
|
}
|
||||||
@ -145,7 +147,7 @@ func (c *Certs) threadCompile() {
|
|||||||
// compile map and check errors
|
// compile map and check errors
|
||||||
err := c.internalCompile(certMap)
|
err := c.internalCompile(certMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[Certs] Compile failed: %s\n", err)
|
Logger.Infof("Compile failed: %s\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,7 +170,7 @@ func (c *Certs) internalCompile(m map[string]*tls.Certificate) error {
|
|||||||
return fmt.Errorf("failed to read cert dir: %w", err)
|
return fmt.Errorf("failed to read cert dir: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("[Certs] Compiling lookup table for %d certificates\n", len(files))
|
Logger.Infof("Compiling lookup table for %d certificates\n", len(files))
|
||||||
|
|
||||||
// find and parse certs
|
// find and parse certs
|
||||||
for _, i := range files {
|
for _, i := range files {
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/1f349/violet/domains"
|
"github.com/1f349/violet/domains"
|
||||||
errorPages "github.com/1f349/violet/error-pages"
|
errorPages "github.com/1f349/violet/error-pages"
|
||||||
"github.com/1f349/violet/favicons"
|
"github.com/1f349/violet/favicons"
|
||||||
|
"github.com/1f349/violet/logger"
|
||||||
"github.com/1f349/violet/proxy"
|
"github.com/1f349/violet/proxy"
|
||||||
"github.com/1f349/violet/proxy/websocket"
|
"github.com/1f349/violet/proxy/websocket"
|
||||||
"github.com/1f349/violet/router"
|
"github.com/1f349/violet/router"
|
||||||
@ -17,12 +18,11 @@ import (
|
|||||||
"github.com/1f349/violet/servers/api"
|
"github.com/1f349/violet/servers/api"
|
||||||
"github.com/1f349/violet/servers/conf"
|
"github.com/1f349/violet/servers/conf"
|
||||||
"github.com/1f349/violet/utils"
|
"github.com/1f349/violet/utils"
|
||||||
"github.com/mrmelon54/exit-reload"
|
|
||||||
"github.com/google/subcommands"
|
"github.com/google/subcommands"
|
||||||
|
"github.com/mrmelon54/exit-reload"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/client_golang/prometheus/collectors"
|
"github.com/prometheus/client_golang/prometheus/collectors"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -45,19 +45,19 @@ func (s *serveCmd) Usage() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *serveCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
|
func (s *serveCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
|
||||||
log.Println("[Violet] Starting...")
|
logger.Logger.Info("Starting...")
|
||||||
|
|
||||||
if s.configPath == "" {
|
if s.configPath == "" {
|
||||||
log.Println("[Violet] Error: config flag is missing")
|
logger.Logger.Info("Error: config flag is missing")
|
||||||
return subcommands.ExitUsageError
|
return subcommands.ExitUsageError
|
||||||
}
|
}
|
||||||
|
|
||||||
openConf, err := os.Open(s.configPath)
|
openConf, err := os.Open(s.configPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
log.Println("[Violet] Error: missing config file")
|
logger.Logger.Info("Error: missing config file")
|
||||||
} else {
|
} else {
|
||||||
log.Println("[Violet] Error: open config file: ", err)
|
logger.Logger.Info("Error: open config file: ", err)
|
||||||
}
|
}
|
||||||
return subcommands.ExitFailure
|
return subcommands.ExitFailure
|
||||||
}
|
}
|
||||||
@ -65,7 +65,7 @@ func (s *serveCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{})
|
|||||||
var config startUpConfig
|
var config startUpConfig
|
||||||
err = json.NewDecoder(openConf).Decode(&config)
|
err = json.NewDecoder(openConf).Decode(&config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[Violet] Error: invalid config file: ", err)
|
logger.Logger.Info("Error: invalid config file: ", err)
|
||||||
return subcommands.ExitFailure
|
return subcommands.ExitFailure
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,12 +81,12 @@ func normalLoad(startUp startUpConfig, wd string) {
|
|||||||
// create path to cert dir
|
// create path to cert dir
|
||||||
err := os.MkdirAll(filepath.Join(wd, "certs"), os.ModePerm)
|
err := os.MkdirAll(filepath.Join(wd, "certs"), os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("[Violet] Failed to create certificate path")
|
logger.Logger.Fatal("Failed to create certificate path")
|
||||||
}
|
}
|
||||||
// create path to key dir
|
// create path to key dir
|
||||||
err = os.MkdirAll(filepath.Join(wd, "keys"), os.ModePerm)
|
err = os.MkdirAll(filepath.Join(wd, "keys"), os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("[Violet] Failed to create certificate key path")
|
logger.Logger.Fatal("Failed to create certificate key path")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,20 +96,20 @@ func normalLoad(startUp startUpConfig, wd string) {
|
|||||||
errorPageDir = os.DirFS(startUp.ErrorPagePath)
|
errorPageDir = os.DirFS(startUp.ErrorPagePath)
|
||||||
err := os.MkdirAll(startUp.ErrorPagePath, os.ModePerm)
|
err := os.MkdirAll(startUp.ErrorPagePath, os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("[Violet] Failed to create error page path '%s'", startUp.ErrorPagePath)
|
logger.Logger.Fatal("Failed to create error page", "path", startUp.ErrorPagePath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// load the MJWT RSA public key from a pem encoded file
|
// load the MJWT RSA public key from a pem encoded file
|
||||||
mJwtVerify, err := mjwt.NewMJwtVerifierFromFile(filepath.Join(wd, "signer.public.pem"))
|
mJwtVerify, err := mjwt.NewMJwtVerifierFromFile(filepath.Join(wd, "signer.public.pem"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("[Violet] Failed to load MJWT verifier public key from file '%s': %s", filepath.Join(wd, "signer.public.pem"), err)
|
logger.Logger.Fatal("Failed to load MJWT verifier public key", "file", filepath.Join(wd, "signer.public.pem"), "err", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// open sqlite database
|
// open sqlite database
|
||||||
db, err := violet.InitDB(filepath.Join(wd, "violet.db.sqlite"))
|
db, err := violet.InitDB(filepath.Join(wd, "violet.db.sqlite"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("[Violet] Failed to open database")
|
logger.Logger.Fatal("Failed to open database", "err", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
certDir := os.DirFS(filepath.Join(wd, "certs"))
|
certDir := os.DirFS(filepath.Join(wd, "certs"))
|
||||||
@ -155,20 +155,23 @@ func normalLoad(startUp startUpConfig, wd string) {
|
|||||||
if srvConf.ApiListen != "" {
|
if srvConf.ApiListen != "" {
|
||||||
srvApi = api.NewApiServer(srvConf, allCompilables, promRegistry)
|
srvApi = api.NewApiServer(srvConf, allCompilables, promRegistry)
|
||||||
srvApi.SetKeepAlivesEnabled(false)
|
srvApi.SetKeepAlivesEnabled(false)
|
||||||
log.Printf("[API] Starting API server on: '%s'\n", srvApi.Addr)
|
l := logger.Logger.With("server", "API")
|
||||||
go utils.RunBackgroundHttp("API", srvApi)
|
l.Info("Starting server", "addr", srvApi.Addr)
|
||||||
|
go utils.RunBackgroundHttp(l, srvApi)
|
||||||
}
|
}
|
||||||
if srvConf.HttpListen != "" {
|
if srvConf.HttpListen != "" {
|
||||||
srvHttp = servers.NewHttpServer(srvConf, promRegistry)
|
srvHttp = servers.NewHttpServer(srvConf, promRegistry)
|
||||||
srvHttp.SetKeepAlivesEnabled(false)
|
srvHttp.SetKeepAlivesEnabled(false)
|
||||||
log.Printf("[HTTP] Starting HTTP server on: '%s'\n", srvHttp.Addr)
|
l := logger.Logger.With("server", "HTTP")
|
||||||
go utils.RunBackgroundHttp("HTTP", srvHttp)
|
l.Info("Starting server", "addr", srvHttp.Addr)
|
||||||
|
go utils.RunBackgroundHttp(l, srvHttp)
|
||||||
}
|
}
|
||||||
if srvConf.HttpsListen != "" {
|
if srvConf.HttpsListen != "" {
|
||||||
srvHttps = servers.NewHttpsServer(srvConf, promRegistry)
|
srvHttps = servers.NewHttpsServer(srvConf, promRegistry)
|
||||||
srvHttps.SetKeepAlivesEnabled(false)
|
srvHttps.SetKeepAlivesEnabled(false)
|
||||||
log.Printf("[HTTPS] Starting HTTPS server on: '%s'\n", srvHttps.Addr)
|
l := logger.Logger.With("server", "HTTPS")
|
||||||
go utils.RunBackgroundHttps("HTTPS", srvHttps)
|
l.Info("Starting server", "addr", srvHttps.Addr)
|
||||||
|
go utils.RunBackgroundHttps(l, srvHttps)
|
||||||
}
|
}
|
||||||
|
|
||||||
exit_reload.ExitReload("Violet", func() {
|
exit_reload.ExitReload("Violet", func() {
|
||||||
|
@ -7,13 +7,13 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/1f349/violet"
|
"github.com/1f349/violet"
|
||||||
"github.com/1f349/violet/domains"
|
"github.com/1f349/violet/domains"
|
||||||
|
"github.com/1f349/violet/logger"
|
||||||
"github.com/1f349/violet/proxy"
|
"github.com/1f349/violet/proxy"
|
||||||
"github.com/1f349/violet/proxy/websocket"
|
"github.com/1f349/violet/proxy/websocket"
|
||||||
"github.com/1f349/violet/router"
|
"github.com/1f349/violet/router"
|
||||||
"github.com/1f349/violet/target"
|
"github.com/1f349/violet/target"
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
"github.com/google/subcommands"
|
"github.com/google/subcommands"
|
||||||
"log"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
@ -42,7 +42,7 @@ func (s *setupCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{})
|
|||||||
// get absolute path to specify files
|
// get absolute path to specify files
|
||||||
wdAbs, err := filepath.Abs(s.wdPath)
|
wdAbs, err := filepath.Abs(s.wdPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("[Violet] Failed to get full directory path: ", err)
|
fmt.Println("Failed to get full directory path: ", err)
|
||||||
return subcommands.ExitFailure
|
return subcommands.ExitFailure
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,11 +50,11 @@ func (s *setupCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{})
|
|||||||
createFile := false
|
createFile := false
|
||||||
err = survey.AskOne(&survey.Confirm{Message: fmt.Sprintf("Create Violet config files in this directory: '%s'?", wdAbs)}, &createFile)
|
err = survey.AskOne(&survey.Confirm{Message: fmt.Sprintf("Create Violet config files in this directory: '%s'?", wdAbs)}, &createFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("[Violet] Error: ", err)
|
fmt.Println("Error: ", err)
|
||||||
return subcommands.ExitFailure
|
return subcommands.ExitFailure
|
||||||
}
|
}
|
||||||
if !createFile {
|
if !createFile {
|
||||||
fmt.Println("[Violet] Goodbye")
|
fmt.Println("Goodbye")
|
||||||
return subcommands.ExitSuccess
|
return subcommands.ExitSuccess
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ func (s *setupCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{})
|
|||||||
},
|
},
|
||||||
}, &answers)
|
}, &answers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("[Violet] Error: ", err)
|
fmt.Println("Error: ", err)
|
||||||
return subcommands.ExitFailure
|
return subcommands.ExitFailure
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,14 +142,14 @@ func (s *setupCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{})
|
|||||||
RateLimit: answers.RateLimit,
|
RateLimit: answers.RateLimit,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("[Violet] Failed to write config file: ", err)
|
fmt.Println("Failed to write config file: ", err)
|
||||||
return subcommands.ExitFailure
|
return subcommands.ExitFailure
|
||||||
}
|
}
|
||||||
|
|
||||||
// open sqlite database
|
// open sqlite database
|
||||||
db, err := violet.InitDB(databaseFile)
|
db, err := violet.InitDB(databaseFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("[Violet] Failed to open database '%s'...", databaseFile)
|
logger.Logger.Fatal("Failed to open database", "err", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// domain manager to add a domain, no need to compile here as the program needs
|
// domain manager to add a domain, no need to compile here as the program needs
|
||||||
@ -168,14 +168,14 @@ func (s *setupCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{})
|
|||||||
return nil
|
return nil
|
||||||
}))
|
}))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("[Violet] Error: ", err)
|
fmt.Println("Error: ", err)
|
||||||
return subcommands.ExitFailure
|
return subcommands.ExitFailure
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse the api url
|
// parse the api url
|
||||||
apiUrl, err := url.Parse(answers.ApiUrl)
|
apiUrl, err := url.Parse(answers.ApiUrl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("[Violet] Failed to parse API URL: ", err)
|
fmt.Println("Failed to parse API URL: ", err)
|
||||||
return subcommands.ExitFailure
|
return subcommands.ExitFailure
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,13 +191,13 @@ func (s *setupCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{})
|
|||||||
Active: true,
|
Active: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("[Violet] Failed to insert api route into database: ", err)
|
fmt.Println("Failed to insert api route into database: ", err)
|
||||||
return subcommands.ExitFailure
|
return subcommands.ExitFailure
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("[Violet] Setup complete")
|
fmt.Println("Setup complete")
|
||||||
fmt.Printf("[Violet] Run the reverse proxy with `violet serve -conf %s`\n", confFile)
|
fmt.Printf("Run the reverse proxy with `violet serve -conf %s`\n", confFile)
|
||||||
|
|
||||||
return subcommands.ExitSuccess
|
return subcommands.ExitSuccess
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,15 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
_ "embed"
|
_ "embed"
|
||||||
"github.com/1f349/violet/database"
|
"github.com/1f349/violet/database"
|
||||||
|
"github.com/1f349/violet/logger"
|
||||||
"github.com/1f349/violet/utils"
|
"github.com/1f349/violet/utils"
|
||||||
"github.com/mrmelon54/rescheduler"
|
"github.com/mrmelon54/rescheduler"
|
||||||
"log"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var Logger = logger.Logger.WithPrefix("Violet Domains")
|
||||||
|
|
||||||
// Domains is the domain list and management system.
|
// Domains is the domain list and management system.
|
||||||
type Domains struct {
|
type Domains struct {
|
||||||
db *database.Queries
|
db *database.Queries
|
||||||
@ -68,7 +70,7 @@ func (d *Domains) threadCompile() {
|
|||||||
// compile map and check errors
|
// compile map and check errors
|
||||||
err := d.internalCompile(domainMap)
|
err := d.internalCompile(domainMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[Domains] Compile failed: %s\n", err)
|
Logger.Info("Compile faile", "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +83,7 @@ func (d *Domains) threadCompile() {
|
|||||||
// internalCompile is a hidden internal method for querying the database during
|
// internalCompile is a hidden internal method for querying the database during
|
||||||
// the Compile() method.
|
// the Compile() method.
|
||||||
func (d *Domains) internalCompile(m map[string]struct{}) error {
|
func (d *Domains) internalCompile(m map[string]struct{}) error {
|
||||||
log.Println("[Domains] Updating domains from database")
|
Logger.Info("Updating domains from database")
|
||||||
|
|
||||||
// sql or something?
|
// sql or something?
|
||||||
rows, err := d.db.GetActiveDomains(context.Background())
|
rows, err := d.db.GetActiveDomains(context.Background())
|
||||||
@ -105,7 +107,7 @@ func (d *Domains) Put(domain string, active bool) {
|
|||||||
Active: active,
|
Active: active,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[Violet] Database error: %s\n", err)
|
logger.Logger.Infof("Database error: %s\n", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,6 +116,6 @@ func (d *Domains) Delete(domain string) {
|
|||||||
defer d.s.Unlock()
|
defer d.s.Unlock()
|
||||||
err := d.db.DeleteDomain(context.Background(), domain)
|
err := d.db.DeleteDomain(context.Background(), domain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[Violet] Database error: %s\n", err)
|
logger.Logger.Infof("Database error: %s\n", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,9 @@ package error_pages
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/1f349/violet/logger"
|
||||||
"github.com/mrmelon54/rescheduler"
|
"github.com/mrmelon54/rescheduler"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -12,6 +12,8 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var Logger = logger.Logger.WithPrefix("Violet Error Pages")
|
||||||
|
|
||||||
// ErrorPages stores the custom error pages and is called by the servers to
|
// ErrorPages stores the custom error pages and is called by the servers to
|
||||||
// output meaningful pages for HTTP error codes
|
// output meaningful pages for HTTP error codes
|
||||||
type ErrorPages struct {
|
type ErrorPages struct {
|
||||||
@ -78,7 +80,7 @@ func (e *ErrorPages) threadCompile() {
|
|||||||
if e.dir != nil {
|
if e.dir != nil {
|
||||||
err := e.internalCompile(errorPageMap)
|
err := e.internalCompile(errorPageMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[ErrorPages] Compile failed: %s\n", err)
|
Logger.Info("Compile failed", "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,7 +98,7 @@ func (e *ErrorPages) internalCompile(m map[int]func(rw http.ResponseWriter)) err
|
|||||||
return fmt.Errorf("failed to read error pages dir: %w", err)
|
return fmt.Errorf("failed to read error pages dir: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("[ErrorPages] Compiling lookup table for %d error pages\n", len(files))
|
Logger.Info("Compiling lookup table", "page count", len(files))
|
||||||
|
|
||||||
// find and load error pages
|
// find and load error pages
|
||||||
for _, i := range files {
|
for _, i := range files {
|
||||||
@ -111,20 +113,20 @@ func (e *ErrorPages) internalCompile(m map[int]func(rw http.ResponseWriter)) err
|
|||||||
|
|
||||||
// if the extension is not 'html' then ignore the file
|
// if the extension is not 'html' then ignore the file
|
||||||
if ext != ".html" {
|
if ext != ".html" {
|
||||||
log.Printf("[ErrorPages] WARNING: ignoring non '.html' file in error pages directory: '%s'\n", name)
|
Logger.Warn("Ignoring non '.html' file in error pages directory", "name", name)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the name can't be
|
// if the name can't be
|
||||||
nameInt, err := strconv.Atoi(strings.TrimSuffix(name, ".html"))
|
nameInt, err := strconv.Atoi(strings.TrimSuffix(name, ".html"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[ErrorPages] WARNING: ignoring invalid error page in error pages directory: '%s'\n", name)
|
Logger.Warn("Ignoring invalid error page in error pages directory", "name", name)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if code is in range 100-599
|
// check if code is in range 100-599
|
||||||
if nameInt < 100 || nameInt >= 600 {
|
if nameInt < 100 || nameInt >= 600 {
|
||||||
log.Printf("[ErrorPages] WARNING: ignoring invalid error page in error pages directory must be 100-599: '%s'\n", name)
|
Logger.Warn("Ignoring invalid error page in error pages directory must be 100-599", "name", name)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ func (l *FaviconList) PreProcess(convert func(in []byte) ([]byte, error)) error
|
|||||||
// download SVG
|
// download SVG
|
||||||
l.Svg.Raw, err = getFaviconViaRequest(l.Svg.Url)
|
l.Svg.Raw, err = getFaviconViaRequest(l.Svg.Url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("[Favicons] Failed to fetch SVG icon: %w", err)
|
return fmt.Errorf("favicons: failed to fetch SVG icon: %w", err)
|
||||||
}
|
}
|
||||||
l.Svg.Hash = hex.EncodeToString(sha256.New().Sum(l.Svg.Raw))
|
l.Svg.Hash = hex.EncodeToString(sha256.New().Sum(l.Svg.Raw))
|
||||||
}
|
}
|
||||||
@ -84,14 +84,14 @@ func (l *FaviconList) PreProcess(convert func(in []byte) ([]byte, error)) error
|
|||||||
// download PNG
|
// download PNG
|
||||||
l.Png.Raw, err = getFaviconViaRequest(l.Png.Url)
|
l.Png.Raw, err = getFaviconViaRequest(l.Png.Url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("[Favicons] Failed to fetch PNG icon: %w", err)
|
return fmt.Errorf("favicons: failed to fetch PNG icon: %w", err)
|
||||||
}
|
}
|
||||||
} else if l.Svg != nil {
|
} else if l.Svg != nil {
|
||||||
// generate PNG from SVG
|
// generate PNG from SVG
|
||||||
l.Png = &FaviconImage{}
|
l.Png = &FaviconImage{}
|
||||||
l.Png.Raw, err = convert(l.Svg.Raw)
|
l.Png.Raw, err = convert(l.Svg.Raw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("[Favicons] Failed to generate PNG icon: %w", err)
|
return fmt.Errorf("favicons: failed to generate PNG icon: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,19 +100,19 @@ func (l *FaviconList) PreProcess(convert func(in []byte) ([]byte, error)) error
|
|||||||
// download ICO
|
// download ICO
|
||||||
l.Ico.Raw, err = getFaviconViaRequest(l.Ico.Url)
|
l.Ico.Raw, err = getFaviconViaRequest(l.Ico.Url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("[Favicons] Failed to fetch ICO icon: %w", err)
|
return fmt.Errorf("favicons: failed to fetch ICO icon: %w", err)
|
||||||
}
|
}
|
||||||
} else if l.Png != nil {
|
} else if l.Png != nil {
|
||||||
// generate ICO from PNG
|
// generate ICO from PNG
|
||||||
l.Ico = &FaviconImage{}
|
l.Ico = &FaviconImage{}
|
||||||
decode, err := png.Decode(bytes.NewReader(l.Png.Raw))
|
decode, err := png.Decode(bytes.NewReader(l.Png.Raw))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("[Favicons] Failed to decode PNG icon: %w", err)
|
return fmt.Errorf("favicons: failed to decode PNG icon: %w", err)
|
||||||
}
|
}
|
||||||
b := decode.Bounds()
|
b := decode.Bounds()
|
||||||
l.Ico.Raw, err = png2ico.ConvertPngToIco(l.Png.Raw, b.Dx(), b.Dy())
|
l.Ico.Raw, err = png2ico.ConvertPngToIco(l.Png.Raw, b.Dx(), b.Dy())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("[Favicons] Failed to generate ICO icon: %w", err)
|
return fmt.Errorf("favicons: failed to generate ICO icon: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,16 +139,16 @@ func (l *FaviconList) genSha256() {
|
|||||||
var getFaviconViaRequest = func(url string) ([]byte, error) {
|
var getFaviconViaRequest = func(url string) ([]byte, error) {
|
||||||
req, err := http.NewRequest(http.MethodGet, url, nil)
|
req, err := http.NewRequest(http.MethodGet, url, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("[Favicons] Failed to send request '%s': %w", url, err)
|
return nil, fmt.Errorf("favicons: Failed to send request '%s': %w", url, err)
|
||||||
}
|
}
|
||||||
req.Header.Set("X-Violet-Raw-Favicon", "1")
|
req.Header.Set("X-Violet-Raw-Favicon", "1")
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("[Favicons] Failed to do request '%s': %w", url, err)
|
return nil, fmt.Errorf("favicons: failed to do request '%s': %w", url, err)
|
||||||
}
|
}
|
||||||
rawBody, err := io.ReadAll(resp.Body)
|
rawBody, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("[Favicons] Failed to read response '%s': %w", url, err)
|
return nil, fmt.Errorf("favicons: failed to read response '%s': %w", url, err)
|
||||||
}
|
}
|
||||||
return rawBody, nil
|
return rawBody, nil
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,14 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/1f349/violet/database"
|
"github.com/1f349/violet/database"
|
||||||
|
"github.com/1f349/violet/logger"
|
||||||
"github.com/mrmelon54/rescheduler"
|
"github.com/mrmelon54/rescheduler"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
"log"
|
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var Logger = logger.Logger.WithPrefix("Violet Favicons")
|
||||||
|
|
||||||
var ErrFaviconNotFound = errors.New("favicon not found")
|
var ErrFaviconNotFound = errors.New("favicon not found")
|
||||||
|
|
||||||
// Favicons is a dynamic favicon generator which supports overwriting favicons
|
// Favicons is a dynamic favicon generator which supports overwriting favicons
|
||||||
@ -66,7 +68,7 @@ func (f *Favicons) threadCompile() {
|
|||||||
err := f.internalCompile(favicons)
|
err := f.internalCompile(favicons)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// log compile errors
|
// log compile errors
|
||||||
log.Printf("[Favicons] Compile failed: %s\n", err)
|
Logger.Info("Compile failed", "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
go.mod
10
go.mod
@ -5,6 +5,7 @@ go 1.22
|
|||||||
require (
|
require (
|
||||||
github.com/1f349/mjwt v0.2.5
|
github.com/1f349/mjwt v0.2.5
|
||||||
github.com/AlecAivazis/survey/v2 v2.3.7
|
github.com/AlecAivazis/survey/v2 v2.3.7
|
||||||
|
github.com/charmbracelet/log v0.4.0
|
||||||
github.com/golang-migrate/migrate/v4 v4.17.1
|
github.com/golang-migrate/migrate/v4 v4.17.1
|
||||||
github.com/google/subcommands v1.2.0
|
github.com/google/subcommands v1.2.0
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
@ -25,25 +26,34 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||||
github.com/becheran/wildmatch-go v1.0.0 // indirect
|
github.com/becheran/wildmatch-go v1.0.0 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
|
github.com/charmbracelet/lipgloss v0.10.0 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/go-logfmt/logfmt v0.6.0 // indirect
|
||||||
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
||||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||||
github.com/kr/text v0.2.0 // indirect
|
github.com/kr/text v0.2.0 // indirect
|
||||||
|
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
|
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
|
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
|
||||||
|
github.com/muesli/reflow v0.3.0 // indirect
|
||||||
|
github.com/muesli/termenv v0.15.2 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/prometheus/client_model v0.6.1 // indirect
|
github.com/prometheus/client_model v0.6.1 // indirect
|
||||||
github.com/prometheus/common v0.53.0 // indirect
|
github.com/prometheus/common v0.53.0 // indirect
|
||||||
github.com/prometheus/procfs v0.14.0 // indirect
|
github.com/prometheus/procfs v0.14.0 // indirect
|
||||||
|
github.com/rivo/uniseg v0.4.7 // indirect
|
||||||
github.com/rogpeppe/go-internal v1.12.0 // indirect
|
github.com/rogpeppe/go-internal v1.12.0 // indirect
|
||||||
go.uber.org/atomic v1.11.0 // indirect
|
go.uber.org/atomic v1.11.0 // indirect
|
||||||
|
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
|
||||||
golang.org/x/sys v0.20.0 // indirect
|
golang.org/x/sys v0.20.0 // indirect
|
||||||
golang.org/x/term v0.20.0 // indirect
|
golang.org/x/term v0.20.0 // indirect
|
||||||
golang.org/x/text v0.15.0 // indirect
|
golang.org/x/text v0.15.0 // indirect
|
||||||
|
23
go.sum
23
go.sum
@ -4,18 +4,26 @@ github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkk
|
|||||||
github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo=
|
github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo=
|
||||||
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=
|
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=
|
||||||
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w=
|
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w=
|
||||||
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
||||||
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
||||||
github.com/becheran/wildmatch-go v1.0.0 h1:mE3dGGkTmpKtT4Z+88t8RStG40yN9T+kFEGj2PZFSzA=
|
github.com/becheran/wildmatch-go v1.0.0 h1:mE3dGGkTmpKtT4Z+88t8RStG40yN9T+kFEGj2PZFSzA=
|
||||||
github.com/becheran/wildmatch-go v1.0.0/go.mod h1:gbMvj0NtVdJ15Mg/mH9uxk2R1QCistMyU7d9KFzroX4=
|
github.com/becheran/wildmatch-go v1.0.0/go.mod h1:gbMvj0NtVdJ15Mg/mH9uxk2R1QCistMyU7d9KFzroX4=
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
|
github.com/charmbracelet/lipgloss v0.10.0 h1:KWeXFSexGcfahHX+54URiZGkBFazf70JNMtwg/AFW3s=
|
||||||
|
github.com/charmbracelet/lipgloss v0.10.0/go.mod h1:Wig9DSfvANsxqkRsqj6x87irdy123SR4dOXlKa91ciE=
|
||||||
|
github.com/charmbracelet/log v0.4.0 h1:G9bQAcx8rWA2T3pWvx7YtPTPwgqpk7D68BX21IRW8ZM=
|
||||||
|
github.com/charmbracelet/log v0.4.0/go.mod h1:63bXt/djrizTec0l11H20t8FDSvA4CRZJ1KH22MdptM=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI=
|
github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI=
|
||||||
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
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/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
|
||||||
|
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||||
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
|
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
|
||||||
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||||
github.com/golang-migrate/migrate/v4 v4.17.1 h1:4zQ6iqL6t6AiItphxJctQb3cFqWiSpMnX7wLTPnnYO4=
|
github.com/golang-migrate/migrate/v4 v4.17.1 h1:4zQ6iqL6t6AiItphxJctQb3cFqWiSpMnX7wLTPnnYO4=
|
||||||
@ -45,6 +53,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
|||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
|
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
||||||
|
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
@ -52,6 +62,9 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
|
|||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
|
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||||
|
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||||
|
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
|
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
|
||||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||||
@ -67,6 +80,10 @@ github.com/mrmelon54/rescheduler v0.0.3 h1:TrkJL6S7PKvXuo1mvdgRgsILA/pk5L1lrXhV/
|
|||||||
github.com/mrmelon54/rescheduler v0.0.3/go.mod h1:q415n6W1xcePPP5Rix6FOiADgcN66BYMyNOsFnNyoWQ=
|
github.com/mrmelon54/rescheduler v0.0.3/go.mod h1:q415n6W1xcePPP5Rix6FOiADgcN66BYMyNOsFnNyoWQ=
|
||||||
github.com/mrmelon54/trie v0.0.3 h1:wZmws84FiGNBZJ00garLyQ2EQhtx0SipVoV7fK8+kZE=
|
github.com/mrmelon54/trie v0.0.3 h1:wZmws84FiGNBZJ00garLyQ2EQhtx0SipVoV7fK8+kZE=
|
||||||
github.com/mrmelon54/trie v0.0.3/go.mod h1:d3hl0YUBSWR3XN4S9BDLkGVzLT4VgwP2mZkBJM6uFpw=
|
github.com/mrmelon54/trie v0.0.3/go.mod h1:d3hl0YUBSWR3XN4S9BDLkGVzLT4VgwP2mZkBJM6uFpw=
|
||||||
|
github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
|
||||||
|
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
|
||||||
|
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
|
||||||
|
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
@ -79,6 +96,10 @@ github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+a
|
|||||||
github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U=
|
github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U=
|
||||||
github.com/prometheus/procfs v0.14.0 h1:Lw4VdGGoKEZilJsayHf0B+9YgLGREba2C6xr+Fdfq6s=
|
github.com/prometheus/procfs v0.14.0 h1:Lw4VdGGoKEZilJsayHf0B+9YgLGREba2C6xr+Fdfq6s=
|
||||||
github.com/prometheus/procfs v0.14.0/go.mod h1:XL+Iwz8k8ZabyZfMFHPiilCniixqQarAy5Mu67pHlNQ=
|
github.com/prometheus/procfs v0.14.0/go.mod h1:XL+Iwz8k8ZabyZfMFHPiilCniixqQarAy5Mu67pHlNQ=
|
||||||
|
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
|
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
|
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||||
|
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||||
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||||
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||||
github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po=
|
github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po=
|
||||||
@ -94,6 +115,8 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
|||||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
|
||||||
|
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
12
logger/logger.go
Normal file
12
logger/logger.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package logger
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/charmbracelet/log"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Logger = log.NewWithOptions(os.Stderr, log.Options{
|
||||||
|
ReportCaller: true,
|
||||||
|
ReportTimestamp: true,
|
||||||
|
Prefix: "Violet",
|
||||||
|
})
|
@ -2,15 +2,19 @@ package proxy
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"github.com/1f349/violet/logger"
|
||||||
"github.com/1f349/violet/proxy/websocket"
|
"github.com/1f349/violet/proxy/websocket"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"log"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var loggerSecure = logger.Logger.WithPrefix("Violet Secure Transport")
|
||||||
|
var loggerInsecure = logger.Logger.WithPrefix("Violet Insecure Transport")
|
||||||
|
var loggerWebsocket = logger.Logger.WithPrefix("Violet Websocket Transport")
|
||||||
|
|
||||||
type HybridTransport struct {
|
type HybridTransport struct {
|
||||||
baseDialer *net.Dialer
|
baseDialer *net.Dialer
|
||||||
normalTransport http.RoundTripper
|
normalTransport http.RoundTripper
|
||||||
@ -72,23 +76,23 @@ func NewHybridTransportWithCalls(normal, insecure http.RoundTripper, ws *websock
|
|||||||
// SecureRoundTrip calls the secure transport
|
// SecureRoundTrip calls the secure transport
|
||||||
func (h *HybridTransport) SecureRoundTrip(req *http.Request) (*http.Response, error) {
|
func (h *HybridTransport) SecureRoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
u := uuid.New()
|
u := uuid.New()
|
||||||
log.Println("[Transport] Start upgrade:", u)
|
loggerSecure.Info("Start upgrade", "id", u)
|
||||||
defer log.Println("[Transport] Stop upgrade:", u)
|
defer loggerSecure.Info("Stop upgrade", "id", u)
|
||||||
return h.normalTransport.RoundTrip(req)
|
return h.normalTransport.RoundTrip(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
// InsecureRoundTrip calls the insecure transport
|
// InsecureRoundTrip calls the insecure transport
|
||||||
func (h *HybridTransport) InsecureRoundTrip(req *http.Request) (*http.Response, error) {
|
func (h *HybridTransport) InsecureRoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
u := uuid.New()
|
u := uuid.New()
|
||||||
log.Println("[Transport insecure] Start upgrade:", u)
|
loggerInsecure.Info("Start upgrade", "id", u)
|
||||||
defer log.Println("[Transport insecure] Stop upgrade:", u)
|
defer loggerInsecure.Info("Stop upgrade", "id", u)
|
||||||
return h.insecureTransport.RoundTrip(req)
|
return h.insecureTransport.RoundTrip(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConnectWebsocket calls the websocket upgrader and thus hijacks the connection
|
// ConnectWebsocket calls the websocket upgrader and thus hijacks the connection
|
||||||
func (h *HybridTransport) ConnectWebsocket(rw http.ResponseWriter, req *http.Request) {
|
func (h *HybridTransport) ConnectWebsocket(rw http.ResponseWriter, req *http.Request) {
|
||||||
u := uuid.New()
|
u := uuid.New()
|
||||||
log.Println("[Websocket] Start upgrade:", u)
|
loggerWebsocket.Info("Start upgrade", "id", u)
|
||||||
h.ws.Upgrade(rw, req)
|
h.ws.Upgrade(rw, req)
|
||||||
log.Println("[Websocket] Stop upgrade:", u)
|
loggerWebsocket.Info("Stop upgrade", "id", u)
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
package websocket
|
package websocket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/1f349/violet/logger"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var Logger = logger.Logger.WithPrefix("Violet Websocket")
|
||||||
|
|
||||||
var upgrader = websocket.Upgrader{
|
var upgrader = websocket.Upgrader{
|
||||||
HandshakeTimeout: time.Second * 5,
|
HandshakeTimeout: time.Second * 5,
|
||||||
ReadBufferSize: 1024,
|
ReadBufferSize: 1024,
|
||||||
@ -34,7 +36,7 @@ func NewServer() *Server {
|
|||||||
|
|
||||||
func (s *Server) Upgrade(rw http.ResponseWriter, req *http.Request) {
|
func (s *Server) Upgrade(rw http.ResponseWriter, req *http.Request) {
|
||||||
req.URL.Scheme = "ws"
|
req.URL.Scheme = "ws"
|
||||||
log.Printf("[Websocket] Upgrading request to '%s' from '%s'\n", req.URL.String(), req.Header.Get("Origin"))
|
Logger.Info("Upgrading request", "url", req.URL, "origin", req.Header.Get("Origin"))
|
||||||
|
|
||||||
c, err := upgrader.Upgrade(rw, req, nil)
|
c, err := upgrader.Upgrade(rw, req, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -54,12 +56,12 @@ func (s *Server) Upgrade(rw http.ResponseWriter, req *http.Request) {
|
|||||||
s.conns[c.RemoteAddr().String()] = c
|
s.conns[c.RemoteAddr().String()] = c
|
||||||
s.connLock.Unlock()
|
s.connLock.Unlock()
|
||||||
|
|
||||||
log.Printf("[Websocket] Dialing: '%s'\n", req.URL.String())
|
Logger.Info("Dialing", "url", req.URL)
|
||||||
|
|
||||||
// dial for internal connection
|
// dial for internal connection
|
||||||
ic, _, err := websocket.DefaultDialer.DialContext(req.Context(), req.URL.String(), nil)
|
ic, _, err := websocket.DefaultDialer.DialContext(req.Context(), req.URL.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[Websocket] Failed to dial '%s': %s\n", req.URL.String(), err)
|
Logger.Info("Failed to dial", "url", req.URL, "err", err)
|
||||||
s.Remove(c)
|
s.Remove(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -73,7 +75,7 @@ func (s *Server) Upgrade(rw http.ResponseWriter, req *http.Request) {
|
|||||||
go s.wsRelay(d2, ic, c)
|
go s.wsRelay(d2, ic, c)
|
||||||
|
|
||||||
// wait for done signal and close both connections
|
// wait for done signal and close both connections
|
||||||
log.Println("[Websocket] Completed websocket hijacking")
|
Logger.Info("Completed websocket hijacking")
|
||||||
|
|
||||||
// waiting until d1 or d2 close then automatically defer close both connections
|
// waiting until d1 or d2 close then automatically defer close both connections
|
||||||
select {
|
select {
|
||||||
@ -89,7 +91,7 @@ func (s *Server) wsRelay(done chan struct{}, a, b *websocket.Conn) {
|
|||||||
for {
|
for {
|
||||||
mt, message, err := a.ReadMessage()
|
mt, message, err := a.ReadMessage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Websocket read message error: ", err)
|
Logger.Info("Read message", "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if b.WriteMessage(mt, message) != nil {
|
if b.WriteMessage(mt, message) != nil {
|
||||||
|
@ -4,15 +4,17 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
_ "embed"
|
_ "embed"
|
||||||
"github.com/1f349/violet/database"
|
"github.com/1f349/violet/database"
|
||||||
|
"github.com/1f349/violet/logger"
|
||||||
"github.com/1f349/violet/proxy"
|
"github.com/1f349/violet/proxy"
|
||||||
"github.com/1f349/violet/target"
|
"github.com/1f349/violet/target"
|
||||||
"github.com/mrmelon54/rescheduler"
|
"github.com/mrmelon54/rescheduler"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var Logger = logger.Logger.WithPrefix("Violet Manager")
|
||||||
|
|
||||||
// Manager is a database and mutex wrap around router allowing it to be
|
// Manager is a database and mutex wrap around router allowing it to be
|
||||||
// dynamically regenerated after updating the database of routes.
|
// dynamically regenerated after updating the database of routes.
|
||||||
type Manager struct {
|
type Manager struct {
|
||||||
@ -54,7 +56,7 @@ func (m *Manager) threadCompile() {
|
|||||||
// compile router and check errors
|
// compile router and check errors
|
||||||
err := m.internalCompile(router)
|
err := m.internalCompile(router)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[Manager] Compile failed: %s\n", err)
|
Logger.Info("Compile failed", "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +69,7 @@ func (m *Manager) threadCompile() {
|
|||||||
// internalCompile is a hidden internal method for querying the database during
|
// internalCompile is a hidden internal method for querying the database during
|
||||||
// the Compile() method.
|
// the Compile() method.
|
||||||
func (m *Manager) internalCompile(router *Router) error {
|
func (m *Manager) internalCompile(router *Router) error {
|
||||||
log.Println("[Manager] Updating routes from database")
|
Logger.Info("Updating routes from database")
|
||||||
|
|
||||||
// sql or something?
|
// sql or something?
|
||||||
routeRows, err := m.db.GetActiveRoutes(context.Background())
|
routeRows, err := m.db.GetActiveRoutes(context.Background())
|
||||||
|
@ -3,11 +3,11 @@ package api
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/1f349/mjwt"
|
"github.com/1f349/mjwt"
|
||||||
|
"github.com/1f349/violet/logger"
|
||||||
"github.com/1f349/violet/router"
|
"github.com/1f349/violet/router"
|
||||||
"github.com/1f349/violet/target"
|
"github.com/1f349/violet/target"
|
||||||
"github.com/1f349/violet/utils"
|
"github.com/1f349/violet/utils"
|
||||||
"github.com/julienschmidt/httprouter"
|
"github.com/julienschmidt/httprouter"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@ -19,7 +19,7 @@ func SetupTargetApis(r *httprouter.Router, verify mjwt.Verifier, manager *router
|
|||||||
|
|
||||||
routes, err := manager.GetAllRoutes(domains)
|
routes, err := manager.GetAllRoutes(domains)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[Violet] Failed to get routes from database: %s\n", err)
|
logger.Logger.Infof("Failed to get routes from database: %s\n", err)
|
||||||
apiError(rw, http.StatusInternalServerError, "Failed to get routes from database")
|
apiError(rw, http.StatusInternalServerError, "Failed to get routes from database")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -29,7 +29,7 @@ func SetupTargetApis(r *httprouter.Router, verify mjwt.Verifier, manager *router
|
|||||||
r.POST("/route", parseJsonAndCheckOwnership[routeSource](verify, "route", func(rw http.ResponseWriter, req *http.Request, params httprouter.Params, b AuthClaims, t routeSource) {
|
r.POST("/route", parseJsonAndCheckOwnership[routeSource](verify, "route", func(rw http.ResponseWriter, req *http.Request, params httprouter.Params, b AuthClaims, t routeSource) {
|
||||||
err := manager.InsertRoute(target.RouteWithActive(t))
|
err := manager.InsertRoute(target.RouteWithActive(t))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[Violet] Failed to insert route into database: %s\n", err)
|
logger.Logger.Infof("Failed to insert route into database: %s\n", err)
|
||||||
apiError(rw, http.StatusInternalServerError, "Failed to insert route into database")
|
apiError(rw, http.StatusInternalServerError, "Failed to insert route into database")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -38,7 +38,7 @@ func SetupTargetApis(r *httprouter.Router, verify mjwt.Verifier, manager *router
|
|||||||
r.DELETE("/route", parseJsonAndCheckOwnership[sourceJson](verify, "route", func(rw http.ResponseWriter, req *http.Request, params httprouter.Params, b AuthClaims, t sourceJson) {
|
r.DELETE("/route", parseJsonAndCheckOwnership[sourceJson](verify, "route", func(rw http.ResponseWriter, req *http.Request, params httprouter.Params, b AuthClaims, t sourceJson) {
|
||||||
err := manager.DeleteRoute(t.Src)
|
err := manager.DeleteRoute(t.Src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[Violet] Failed to delete route from database: %s\n", err)
|
logger.Logger.Infof("Failed to delete route from database: %s\n", err)
|
||||||
apiError(rw, http.StatusInternalServerError, "Failed to delete route from database")
|
apiError(rw, http.StatusInternalServerError, "Failed to delete route from database")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -51,7 +51,7 @@ func SetupTargetApis(r *httprouter.Router, verify mjwt.Verifier, manager *router
|
|||||||
|
|
||||||
redirects, err := manager.GetAllRedirects(domains)
|
redirects, err := manager.GetAllRedirects(domains)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[Violet] Failed to get redirects from database: %s\n", err)
|
logger.Logger.Infof("Failed to get redirects from database: %s\n", err)
|
||||||
apiError(rw, http.StatusInternalServerError, "Failed to get redirects from database")
|
apiError(rw, http.StatusInternalServerError, "Failed to get redirects from database")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -61,7 +61,7 @@ func SetupTargetApis(r *httprouter.Router, verify mjwt.Verifier, manager *router
|
|||||||
r.POST("/redirect", parseJsonAndCheckOwnership[redirectSource](verify, "redirect", func(rw http.ResponseWriter, req *http.Request, params httprouter.Params, b AuthClaims, t redirectSource) {
|
r.POST("/redirect", parseJsonAndCheckOwnership[redirectSource](verify, "redirect", func(rw http.ResponseWriter, req *http.Request, params httprouter.Params, b AuthClaims, t redirectSource) {
|
||||||
err := manager.InsertRedirect(target.RedirectWithActive(t))
|
err := manager.InsertRedirect(target.RedirectWithActive(t))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[Violet] Failed to insert redirect into database: %s\n", err)
|
logger.Logger.Infof("Failed to insert redirect into database: %s\n", err)
|
||||||
apiError(rw, http.StatusInternalServerError, "Failed to insert redirect into database")
|
apiError(rw, http.StatusInternalServerError, "Failed to insert redirect into database")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -70,7 +70,7 @@ func SetupTargetApis(r *httprouter.Router, verify mjwt.Verifier, manager *router
|
|||||||
r.DELETE("/redirect", parseJsonAndCheckOwnership[sourceJson](verify, "redirect", func(rw http.ResponseWriter, req *http.Request, params httprouter.Params, b AuthClaims, t sourceJson) {
|
r.DELETE("/redirect", parseJsonAndCheckOwnership[sourceJson](verify, "redirect", func(rw http.ResponseWriter, req *http.Request, params httprouter.Params, b AuthClaims, t sourceJson) {
|
||||||
err := manager.DeleteRedirect(t.Src)
|
err := manager.DeleteRedirect(t.Src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[Violet] Failed to delete redirect from database: %s\n", err)
|
logger.Logger.Infof("Failed to delete redirect from database: %s\n", err)
|
||||||
apiError(rw, http.StatusInternalServerError, "Failed to delete redirect from database")
|
apiError(rw, http.StatusInternalServerError, "Failed to delete redirect from database")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,13 @@ import (
|
|||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/1f349/violet/favicons"
|
"github.com/1f349/violet/favicons"
|
||||||
|
"github.com/1f349/violet/logger"
|
||||||
"github.com/1f349/violet/servers/conf"
|
"github.com/1f349/violet/servers/conf"
|
||||||
"github.com/1f349/violet/servers/metrics"
|
"github.com/1f349/violet/servers/metrics"
|
||||||
"github.com/1f349/violet/utils"
|
"github.com/1f349/violet/utils"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/sethvargo/go-limiter/httplimit"
|
"github.com/sethvargo/go-limiter/httplimit"
|
||||||
"github.com/sethvargo/go-limiter/memorystore"
|
"github.com/sethvargo/go-limiter/memorystore"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"path"
|
"path"
|
||||||
"runtime"
|
"runtime"
|
||||||
@ -21,7 +21,7 @@ import (
|
|||||||
// endpoints for the reverse proxy.
|
// endpoints for the reverse proxy.
|
||||||
func NewHttpsServer(conf *conf.Conf, registry *prometheus.Registry) *http.Server {
|
func NewHttpsServer(conf *conf.Conf, registry *prometheus.Registry) *http.Server {
|
||||||
r := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
r := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||||
log.Printf("[Debug] Request: %s - '%s' - '%s' - '%s' - len: %d - thread: %d\n", req.Method, req.URL.String(), req.RemoteAddr, req.Host, req.ContentLength, runtime.NumGoroutine())
|
logger.Logger.Debug("Request", "method", req.Method, "url", req.URL, "remote", req.RemoteAddr, "host", req.Host, "length", req.ContentLength, "goroutine", runtime.NumGoroutine())
|
||||||
conf.Router.ServeHTTP(rw, req)
|
conf.Router.ServeHTTP(rw, req)
|
||||||
})
|
})
|
||||||
favMiddleware := setupFaviconMiddleware(conf.Favicons, r)
|
favMiddleware := setupFaviconMiddleware(conf.Favicons, r)
|
||||||
@ -88,13 +88,13 @@ func setupRateLimiter(rateLimit uint64, next http.Handler) http.Handler {
|
|||||||
Interval: time.Minute,
|
Interval: time.Minute,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln(err)
|
logger.Logger.Fatal("Failed to initialize memory store", "err", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a middleware using ips as the key for rate limits
|
// create a middleware using ips as the key for rate limits
|
||||||
middleware, err := httplimit.NewMiddleware(store, httplimit.IPKeyFunc())
|
middleware, err := httplimit.NewMiddleware(store, httplimit.IPKeyFunc())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln(err)
|
logger.Logger.Fatal("Failed to initialize httplimit middleware", "err", err)
|
||||||
}
|
}
|
||||||
return middleware.Handle(next)
|
return middleware.Handle(next)
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package target
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/1f349/violet/logger"
|
||||||
"github.com/1f349/violet/proxy"
|
"github.com/1f349/violet/proxy"
|
||||||
"github.com/1f349/violet/utils"
|
"github.com/1f349/violet/utils"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
@ -9,7 +10,6 @@ import (
|
|||||||
"github.com/rs/cors"
|
"github.com/rs/cors"
|
||||||
"golang.org/x/net/http/httpguts"
|
"golang.org/x/net/http/httpguts"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/textproto"
|
"net/textproto"
|
||||||
@ -18,6 +18,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var Logger = logger.Logger.WithPrefix("Violet Serve Route")
|
||||||
|
|
||||||
// serveApiCors outputs the cors headers to make APIs work.
|
// serveApiCors outputs the cors headers to make APIs work.
|
||||||
var serveApiCors = cors.New(cors.Options{
|
var serveApiCors = cors.New(cors.Options{
|
||||||
// allow all origins for api requests
|
// allow all origins for api requests
|
||||||
@ -128,7 +130,7 @@ func (r Route) internalServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
|||||||
// create the internal request
|
// create the internal request
|
||||||
req2, err := http.NewRequest(req.Method, u.String(), req.Body)
|
req2, err := http.NewRequest(req.Method, u.String(), req.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[ServeRoute::ServeHTTP()] Error generating new request: %s\n", err)
|
Logger.Warn("Error generating new request", "err", err)
|
||||||
utils.RespondVioletError(rw, http.StatusBadGateway, "error generating new request")
|
utils.RespondVioletError(rw, http.StatusBadGateway, "error generating new request")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -179,7 +181,7 @@ func (r Route) internalServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
|||||||
resp, err = r.Proxy.SecureRoundTrip(req2)
|
resp, err = r.Proxy.SecureRoundTrip(req2)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[ServeRoute::ServeHTTP()] Error receiving internal round trip response: %s\n", err)
|
Logger.Warn("Error receiving internal round trip response", "err", err)
|
||||||
utils.RespondVioletError(rw, http.StatusBadGateway, "error receiving internal round trip response")
|
utils.RespondVioletError(rw, http.StatusBadGateway, "error receiving internal round trip response")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -191,7 +193,7 @@ func (r Route) internalServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
|||||||
|
|
||||||
if resp.StatusCode == http.StatusLoopDetected {
|
if resp.StatusCode == http.StatusLoopDetected {
|
||||||
u := uuid.New()
|
u := uuid.New()
|
||||||
log.Printf("[ServeRoute::ServeHTTP()] Loop Detected: %s %s '%s' -> '%s'\n", u, req.Method, req.URL.String(), req2.URL.String())
|
Logger.Warn("Loop Detected", "id", u, "method", req.Method, "url", req.URL, "url2", req2.URL.String())
|
||||||
utils.RespondVioletError(rw, http.StatusLoopDetected, "error loop detected: "+u.String())
|
utils.RespondVioletError(rw, http.StatusLoopDetected, "error loop detected: "+u.String())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -2,33 +2,33 @@ package utils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
"github.com/charmbracelet/log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// logHttpServerError is the internal function powering the logging in
|
// logHttpServerError is the internal function powering the logging in
|
||||||
// RunBackgroundHttp and RunBackgroundHttps.
|
// RunBackgroundHttp and RunBackgroundHttps.
|
||||||
func logHttpServerError(prefix string, err error) {
|
func logHttpServerError(logger *log.Logger, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, http.ErrServerClosed) {
|
if errors.Is(err, http.ErrServerClosed) {
|
||||||
log.Printf("[%s] The http server shutdown successfully\n", prefix)
|
logger.Info("The http server shutdown successfully")
|
||||||
} else {
|
} else {
|
||||||
log.Printf("[%s] Error trying to host the http server: %s\n", prefix, err.Error())
|
logger.Info("Error trying to host the http server", "err", err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunBackgroundHttp runs a http server and logs when the server closes or
|
// RunBackgroundHttp runs a http server and logs when the server closes or
|
||||||
// errors.
|
// errors.
|
||||||
func RunBackgroundHttp(prefix string, s *http.Server) {
|
func RunBackgroundHttp(logger *log.Logger, s *http.Server) {
|
||||||
logHttpServerError(prefix, s.ListenAndServe())
|
logHttpServerError(logger, s.ListenAndServe())
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunBackgroundHttps runs a http server with TLS encryption and logs when the
|
// RunBackgroundHttps runs a http server with TLS encryption and logs when the
|
||||||
// server closes or errors.
|
// server closes or errors.
|
||||||
func RunBackgroundHttps(prefix string, s *http.Server) {
|
func RunBackgroundHttps(logger *log.Logger, s *http.Server) {
|
||||||
logHttpServerError(prefix, s.ListenAndServeTLS("", ""))
|
logHttpServerError(logger, s.ListenAndServeTLS("", ""))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBearer returns the bearer from the Authorization header or an empty string
|
// GetBearer returns the bearer from the Authorization header or an empty string
|
||||||
|
Loading…
Reference in New Issue
Block a user