realxlfd 2 months ago
parent
commit
6f52ceeb73
  1. 88
      cli/logger/index.go
  2. 13
      net/app/reverse_proxy/logger.go
  3. 139
      net/app/reverse_proxy/server.go
  4. 11
      proc/index.go
  5. 57
      test/str_test.go
  6. 80
      utils/file/fos/remove_null_dirs.go

88
cli/logger/index.go

@ -0,0 +1,88 @@
package logger
import (
"fmt"
"time"
"git.realxlfd.cc/RealXLFD/golib/utils/str"
"github.com/gookit/color"
)
type Logger struct {
Level Level
HideTime bool
}
type Level int
const (
LevelSlient Level = iota - 3
LevelError
LevelWarn
LevelInfo
LevelDebug
)
var (
red = color.FgRed.Render
yellow = color.FgYellow.Render
green = color.FgGreen.Render
gray = color.FgGray.Render
)
var (
argError = red("ERR")
argWarn = yellow("WRN")
argInfo = green("INF")
argDebug = "DBG"
)
var (
Timer = func() string {
return time.Now().Format(time.Kitchen)
}
)
func (l Logger) Info(msg ...interface{}) {
if l.Level < LevelInfo {
return
}
timeStamp := ""
if !l.HideTime {
timeStamp = str.Join(Timer(), " ")
}
fmt.Println(str.Join(timeStamp, argInfo), msg)
}
func (l Logger) Debug(msg ...interface{}) {
if l.Level < LevelDebug {
return
}
timeStamp := ""
if !l.HideTime {
timeStamp = str.Join(Timer(), " ")
}
fmt.Println(str.Join(timeStamp, argDebug), msg)
}
func (l Logger) Warn(msg ...interface{}) {
if l.Level < LevelWarn {
return
}
timeStamp := ""
if !l.HideTime {
timeStamp = str.Join(Timer(), " ")
}
fmt.Println(str.Join(timeStamp, argWarn), msg)
}
func (l Logger) Error(msg ...interface{}) {
if l.Level < LevelError {
return
}
timeStamp := ""
if !l.HideTime {
timeStamp = str.Join(Timer(), " ")
}
fmt.Println(str.Join(timeStamp, argError), msg)
}

13
net/app/reverse_proxy/logger.go

@ -0,0 +1,13 @@
package rproxy
import (
"git.realxlfd.cc/RealXLFD/golib/cli/logger"
)
var (
l = &logger.Logger{}
)
func SetLogLevel(level logger.Level) {
l.Level = level
}

139
net/app/reverse_proxy/server.go

@ -0,0 +1,139 @@
package rproxy
import (
"context"
"errors"
"fmt"
"net/http"
"net/http/httputil"
"net/url"
"time"
"git.realxlfd.cc/RealXLFD/golib/utils/str"
)
type Server struct {
config *config
revProxyClient *httputil.ReverseProxy
httpServer *http.Server
}
type config struct {
Port int
TargetURL *url.URL
ProxyURL *url.URL
Handler func(r *http.Request)
}
func CreateServer(port int, target *url.URL) *Server {
if port < 80 || port > 65535 {
panic("port out of range (80-65535)")
}
conf := &config{
Port: port,
TargetURL: target,
ProxyURL: nil,
Handler: func(r *http.Request) {},
}
reverseProxy := httputil.NewSingleHostReverseProxy(conf.TargetURL)
server := &Server{
config: conf,
revProxyClient: reverseProxy,
httpServer: nil,
}
return server
}
func (s *Server) WithTransportProxy(proxy string) *Server {
if proxy == "" {
return s
}
proxyURL, err := url.Parse(proxy)
if err != nil {
panic(err)
}
s.config.ProxyURL = proxyURL
s.revProxyClient.Transport = &http.Transport{
Proxy: http.ProxyURL(proxyURL),
}
return s
}
func (s *Server) WithRequestHandler(f func(r *http.Request)) *Server {
s.config.Handler = f
return s
}
func (s *Server) Run() *Server {
if s.httpServer != nil {
return s
}
go func() {
err := s.runner()()
if err != nil {
logger.Error(fmt.Sprintf("server failed: %s", err.Error()))
}
}()
return s
}
func (s *Server) RunSync() error {
if s.httpServer != nil {
return errors.New("server already running")
}
exitCh := make(chan error)
go func() {
exitCh <- s.runner()()
}()
err := <-exitCh
return err
}
func (s *Server) runner() func() error {
return func() error {
mux := http.NewServeMux()
mux.HandleFunc("/", s.requestHandler())
httpServer := &http.Server{
Addr: fmt.Sprintf(":%d", s.config.Port),
Handler: mux,
}
return httpServer.ListenAndServe()
}
}
func (s *Server) IsRunning() bool {
return s.httpServer != nil
}
func (s *Server) Stop() error {
if !s.IsRunning() {
return errors.New("server has already stopped")
}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
err := s.httpServer.Shutdown(ctx)
return err
}
func (s *Server) requestHandler() func(
w http.ResponseWriter, r *http.Request,
) {
return func(w http.ResponseWriter, r *http.Request) {
var proxyInfo string
if s.config.ProxyURL != nil {
proxyInfo = fmt.Sprintf(" -> [%s]", s.config.ProxyURL.Host)
}
logger.Info(
fmt.Sprintf(
"%s -> [:%d]%s -> %s",
r.RemoteAddr,
s.config.Port,
proxyInfo,
str.Trim(
str.Join(s.config.TargetURL.Host, r.RequestURI),
20,
),
),
)
r.Host = s.config.TargetURL.Host
s.config.Handler(r)
s.revProxyClient.ServeHTTP(w, r)
}
}

