diff --git a/build.gradle b/build.gradle index e551d37..b466cc6 100644 --- a/build.gradle +++ b/build.gradle @@ -16,5 +16,9 @@ dependencies { compile group: 'javax.ws.rs', name: 'javax.ws.rs-api', version: '2.0-m02' compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.9.8' compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.8' + compile group: 'org.zeroturnaround', name: 'zt-exec', version: '1.10' + compile group: 'org.zeroturnaround', name: 'zt-process-killer', version: '1.9' + compile group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.26' testCompile group: 'junit', name: 'junit', version: '4.12' + testCompile group: 'com.mashape.unirest', name: 'unirest-java', version: '1.4.9' } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 115e6ac..d9cef9d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Thu Apr 11 14:32:28 PDT 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10-all.zip diff --git a/src/main/java/MitmproxyJava.java b/src/main/java/MitmproxyJava.java index 913d580..291ecb0 100644 --- a/src/main/java/MitmproxyJava.java +++ b/src/main/java/MitmproxyJava.java @@ -1,25 +1,85 @@ -import org.java_websocket.client.WebSocketClient; -import org.java_websocket.handshake.ServerHandshake; +import org.zeroturnaround.exec.ProcessExecutor; +import org.zeroturnaround.exec.ProcessResult; +import org.zeroturnaround.exec.stream.slf4j.Slf4jStream; import java.io.IOException; import java.net.InetSocketAddress; -import java.net.URI; +import java.net.Socket; import java.net.URISyntaxException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeoutException; import java.util.function.Function; public class MitmproxyJava { + private String mitmproxyPath; private MitmproxyServer server; + private Future mitmproxyProcess; public static final int WEBSOCKET_PORT = 8765; - public MitmproxyJava(Function messageInterceptor) throws URISyntaxException { + public MitmproxyJava(String mitmproxyPath, Function messageInterceptor) throws URISyntaxException { + this.mitmproxyPath = mitmproxyPath; server = new MitmproxyServer(new InetSocketAddress("localhost", WEBSOCKET_PORT), messageInterceptor); - server.run(); + server.start(); System.out.println("you started me"); } + public void start() throws IOException, InterruptedException, ExecutionException, TimeoutException { + System.out.println("starting mitmproxy on port 8080"); + mitmproxyProcess = new ProcessExecutor() + .command(mitmproxyPath, "--anticache", "-s", "scripts/proxy.py") + .redirectOutput(Slf4jStream.ofCaller().asInfo()) + .destroyOnExit() + .start() + .getFuture(); + + waitForPortToBeInUse(8080); + System.out.println("done waiting"); + + } + public void stop() throws IOException, InterruptedException { + mitmproxyProcess.cancel(true); server.stop(); } + + private void waitForPortToBeInUse(int port) throws TimeoutException { + boolean inUse = false; + Socket s = null; + int tries = 0; + int maxTries = 60 * 1000 / 100; + + while (!inUse) { + try + { + s = new Socket("localhost", port); + } + catch (IOException e) + { + inUse = false; + } + finally + { + if(s != null) { + inUse = true; + try { + s.close(); + } catch (Exception e) { + } + break; + } + } + tries++; + if (tries == maxTries) { + throw new TimeoutException("Timed out waiting for mitmproxy to start"); + } + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } } diff --git a/src/main/java/MitmproxyServer.java b/src/main/java/MitmproxyServer.java index 41e964c..0405d8f 100644 --- a/src/main/java/MitmproxyServer.java +++ b/src/main/java/MitmproxyServer.java @@ -72,6 +72,6 @@ public void onError(WebSocket conn, Exception ex) { @Override public void onStart() { - System.out.println("server started successfully"); + System.out.println("websocket server started successfully"); } } diff --git a/src/test/java/MitmproxyJavaTest.java b/src/test/java/MitmproxyJavaTest.java index ddb55aa..169b6f8 100644 --- a/src/test/java/MitmproxyJavaTest.java +++ b/src/test/java/MitmproxyJavaTest.java @@ -1,17 +1,24 @@ -import org.junit.jupiter.api.Test; +import com.mashape.unirest.http.HttpResponse; +import com.mashape.unirest.http.Unirest; +import com.mashape.unirest.http.exceptions.UnirestException; +import com.mashape.unirest.request.GetRequest; +import org.apache.http.HttpHost; +import org.junit.Test; import java.io.IOException; -import java.net.URI; import java.net.URISyntaxException; -import java.util.function.Function; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; -import static org.junit.jupiter.api.Assertions.*; +import static junit.framework.TestCase.assertTrue; public class MitmproxyJavaTest { @Test public void ConstructorTest() throws URISyntaxException, IOException, InterruptedException { - MitmproxyJava proxy = new MitmproxyJava((InterceptedMessage m) -> { + MitmproxyJava proxy = new MitmproxyJava("/usr/local/bin/mitmdump", (InterceptedMessage m) -> { System.out.println(m.requestURL.toString()); return m; }); @@ -20,6 +27,28 @@ public void ConstructorTest() throws URISyntaxException, IOException, Interrupte } //todo test not modifying (by not returning) - + //todo test modifying a response + + @Test + public void StartTest() throws InterruptedException, ExecutionException, TimeoutException, IOException, URISyntaxException, UnirestException { + List messages = new ArrayList(); + + MitmproxyJava proxy = new MitmproxyJava("/usr/local/bin/mitmdump", (InterceptedMessage m) -> { + messages.add(m); + return m; + }); + proxy.start(); + + Unirest.setProxy(new HttpHost("localhost", 8080)); + Unirest.get("http://appium.io").asString(); + + proxy.stop(); + + assertTrue(messages.size() > 0); + + InterceptedMessage appiumIORequest = messages.stream().filter((m) -> m.requestURL.getHost().equals("appium.io")).findFirst().get(); + + assertTrue(appiumIORequest.responseCode == 200); + } } \ No newline at end of file