Files
tunnel-please/server/middleware.go
bagas 69c3e78728
All checks were successful
Docker Build and Push / build-and-push (push) Successful in 5m7s
fix: correct read/write handling in CustomWriter
2025-12-06 22:18:43 +07:00

177 lines
3.8 KiB
Go

package server
import (
"fmt"
"net"
"time"
)
type RequestMiddleware interface {
HandleRequest(header *RequestHeaderFactory) error
}
type ResponseMiddleware interface {
HandleResponse(header *ResponseHeaderFactory, body []byte) error
}
type TunnelFingerprint struct{}
func NewTunnelFingerprint() *TunnelFingerprint {
return &TunnelFingerprint{}
}
func (h *TunnelFingerprint) HandleResponse(header *ResponseHeaderFactory, body []byte) error {
header.Set("Server", "Tunnel Please")
return nil
}
type RequestLogger struct {
interaction Interaction
remoteAddr net.Addr
}
func NewRequestLogger(interaction Interaction, remoteAddr net.Addr) *RequestLogger {
return &RequestLogger{
interaction: interaction,
remoteAddr: remoteAddr,
}
}
func (rl *RequestLogger) HandleRequest(header *RequestHeaderFactory) error {
rl.interaction.SendMessage(fmt.Sprintf("\033[32m%s %s -> %s %s \033[0m\r\n", time.Now().UTC().Format(time.RFC3339), rl.remoteAddr.String(), header.Method, header.Path))
return nil
}
type ForwardedFor struct {
addr net.Addr
}
func NewForwardedFor(addr net.Addr) *ForwardedFor {
return &ForwardedFor{addr: addr}
}
func (ff *ForwardedFor) HandleRequest(header *RequestHeaderFactory) error {
host, _, err := net.SplitHostPort(ff.addr.String())
if err != nil {
return err
}
header.Set("X-Forwarded-For", host)
return nil
}
//TODO: Implement caching atau enggak
//const maxCacheSize = 50 * 1024 * 1024
//
//type DiskCacheMiddleware struct {
// dir string
// mu sync.Mutex
// file *os.File
// path string
// cacheable bool
//}
//
//func NewDiskCacheMiddleware() *DiskCacheMiddleware {
// return &DiskCacheMiddleware{dir: "cache"}
//}
//
//func (c *DiskCacheMiddleware) ensureDir() error {
// return os.MkdirAll(c.dir, 0755)
//}
//
//func (c *DiskCacheMiddleware) cacheKey(method, path string) string {
// return fmt.Sprintf("%s_%s.cache", method, base64.URLEncoding.EncodeToString([]byte(path)))
//}
//
//func (c *DiskCacheMiddleware) filePath(method, path string) string {
// return filepath.Join(c.dir, c.cacheKey(method, path))
//}
//
//func fileExists(path string) bool {
// _, err := os.Stat(path)
// if err == nil {
// return true
// }
// if os.IsNotExist(err) {
// return false
// }
// return false
//}
//
//func canCacheRequest(header *RequestHeaderFactory) bool {
// if header.Method != "GET" {
// return false
// }
//
// if cacheControl := header.Get("Cache-Control"); cacheControl != "" {
// if strings.Contains(cacheControl, "no-store") || strings.Contains(cacheControl, "private") || strings.Contains(cacheControl, "no-cache") || strings.Contains(cacheControl, "max-age=0") {
// return false
// }
// }
//
// if header.Get("Authorization") != "" {
// return false
// }
//
// if header.Get("Cookie") != "" {
// return false
// }
//
// return true
//}
//
//func (c *DiskCacheMiddleware) HandleRequest(header *RequestHeaderFactory) error {
// if !canCacheRequest(header) {
// c.cacheable = false
// return nil
// }
//
// c.cacheable = true
// _ = c.ensureDir()
// path := c.filePath(header.Method, header.Path)
//
// if fileExists(path + ".finish") {
// c.file = nil
// return nil
// }
//
// if c.file != nil {
// err := c.file.Close()
// if err != nil {
// return err
// }
// err = os.Rename(c.path, c.path+".finish")
// if err != nil {
// return err
// }
// }
//
// c.path = path
// f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
// if err != nil {
// return err
// }
//
// c.file = f
//
// return nil
//}
//
//func (c *DiskCacheMiddleware) HandleResponse(header *ResponseHeaderFactory, body []byte) error {
// if !c.cacheable {
// return nil
// }
//
// if c.file == nil {
// header.Set("X-Cache", "HIT")
// return nil
// }
//
// _, err := c.file.Write(body)
// if err != nil {
// return err
// }
//
// header.Set("X-Cache", "MISS")
// return nil
//}