11
proc/index.go

@ -0,0 +1,11 @@
package proc
import (
"sync"
)
func JustWait() {
lock := sync.Mutex{}
lock.Lock()
lock.Lock()
}

57
test/str_test.go

@ -0,0 +1,57 @@
package test
import (
"testing"
"git.realxlfd.cc/RealXLFD/golib/utils/str"
"github.com/stretchr/testify/assert"
)
func TestNewFilter(t *testing.T) {
preclude := []string{"test1", "test2"}
filter := str.NewFilter(preclude...)
assert.True(t, filter.Contains("test1"))
assert.True(t, filter.Contains("test2"))
assert.False(t, filter.Contains("test3"))
}
func TestContains(t *testing.T) {
preclude := []string{"test1", "test2"}
filter := str.NewFilter(preclude...)
assert.True(t, filter.Contains("test1"))
assert.False(t, filter.Contains("test3"))
}
func TestGetCount(t *testing.T) {
preclude := []string{"test1", "test2"}
filter := str.NewFilter(preclude...)
filter.Count("test1")
filter.Count("test1")
assert.Equal(t, 2, filter.GetCount("test1"))
assert.Equal(t, 0, filter.GetCount("test2"))
}
func TestCount(t *testing.T) {
preclude := []string{"test1", "test2"}
filter := str.NewFilter(preclude...)
filter.Count("test1")
filter.Count("test1")
filter.Count("test2")
assert.Equal(t, 2, filter.GetCount("test1"))
assert.Equal(t, 1, filter.GetCount("test2"))
}
func TestCountWithNonExistentKey(t *testing.T) {
preclude := []string{"test1", "test2"}
filter := str.NewFilter(preclude...)
filter.Count("test3")
assert.Equal(t, 0, filter.GetCount("test3"))
}

80
utils/file/fos/remove_null_dirs.go

@ -0,0 +1,80 @@
package fos
import (
"errors"
"io/fs"
"os"
"path/filepath"
"git.realxlfd.cc/RealXLFD/golib/utils/str"
)
func RemoveNullDirs(path string, ignoreTypes ...string) error {
var stat fs.FileInfo
var err error
stat, err = os.Stat(path)
if err != nil || !stat.IsDir() {
return errors.New("remover: path have to be a directory")
}
filter := str.NewFilter(ignoreTypes...)
var dirs []fs.DirEntry
dirs, err = os.ReadDir(path)
for _, dir := range dirs {
if !dir.IsDir() {
ext := filepath.Ext(dir.Name())
if ext != "" {
ext = ext[1:]
}
if filter.Contains(ext) {
err = os.Remove(filepath.Join(path, dir.Name()))
if err != nil {
return err
}
}
continue
}
err, _ = removeNullDir(filepath.Join(path, dir.Name()), filter)
if err != nil {
return err
}
}
return nil
}
func removeNullDir(path string, filter *str.Filter) (
err error, isNull bool,
) {
isNull = true
var isChildNull bool
dirs, err := os.ReadDir(path)
if err != nil {
return err, false
}
for _, dir := range dirs {
if dir.IsDir() {
err, isChildNull = removeNullDir(
filepath.Join(path, dir.Name()), filter,
)
if err != nil {
return err, false
}
if !isChildNull {
isNull = false
}
continue
}
ext := filepath.Ext(dir.Name())
if ext != "" {
ext = ext[1:]
}
if filter.Contains(ext) {
continue
}
isNull = false
}
if isNull {
err = os.RemoveAll(path)
return err, true
}
return nil, isNull
}
Loading…
Cancel
Save