Allow adding URLs to custom rules. #1276
This commit is contained in:
@@ -123,7 +123,7 @@
|
||||
<string name="route_entry_bypass_lan_chn">"LAN 及び中国本土のアドレスを迂回する"</string>
|
||||
<string name="route_entry_chinalist">"中国本土のアドレス以外を迂回する"</string>
|
||||
<string name="proxied_apps_summary_v21">"選択したアプリにプロキシを設定する"</string>
|
||||
<string name="acl_rule_templates_generic">"サブネット/ホスト名 PCRE パターン"</string>
|
||||
<string name="acl_rule_templates_generic">"URL/サブネット/ホスト名 PCRE パターン"</string>
|
||||
<string name="acl_rule_templates_domain">"ドメイン及び全てのサブドメイン"</string>
|
||||
|
||||
<!-- plugin -->
|
||||
|
||||
@@ -45,4 +45,4 @@
|
||||
<string name="tcp_fastopen_summary_unsupported">"지원하지 않는 버전의 커널입니다: %s < 3.7.1"</string>
|
||||
<string name="udp_dns">"DNS 포워딩"</string>
|
||||
<string name="udp_dns_summary">"모든 DNS 요청을 외부로 포워딩 합니다"</string>
|
||||
</resources>
|
||||
</resources>
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
<string name="route_entry_bypass_lan_chn">"Все, кроме LAN и Китая"</string>
|
||||
<string name="route_entry_chinalist">"Список Китай"</string>
|
||||
<string name="proxied_apps_summary_v21">"Установить прокси для выбранных приложений"</string>
|
||||
<string name="acl_rule_templates_generic">"Подсеть/Регулярное выражение (PCRE) имени хоста"</string>
|
||||
<string name="acl_rule_templates_generic">"URL/Подсеть/Регулярное выражение (PCRE) имени хоста"</string>
|
||||
<string name="acl_rule_templates_domain">"Доменное имя и все его поддомены"</string>
|
||||
|
||||
<!-- plugin -->
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
<string name="route_entry_bypass_lan_chn">"绕过局域网及中国大陆地址"</string>
|
||||
<string name="route_entry_chinalist">"仅代理中国大陆地址"</string>
|
||||
<string name="proxied_apps_summary_v21">"为应用程序分别设置代理"</string>
|
||||
<string name="acl_rule_templates_generic">"子网/域名 PCRE 正则表达式"</string>
|
||||
<string name="acl_rule_templates_generic">"URL/子网/域名 PCRE 正则表达式"</string>
|
||||
<string name="acl_rule_templates_domain">"域名及其子域名"</string>
|
||||
|
||||
<!-- plugin -->
|
||||
|
||||
@@ -122,7 +122,7 @@
|
||||
<string name="route_entry_bypass_lan_chn">"略過區域網路及中國大陸"</string>
|
||||
<string name="route_entry_chinalist">"China List"</string>
|
||||
<string name="proxied_apps_summary_v21">"為已選擇的應用程式設定 Proxy"</string>
|
||||
<string name="acl_rule_templates_generic">"子網路/主機名稱 PCRE 模式"</string>
|
||||
<string name="acl_rule_templates_generic">"URL/子網路/主機名稱 PCRE 模式"</string>
|
||||
<string name="acl_rule_templates_domain">"網域及其所有子網域"</string>
|
||||
|
||||
<!-- plugin -->
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
<string name="custom_rules">Custom rules</string>
|
||||
<string name="action_selection">Selection…</string>
|
||||
<string name="action_add_rule">Add rule(s)…</string>
|
||||
<string name="acl_rule_templates_generic">Subnet/Hostname PCRE pattern</string>
|
||||
<string name="acl_rule_templates_generic">URL, Subnet or Hostname PCRE pattern</string>
|
||||
<string name="acl_rule_templates_domain">Domain name and all its subdomain names</string>
|
||||
<string name="edit_rule">Edit rule</string>
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@ trait BaseService extends Service {
|
||||
}
|
||||
|
||||
if (profile.route == Acl.CUSTOM_RULES) // rationalize custom rules
|
||||
Acl.save(Acl.CUSTOM_RULES, new Acl().fromId(Acl.CUSTOM_RULES))
|
||||
Acl.save(Acl.CUSTOM_RULES, new Acl().fromId(Acl.CUSTOM_RULES), true)
|
||||
|
||||
plugin = new PluginConfiguration(profile.plugin).selectedOptions
|
||||
pluginPath = PluginManager.init(plugin)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.github.shadowsocks.acl
|
||||
|
||||
import java.io.{File, FileNotFoundException}
|
||||
import java.io.{File, FileNotFoundException, IOException}
|
||||
|
||||
import com.github.shadowsocks.ShadowsocksApplication.app
|
||||
import com.github.shadowsocks.utils.IOUtils
|
||||
@@ -22,6 +22,7 @@ class Acl {
|
||||
val bypassHostnames = new mutable.SortedList[String]()
|
||||
val proxyHostnames = new mutable.SortedList[String]()
|
||||
val subnets = new mutable.SortedList[Subnet]()
|
||||
val urls = new mutable.SortedList[String]()
|
||||
@DatabaseField
|
||||
var bypass: Boolean = _
|
||||
|
||||
@@ -40,6 +41,10 @@ class Acl {
|
||||
subnets.clear()
|
||||
subnets ++= value.split("\n").map(Subnet.fromString)
|
||||
}
|
||||
def setUrlRules(value: String) {
|
||||
urls.clear()
|
||||
urls ++= value.split("\n")
|
||||
}
|
||||
|
||||
def fromAcl(other: Acl): Acl = {
|
||||
bypassHostnames.clear()
|
||||
@@ -48,21 +53,35 @@ class Acl {
|
||||
proxyHostnames ++= other.proxyHostnames
|
||||
subnets.clear()
|
||||
subnets ++= other.subnets
|
||||
urls.clear()
|
||||
urls ++= other.urls
|
||||
bypass = other.bypass
|
||||
this
|
||||
}
|
||||
def fromSource(value: Source, defaultBypass: Boolean = false): Acl = {
|
||||
def fromSource(value: Source, defaultBypass: Boolean = true): Acl = {
|
||||
bypassHostnames.clear()
|
||||
proxyHostnames.clear()
|
||||
this.subnets.clear()
|
||||
this.urls.clear()
|
||||
bypass = defaultBypass
|
||||
lazy val bypassSubnets = new mutable.SortedList[Subnet]()
|
||||
lazy val proxySubnets = new mutable.SortedList[Subnet]()
|
||||
var hostnames: mutable.SortedList[String] = if (defaultBypass) proxyHostnames else bypassHostnames
|
||||
var subnets: mutable.SortedList[Subnet] = if (defaultBypass) proxySubnets else bypassSubnets
|
||||
var in_urls = false
|
||||
for (line <- value.getLines()) (line.indexOf('#') match {
|
||||
case -1 => line
|
||||
case index => line.substring(0, index) // trim comments
|
||||
case -1 => if (!in_urls) line else ""
|
||||
case index => {
|
||||
line.indexOf("URLS_BEGIN") match {
|
||||
case -1 =>
|
||||
case index => in_urls = true
|
||||
}
|
||||
line.indexOf("URLS_END") match {
|
||||
case -1 =>
|
||||
case index => in_urls = false
|
||||
}
|
||||
"" // ignore any comment lines
|
||||
}
|
||||
}).trim match {
|
||||
case "[outbound_block_list]" =>
|
||||
hostnames = null
|
||||
@@ -76,7 +95,10 @@ class Acl {
|
||||
case "[reject_all]" | "[bypass_all]" => bypass = true
|
||||
case "[accept_all]" | "[proxy_all]" => bypass = false
|
||||
case input if subnets != null && input.nonEmpty => try subnets += Subnet.fromString(input) catch {
|
||||
case _: IllegalArgumentException => hostnames += input
|
||||
case _: IllegalArgumentException => if (input.startsWith("http://") || input.startsWith("https://")) {
|
||||
urls += input
|
||||
}
|
||||
hostnames += input
|
||||
}
|
||||
case _ =>
|
||||
}
|
||||
@@ -85,9 +107,24 @@ class Acl {
|
||||
}
|
||||
final def fromId(id: String): Acl = fromSource(Source.fromFile(Acl.getFile(id)))
|
||||
|
||||
override def toString: String = {
|
||||
def getAclString(network: Boolean): String = {
|
||||
val result = new StringBuilder()
|
||||
result.append(if (bypass) "[bypass_all]\n" else "[proxy_all]\n")
|
||||
if (urls.nonEmpty) {
|
||||
result.append("#URLS_BEGIN\n")
|
||||
result.append(urls.mkString("\n"))
|
||||
if (network) {
|
||||
try {
|
||||
urls.foreach((url: String) => result.append(Source.fromURL(url).mkString))
|
||||
} catch {
|
||||
case e: IOException => // ignore
|
||||
}
|
||||
}
|
||||
result.append("#URLS_END\n")
|
||||
|
||||
}
|
||||
if (result.isEmpty) {
|
||||
result.append(if (bypass) "[bypass_all]\n" else "[proxy_all]\n")
|
||||
}
|
||||
val (bypassList, proxyList) =
|
||||
if (bypass) (bypassHostnames.toStream, subnets.toStream.map(_.toString) #::: proxyHostnames.toStream)
|
||||
else (subnets.toStream.map(_.toString) #::: bypassHostnames.toStream, proxyHostnames.toStream)
|
||||
@@ -104,6 +141,10 @@ class Acl {
|
||||
result.toString
|
||||
}
|
||||
|
||||
override def toString: String = {
|
||||
getAclString(false)
|
||||
}
|
||||
|
||||
def isValidCustomRules: Boolean = bypass && bypassHostnames.isEmpty
|
||||
|
||||
// Don't change: dummy fields for OrmLite interaction
|
||||
@@ -134,9 +175,9 @@ object Acl {
|
||||
try acl.fromId(CUSTOM_RULES) catch {
|
||||
case _: FileNotFoundException =>
|
||||
}
|
||||
acl.bypass = true
|
||||
acl.bypassHostnames.clear() // everything is bypassed
|
||||
acl
|
||||
}
|
||||
def save(id: String, acl: Acl): Unit = IOUtils.writeString(getFile(id), acl.toString)
|
||||
def save(id: String, acl: Acl, network: Boolean = false): Unit = {
|
||||
IOUtils.writeString(getFile(id), acl.getAclString(network))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user