@@ -10,7 +10,6 @@ import (
1010 "net"
1111 "net/http"
1212 "os"
13- "path/filepath"
1413 "strings"
1514 "time"
1615
@@ -49,8 +48,9 @@ type Config struct {
4948 AllowedIPAddresses []string `yaml:"allowedIPAddresses,omitempty"`
5049 AddCountryHeader bool `yaml:"addCountryHeader"`
5150 HTTPStatusCodeDeniedRequest int `yaml:"httpStatusCodeDeniedRequest"`
52- LogFilePath string `yaml:"logFilePath"`
5351 RedirectURLIfDenied string `yaml:"redirectUrlIfDenied"`
52+ LogFilePath string `yaml:"logFilePath"`
53+ IPDatabaseCachePath string `yaml:"ipDatabaseCachePath"`
5454}
5555
5656type ipEntry struct {
@@ -91,6 +91,7 @@ type GeoBlock struct {
9191 redirectURLIfDenied string
9292 name string
9393 infoLogger * log.Logger
94+ ipDatabasePersistence * CachePersist
9495}
9596
9697// New created a new GeoBlock plugin.
@@ -130,27 +131,14 @@ func New(ctx context.Context, next http.Handler, config *Config, name string) (h
130131 printConfiguration (name , config , infoLogger )
131132 }
132133
133- // create LRU cache for IP lookup
134- cache , err := lru .NewLRUCache (config .CacheSize )
135- if err != nil {
136- infoLogger .Fatal (err )
137- }
138-
139134 // create custom log target if needed
140- logFile , err := initializeLogFile ( name , config .LogFilePath , infoLogger )
135+ logFile , err := CreateCustomLogTarget ( ctx , infoLogger , name , config .LogFilePath )
141136 if err != nil {
142- infoLogger .Printf ( "%s: Error initializing log file: %v \n " , name , err )
137+ infoLogger .Fatal ( err )
143138 }
144139
145- // Set up a goroutine to close the file when the context is done
146- if logFile != nil {
147- go func (logger * log.Logger ) {
148- <- ctx .Done () // Wait for context cancellation
149- logger .SetOutput (os .Stdout )
150- logFile .Close ()
151- logger .Printf ("%s: Log file closed for middleware\n " , name )
152- }(infoLogger )
153- }
140+ // initialize local IP lookup cache
141+ cache , ipDB := InitializeCache (ctx , infoLogger , name , config .CacheSize , config .IPDatabaseCachePath )
154142
155143 return & GeoBlock {
156144 next : next ,
@@ -179,6 +167,7 @@ func New(ctx context.Context, next http.Handler, config *Config, name string) (h
179167 redirectURLIfDenied : config .RedirectURLIfDenied ,
180168 name : name ,
181169 infoLogger : infoLogger ,
170+ ipDatabasePersistence : ipDB , // may be nil => feature OFF
182171 }, nil
183172}
184173
@@ -286,6 +275,8 @@ func (a *GeoBlock) allowDenyCachedRequestIP(requestIPAddr *net.IP, req *http.Req
286275 }
287276 } else {
288277 entry = cacheEntry .(ipEntry )
278+ // order has changed
279+ a .ipDatabasePersistence .MarkDirty ()
289280 }
290281
291282 if a .logAPIRequests {
@@ -351,6 +342,8 @@ func (a *GeoBlock) cachedRequestIP(requestIPAddr *net.IP, req *http.Request) (bo
351342 }
352343 } else {
353344 entry = cacheEntry .(ipEntry )
345+ // order has changed
346+ a .ipDatabasePersistence .MarkDirty ()
354347 }
355348
356349 if a .logAPIRequests {
@@ -414,6 +407,7 @@ func (a *GeoBlock) createNewIPEntry(req *http.Request, ipAddressString string) (
414407
415408 entry = ipEntry {Country : country , Timestamp : time .Now ()}
416409 a .database .Add (ipAddressString , entry )
410+ a .ipDatabasePersistence .MarkDirty () // new entry in the cache
417411
418412 if a .logAPIRequests {
419413 a .infoLogger .Printf ("%s: [%s] added to database: %s" , a .name , ipAddressString , entry )
@@ -638,44 +632,3 @@ func printConfiguration(name string, config *Config, logger *log.Logger) {
638632 logger .Printf ("%s: Redirect URL on denied requests: %s" , name , config .RedirectURLIfDenied )
639633 }
640634}
641-
642- func initializeLogFile (name string , logFilePath string , logger * log.Logger ) (* os.File , error ) {
643- if len (logFilePath ) == 0 {
644- return nil , nil
645- }
646-
647- writeable , err := isFolder (logFilePath )
648- if err != nil {
649- logger .Printf ("%s: %s" , name , err )
650- return nil , err
651- } else if ! writeable {
652- logger .Printf ("%s: Specified log folder is not writeable: %s" , name , logFilePath )
653- return nil , fmt .Errorf ("%s: folder is not writeable: %s" , name , logFilePath )
654- }
655-
656- logFile , err := os .OpenFile (logFilePath , os .O_RDWR | os .O_CREATE | os .O_APPEND , filePermissions )
657- if err != nil {
658- logger .Printf ("%s: Failed to open log file: %v\n " , name , err )
659- return nil , err
660- }
661-
662- logger .SetOutput (logFile )
663- return logFile , nil
664- }
665-
666- func isFolder (filePath string ) (bool , error ) {
667- dirPath := filepath .Dir (filePath )
668- info , err := os .Stat (dirPath )
669- if err != nil {
670- if os .IsNotExist (err ) {
671- return false , fmt .Errorf ("path does not exist" )
672- }
673- return false , fmt .Errorf ("error checking path: %w" , err )
674- }
675-
676- if ! info .IsDir () {
677- return false , fmt .Errorf ("folder does not exist" )
678- }
679-
680- return true , nil
681- }
0 commit comments