Repository: ilanyu/ReverseProxy-Android Branch: master Commit: 859939ae0651 Files: 29 Total size: 31.3 KB Directory structure: gitextract_nbkhwz0l/ ├── .gitignore ├── Mobile/ │ ├── Mobile.aar │ └── build.gradle ├── README.md ├── app/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── com/ │ │ └── lanyus/ │ │ └── reverseproxy/ │ │ └── ExampleInstrumentedTest.java │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── golang/ │ │ │ ├── cmd.go │ │ │ ├── handle.go │ │ │ └── main.go │ │ ├── java/ │ │ │ └── com/ │ │ │ └── lanyus/ │ │ │ └── reverseproxy/ │ │ │ └── MainActivity.java │ │ └── res/ │ │ ├── drawable/ │ │ │ └── ic_launcher_background.xml │ │ ├── drawable-v24/ │ │ │ └── ic_launcher_foreground.xml │ │ ├── layout/ │ │ │ └── activity_main.xml │ │ ├── mipmap-anydpi-v26/ │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ └── values/ │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test/ │ └── java/ │ └── com/ │ └── lanyus/ │ └── reverseproxy/ │ └── ExampleUnitTest.java ├── build.gradle ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat └── settings.gradle ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ ### Example user template template ### Example user template # IntelliJ project files .idea *.iml out gen### Android template # Built application files *.apk *.ap_ # Files for the ART/Dalvik VM *.dex # Java class files *.class # Generated files bin/ gen/ out/ # Gradle files .gradle/ build/ # Local configuration file (sdk path, etc) local.properties # Proguard folder generated by Eclipse proguard/ # Log Files *.log # Android Studio Navigation editor temp files .navigation/ # Android Studio captures folder captures/ # IntelliJ .idea/workspace.xml .idea/tasks.xml .idea/gradle.xml .idea/dictionaries .idea/libraries # Keystore files # Uncomment the following line if you do not want to check your keystore files in. #*.jks # External native build folder generated in Android Studio 2.2 and later .externalNativeBuild # Google Services (e.g. APIs or Firebase) google-services.json # Freeline freeline.py freeline/ freeline_project_description.json ### JetBrains template # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 # User-specific stuff: .idea/**/workspace.xml .idea/**/tasks.xml # Sensitive or high-churn files: .idea/**/dataSources/ .idea/**/dataSources.ids .idea/**/dataSources.xml .idea/**/dataSources.local.xml .idea/**/sqlDataSources.xml .idea/**/dynamic.xml .idea/**/uiDesigner.xml # Gradle: .idea/**/gradle.xml .idea/**/libraries # CMake cmake-build-debug/ cmake-build-release/ # Mongo Explorer plugin: .idea/**/mongoSettings.xml ## File-based project format: *.iws ## Plugin-specific files: # mpeltonen/sbt-idea plugin .idea_modules/ # JIRA plugin atlassian-ide-plugin.xml # Cursive Clojure plugin .idea/replstate.xml # Crashlytics plugin (for Android Studio and IntelliJ) com_crashlytics_export_strings.xml crashlytics.properties crashlytics-build.properties fabric.properties ================================================ FILE: Mobile/build.gradle ================================================ configurations.maybeCreate("default") artifacts.add("default", file('Mobile.aar')) ================================================ FILE: README.md ================================================ # ReverseProxy-Android ReverseProxy-Android ================================================ FILE: app/.gitignore ================================================ /build ================================================ FILE: app/build.gradle ================================================ apply plugin: 'com.android.application' android { compileSdkVersion 26 defaultConfig { applicationId "com.lanyus.reverseproxy" minSdkVersion 16 targetSdkVersion 26 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'com.android.support:appcompat-v7:26.1.0' implementation 'com.android.support.constraint:constraint-layout:1.0.2' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.1' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' implementation project(':Mobile') } ================================================ FILE: app/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # You can control the set of applied configuration files using the # proguardFiles setting in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} # Uncomment this to preserve the line number information for # debugging stack traces. #-keepattributes SourceFile,LineNumberTable # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile ================================================ FILE: app/src/androidTest/java/com/lanyus/reverseproxy/ExampleInstrumentedTest.java ================================================ package com.lanyus.reverseproxy; import android.content.Context; import android.support.test.InstrumentationRegistry; import android.support.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; import static org.junit.Assert.*; /** * Instrumented test, which will execute on an Android device. * * @see Testing documentation */ @RunWith(AndroidJUnit4.class) public class ExampleInstrumentedTest { @Test public void useAppContext() throws Exception { // Context of the app under test. Context appContext = InstrumentationRegistry.getTargetContext(); assertEquals("com.lanyus.reverseproxy", appContext.getPackageName()); } } ================================================ FILE: app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: app/src/main/golang/cmd.go ================================================ package Mobile import "flag" type Cmd struct { bind string remote string ip string } func parseCmd() Cmd { var cmd Cmd flag.StringVar(&cmd.bind, "l", "0.0.0.0:8888", "listen on ip:port") flag.StringVar(&cmd.remote, "r", "http://idea.lanyus.com:80", "reverse proxy addr") flag.StringVar(&cmd.ip, "ip", "", "reverse proxy addr server ip") flag.Parse() return cmd } ================================================ FILE: app/src/main/golang/handle.go ================================================ package Mobile import ( "net/http" "net/url" "net/http/httputil" "log" "net" "time" "context" "github.com/bogdanovich/dns_resolver" "strings" ) type handle struct { reverseProxy string } func (this *handle) ServeHTTP(w http.ResponseWriter, r *http.Request) { log.Println(r.RemoteAddr + " " + r.Method + " " + r.URL.String() + " " + r.Proto + " " + r.UserAgent()) remote, err := url.Parse(this.reverseProxy) if err != nil { log.Fatalln(err) } dialer := &net.Dialer{ Timeout: 30 * time.Second, KeepAlive: 30 * time.Second, DualStack: true, } http.DefaultTransport.(*http.Transport).DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) { remote := strings.Split(addr, ":") if cmd.ip == "" { resolver := dns_resolver.New([]string{"114.114.114.114", "114.114.115.115", "119.29.29.29", "223.5.5.5", "8.8.8.8", "208.67.222.222", "208.67.220.220"}) resolver.RetryTimes = 5 ip, err := resolver.LookupHost(remote[0]) if err != nil { log.Println(err) } cmd.ip = ip[0].String() } addr = cmd.ip + ":" + remote[1] return dialer.DialContext(ctx, network, addr) } proxy := httputil.NewSingleHostReverseProxy(remote) r.Host = remote.Host proxy.ServeHTTP(w, r) } ================================================ FILE: app/src/main/golang/main.go ================================================ package Mobile import ( "net/http" "log" ) var cmd Cmd var srv http.Server func StartServer(bind string, remote string) { log.Printf("Listening on %s, forwarding to %s", bind, remote) h := &handle{reverseProxy: remote} srv.Addr = bind srv.Handler = h go func() { if err := srv.ListenAndServe(); err != nil { log.Fatalln("ListenAndServe: ", err) } }() } func StopServer() { if err := srv.Shutdown(nil) ; err != nil { log.Println(err) } } func main() { cmd = parseCmd() StartServer(cmd.bind, cmd.remote) } ================================================ FILE: app/src/main/java/com/lanyus/reverseproxy/MainActivity.java ================================================ package com.lanyus.reverseproxy; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import java.net.Inet4Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.util.Enumeration; public class MainActivity extends AppCompatActivity { private Button startButton; private Button stopButton; private EditText bindText; private EditText remoteText; private TextView ipView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); startButton = findViewById(R.id.start); stopButton = findViewById(R.id.stop); bindText = findViewById(R.id.bind); remoteText = findViewById(R.id.remote); ipView = findViewById(R.id.ip); String ip = getIPAddress(this); if (ip != null) { ipView.setText(ip); } } public void startServer(View view) { startButton.setEnabled(false); stopButton.setEnabled(true); Mobile.Mobile.startServer(bindText.getText().toString(), remoteText.getText().toString()); } public void stopServer(View view) { startButton.setEnabled(true); stopButton.setEnabled(false); Mobile.Mobile.stopServer(); } public static String getIPAddress(Context context) { NetworkInfo info = ((ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo(); if (info != null && info.isConnected()) { if (info.getType() == ConnectivityManager.TYPE_MOBILE) { try { for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) { NetworkInterface intf = en.nextElement(); for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) { InetAddress inetAddress = enumIpAddr.nextElement(); if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) { return inetAddress.getHostAddress(); } } } } catch (SocketException e) { e.printStackTrace(); } } else if (info.getType() == ConnectivityManager.TYPE_WIFI) { WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE); WifiInfo wifiInfo = null; if (wifiManager != null) { wifiInfo = wifiManager.getConnectionInfo(); } if (wifiInfo != null) { return intIP2StringIP(wifiInfo.getIpAddress()); } } } else { return null; } return null; } /** * 将得到的int类型的IP转换为String类型 * * @param ip * @return */ public static String intIP2StringIP(int ip) { return (ip & 0xFF) + "." + ((ip >> 8) & 0xFF) + "." + ((ip >> 16) & 0xFF) + "." + (ip >> 24 & 0xFF); } } ================================================ FILE: app/src/main/res/drawable/ic_launcher_background.xml ================================================ ================================================ FILE: app/src/main/res/drawable-v24/ic_launcher_foreground.xml ================================================ ================================================ FILE: app/src/main/res/layout/activity_main.xml ================================================