@@ -1177,6 +1177,145 @@ func TestCustomLogFile(t *testing.T) {
11771177 assertStatusCode (t , recorder .Result (), http .StatusOK )
11781178}
11791179
1180+ func TestLogDeniedDueToHeaderError_FirstCall (t * testing.T ) {
1181+ apiHandler := & CountryCodeHandler {ResponseCountryCode : "CA" }
1182+
1183+ // set up our fake api server
1184+ var apiStub = httptest .NewServer (apiHandler )
1185+
1186+ tempDir , err := os .MkdirTemp ("" , "logtest" )
1187+ if err != nil {
1188+ t .Fatalf ("Failed to create temporary directory: %v" , err )
1189+ }
1190+ defer os .RemoveAll (tempDir )
1191+
1192+ cfg := createTesterConfig ()
1193+ cfg .API = apiStub .URL + "/{ip}"
1194+ cfg .Countries = append (cfg .Countries , "CH" )
1195+ cfg .IPGeolocationHTTPHeaderField = ipGeolocationHTTPHeaderField
1196+ cfg .LogFilePath = tempDir + "/info.log"
1197+ cfg .LogAllowedRequests = true
1198+
1199+ ctx := context .Background ()
1200+ next := http .HandlerFunc (func (_ http.ResponseWriter , _ * http.Request ) {})
1201+
1202+ handler , err := geoblock .New (ctx , next , cfg , "GeoBlock" )
1203+ if err != nil {
1204+ t .Fatal (err )
1205+ }
1206+
1207+ recorder := httptest .NewRecorder ()
1208+
1209+ req , err := http .NewRequestWithContext (ctx , http .MethodGet , "http://localhost" , nil )
1210+ if err != nil {
1211+ t .Fatal (err )
1212+ }
1213+
1214+ req .Header .Add (xForwardedFor , chExampleIP )
1215+ req .Header .Set (cfg .IPGeolocationHTTPHeaderField , "C" )
1216+
1217+ handler .ServeHTTP (recorder , req )
1218+
1219+ assertStatusCode (t , recorder .Result (), http .StatusForbidden )
1220+
1221+ content , err := os .ReadFile (cfg .LogFilePath )
1222+ if err != nil {
1223+ t .Fatalf ("Failed to read log file: %v" , err )
1224+ }
1225+
1226+ wrongCountryCode := "Failed to read country from HTTP header field [cf-ipcountry], continuing with API lookup"
1227+ countryNotAllowed := "request denied [82.220.110.18] for country [CA] due to: country is not allowed"
1228+
1229+ if len (content ) == 0 ||
1230+ ! strings .Contains (string (content ), wrongCountryCode ) ||
1231+ ! strings .Contains (string (content ), countryNotAllowed ) {
1232+ t .Fatalf ("Empty custom log file or missing expected log lines." )
1233+ }
1234+ }
1235+
1236+ func TestTimeoutOnApiResponse_DenyWhenIgnoreTimeoutFalse (t * testing.T ) {
1237+ tempDir , err := os .MkdirTemp ("" , "logtest" )
1238+ if err != nil {
1239+ t .Fatalf ("Failed to create temporary directory: %v" , err )
1240+ }
1241+ defer os .RemoveAll (tempDir )
1242+
1243+ // Stub server that responds too slowly for our client timeout.
1244+ apiStub := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , _ * http.Request ) {
1245+ time .Sleep (50 * time .Millisecond ) // > APITimeoutMs below
1246+ w .WriteHeader (http .StatusOK )
1247+ _ , _ = w .Write ([]byte ("CH" ))
1248+ }))
1249+ defer apiStub .Close ()
1250+
1251+ cfg := createTesterConfig ()
1252+ cfg .API = apiStub .URL + "/{ip}"
1253+ cfg .Countries = append (cfg .Countries , "CH" )
1254+ cfg .APITimeoutMs = 5 // 5ms client timeout
1255+ cfg .IgnoreAPITimeout = false // timeouts should DENY
1256+ cfg .LogFilePath = tempDir + "/info.log"
1257+ cfg .LogAllowedRequests = true
1258+
1259+ ctx := context .Background ()
1260+ next := http .HandlerFunc (func (_ http.ResponseWriter , _ * http.Request ) {})
1261+
1262+ handler , err := geoblock .New (ctx , next , cfg , "GeoBlock" )
1263+ if err != nil {
1264+ t .Fatal (err )
1265+ }
1266+
1267+ rec := httptest .NewRecorder ()
1268+ req := httptest .NewRequest (http .MethodGet , "http://localhost" , nil )
1269+ req .Header .Add (xForwardedFor , chExampleIP )
1270+
1271+ handler .ServeHTTP (rec , req )
1272+
1273+ assertStatusCode (t , rec .Result (), http .StatusForbidden )
1274+
1275+ content , err := os .ReadFile (cfg .LogFilePath )
1276+ if err != nil {
1277+ t .Fatalf ("Failed to read log file: %v" , err )
1278+ }
1279+
1280+ timeoutError := "context deadline exceeded"
1281+
1282+ if len (content ) == 0 || ! strings .Contains (string (content ), timeoutError ) {
1283+ t .Fatalf ("Empty custom log file or missing expected log lines." )
1284+ }
1285+ }
1286+
1287+ func TestTimeoutOnApiResponse_AllowWhenIgnoreTimeoutTrue (t * testing.T ) {
1288+ // Stub server that responds too slowly for our client timeout.
1289+ apiStub := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , _ * http.Request ) {
1290+ time .Sleep (50 * time .Millisecond ) // > APITimeoutMs below
1291+ w .WriteHeader (http .StatusOK )
1292+ _ , _ = w .Write ([]byte ("CH" ))
1293+ }))
1294+ defer apiStub .Close ()
1295+
1296+ cfg := createTesterConfig ()
1297+ cfg .API = apiStub .URL + "/{ip}"
1298+ cfg .Countries = append (cfg .Countries , "CH" )
1299+ cfg .APITimeoutMs = 5 // 5ms client timeout
1300+ cfg .IgnoreAPITimeout = true // timeouts should ALLOW
1301+
1302+ ctx := context .Background ()
1303+ next := http .HandlerFunc (func (_ http.ResponseWriter , _ * http.Request ) {})
1304+
1305+ handler , err := geoblock .New (ctx , next , cfg , "GeoBlock" )
1306+ if err != nil {
1307+ t .Fatal (err )
1308+ }
1309+
1310+ rec := httptest .NewRecorder ()
1311+ req := httptest .NewRequest (http .MethodGet , "http://localhost" , nil )
1312+ req .Header .Add (xForwardedFor , chExampleIP )
1313+
1314+ handler .ServeHTTP (rec , req )
1315+
1316+ assertStatusCode (t , rec .Result (), http .StatusOK )
1317+ }
1318+
11801319func assertStatusCode (t * testing.T , req * http.Response , expected int ) {
11811320 t .Helper ()
11821321
0 commit comments