Skip to content

Commit 7552b32

Browse files
Bypass cache for origin IP lookups to avoid serving stale data
1 parent a595078 commit 7552b32

2 files changed

Lines changed: 28 additions & 0 deletions

File tree

‎src/main/java/co/ipregistry/api/client/IpregistryClient.java‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,12 @@ public IpInfo lookup(final InetAddress ip, final IpregistryOption... options) th
126126
* @throws ClientException if a client issue happens.
127127
*/
128128
public IpInfo lookup(final String ip, final IpregistryOption... options) throws ApiException, ClientException {
129+
// Origin (requester) IP lookups cannot be safely cached: the actual IP is only known from
130+
// the response, so an empty cache key would risk returning data for a different requester.
131+
if (ip == null || ip.isEmpty()) {
132+
return requestHandler.lookup(ip, options);
133+
}
134+
129135
final String cacheKey = buildCacheKey(ip, options);
130136
IpInfo cacheValue = this.cache.get(cacheKey);
131137

‎src/test/java/co/ipregistry/api/client/IpregistryClientTest.java‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import co.ipregistry.api.client.exceptions.IpregistryException;
3939
import co.ipregistry.api.client.model.IpInfo;
4040
import co.ipregistry.api.client.model.IpInfoList;
41+
import co.ipregistry.api.client.model.RequesterIpInfo;
4142
import co.ipregistry.api.client.request.DefaultRequestHandler;
4243
import org.junit.jupiter.api.Assertions;
4344
import org.junit.jupiter.api.Test;
@@ -164,6 +165,27 @@ void testBatchRequestAllCachedSkipsApiCall() throws IpregistryException {
164165
Assertions.assertSame(ipdata1111, response.get(1));
165166
}
166167

168+
@Test
169+
void testOriginIpLookupBypassesCache() throws IpregistryException {
170+
final IpregistryConfig config =
171+
IpregistryConfig.builder().apiKey("test").build();
172+
173+
final IpregistryCache cache = Mockito.spy(new InMemoryCache());
174+
final DefaultRequestHandler requestHandler = Mockito.spy(new DefaultRequestHandler(config));
175+
176+
final RequesterIpInfo originInfo = new RequesterIpInfo();
177+
Mockito.doReturn(originInfo).when(requestHandler).lookup("");
178+
179+
final IpregistryClient client = new IpregistryClient(config, cache, requestHandler);
180+
181+
final RequesterIpInfo response = client.lookup();
182+
183+
// Origin lookups must never touch the cache, as they cannot be keyed by the actual IP.
184+
Mockito.verify(cache, Mockito.never()).get(Mockito.anyString());
185+
Mockito.verify(cache, Mockito.never()).put(Mockito.anyString(), Mockito.any(IpInfo.class));
186+
Assertions.assertSame(originInfo, response);
187+
}
188+
167189
@Test
168190
void testCloseClosesRequestHandler() throws Exception {
169191
final IpregistryConfig config =

0 commit comments

Comments
 (0)