package aQute.bnd.comm.tests;
import java.io.File;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import aQute.bnd.http.HttpClient;
import aQute.bnd.service.url.State;
import aQute.bnd.service.url.TaggedData;
import aQute.http.testservers.HttpTestServer.Config;
import aQute.http.testservers.Httpbin;
import aQute.lib.io.IO;
import junit.framework.TestCase;
public class HttpClientCacheTest extends TestCase {
File tmp = IO.getFile("generated/tmp");
File cache = IO.getFile(tmp, "cache");
private Httpbin httpServer;
String etag;
/*
* Add a method where we can set the returned etag
*/
public class MyHttpBin extends Httpbin {
public MyHttpBin(Config config) throws Exception {
super(config);
}
@SuppressWarnings("unused")
public void _testetag(Request rq, Response rsp) throws Exception {
String requestedTag = rq.headers.get("If-None-Match");
String qetag = etag;
if (!etag.isEmpty())
rsp.headers.put("ETag", qetag);
if (requestedTag != null) {
if (requestedTag.equals("*") || requestedTag.equals(qetag)) {
rsp.code = HttpURLConnection.HTTP_NOT_MODIFIED;
rsp.length = 0;
return;
}
}
rsp.content = etag != null ? etag.getBytes(StandardCharsets.UTF_8) : new byte[0];
return;
}
}
public void setUp() throws Exception {
IO.delete(tmp);
tmp.mkdirs();
Config config = new Config();
config.https = false;
httpServer = new MyHttpBin(config);
httpServer.start();
}
public void tearDown() {
IO.delete(tmp);
}
public void testGetNewThenUnmodifiedThenModified() throws URISyntaxException, Exception {
try (HttpClient client = new HttpClient();) {
client.setCache(cache);
// Set a tag, but it must always fetch the file
etag = "1234";
File go1 = client.build().useCache().go(new URI(httpServer.getBaseURI() + "/testetag"));
assertTrue(go1.isFile());
assertEquals("1234", IO.collect(go1));
// Set time very old so we can see if the file is updated
go1.setLastModified(1000);
File go2 = client.build().useCache().go(new URI(httpServer.getBaseURI() + "/testetag"));
assertEquals(go1, go2);
assertEquals("1234", IO.collect(go1));
assertEquals(1000, go2.lastModified());
// New tag (i.e. file is updated on server) but we use the stale
// period to NOT fetch a new one
etag = "5678";
go1.setLastModified(System.currentTimeMillis());
File go3 = client.build().useCache(10000).go(new URI(httpServer.getBaseURI() + "/testetag"));
assertEquals(go1, go3);
assertEquals("1234", IO.collect(go3));
// We have a stale copy, see if we fetch a new copy
File go4 = client.build().useCache().go(new URI(httpServer.getBaseURI() + "/testetag"));
assertEquals(go1, go4);
assertEquals("5678", IO.collect(go3));
}
}
/**
* Use the cached form but use our own file, not one from the central cache
*
* @throws Exception
*/
public void testPrivateFile() throws Exception {
try (HttpClient client = new HttpClient();) {
client.setCache(new File(tmp, "cache"));
etag = "1234";
File t1 = new File(tmp, "abc.txt");
//
// File does not exist
//
assertFalse("File should not exist", t1.isFile());
TaggedData tag = client.build().useCache(t1).asTag().go(new URI(httpServer.getBaseURI() + "/testetag"));
assertTrue("Expected the file to be created (not unmodified)", tag.isOk());
assertTrue("Just created the file", t1.isFile());
assertEquals("Should be the tag we set", "1234", tag.getTag());
tag = client.build().useCache(t1, 100000).asTag().go(new URI(httpServer.getBaseURI() + "/testetag"));
assertEquals("Expected file to be 'fresh'", State.UNMODIFIED, tag.getState());
tag = client.build().useCache(t1).asTag().go(new URI(httpServer.getBaseURI() + "/testetag"));
assertTrue("Should have checked so we should have unmodified", tag.isNotModified());
etag = "5678";
tag = client.build().useCache(t1, 100000).asTag().go(new URI(httpServer.getBaseURI() + "/testetag"));
assertEquals("Since it is still fresh, we expect no new fetch", State.UNMODIFIED, tag.getState());
tag = client.build().useCache(t1).asTag().go(new URI(httpServer.getBaseURI() + "/testetag"));
assertEquals("We should have fetched it with the new etag", "5678", tag.getTag());
assertTrue("And it should have been modified", tag.isOk());
String s = client.build().useCache(t1).get(String.class).go(new URI(httpServer.getBaseURI() + "/testetag"));
assertEquals("Content check", "5678", s);
byte[] b = client.build().useCache(t1).get(byte[].class).go(new URI(httpServer.getBaseURI() + "/testetag"));
assertTrue("Content check", Arrays.equals("5678".getBytes(), b));
}
}
}