mirror of
https://github.com/apache/cordova-android.git
synced 2025-02-20 23:56:20 +08:00
CB-8702 Add API for plugins to override shouldInterceptRequest
with a stream
This commit is contained in:
parent
15530a4820
commit
8d5cb00bec
@ -28,6 +28,9 @@ import org.json.JSONException;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Plugins must extend this class and override one of the execute methods.
|
||||
*/
|
||||
@ -249,11 +252,53 @@ public class CordovaPlugin {
|
||||
|
||||
/**
|
||||
* Hook for redirecting requests. Applies to WebView requests as well as requests made by plugins.
|
||||
* To handle the request directly, return a URI in the form:
|
||||
*
|
||||
* cdvplugin://pluginId/...
|
||||
*
|
||||
* And implement handleOpenForRead().
|
||||
* To make this easier, use the toPluginUri() and fromPluginUri() helpers:
|
||||
*
|
||||
* public Uri remapUri(Uri uri) { return toPluginUri(uri); }
|
||||
*
|
||||
* public CordovaResourceApi.OpenForReadResult handleOpenForRead(Uri uri) throws IOException {
|
||||
* Uri origUri = fromPluginUri(uri);
|
||||
* ...
|
||||
* }
|
||||
*/
|
||||
public Uri remapUri(Uri uri) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called to handle CordovaResourceApi.openForRead() calls for a cdvplugin://pluginId/ URL.
|
||||
* Should never return null.
|
||||
* Added in cordova-android@4.0.0
|
||||
*/
|
||||
public CordovaResourceApi.OpenForReadResult handleOpenForRead(Uri uri) throws IOException {
|
||||
throw new FileNotFoundException("Plugin can't handle uri: " + uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refer to remapUri()
|
||||
* Added in cordova-android@4.0.0
|
||||
*/
|
||||
protected Uri toPluginUri(Uri origUri) {
|
||||
return new Uri.Builder()
|
||||
.scheme(CordovaResourceApi.PLUGIN_URI_SCHEME)
|
||||
.authority(serviceName)
|
||||
.appendQueryParameter("origUri", origUri.toString())
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Refer to remapUri()
|
||||
* Added in cordova-android@4.0.0
|
||||
*/
|
||||
protected Uri fromPluginUri(Uri pluginUri) {
|
||||
return Uri.parse(pluginUri.getQueryParameter("origUri"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the WebView does a top-level navigation or refreshes.
|
||||
*
|
||||
|
@ -72,8 +72,11 @@ public class CordovaResourceApi {
|
||||
public static final int URI_TYPE_DATA = 4;
|
||||
public static final int URI_TYPE_HTTP = 5;
|
||||
public static final int URI_TYPE_HTTPS = 6;
|
||||
public static final int URI_TYPE_PLUGIN = 7;
|
||||
public static final int URI_TYPE_UNKNOWN = -1;
|
||||
|
||||
|
||||
public static final String PLUGIN_URI_SCHEME = "cdvplugin";
|
||||
|
||||
private static final String[] LOCAL_FILE_PROJECTION = { "_data" };
|
||||
|
||||
public static Thread jsThread;
|
||||
@ -123,6 +126,9 @@ public class CordovaResourceApi {
|
||||
if ("https".equals(scheme)) {
|
||||
return URI_TYPE_HTTPS;
|
||||
}
|
||||
if (PLUGIN_URI_SCHEME.equals(scheme)) {
|
||||
return URI_TYPE_PLUGIN;
|
||||
}
|
||||
return URI_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
@ -282,6 +288,14 @@ public class CordovaResourceApi {
|
||||
InputStream inputStream = conn.getInputStream();
|
||||
return new OpenForReadResult(uri, inputStream, mimeType, length, null);
|
||||
}
|
||||
case URI_TYPE_PLUGIN: {
|
||||
String pluginId = uri.getHost();
|
||||
CordovaPlugin plugin = pluginManager.getPlugin(pluginId);
|
||||
if (plugin == null) {
|
||||
throw new FileNotFoundException("Invalid plugin ID in URI: " + uri);
|
||||
}
|
||||
return plugin.handleOpenForRead(uri);
|
||||
}
|
||||
}
|
||||
throw new FileNotFoundException("URI not supported by CordovaResourceApi: " + uri);
|
||||
}
|
||||
@ -431,7 +445,7 @@ public class CordovaResourceApi {
|
||||
public final long length;
|
||||
public final AssetFileDescriptor assetFd;
|
||||
|
||||
OpenForReadResult(Uri uri, InputStream inputStream, String mimeType, long length, AssetFileDescriptor assetFd) {
|
||||
public OpenForReadResult(Uri uri, InputStream inputStream, String mimeType, long length, AssetFileDescriptor assetFd) {
|
||||
this.uri = uri;
|
||||
this.inputStream = inputStream;
|
||||
this.mimeType = mimeType;
|
||||
|
@ -36,9 +36,11 @@ import org.apache.cordova.PluginEntry;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class CordovaResourceApiTest extends BaseCordovaIntegrationTest {
|
||||
@ -58,8 +60,18 @@ public class CordovaResourceApiTest extends BaseCordovaIntegrationTest {
|
||||
return cordovaWebView.getResourceApi().remapUri(
|
||||
Uri.parse("data:text/plain;charset=utf-8,pass"));
|
||||
}
|
||||
if (uri.getQuery() != null && uri.getQuery().contains("pluginUri")) {
|
||||
return toPluginUri(uri);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public OpenForReadResult handleOpenForRead(Uri uri) throws IOException {
|
||||
Uri orig = fromPluginUri(uri);
|
||||
ByteArrayInputStream retStream = new ByteArrayInputStream(orig.toString().getBytes(StandardCharsets.UTF_8));
|
||||
return new OpenForReadResult(uri, retStream, "text/plain", retStream.available(), null);
|
||||
}
|
||||
@Override
|
||||
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
|
||||
synchronized (CordovaResourceApiTest.this) {
|
||||
execPayload = args.getString(0);
|
||||
@ -214,6 +226,16 @@ public class CordovaResourceApiTest extends BaseCordovaIntegrationTest {
|
||||
String data = new Scanner(readResult.inputStream, "UTF-8").useDelimiter("\\A").next();
|
||||
assertEquals("pass", data);
|
||||
}
|
||||
// testPluginUris
|
||||
{
|
||||
String origUri = "http://orig/foo?pluginUri";
|
||||
Uri uri = resourceApi.remapUri(Uri.parse(origUri));
|
||||
OpenForReadResult readResult = resourceApi.openForRead(uri);
|
||||
assertEquals("openForRead mime-type", "text/plain", readResult.mimeType);
|
||||
String data = new Scanner(readResult.inputStream, "UTF-8").useDelimiter("\\A").next();
|
||||
assertEquals(origUri, data);
|
||||
assertEquals(origUri.length(), readResult.length);
|
||||
}
|
||||
}
|
||||
|
||||
public void testWebViewRequestIntercept() throws Throwable
|
||||
|
Loading…
Reference in New Issue
Block a user