Skip to content

Commit 6f18248

Browse files
authored
fix(Android): Handle Range Requests for proper media file handling (#298)
Properly handle requests with Range header and return appropriate headers so audio and video tags work correcly and you can go forward or backward ond them fix #248, fix #205, fix #141
1 parent 6668669 commit 6f18248

File tree

2 files changed

+31
-6
lines changed

2 files changed

+31
-6
lines changed

src/android/com/ionicframework/cordova/webview/IonicWebViewEngine.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,13 @@ public ServerClient(SystemWebViewEngine parentEngine, ConfigXmlParser parser) {
121121
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
122122
@Override
123123
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
124-
return localServer.shouldInterceptRequest(request.getUrl());
124+
return localServer.shouldInterceptRequest(request.getUrl(), request);
125125
}
126126

127127
@TargetApi(Build.VERSION_CODES.KITKAT)
128128
@Override
129129
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
130-
return localServer.shouldInterceptRequest(Uri.parse(url));
130+
return localServer.shouldInterceptRequest(Uri.parse(url), null);
131131
}
132132

133133
@Override

src/android/com/ionicframework/cordova/webview/WebViewLocalServer.java

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import android.net.Uri;
2020
import android.os.Build;
2121
import android.util.Log;
22+
import android.webkit.WebResourceRequest;
2223
import android.webkit.WebResourceResponse;
2324

2425
import org.apache.cordova.ConfigXmlParser;
@@ -213,7 +214,7 @@ private static WebResourceResponse createWebResourceResponse(String mimeType, St
213214
* @param uri the request Uri to process.
214215
* @return a response if the request URL had a matching handler, null if no handler was found.
215216
*/
216-
public WebResourceResponse shouldInterceptRequest(Uri uri) {
217+
public WebResourceResponse shouldInterceptRequest(Uri uri, WebResourceRequest request) {
217218
PathHandler handler;
218219
synchronized (uriMatcher) {
219220
handler = (PathHandler) uriMatcher.match(uri);
@@ -224,7 +225,7 @@ public WebResourceResponse shouldInterceptRequest(Uri uri) {
224225

225226
if (isLocalFile(uri) || uri.getAuthority().equals(this.authority)) {
226227
Log.d("SERVER", "Handling local request: " + uri.toString());
227-
return handleLocalRequest(uri, handler);
228+
return handleLocalRequest(uri, handler, request);
228229
} else {
229230
return handleProxyRequest(uri, handler);
230231
}
@@ -237,9 +238,33 @@ private boolean isLocalFile(Uri uri) {
237238
}
238239
return false;
239240
}
240-
private WebResourceResponse handleLocalRequest(Uri uri, PathHandler handler) {
241-
String path = uri.getPath();
242241

242+
243+
private WebResourceResponse handleLocalRequest(Uri uri, PathHandler handler, WebResourceRequest request) {
244+
String path = uri.getPath();
245+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && request != null && request.getRequestHeaders().get("Range") != null) {
246+
InputStream responseStream = new LollipopLazyInputStream(handler, uri);
247+
String mimeType = getMimeType(path, responseStream);
248+
Map<String, String> tempResponseHeaders = handler.getResponseHeaders();
249+
int statusCode = 206;
250+
try {
251+
int totalRange = responseStream.available();
252+
String rangeString = request.getRequestHeaders().get("Range");
253+
String[] parts = rangeString.split("=");
254+
String[] streamParts = parts[1].split("-");
255+
String fromRange = streamParts[0];
256+
int range = totalRange-1;
257+
if (streamParts.length > 1) {
258+
range = Integer.parseInt(streamParts[1]);
259+
}
260+
tempResponseHeaders.put("Accept-Ranges", "bytes");
261+
tempResponseHeaders.put("Content-Range", "bytes " + fromRange + "-" + range + "/" + totalRange);
262+
} catch (IOException e) {
263+
statusCode = 404;
264+
}
265+
return createWebResourceResponse(mimeType, handler.getEncoding(),
266+
statusCode, handler.getReasonPhrase(), tempResponseHeaders, responseStream);
267+
}
243268
if (isLocalFile(uri)) {
244269
InputStream responseStream = new LollipopLazyInputStream(handler, uri);
245270
String mimeType = getMimeType(path, responseStream);

0 commit comments

Comments
 (0)