Add custom HTTP headers for subscription updates
https://github.com/2dust/v2rayNG/pull/5856
This commit is contained in:
1 parent
69cf1e70c1
commit
1eaea8e161
9 files changed
+49
-21
No files matched your search
@@ -6,5 +6,6 @@ data class UrlContentRequest(
|
||||
val httpPort: Int = 0,
|
||||
val proxyUsername: String? = null,
|
||||
val proxyPassword: String? = null,
|
||||
val userAgent: String? = null
|
||||
val userAgent: String? = null,
|
||||
val requestHeaders: String? = null
|
||||
)
|
||||
@@ -13,5 +13,6 @@ data class SubscriptionItem(
|
||||
var filter: String? = null,
|
||||
var allowInsecureUrl: Boolean = false,
|
||||
var userAgent: String? = null,
|
||||
var requestHeaders: String? = null,
|
||||
)
|
||||
|
||||
@@ -557,6 +557,7 @@ object AngConfigManager {
|
||||
}
|
||||
LogUtil.i(AppConfig.TAG, url)
|
||||
val userAgent = it.subscription.userAgent
|
||||
val requestHeaders = it.subscription.requestHeaders
|
||||
val proxyUsername = SettingsManager.getSocksUsername()
|
||||
val proxyPassword = SettingsManager.getSocksPassword()
|
||||
|
||||
@@ -566,6 +567,7 @@ object AngConfigManager {
|
||||
UrlContentRequest(
|
||||
url = url,
|
||||
userAgent = userAgent,
|
||||
requestHeaders = requestHeaders,
|
||||
timeout = 15000,
|
||||
httpPort = httpPort,
|
||||
proxyUsername = proxyUsername,
|
||||
@@ -581,7 +583,8 @@ object AngConfigManager {
|
||||
HttpUtil.getUrlContentWithUserAgent(
|
||||
UrlContentRequest(
|
||||
url = url,
|
||||
userAgent = userAgent
|
||||
userAgent = userAgent,
|
||||
requestHeaders = requestHeaders
|
||||
)
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
|
||||
@@ -75,7 +75,6 @@ class SubEditActivity : BaseComponentActivity() {
|
||||
}
|
||||
|
||||
private fun saveServer(subItem: SubscriptionItem): Boolean {
|
||||
val intervalMinutes = subItem.updateInterval
|
||||
|
||||
if (TextUtils.isEmpty(subItem.remarks)) {
|
||||
toast(R.string.sub_setting_remarks)
|
||||
@@ -94,6 +93,11 @@ class SubEditActivity : BaseComponentActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
if (subItem.autoUpdate && subItem.updateInterval < AppConfig.SUBSCRIPTION_MIN_INTERVAL_MINUTES) {
|
||||
toast(R.string.toast_invalid_update_interval)
|
||||
return false
|
||||
}
|
||||
|
||||
MmkvManager.encodeSubscription(editSubId, subItem)
|
||||
SubscriptionUpdater.syncOne(subId = editSubId)
|
||||
SettingsChangeManager.makeSetupGroupTab()
|
||||
@@ -123,11 +127,11 @@ fun SubEditScreen(
|
||||
onSave: (SubscriptionItem) -> Boolean,
|
||||
onDelete: () -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
|
||||
//val context = LocalContext.current
|
||||
var remarks by rememberSaveable { mutableStateOf(initial.remarks.orEmpty()) }
|
||||
var url by rememberSaveable { mutableStateOf(initial.url.orEmpty()) }
|
||||
var userAgent by rememberSaveable { mutableStateOf(initial.userAgent.orEmpty()) }
|
||||
var requestHeaders by rememberSaveable { mutableStateOf(initial.requestHeaders.orEmpty()) }
|
||||
var filter by rememberSaveable { mutableStateOf(initial.filter ?: "") }
|
||||
var enabled by rememberSaveable { mutableStateOf(initial.enabled) }
|
||||
var autoUpdate by rememberSaveable { mutableStateOf(initial.autoUpdate) }
|
||||
@@ -145,25 +149,11 @@ fun SubEditScreen(
|
||||
subItem.remarks = remarks
|
||||
subItem.url = url
|
||||
subItem.userAgent = userAgent
|
||||
subItem.requestHeaders = requestHeaders
|
||||
subItem.filter = filter
|
||||
subItem.enabled = enabled
|
||||
subItem.autoUpdate = autoUpdate
|
||||
val intervalInput = updateInterval.trim()
|
||||
val intervalMinutes = intervalInput.toLongOrNull()
|
||||
if (autoUpdate) {
|
||||
if (intervalMinutes == null) {
|
||||
subItem.updateInterval = SubscriptionItem().updateInterval
|
||||
} else if (intervalMinutes < AppConfig.SUBSCRIPTION_MIN_INTERVAL_MINUTES) {
|
||||
context.toast(context.getString(R.string.toast_invalid_update_interval))
|
||||
return null
|
||||
} else {
|
||||
subItem.updateInterval = intervalMinutes
|
||||
}
|
||||
} else {
|
||||
if (intervalMinutes != null && intervalMinutes >= AppConfig.SUBSCRIPTION_MIN_INTERVAL_MINUTES) {
|
||||
subItem.updateInterval = intervalMinutes
|
||||
}
|
||||
}
|
||||
subItem.updateInterval = updateInterval.toLong()
|
||||
subItem.prevProfile = prevProfile
|
||||
subItem.nextProfile = nextProfile
|
||||
subItem.allowInsecureUrl = allowInsecureUrl
|
||||
@@ -203,6 +193,7 @@ fun SubEditScreen(
|
||||
FormTextField(stringResource(R.string.sub_setting_remarks), remarks, { remarks = it })
|
||||
FormTextField(stringResource(R.string.sub_setting_url), url, { url = it })
|
||||
FormTextField(stringResource(R.string.sub_setting_user_agent), userAgent, { userAgent = it })
|
||||
FormTextField(stringResource(R.string.sub_setting_request_headers), requestHeaders, { requestHeaders = it })
|
||||
FormTextField(stringResource(R.string.sub_setting_filter), filter, { filter = it })
|
||||
SettingsSwitchItem(
|
||||
title = stringResource(R.string.sub_setting_enable),
|
||||
|
||||
@@ -164,6 +164,16 @@ object HttpUtil {
|
||||
|
||||
applyEmbeddedBasicAuthHeader(currentUrl, requestBuilder)
|
||||
|
||||
|
||||
val headersMap = JsonUtil.parseHeadersToMap(request.requestHeaders)
|
||||
for ((key, value) in headersMap) {
|
||||
LogUtil.d(AppConfig.TAG, "Adding custom header: $key = $value")
|
||||
try {
|
||||
requestBuilder.header(key, value)
|
||||
} catch (_: IllegalArgumentException) {
|
||||
}
|
||||
}
|
||||
|
||||
if (request.httpPort != 0 && !request.proxyUsername.isNullOrBlank() && !request.proxyPassword.isNullOrBlank()) {
|
||||
requestBuilder.header("Proxy-Authorization", Credentials.basic(request.proxyUsername, request.proxyPassword))
|
||||
}
|
||||
|
||||
@@ -92,4 +92,23 @@ object JsonUtil {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
fun parseHeadersToMap(headersJson: String?): Map<String, String> {
|
||||
val headerMap = mutableMapOf<String, String>()
|
||||
val jsonObject = parseString(headersJson) ?: return headerMap
|
||||
try {
|
||||
for ((key, jsonElement) in jsonObject.entrySet()) {
|
||||
if (key.isNullOrBlank() || jsonElement == null || jsonElement.isJsonNull) {
|
||||
continue
|
||||
}
|
||||
val value = if (jsonElement.isJsonPrimitive) jsonElement.asString else jsonElement.toString()
|
||||
if (value.isNotBlank()) {
|
||||
headerMap[key] = value
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
LogUtil.e(AppConfig.TAG, "Failed to parse headers JSON", e)
|
||||
}
|
||||
return headerMap
|
||||
}
|
||||
}
|
||||
@@ -305,6 +305,7 @@
|
||||
<string name="sub_setting_remarks">备注</string>
|
||||
<string name="sub_setting_url">可选地址 (url)</string>
|
||||
<string name="sub_setting_user_agent">User Agent</string>
|
||||
<string name="sub_setting_request_headers">请求头(JSON 格式)</string>
|
||||
<string name="sub_setting_filter">别名正则过滤</string>
|
||||
<string name="sub_setting_enable">启用更新</string>
|
||||
<string name="sub_auto_update">启用自动更新</string>
|
||||
|
||||
@@ -304,6 +304,7 @@
|
||||
<string name="sub_setting_remarks">備註</string>
|
||||
<string name="sub_setting_url">可選位址(url)</string>
|
||||
<string name="sub_setting_user_agent">User Agent</string>
|
||||
<string name="sub_setting_request_headers">請求頭(JSON 格式)</string>
|
||||
<string name="sub_setting_filter">別名正規過濾</string>
|
||||
<string name="sub_setting_enable">啟用更新</string>
|
||||
<string name="sub_auto_update">啟用自動更新</string>
|
||||
|
||||
@@ -311,6 +311,7 @@
|
||||
<string name="sub_setting_remarks">remarks</string>
|
||||
<string name="sub_setting_url">Optional URL</string>
|
||||
<string name="sub_setting_user_agent">User Agent</string>
|
||||
<string name="sub_setting_request_headers">Request Headers (JSON format)</string>
|
||||
<string name="sub_setting_filter">Remarks regular filter</string>
|
||||
<string name="sub_setting_enable">Enable update</string>
|
||||
<string name="sub_auto_update">Enable automatic update</string>
|
||||
|
||||
Reference in new issue
Block a user