@@ -2,74 +2,98 @@ package traefik_safeline
22
33import (
44 "context"
5- "encoding/json "
5+ "fmt "
66 "log"
77 "net/http"
88 "os"
9+ "sync"
910
10- "github.com/xbingW /t1k"
11+ t1k "github.com/chaitin /t1k-go "
1112)
1213
1314// Package example a example plugin.
1415
1516// Config the plugin configuration.
1617type Config struct {
1718 // Addr is the address for the detector
18- Addr string `yaml:"addr"`
19- // Get ip from header, if not set, get ip from remote addr
20- IpHeader string `yaml:"ipHeader"`
21- // When ip_header has multiple ip, use this to get the ip
22- //
23- //for example, X-Forwarded-For: ip1, ip2, ip3
24- // when ip_last_index is 0, the client ip is ip3
25- // when ip_last_index is 1, the client ip is ip2
26- // when ip_last_index is 2, the client ip is ip1
27- IPRightIndex uint `yaml:"ipRightIndex"`
19+ Addr string `yaml:"addr"`
20+ PoolSize int `yaml:"pool_size"`
2821}
2922
3023// CreateConfig creates the default plugin configuration.
3124func CreateConfig () * Config {
3225 return & Config {
33- Addr : "" ,
34- IpHeader : "" ,
35- IPRightIndex : 0 ,
26+ Addr : "" ,
27+ PoolSize : 100 ,
3628 }
3729}
3830
3931// Safeline a plugin.
4032type Safeline struct {
4133 next http.Handler
34+ server * t1k.Server
4235 name string
4336 config * Config
4437 logger * log.Logger
38+ mu sync.Mutex
4539}
4640
4741// New created a new plugin.
4842func New (ctx context.Context , next http.Handler , config * Config , name string ) (http.Handler , error ) {
43+ logger := log .New (os .Stdout , "safeline" , log .LstdFlags )
44+ logger .Printf ("config: %+v" , config )
4945 return & Safeline {
5046 next : next ,
5147 name : name ,
5248 config : config ,
53- logger : log . New ( os . Stdout , "safeline" , log . LstdFlags ) ,
49+ logger : logger ,
5450 }, nil
5551}
5652
53+ func (s * Safeline ) initServer () error {
54+ if s .server != nil {
55+ return nil
56+ }
57+ s .mu .Lock ()
58+ defer s .mu .Unlock ()
59+ if s .server == nil {
60+ server , err := t1k .NewWithPoolSize (s .config .Addr , s .config .PoolSize )
61+ if err != nil {
62+ return err
63+ }
64+ s .server = server
65+ }
66+ return nil
67+ }
68+
5769func (s * Safeline ) ServeHTTP (rw http.ResponseWriter , req * http.Request ) {
58- d := t1k .NewDetector (t1k.Config {
59- Addr : s .config .Addr ,
60- IpHeader : s .config .IpHeader ,
61- IPRightIndex : s .config .IPRightIndex ,
62- })
63- resp , err := d .DetectorRequest (req )
70+ defer func () {
71+ if r := recover (); r != nil {
72+ s .logger .Printf ("panic: %s" , r )
73+ }
74+ }()
75+ if err := s .initServer (); err != nil {
76+ s .logger .Printf ("error in initServer: %s" , err )
77+ s .next .ServeHTTP (rw , req )
78+ return
79+ }
80+ rw .Header ().Set ("X-Chaitin-waf" , "safeline" )
81+ result , err := s .server .DetectHttpRequest (req )
6482 if err != nil {
65- s .logger .Printf ("Failed to detect request: %v" , err )
83+ s .logger .Printf ("error in detection: \n %+v\n " , err )
84+ s .next .ServeHTTP (rw , req )
85+ return
6686 }
67- if resp != nil && ! resp .Allowed () {
68- rw .WriteHeader (resp .StatusCode ())
69- if err := json .NewEncoder (rw ).Encode (resp .BlockMessage ()); err != nil {
70- s .logger .Printf ("Failed to encode block message: %v" , err )
71- }
87+ if result .Blocked () {
88+ rw .WriteHeader (result .StatusCode ())
89+ msg := fmt .Sprintf (`{"code": %d, "success":false, "message": "blocked by Chaitin SafeLine Web Application Firewall", "event_id": "%s"}` ,
90+ result .StatusCode (),
91+ result .EventID (),
92+ )
93+ _ , _ = rw .Write ([]byte (msg ))
7294 return
7395 }
7496 s .next .ServeHTTP (rw , req )
97+ //rw.WriteHeader(http.StatusForbidden)
98+ //_, _ = rw.Write([]byte("Inject by safeline\n"))
7599}
0 commit comments