Commit 390cb522 authored by Max Lv's avatar Max Lv

Fix #1351

parent b14fdcae
...@@ -19,20 +19,19 @@ import scala.io.Source ...@@ -19,20 +19,19 @@ import scala.io.Source
class Acl { class Acl {
@DatabaseField(generatedId = true) @DatabaseField(generatedId = true)
var id: Int = _ var id: Int = _
val bypassHostnames = new mutable.SortedList[String]()
val proxyHostnames = new mutable.SortedList[String]() val hostnames = new mutable.SortedList[String]()
val subnets = new mutable.SortedList[Subnet]() val subnets = new mutable.SortedList[Subnet]()
val urls = new mutable.SortedList[String]() val urls = new mutable.SortedList[String]()
@DatabaseField @DatabaseField
var bypass: Boolean = _ var bypass: Boolean = _
def isUrl(url: String): Boolean = url.startsWith("http://") || url.startsWith("https://") def isUrl(url: String): Boolean = url.startsWith("http://") || url.startsWith("https://")
def fromAcl(other: Acl): Acl = { def fromAcl(other: Acl): Acl = {
bypassHostnames.clear() hostnames.clear()
bypassHostnames ++= other.bypassHostnames hostnames ++= other.hostnames
proxyHostnames.clear()
proxyHostnames ++= other.proxyHostnames
subnets.clear() subnets.clear()
subnets ++= other.subnets subnets ++= other.subnets
urls.clear() urls.clear()
...@@ -40,16 +39,11 @@ class Acl { ...@@ -40,16 +39,11 @@ class Acl {
bypass = other.bypass bypass = other.bypass
this this
} }
def fromSource(value: Source, defaultBypass: Boolean = true): Acl = { def fromSource(value: Source, defaultBypass: Boolean = true): Acl = {
bypassHostnames.clear() subnets.clear()
proxyHostnames.clear() urls.clear()
this.subnets.clear()
this.urls.clear()
bypass = defaultBypass 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 var in_urls = false
for (line <- value.getLines()) (line.trim.indexOf('#') match { for (line <- value.getLines()) (line.trim.indexOf('#') match {
case 0 => { case 0 => {
...@@ -65,17 +59,12 @@ class Acl { ...@@ -65,17 +59,12 @@ class Acl {
} }
case index => if (!in_urls) line else "" case index => if (!in_urls) line else ""
}).trim match { }).trim match {
// Ignore all section controls
case "[outbound_block_list]" => case "[outbound_block_list]" =>
hostnames = null
subnets = null
case "[black_list]" | "[bypass_list]" => case "[black_list]" | "[bypass_list]" =>
hostnames = bypassHostnames
subnets = bypassSubnets
case "[white_list]" | "[proxy_list]" => case "[white_list]" | "[proxy_list]" =>
hostnames = proxyHostnames case "[reject_all]" | "[bypass_all]" =>
subnets = proxySubnets case "[accept_all]" | "[proxy_all]" =>
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 input if subnets != null && input.nonEmpty => try subnets += Subnet.fromString(input) catch {
case _: IllegalArgumentException => if (isUrl(input)) { case _: IllegalArgumentException => if (isUrl(input)) {
urls += input urls += input
...@@ -85,7 +74,6 @@ class Acl { ...@@ -85,7 +74,6 @@ class Acl {
} }
case _ => case _ =>
} }
this.subnets ++= (if (bypass) proxySubnets else bypassSubnets)
this this
} }
final def fromId(id: String): Acl = fromSource(Source.fromFile(Acl.getFile(id))) final def fromId(id: String): Acl = fromSource(Source.fromFile(Acl.getFile(id)))
...@@ -103,21 +91,15 @@ class Acl { ...@@ -103,21 +91,15 @@ class Acl {
} }
result.append("\n#NETWORK_ACL_END\n") result.append("\n#NETWORK_ACL_END\n")
} }
result.append("\n")
} }
if (result.isEmpty) { if (result.isEmpty) {
result.append(if (bypass) "[bypass_all]\n" else "[proxy_all]\n") result.append("[bypass_all]\n")
}
val (bypassList, proxyList) =
if (bypass) (bypassHostnames.toStream, subnets.toStream.map(_.toString) #::: proxyHostnames.toStream)
else (subnets.toStream.map(_.toString) #::: bypassHostnames.toStream, proxyHostnames.toStream)
if (bypassList.nonEmpty) {
result.append("[bypass_list]\n")
result.append(bypassList.mkString("\n"))
result.append('\n')
} }
if (proxyList.nonEmpty) { val list = subnets.toStream.map(_.toString) #::: hostnames.toStream
if (list.nonEmpty) {
result.append("[proxy_list]\n") result.append("[proxy_list]\n")
result.append(proxyList.mkString("\n")) result.append(list.mkString("\n"))
result.append('\n') result.append('\n')
} }
result.toString result.toString
...@@ -127,7 +109,7 @@ class Acl { ...@@ -127,7 +109,7 @@ class Acl {
getAclString(false) getAclString(false)
} }
def isValidCustomRules: Boolean = bypass && bypassHostnames.isEmpty def isValidCustomRules: Boolean = !hostnames.isEmpty
// Don't change: dummy fields for OrmLite interaction // Don't change: dummy fields for OrmLite interaction
......
...@@ -125,7 +125,7 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi ...@@ -125,7 +125,7 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi
}) })
} }
def getItemCount: Int = acl.subnets.size + acl.proxyHostnames.size + acl.urls.size def getItemCount: Int = acl.subnets.size + acl.hostnames.size + acl.urls.size
def onBindViewHolder(vh: AclRuleViewHolder, i: Int): Unit = { def onBindViewHolder(vh: AclRuleViewHolder, i: Int): Unit = {
val j = i - acl.urls.size val j = i - acl.urls.size
val k = i - acl.subnets.size - acl.urls.size val k = i - acl.subnets.size - acl.urls.size
...@@ -134,7 +134,7 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi ...@@ -134,7 +134,7 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi
else if (k < 0) else if (k < 0)
vh.bind(acl.subnets(j)) vh.bind(acl.subnets(j))
else else
vh.bind(acl.proxyHostnames(k)) vh.bind(acl.hostnames(k))
} }
def onCreateViewHolder(vg: ViewGroup, i: Int) = new AclRuleViewHolder(LayoutInflater.from(vg.getContext) def onCreateViewHolder(vg: ViewGroup, i: Int) = new AclRuleViewHolder(LayoutInflater.from(vg.getContext)
.inflate(android.R.layout.simple_list_item_1, vg, false)) .inflate(android.R.layout.simple_list_item_1, vg, false))
...@@ -151,18 +151,18 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi ...@@ -151,18 +151,18 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi
apply() apply()
index index
} else -1 } else -1
def addHostname(hostname: String): Int = if (acl.proxyHostnames.add(hostname)) { def addHostname(hostname: String): Int = if (acl.hostnames.add(hostname)) {
val index = acl.proxyHostnames.indexOf(hostname) + acl.urls.size + acl.subnets.size val index = acl.hostnames.indexOf(hostname) + acl.urls.size + acl.subnets.size
notifyItemInserted(index) notifyItemInserted(index)
apply() apply()
index index
} else -1 } else -1
def addToProxy(input: String): Int = { def addToProxy(input: String): Int = {
val acl = new Acl().fromSource(Source.fromString(input), defaultBypass = true) val acl = new Acl().fromSource(Source.fromString(input))
var result = -1 var result = -1
for (url <- acl.urls) result = addUrl(url) for (url <- acl.urls) result = addUrl(url)
for (hostname <- acl.proxyHostnames) result = addHostname(hostname) for (hostname <- acl.hostnames) result = addHostname(hostname)
if (acl.bypass) for (subnet <- acl.subnets) result = addSubnet(subnet) for (subnet <- acl.subnets) result = addSubnet(subnet)
result result
} }
def addFromTemplate(template: Int, text: CharSequence): Int = template match { def addFromTemplate(template: Int, text: CharSequence): Int = template match {
...@@ -186,8 +186,8 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi ...@@ -186,8 +186,8 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi
undoManager.remove((i, acl.subnets(j))) undoManager.remove((i, acl.subnets(j)))
acl.subnets.remove(j) acl.subnets.remove(j)
} else { } else {
undoManager.remove((i, acl.proxyHostnames(k))) undoManager.remove((i, acl.hostnames(k)))
acl.proxyHostnames.remove(k) acl.hostnames.remove(k)
} }
notifyItemRemoved(i) notifyItemRemoved(i)
apply() apply()
...@@ -202,9 +202,9 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi ...@@ -202,9 +202,9 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi
acl.urls.remove(hostname) acl.urls.remove(hostname)
apply() apply()
} else { } else {
notifyItemRemoved(acl.proxyHostnames.indexOf(hostname) notifyItemRemoved(acl.hostnames.indexOf(hostname)
+ acl.urls.size + acl.subnets.size) + acl.urls.size + acl.subnets.size)
acl.proxyHostnames.remove(hostname) acl.hostnames.remove(hostname)
apply() apply()
} }
} }
...@@ -221,8 +221,8 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi ...@@ -221,8 +221,8 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi
apply() apply()
} }
} else { } else {
if (acl.proxyHostnames.insert(hostname)) { if (acl.hostnames.insert(hostname)) {
notifyItemInserted(acl.proxyHostnames.indexOf(hostname) + acl.urls.size + acl.subnets.size) notifyItemInserted(acl.hostnames.indexOf(hostname) + acl.urls.size + acl.subnets.size)
apply() apply()
} }
} }
...@@ -236,7 +236,7 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi ...@@ -236,7 +236,7 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi
selectedItems.clear() selectedItems.clear()
selectedItems ++= acl.urls selectedItems ++= acl.urls
selectedItems ++= acl.subnets selectedItems ++= acl.subnets
selectedItems ++= acl.proxyHostnames selectedItems ++= acl.hostnames
onSelectedItemsUpdated() onSelectedItemsUpdated()
notifyDataSetChanged() notifyDataSetChanged()
} }
...@@ -245,7 +245,7 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi ...@@ -245,7 +245,7 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi
val j = i - acl.subnets.size val j = i - acl.subnets.size
try { try {
(if (j < 0) acl.subnets(i).address.getHostAddress.substring(0, 1) else { (if (j < 0) acl.subnets(i).address.getHostAddress.substring(0, 1) else {
val hostname = acl.proxyHostnames(i) val hostname = acl.hostnames(i)
PATTERN_DOMAIN.findFirstMatchIn(hostname) match { PATTERN_DOMAIN.findFirstMatchIn(hostname) match {
case Some(m) => m.matched.replaceAll("\\\\.", ".") // don't convert IDN yet case Some(m) => m.matched.replaceAll("\\\\.", ".") // don't convert IDN yet
case None => hostname case None => hostname
...@@ -341,7 +341,7 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi ...@@ -341,7 +341,7 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi
case R.id.action_import_gfwlist => case R.id.action_import_gfwlist =>
val acl = new Acl().fromId(Acl.GFWLIST) val acl = new Acl().fromId(Acl.GFWLIST)
acl.subnets.foreach(adapter.addSubnet) acl.subnets.foreach(adapter.addSubnet)
acl.proxyHostnames.foreach(adapter.addHostname) acl.hostnames.foreach(adapter.addHostname)
true true
case _ => false case _ => false
} }
......
sbt.version=0.13.16
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment