Abstract RequestModifier, AdHocRequestModifier, RequestModifierOptions

This commit is contained in:
Kelvin 2023-12-12 14:44:07 +01:00
parent 73dd52af28
commit 49b5b16641
11 changed files with 136 additions and 52 deletions

View file

@ -0,0 +1,14 @@
package com.futo.platformplayer.api.media.models.modifier
class AdhocRequestModifier: IRequestModifier {
val _handler: (String, Map<String,String>)->IRequest;
override var allowByteSkip: Boolean = false;
constructor(modifyReq: (String, Map<String,String>)->IRequest) {
_handler = modifyReq;
}
override fun modifyRequest(url: String, headers: Map<String, String>): IRequest {
return _handler(url, headers);
}
}

View file

@ -0,0 +1,6 @@
package com.futo.platformplayer.api.media.models.modifier
interface IModifierOptions {
val applyAuthClient: String?;
val applyCookieClient: String?;
}

View file

@ -0,0 +1,6 @@
package com.futo.platformplayer.api.media.models.modifier
interface IRequest {
val url: String?;
val headers: Map<String, String>;
}

View file

@ -0,0 +1,7 @@
package com.futo.platformplayer.api.media.models.modifier
interface IRequestModifier {
var allowByteSkip: Boolean;
fun modifyRequest(url: String, headers: Map<String, String>): IRequest
}

View file

