mirror of
https://github.com/apache/cordova-android.git
synced 2025-02-26 12:03:28 +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.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plugins must extend this class and override one of the execute methods.
|
* 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.
|
* 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) {
|
public Uri remapUri(Uri uri) {
|
||||||
return null;
|
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.
|
* 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_DATA = 4;
|
||||||
public static final int URI_TYPE_HTTP = 5;
|
public static final int URI_TYPE_HTTP = 5;
|
||||||
public static final int URI_TYPE_HTTPS = 6;
|
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 int URI_TYPE_UNKNOWN = -1;
|
||||||
|
|
||||||
|
public static final String PLUGIN_URI_SCHEME = "cdvplugin";
|
||||||
|
|
||||||
private static final String[] LOCAL_FILE_PROJECTION = { "_data" };
|
private static final String[] LOCAL_FILE_PROJECTION = { "_data" };
|
||||||
|
|
||||||
public static Thread jsThread;
|
public static Thread jsThread;
|
||||||
@ -123,6 +126,9 @@ public class CordovaResourceApi {
|
|||||||
if ("https".equals(scheme)) {
|
if ("https".equals(scheme)) {
|
||||||
return URI_TYPE_HTTPS;
|
return URI_TYPE_HTTPS;
|
||||||
}
|
}
|
||||||
|
if (PLUGIN_URI_SCHEME.equals(scheme)) {
|
||||||
|
return URI_TYPE_PLUGIN;
|
||||||
|
}
|
||||||
return URI_TYPE_UNKNOWN;
|
return URI_TYPE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,6 +288,14 @@ public class CordovaResourceApi {
|
|||||||
InputStream inputStream = conn.getInputStream();
|
InputStream inputStream = conn.getInputStream();
|
||||||
return new OpenForReadResult(uri, inputStream, mimeType, length, null);
|
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);
|
throw new FileNotFoundException("URI not supported by CordovaResourceApi: " + uri);
|
||||||
}
|
}
|
||||||
@ -431,7 +445,7 @@ public class CordovaResourceApi {
|
|||||||
public final long length;
|
public final long length;
|
||||||
public final AssetFileDescriptor assetFd;
|
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.uri = uri;
|
||||||
this.inputStream = inputStream;
|
this.inputStream = inputStream;
|
||||||
this.mimeType = mimeType;
|
this.mimeType = mimeType;
|
||||||
|
@ -36,9 +36,11 @@ import org.apache.cordova.PluginEntry;
|
|||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
|
||||||
public class CordovaResourceApiTest extends BaseCordovaIntegrationTest {
|
public class CordovaResourceApiTest extends BaseCordovaIntegrationTest {
|
||||||
@ -58,8 +60,18 @@ public class CordovaResourceApiTest extends BaseCordovaIntegrationTest {
|
|||||||
return cordovaWebView.getResourceApi().remapUri(
|
return cordovaWebView.getResourceApi().remapUri(
|
||||||
Uri.parse("data:text/plain;charset=utf-8,pass"));
|
Uri.parse("data:text/plain;charset=utf-8,pass"));
|
||||||
}
|
}
|
||||||
|
if (uri.getQuery() != null && uri.getQuery().contains("pluginUri")) {
|
||||||
|
return toPluginUri(uri);
|
||||||
|
}
|
||||||
return null;
|
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 {
|
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
|
||||||
synchronized (CordovaResourceApiTest.this) {
|
synchronized (CordovaResourceApiTest.this) {
|
||||||
execPayload = args.getString(0);
|
execPayload = args.getString(0);
|
||||||
@ -214,6 +226,16 @@ public class CordovaResourceApiTest extends BaseCordovaIntegrationTest {
|
|||||||
String data = new Scanner(readResult.inputStream, "UTF-8").useDelimiter("\\A").next();
|
String data = new Scanner(readResult.inputStream, "UTF-8").useDelimiter("\\A").next();
|
||||||
assertEquals("pass", data);
|
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
|
public void testWebViewRequestIntercept() throws Throwable
|
||||||
|
Loading…
Reference in New Issue
Block a user