Commit fb3f7429 authored by Mygod's avatar Mygod

Refine parser

parent 0e0e65c4
...@@ -50,9 +50,8 @@ import com.github.shadowsocks.utils.Parser ...@@ -50,9 +50,8 @@ import com.github.shadowsocks.utils.Parser
class ParserActivity extends AppCompatActivity { class ParserActivity extends AppCompatActivity {
override def onCreate(savedInstanceState: Bundle) { override def onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val data = getIntent.getData.toString val profiles = Parser.findAll(getIntent.getData.toString)
val profile = Parser.parse(data) if (profiles.isEmpty) { // ignore
if (profile.isEmpty) { // ignore
finish() finish()
return return
} }
...@@ -60,11 +59,10 @@ class ParserActivity extends AppCompatActivity { ...@@ -60,11 +59,10 @@ class ParserActivity extends AppCompatActivity {
val dialog = new AlertDialog.Builder(this) val dialog = new AlertDialog.Builder(this)
.setTitle(R.string.add_profile_dialog) .setTitle(R.string.add_profile_dialog)
.setCancelable(false) .setCancelable(false)
.setPositiveButton(android.R.string.yes, ((dialog: DialogInterface, id: Int) => { .setPositiveButton(android.R.string.yes, ((_, _) =>
ShadowsocksApplication.profileManager.createProfile(profile.get) profiles.foreach(ShadowsocksApplication.profileManager.createProfile)): DialogInterface.OnClickListener)
}): DialogInterface.OnClickListener)
.setNegativeButton(android.R.string.no, null) .setNegativeButton(android.R.string.no, null)
.setMessage(data) .setMessage(profiles.mkString("\n"))
.create() .create()
dialog.setOnDismissListener((dialog: DialogInterface) => finish()) // builder method was added in API 17 dialog.setOnDismissListener((dialog: DialogInterface) => finish()) // builder method was added in API 17
dialog.show() dialog.show()
......
...@@ -212,10 +212,8 @@ class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClickListe ...@@ -212,10 +212,8 @@ class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClickListe
override def onActivityResult(requestCode: Int, resultCode: Int, data: Intent) { override def onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
val scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data) val scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data)
if (scanResult != null) Parser.parse(scanResult.getContents) match { if (scanResult != null)
case Some(profile) => ShadowsocksApplication.profileManager.createProfile(profile) Parser.findAll(scanResult.getContents).foreach(ShadowsocksApplication.profileManager.createProfile)
case _ => // ignore
}
} }
def onMenuItemClick(item: MenuItem) = item.getItemId match { def onMenuItemClick(item: MenuItem) = item.getItemId match {
......
...@@ -39,44 +39,35 @@ ...@@ -39,44 +39,35 @@
package com.github.shadowsocks.utils package com.github.shadowsocks.utils
import com.github.shadowsocks.database.Profile
import java.util.Locale import java.util.Locale
import android.net.Uri
import android.util.{Log, Base64} import android.util.{Base64, Log}
import com.github.shadowsocks.database.Profile
object Parser { object Parser {
val TAG = "ShadowParser" val TAG = "ShadowParser"
private val pattern = "(?i)ss://([A-Za-z0-9+/=]+)".r
def generate (profile: Profile): String = "ss://" + Base64.encodeToString("%s:%s@%s:%d".formatLocal(Locale.ENGLISH, def generate (profile: Profile): String = "ss://" + Base64.encodeToString("%s:%s@%s:%d".formatLocal(Locale.ENGLISH,
profile.method, profile.password, profile.host, profile.remotePort).getBytes, Base64.NO_PADDING) profile.method, profile.password, profile.host, profile.remotePort).getBytes, Base64.NO_PADDING)
def parse (data: String): Option[Profile] = { def findAll(data: String) = pattern.findAllMatchIn(data).map(m => try {
try { val content = new String(Base64.decode(m.group(1), Base64.NO_PADDING), "UTF-8")
Log.d(TAG, data) val methodIdx = content.indexOf(':')
val uri = Uri.parse(data.trim) val passwordIdx = content.lastIndexOf('@')
if (uri.getScheme == Scheme.SS) { val hostIdx = content.lastIndexOf(':')
val encoded = data.replace(Scheme.SS + "://", "") val host = content.substring(passwordIdx + 1, hostIdx)
val content = new String(Base64.decode(encoded, Base64.NO_PADDING), "UTF-8")
val methodIdx = content.indexOf(':')
val passwordIdx = content.lastIndexOf('@')
val hostIdx = content.lastIndexOf(':')
val method = content.substring(0, methodIdx)
val password = content.substring(methodIdx + 1, passwordIdx)
val host = content.substring(passwordIdx + 1, hostIdx)
val port = content.substring(hostIdx + 1)
val profile = new Profile val profile = new Profile
profile.name = host profile.name = host
profile.host = host profile.host = host
profile.remotePort = port.toInt profile.remotePort = content.substring(hostIdx + 1).toInt
profile.localPort = 1080 profile.method = content.substring(0, methodIdx).toLowerCase
profile.method = method.toLowerCase profile.password = content.substring(methodIdx + 1, passwordIdx)
profile.password = password profile
return Some(profile) } catch {
} case ex: Exception =>
} catch { Log.e(TAG, "parser error: " + m.source, ex)// Ignore
case ex : Exception => Log.e(TAG, "parser error", ex)// Ignore null
} }).filter(_ != null)
None
}
} }
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