Skip to content

Commit 9353cde

Browse files
committed
📦 2.6.3: return file:// proxy uri for fully cached files
1 parent 0d1131b commit 9353cde

File tree

8 files changed

+117
-20
lines changed

8 files changed

+117
-20
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ repositories {
3636
jcenter()
3737
}
3838
dependencies {
39-
compile 'com.danikula:videocache:2.6.2'
39+
compile 'com.danikula:videocache:2.6.3'
4040
}
4141
```
4242

library/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ publish {
3030
userOrg = 'alexeydanilov'
3131
groupId = 'com.danikula'
3232
artifactId = 'videocache'
33-
publishVersion = '2.6.2'
33+
publishVersion = '2.6.3'
3434
description = 'Cache support for android VideoView'
3535
website = 'https://github.com/danikula/AndroidVideoCache'
3636
}

library/src/main/java/com/danikula/videocache/HttpProxyCacheServer.java

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.danikula.videocache;
22

33
import android.content.Context;
4+
import android.net.Uri;
45

56
import com.danikula.videocache.file.DiskUsage;
67
import com.danikula.videocache.file.FileNameGenerator;
@@ -84,7 +85,37 @@ private HttpProxyCacheServer(Config config) {
8485
}
8586
}
8687

88+
/**
89+
* Returns url that wrap original url and should be used for client (MediaPlayer, ExoPlayer, etc).
90+
* <p>
91+
* If file for this url is fully cached (it means method {@link #isCached(String)} returns {@code true})
92+
* then file:// uri to cached file will be returned.
93+
* <p>
94+
* Calling this method has same effect as calling {@link #getProxyUrl(String, boolean)} with 2nd parameter set to {@code true}.
95+
*
96+
* @param url a url to file that should be cached.
97+
* @return a wrapped by proxy url if file is not fully cached or url pointed to cache file otherwise.
98+
*/
8799
public String getProxyUrl(String url) {
100+
return getProxyUrl(url, true);
101+
}
102+
103+
/**
104+
* Returns url that wrap original url and should be used for client (MediaPlayer, ExoPlayer, etc).
105+
* <p>
106+
* If parameter {@code allowCachedFileUri} is {@code true} and file for this url is fully cached
107+
* (it means method {@link #isCached(String)} returns {@code true}) then file:// uri to cached file will be returned.
108+
*
109+
* @param url a url to file that should be cached.
110+
* @param allowCachedFileUri {@code true} if allow to return file:// uri if url is fully cached
111+
* @return a wrapped by proxy url if file is not fully cached or url pointed to cache file otherwise (if {@code allowCachedFileUri} is {@code true}).
112+
*/
113+
public String getProxyUrl(String url, boolean allowCachedFileUri) {
114+
if (allowCachedFileUri && isCached(url)) {
115+
File cacheFile = getCacheFile(url);
116+
touchFileSafely(cacheFile);
117+
return Uri.fromFile(cacheFile).toString();
118+
}
88119
return isAlive() ? appendToProxyUrl(url) : url;
89120
}
90121

@@ -127,10 +158,7 @@ public void unregisterCacheListener(CacheListener cacheListener) {
127158
*/
128159
public boolean isCached(String url) {
129160
checkNotNull(url, "Url can't be null!");
130-
File cacheDir = config.cacheRoot;
131-
String fileName = config.fileNameGenerator.generate(url);
132-
File cacheFile = new File(cacheDir, fileName);
133-
return cacheFile.exists();
161+
return getCacheFile(url).exists();
134162
}
135163

136164
public void shutdown() {
@@ -158,6 +186,20 @@ private String appendToProxyUrl(String url) {
158186
return String.format(Locale.US, "http://%s:%d/%s", PROXY_HOST, port, ProxyCacheUtils.encode(url));
159187
}
160188

189+
private File getCacheFile(String url) {
190+
File cacheDir = config.cacheRoot;
191+
String fileName = config.fileNameGenerator.generate(url);
192+
return new File(cacheDir, fileName);
193+
}
194+
195+
private void touchFileSafely(File cacheFile) {
196+
try {
197+
config.diskUsage.touch(cacheFile);
198+
} catch (IOException e) {
199+
LOG.error("Error touching file " + cacheFile, e);
200+
}
201+
}
202+
161203
private void shutdownClients() {
162204
synchronized (clientsLock) {
163205
for (HttpProxyCacheServerClients clients : clientsMap.values()) {

sample/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ dependencies {
3838
// compile project(':library')
3939
compile 'com.android.support:support-v4:23.1.0'
4040
compile 'org.androidannotations:androidannotations-api:3.3.2'
41-
compile 'com.danikula:videocache:2.6.2'
41+
compile 'com.danikula:videocache:2.6.3'
4242
compile 'com.viewpagerindicator:library:2.4.2-SNAPSHOT@aar'
4343
apt 'org.androidannotations:androidannotations:3.3.2'
4444
}

sample/src/main/java/com/danikula/videocache/sample/VideoFragment.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,17 @@ private void checkCachedState() {
5555
HttpProxyCacheServer proxy = App.getProxy(getActivity());
5656
boolean fullyCached = proxy.isCached(url);
5757
setCachedState(fullyCached);
58+
if (fullyCached) {
59+
progressBar.setSecondaryProgress(100);
60+
}
5861
}
5962

6063
private void startVideo() {
6164
HttpProxyCacheServer proxy = App.getProxy(getActivity());
6265
proxy.registerCacheListener(this, url);
63-
videoView.setVideoPath(proxy.getProxyUrl(url));
66+
String proxyUrl = proxy.getProxyUrl(url);
67+
Log.d(LOG_TAG, "Use proxy url " + proxyUrl + " instead of original url " + url);
68+
videoView.setVideoPath(proxyUrl);
6469
videoView.start();
6570
}
6671

test/src/test/java/com/danikula/videocache/HttpProxyCacheServerTest.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.danikula.videocache;
22

3+
import android.net.Uri;
34
import android.util.Pair;
45

56
import com.danikula.android.garden.io.IoUtils;
@@ -29,6 +30,7 @@
2930
import static com.danikula.videocache.support.ProxyCacheTestUtils.HTTP_DATA_URL_6_REDIRECTS;
3031
import static com.danikula.videocache.support.ProxyCacheTestUtils.HTTP_DATA_URL_ONE_REDIRECT;
3132
import static com.danikula.videocache.support.ProxyCacheTestUtils.getFileContent;
33+
import static com.danikula.videocache.support.ProxyCacheTestUtils.getPort;
3234
import static com.danikula.videocache.support.ProxyCacheTestUtils.loadAssetFile;
3335
import static com.danikula.videocache.support.ProxyCacheTestUtils.readProxyResponse;
3436
import static org.fest.assertions.api.Assertions.assertThat;
@@ -250,6 +252,50 @@ public void testCheckFileExistForDeletedCacheFile() throws Exception {
250252
assertThat(proxy.isCached(HTTP_DATA_URL)).isFalse();
251253
}
252254

255+
@Test
256+
public void testGetProxiedUrlForEmptyCache() throws Exception {
257+
HttpProxyCacheServer proxy = newProxy(cacheFolder);
258+
String expectedUrl = "http://127.0.0.1:" + getPort(proxy) + "/" + ProxyCacheUtils.encode(HTTP_DATA_URL);
259+
assertThat(proxy.getProxyUrl(HTTP_DATA_URL)).isEqualTo(expectedUrl);
260+
assertThat(proxy.getProxyUrl(HTTP_DATA_URL, true)).isEqualTo(expectedUrl);
261+
assertThat(proxy.getProxyUrl(HTTP_DATA_URL, false)).isEqualTo(expectedUrl);
262+
proxy.shutdown();
263+
}
264+
265+
@Test
266+
public void testGetProxiedUrlForPartialCache() throws Exception {
267+
File cacheDir = RuntimeEnvironment.application.getExternalCacheDir();
268+
File file = new File(cacheDir, new Md5FileNameGenerator().generate(HTTP_DATA_URL));
269+
int partialCacheSize = 1000;
270+
byte[] partialData = ProxyCacheTestUtils.generate(partialCacheSize);
271+
File partialCacheFile = ProxyCacheTestUtils.getTempFile(file);
272+
IoUtils.saveToFile(partialData, partialCacheFile);
273+
274+
HttpProxyCacheServer proxy = newProxy(cacheFolder);
275+
String expectedUrl = "http://127.0.0.1:" + getPort(proxy) + "/" + ProxyCacheUtils.encode(HTTP_DATA_URL);
276+
277+
assertThat(proxy.getProxyUrl(HTTP_DATA_URL)).isEqualTo(expectedUrl);
278+
assertThat(proxy.getProxyUrl(HTTP_DATA_URL, true)).isEqualTo(expectedUrl);
279+
assertThat(proxy.getProxyUrl(HTTP_DATA_URL, false)).isEqualTo(expectedUrl);
280+
281+
proxy.shutdown();
282+
}
283+
284+
@Test
285+
public void testGetProxiedUrlForExistedCache() throws Exception {
286+
HttpProxyCacheServer proxy = newProxy(cacheFolder);
287+
readProxyResponse(proxy, HTTP_DATA_URL, 0);
288+
String proxiedUrl = "http://127.0.0.1:" + getPort(proxy) + "/" + ProxyCacheUtils.encode(HTTP_DATA_URL);
289+
290+
File cachedFile = file(cacheFolder, HTTP_DATA_URL);
291+
String cachedFileUri = Uri.fromFile(cachedFile).toString();
292+
assertThat(proxy.getProxyUrl(HTTP_DATA_URL)).isEqualTo(cachedFileUri);
293+
assertThat(proxy.getProxyUrl(HTTP_DATA_URL, true)).isEqualTo(cachedFileUri);
294+
assertThat(proxy.getProxyUrl(HTTP_DATA_URL, false)).isEqualTo(proxiedUrl);
295+
296+
proxy.shutdown();
297+
}
298+
253299
private Pair<File, Response> readProxyData(String url, int offset) throws IOException {
254300
File file = file(cacheFolder, url);
255301
HttpProxyCacheServer proxy = newProxy(cacheFolder);

test/src/test/java/com/danikula/videocache/PingerTest.java

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@
55

66
import java.io.ByteArrayOutputStream;
77
import java.net.Socket;
8-
import java.util.regex.Matcher;
9-
import java.util.regex.Pattern;
108

9+
import static com.danikula.videocache.support.ProxyCacheTestUtils.getPort;
1110
import static org.fest.assertions.api.Assertions.assertThat;
1211
import static org.mockito.Mockito.mock;
1312
import static org.mockito.Mockito.when;
@@ -53,12 +52,5 @@ public void testResponseToPing() throws Exception {
5352
assertThat(out.toString()).isEqualTo("HTTP/1.1 200 OK\n\nping ok");
5453
}
5554

56-
private int getPort(HttpProxyCacheServer server) {
57-
String proxyUrl = server.getProxyUrl("test");
58-
Pattern pattern = Pattern.compile("http://127.0.0.1:(\\d*)/test");
59-
Matcher matcher = pattern.matcher(proxyUrl);
60-
assertThat(matcher.find()).isTrue();
61-
String portAsString = matcher.group(1);
62-
return Integer.parseInt(portAsString);
63-
}
55+
6456
}

test/src/test/java/com/danikula/videocache/support/ProxyCacheTestUtils.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@
2121
import java.net.URL;
2222
import java.util.Random;
2323
import java.util.UUID;
24+
import java.util.regex.Matcher;
25+
import java.util.regex.Pattern;
2426

27+
import static org.fest.assertions.api.Assertions.assertThat;
2528
import static org.mockito.Matchers.any;
2629
import static org.mockito.Matchers.anyInt;
2730
import static org.mockito.Mockito.doAnswer;
@@ -54,9 +57,9 @@ public static Response readProxyResponse(HttpProxyCacheServer proxy, String url)
5457
}
5558

5659
public static Response readProxyResponse(HttpProxyCacheServer proxy, String url, int offset) throws IOException {
57-
String proxyUrl = proxy.getProxyUrl(url);
60+
String proxyUrl = proxy.getProxyUrl(url, false);
5861
if (!proxyUrl.startsWith("http://127.0.0.1")) {
59-
throw new IllegalStateException("Url " + url + " is not proxied!");
62+
throw new IllegalStateException("Proxy url " + proxyUrl + " is not proxied! Original url is " + url);
6063
}
6164
URL proxiedUrl = new URL(proxyUrl);
6265
HttpURLConnection connection = (HttpURLConnection) proxiedUrl.openConnection();
@@ -135,4 +138,13 @@ public Object answer(InvocationOnMock invocation) throws Throwable {
135138
}).doCallRealMethod().when(spySource).read(any(byte[].class));
136139
return spySource;
137140
}
141+
142+
public static int getPort(HttpProxyCacheServer server) {
143+
String proxyUrl = server.getProxyUrl("test");
144+
Pattern pattern = Pattern.compile("http://127.0.0.1:(\\d*)/test");
145+
Matcher matcher = pattern.matcher(proxyUrl);
146+
assertThat(matcher.find()).isTrue();
147+
String portAsString = matcher.group(1);
148+
return Integer.parseInt(portAsString);
149+
}
138150
}

0 commit comments

Comments
 (0)