@ -57,11 +57,6 @@ class JSHttpClient : ManagedHttpClient {
return newClient;
}
fun applyRequest(req: JSRequestModifier.Request) {
}
//TODO: Use this in beforeRequest to remove dup code
fun applyHeaders(url: Uri, headers: MutableMap<String, String>, applyAuth: Boolean = false, applyOtherCookies: Boolean = false) {
val domain = url.host!!.lowercase();

View file

@ -1,18 +1,81 @@
package com.futo.platformplayer.api.media.platforms.js.models
import android.net.Uri
import com.caoccao.javet.values.reference.V8ValueObject
import com.futo.platformplayer.api.media.models.modifier.IModifierOptions
import com.futo.platformplayer.api.media.models.modifier.IRequest
import com.futo.platformplayer.api.media.platforms.js.JSClient
import com.futo.platformplayer.engine.IV8PluginConfig
import com.futo.platformplayer.getOrThrow
import com.futo.platformplayer.logging.Logger
import com.futo.platformplayer.getOrDefault
@kotlinx.serialization.Serializable
class JSRequest : JSRequestModifier.IRequest {
override val url: String;
override var headers: Map<String, String>;
class JSRequest : IRequest {
private val _v8Url: String?;
private val _v8Headers: Map<String, String>?;
private val _v8Options: Options?;
constructor(config: IV8PluginConfig, obj: V8ValueObject) {
override var url: String? = null;
override lateinit var headers: Map<String, String>;
constructor(plugin: JSClient, url: String?, headers: Map<String, String>?, options: Options?, originalUrl: String?, originalHeaders: Map<String, String>?) {
_v8Url = url;
_v8Headers = headers;
_v8Options = options;
initialize(plugin, originalUrl, originalHeaders);
}
constructor(plugin: JSClient, obj: V8ValueObject, originalUrl: String?, originalHeaders: Map<String, String>?) {
val contextName = "ModifyRequestResponse";
url = obj.getOrThrow(config, "url", contextName);
headers = obj.getOrThrow(config, "headers", contextName);
val config = plugin.config;
_v8Url = obj.getOrDefault<String>(config, "url", contextName, null);
_v8Headers = obj.getOrDefault<Map<String, String>>(config, "headers", contextName, null);
_v8Options = obj.getOrDefault<V8ValueObject>(config, "options", "JSRequestModifier.options", null)?.let {
Options(config, it);
}
initialize(plugin, originalUrl, originalHeaders);
}
private fun initialize(plugin: JSClient, originalUrl: String?, originalHeaders: Map<String, String>?) {
val config = plugin.config;
url = _v8Url ?: originalUrl;
headers = _v8Headers ?: originalHeaders ?: mapOf();
if(_v8Options != null) {
if(_v8Options.applyCookieClient != null && url != null) {
val client = plugin.getHttpClientById(_v8Options.applyCookieClient);
if(client != null) {
val toModifyHeaders = headers.toMutableMap();
client.applyHeaders(Uri.parse(url), toModifyHeaders, false, true);
headers = toModifyHeaders;
}
}
if(_v8Options.applyAuthClient != null && url != null) {
val client = plugin.getHttpClientById(_v8Options.applyAuthClient);
if(client != null) {
val toModifyHeaders = headers.toMutableMap();
client.applyHeaders(Uri.parse(url), toModifyHeaders, true, false);
headers = toModifyHeaders;
}
}
}
}
fun modify(plugin: JSClient, originalUrl: String?, originalHeaders: Map<String, String>?): JSRequest {
return JSRequest(plugin, _v8Url, _v8Headers, _v8Options, originalUrl, originalHeaders);
}
@kotlinx.serialization.Serializable
class Options: IModifierOptions {
override val applyAuthClient: String?;
override val applyCookieClient: String?;
constructor(config: IV8PluginConfig, obj: V8ValueObject) {
applyAuthClient = obj.getOrDefault(config, "applyAuthClient", "JSRequestModifier.options.applyAuthClient", null);
applyCookieClient = obj.getOrDefault(config, "applyCookieClient", "JSRequestModifier.options.applyCookieClient", null);
}
}
companion object {
}
}

View file

@ -2,6 +2,8 @@ package com.futo.platformplayer.api.media.platforms.js.models
import android.net.Uri
import com.caoccao.javet.values.reference.V8ValueObject
import com.futo.platformplayer.api.media.models.modifier.IRequest
import com.futo.platformplayer.api.media.models.modifier.IRequestModifier
import com.futo.platformplayer.api.media.platforms.js.JSClient
import com.futo.platformplayer.engine.IV8PluginConfig
import com.futo.platformplayer.engine.V8Plugin
@ -10,11 +12,11 @@ import com.futo.platformplayer.getOrDefault
import com.futo.platformplayer.getOrNull
import com.futo.platformplayer.getOrThrow
class JSRequestModifier {
class JSRequestModifier: IRequestModifier {
private val _plugin: JSClient;
private val _config: IV8PluginConfig;
private var _modifier: V8ValueObject;
val allowByteSkip: Boolean;
override var allowByteSkip: Boolean;
constructor(plugin: JSClient, modifier: V8ValueObject) {
this._plugin = plugin;
@ -28,7 +30,7 @@ class JSRequestModifier {
throw ScriptImplementationException(config, "RequestModifier is missing modifyRequest", null);
}
fun modifyRequest(url: String, headers: Map<String, String>): IRequest {
override fun modifyRequest(url: String, headers: Map<String, String>): IRequest {
if (_modifier.isClosed) {
return Request(url, headers);
}
@ -37,35 +39,10 @@ class JSRequestModifier {
_modifier.invoke("modifyRequest", url, headers);
} as V8ValueObject;
val req = JSRequest(_config, result);
val options: V8ValueObject? = result.getOrDefault(_config, "options", "JSRequestModifier.options", null);
if(options != null) {
if(options.has("applyCookieClient")) {
val clientId: String = options.getOrThrow(_config, "applyCookieClient", "JSRequestModifier.options.applyCookieClient", false)
val client = _plugin.getHttpClientById(clientId);
if(client != null) {
val toModifyHeaders = req.headers.toMutableMap();
client.applyHeaders(Uri.parse(req.url), toModifyHeaders, false, true);
req.headers = toModifyHeaders;
}
}
if(options.has("applyAuthClient")) {
val clientId: String = options.getOrThrow(_config, "applyAuthClient", "JSRequestModifier.options.applyAuthClient", false)
val client = _plugin.getHttpClientById(clientId);
if(client != null) {
val toModifyHeaders = req.headers.toMutableMap();
client.applyHeaders(Uri.parse(req.url), toModifyHeaders, true, false);
req.headers = toModifyHeaders;
}
}
}
val req = JSRequest(_plugin, result, url, headers);
return req;
}
interface IRequest {
val url: String;
val headers: Map<String, String>;
}
data class Request(override val url: String, override val headers: Map<String, String>) : IRequest;
}

View file

@ -4,12 +4,16 @@ package com.futo.platformplayer.api.media.platforms.js.models.sources
import com.caoccao.javet.values.V8Value
import com.caoccao.javet.values.reference.V8ValueObject
import com.futo.platformplayer.api.media.models.modifier.AdhocRequestModifier
import com.futo.platformplayer.api.media.models.modifier.IRequestModifier
import com.futo.platformplayer.api.media.models.streams.sources.IAudioSource
import com.futo.platformplayer.api.media.models.streams.sources.IVideoSource
import com.futo.platformplayer.api.media.platforms.js.JSClient
import com.futo.platformplayer.api.media.platforms.js.models.JSRequest
import com.futo.platformplayer.api.media.platforms.js.models.JSRequestModifier
import com.futo.platformplayer.engine.IV8PluginConfig
import com.futo.platformplayer.engine.V8Plugin
import com.futo.platformplayer.getOrDefault
import com.futo.platformplayer.orNull
import com.futo.platformplayer.views.video.datasources.JSHttpDataSource
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource
@ -20,6 +24,7 @@ abstract class JSSource {
protected val _config: IV8PluginConfig;
protected val _obj: V8ValueObject;
val hasRequestModifier: Boolean;
private val _requestModifier: JSRequest?;
val type : String;
@ -29,10 +34,18 @@ abstract class JSSource {
this._obj = obj;
this.type = type;
hasRequestModifier = obj.has("getRequestModifier");
_requestModifier = obj.getOrDefault<V8ValueObject>(_config, "requestModifier", "JSSource.requestModifier", null)?.let {
JSRequest(plugin, it, null, null);
}
hasRequestModifier = _requestModifier != null || obj.has("getRequestModifier");
}
fun getRequestModifier(): JSRequestModifier? {
fun getRequestModifier(): IRequestModifier? {
if(_requestModifier != null)
return AdhocRequestModifier { url, headers ->
return@AdhocRequestModifier _requestModifier.modify(_plugin, url, headers);
};
if (!hasRequestModifier || _obj.isClosed) {
return null;
}

View file

@ -9,6 +9,8 @@ import android.net.Uri;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import com.futo.platformplayer.api.media.models.modifier.IRequest;
import com.futo.platformplayer.api.media.models.modifier.IRequestModifier;
import com.futo.platformplayer.api.media.platforms.js.models.JSRequestModifier;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.PlaybackException;
@ -57,7 +59,7 @@ public class JSHttpDataSource extends BaseDataSource implements HttpDataSource {
private int readTimeoutMs;
private boolean allowCrossProtocolRedirects;
private boolean keepPostFor302Redirects;
@Nullable private JSRequestModifier requestModifier = null;
@Nullable private IRequestModifier requestModifier = null;
/** Creates an instance. */
public Factory() {
@ -80,7 +82,7 @@ public class JSHttpDataSource extends BaseDataSource implements HttpDataSource {
* @param requestModifier The request modifier that will be used, or {@code null} to use no request modifier
* @return This factory.
*/
public Factory setRequestModifier(@Nullable JSRequestModifier requestModifier) {
public Factory setRequestModifier(@Nullable IRequestModifier requestModifier) {
this.requestModifier = requestModifier;
return this;
}
@ -225,7 +227,7 @@ public class JSHttpDataSource extends BaseDataSource implements HttpDataSource {
private int responseCode;
private long bytesToRead;
private long bytesRead;
@Nullable private JSRequestModifier requestModifier;
@Nullable private IRequestModifier requestModifier;
private JSHttpDataSource(
@Nullable String userAgent,
@ -235,7 +237,7 @@ public class JSHttpDataSource extends BaseDataSource implements HttpDataSource {
@Nullable RequestProperties defaultRequestProperties,
@Nullable Predicate<String> contentTypePredicate,
boolean keepPostFor302Redirects,
@Nullable JSRequestModifier requestModifier) {
@Nullable IRequestModifier requestModifier) {
super(/* isNetwork= */ true);
this.userAgent = userAgent;
this.connectTimeoutMillis = connectTimeoutMillis;
@ -571,8 +573,9 @@ public class JSHttpDataSource extends BaseDataSource implements HttpDataSource {
String requestUrl = url.toString();
if (requestModifier != null) {
JSRequestModifier.IRequest result = requestModifier.modifyRequest(requestUrl, requestHeaders);
requestUrl = result.getUrl();
IRequest result = requestModifier.modifyRequest(requestUrl, requestHeaders);
String modifiedUrl = result.getUrl();
requestUrl = (modifiedUrl != null) ? modifiedUrl : requestUrl;
requestHeaders = result.getHeaders();
}

@ -1 +1 @@
Subproject commit f2086dc2cf6387f692049f52cdf938313dc53654
Subproject commit f031e10d3852dd7138f2ed312c5e74466f23da32

@ -1 +1 @@
Subproject commit fad5e14f84573796b3989794c35f34a1f88f03a6
Subproject commit d41cc8e848891ef8e949e6d49384b754e7c305c7