Skip to content

Instantly share code, notes, and snippets.

@ambalashov
Forked from thomasdarimont/ProxyProblemExample.java
Last active September 13, 2015 08:31
Show Gist options
  • Select an option

  • Save ambalashov/83c3700deff3d6dd2cd1 to your computer and use it in GitHub Desktop.

Select an option

Save ambalashov/83c3700deff3d6dd2cd1 to your computer and use it in GitHub Desktop.

Revisions

  1. Thomas Darimont revised this gist Oct 7, 2014. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions ProxyProblemExample.java
    Original file line number Diff line number Diff line change
    @@ -14,6 +14,7 @@
    * @author Thomas Darimont
    */
    public class ProxyProblemExample extends Application {

    @Override
    public void start(Stage stage) throws Exception {

  2. Thomas Darimont revised this gist Oct 7, 2014. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions URLStreamFactoryCustomizer.java
    Original file line number Diff line number Diff line change
    @@ -112,6 +112,8 @@ protected URLConnection openConnection(URL url) throws IOException {
    private boolean isWebKitURLLoaderThread(Thread thread) {

    StackTraceElement[] st = thread.getStackTrace();

    //TODO Add more robust stack-trace inspection.
    return st.length > 4 && st[4].getClassName().startsWith("com.sun.webkit.network");
    }
    }
  3. Thomas Darimont revised this gist Oct 7, 2014. 1 changed file with 5 additions and 5 deletions.
    10 changes: 5 additions & 5 deletions URLStreamFactoryCustomizer.java
    Original file line number Diff line number Diff line change
    @@ -92,18 +92,18 @@ public DelegatingScopedProxyAwareUrlStreamHandler(URLStreamHandler delegatee, Pr
    }

    @Override
    protected URLConnection openConnection(URL u) throws IOException {
    protected URLConnection openConnection(URL url) throws IOException {

    try {
    if (isWebKitURLLoaderThread(Thread.currentThread())) {

    //WebKit request loading for the given url, use provided proxy.
    return (URLConnection) openConnectionWithProxyMethod.invoke(delegatee, u, proxy);
    //WebKit requested loading the given url, use provided proxy.
    return (URLConnection) openConnectionWithProxyMethod.invoke(delegatee, url, proxy);
    }

    //Invoke the standard url handler.
    return (URLConnection) openConnectionMethod.invoke(delegatee, u);
    return (URLConnection) openConnectionMethod.invoke(delegatee, url);

    } catch (IllegalAccessException | InvocationTargetException e) {
    throw new RuntimeException(e);
    }
  4. Thomas Darimont revised this gist Oct 7, 2014. 1 changed file with 5 additions and 0 deletions.
    5 changes: 5 additions & 0 deletions URLStreamFactoryCustomizer.java
    Original file line number Diff line number Diff line change
    @@ -96,9 +96,14 @@ protected URLConnection openConnection(URL u) throws IOException {

    try {
    if (isWebKitURLLoaderThread(Thread.currentThread())) {

    //WebKit request loading for the given url, use provided proxy.
    return (URLConnection) openConnectionWithProxyMethod.invoke(delegatee, u, proxy);
    }

    //Invoke the standard url handler.
    return (URLConnection) openConnectionMethod.invoke(delegatee, u);

    } catch (IllegalAccessException | InvocationTargetException e) {
    throw new RuntimeException(e);
    }
  5. Thomas Darimont revised this gist Oct 7, 2014. 1 changed file with 3 additions and 4 deletions.
    7 changes: 3 additions & 4 deletions URLStreamFactoryCustomizer.java
    Original file line number Diff line number Diff line change
    @@ -95,11 +95,10 @@ public DelegatingScopedProxyAwareUrlStreamHandler(URLStreamHandler delegatee, Pr
    protected URLConnection openConnection(URL u) throws IOException {

    try {
    if (!isWebKitURLLoaderThread(Thread.currentThread())) {
    return (URLConnection) openConnectionMethod.invoke(delegatee, u);
    if (isWebKitURLLoaderThread(Thread.currentThread())) {
    return (URLConnection) openConnectionWithProxyMethod.invoke(delegatee, u, proxy);
    }

    return (URLConnection) openConnectionWithProxyMethod.invoke(delegatee, u, proxy);
    return (URLConnection) openConnectionMethod.invoke(delegatee, u);
    } catch (IllegalAccessException | InvocationTargetException e) {
    throw new RuntimeException(e);
    }
  6. Thomas Darimont revised this gist Oct 7, 2014. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions URLStreamFactoryCustomizer.java
    Original file line number Diff line number Diff line change
    @@ -95,7 +95,7 @@ public DelegatingScopedProxyAwareUrlStreamHandler(URLStreamHandler delegatee, Pr
    protected URLConnection openConnection(URL u) throws IOException {

    try {
    if (isWebKitURLLoaderThread(Thread.currentThread())) {
    if (!isWebKitURLLoaderThread(Thread.currentThread())) {
    return (URLConnection) openConnectionMethod.invoke(delegatee, u);
    }

    @@ -108,7 +108,7 @@ protected URLConnection openConnection(URL u) throws IOException {
    private boolean isWebKitURLLoaderThread(Thread thread) {

    StackTraceElement[] st = thread.getStackTrace();
    return st.length > 4 && st[4].getClassName().equals("com.sun.webkit.network");
    return st.length > 4 && st[4].getClassName().startsWith("com.sun.webkit.network");
    }
    }
    }
  7. Thomas Darimont revised this gist Oct 7, 2014. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions URLStreamFactoryCustomizer.java
    Original file line number Diff line number Diff line change
    @@ -107,8 +107,8 @@ protected URLConnection openConnection(URL u) throws IOException {

    private boolean isWebKitURLLoaderThread(Thread thread) {

    StackTraceElement[] st = Thread.currentThread().getStackTrace();
    StackTraceElement[] st = thread.getStackTrace();
    return st.length > 4 && st[4].getClassName().equals("com.sun.webkit.network");
    }
    }
    }
    }
  8. Thomas Darimont revised this gist Oct 7, 2014. 3 changed files with 12 additions and 4 deletions.
    2 changes: 1 addition & 1 deletion ProxyProblemExample.java
    Original file line number Diff line number Diff line change
    @@ -31,7 +31,7 @@ public void start(Stage stage) throws Exception {

    public static void main(String[] args) throws Exception {

    Proxy proxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("127.0.0.1", 8080));
    Proxy proxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(System.getProperty("hack.webkit.http.proxy"), Integer.getInteger("hack.webkit.http.proxyPort")));

    URLStreamFactoryCustomizer.useDedicatedProxyForWebkit(proxy, "http, https");

    9 changes: 9 additions & 0 deletions Readme.MD
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,9 @@
    Run with:
    ```
    -Dhttp.proxy=none.local
    -Dhttp.proxyPort=1234
    -Dhack.webkit.http.proxy=localhost
    -Dhack.webkit.http.proxyPort=8080
    ```

    I used `-Dhttp.proxy=none.local` and `-Dhttp.proxyPort=1234` to "simulate" a non working default proxy configuration for all "other" URL load requests.
    5 changes: 2 additions & 3 deletions URLStreamFactoryCustomizer.java
    Original file line number Diff line number Diff line change
    @@ -34,8 +34,7 @@ private static void tryReplaceOriginalUrlStreamHandlersWithScopeProxyAwareVarian
    handlers.put(protocol, new DelegatingScopedProxyAwareUrlStreamHandler(originalHandler, proxy));
    };

    asList(protocols).stream().forEach(wrapStreamHandlerWithScopedProxyHandler);

    asList(protocols.split(",")).stream().map(String::trim).filter(s -> !s.isEmpty()).forEach(wrapStreamHandlerWithScopedProxyHandler);
    //System.out.println(handlers);

    } catch (Exception ex) {
    @@ -112,4 +111,4 @@ private boolean isWebKitURLLoaderThread(Thread thread) {
    return st.length > 4 && st[4].getClassName().equals("com.sun.webkit.network");
    }
    }
    }
    }
  9. Thomas Darimont created this gist Oct 7, 2014.
    40 changes: 40 additions & 0 deletions ProxyProblemExample.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,40 @@
    package de.tutorials.training.fx.proxy;

    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.StackPane;
    import javafx.scene.web.WebEngine;
    import javafx.scene.web.WebView;
    import javafx.stage.Stage;

    import java.net.InetSocketAddress;
    import java.net.Proxy;

    /**
    * @author Thomas Darimont
    */
    public class ProxyProblemExample extends Application {
    @Override
    public void start(Stage stage) throws Exception {

    StackPane root = new StackPane();

    WebView view = new WebView();
    WebEngine engine = view.getEngine();
    engine.load("https://www.google.com");
    root.getChildren().add(view);

    Scene scene = new Scene(root, 960, 640);
    stage.setScene(scene);
    stage.show();
    }

    public static void main(String[] args) throws Exception {

    Proxy proxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("127.0.0.1", 8080));

    URLStreamFactoryCustomizer.useDedicatedProxyForWebkit(proxy, "http, https");

    Application.launch(ProxyProblemExample.class);
    }
    }
    115 changes: 115 additions & 0 deletions URLStreamFactoryCustomizer.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,115 @@
    package de.tutorials.training.fx.proxy;

    import java.io.IOException;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.net.*;
    import java.util.Hashtable;
    import java.util.function.Consumer;

    import static java.util.Arrays.asList;

    /**
    * @author Thomas Darimont
    */
    public class URLStreamFactoryCustomizer {

    public static void useDedicatedProxyForWebkit(Proxy proxy, String protocols) {

    forceInitializationOfOriginalUrlStreamHandlers();
    tryReplaceOriginalUrlStreamHandlersWithScopeProxyAwareVariants(proxy, protocols);
    }

    private static void tryReplaceOriginalUrlStreamHandlersWithScopeProxyAwareVariants(Proxy proxy, String protocols) {

    try {

    Hashtable handlers = tryExtractInternalHandlerTableFromUrl();
    //System.out.println(handlers);

    Consumer<String> wrapStreamHandlerWithScopedProxyHandler = protocol ->
    {
    URLStreamHandler originalHandler = (URLStreamHandler) handlers.get(protocol);
    handlers.put(protocol, new DelegatingScopedProxyAwareUrlStreamHandler(originalHandler, proxy));
    };

    asList(protocols).stream().forEach(wrapStreamHandlerWithScopedProxyHandler);

    //System.out.println(handlers);

    } catch (Exception ex) {
    throw new RuntimeException(ex);
    }
    }

    private static Hashtable tryExtractInternalHandlerTableFromUrl() {

    try {
    Field handlersField = URL.class.getDeclaredField("handlers");
    handlersField.setAccessible(true);
    return (Hashtable) handlersField.get(null);
    } catch (Exception e) {
    throw new RuntimeException(e);
    }
    }

    private static void forceInitializationOfOriginalUrlStreamHandlers() {

    try {
    new URL("http://.");
    new URL("https://.");
    } catch (MalformedURLException e) {
    throw new RuntimeException(e);
    }
    }

    static class DelegatingScopedProxyAwareUrlStreamHandler extends URLStreamHandler {

    private static final Method openConnectionMethod;
    private static final Method openConnectionWithProxyMethod;

    static {

    try {
    openConnectionMethod = URLStreamHandler.class.getDeclaredMethod("openConnection", URL.class);
    openConnectionWithProxyMethod = URLStreamHandler.class.getDeclaredMethod("openConnection", URL.class, Proxy.class);

    openConnectionMethod.setAccessible(true);
    openConnectionWithProxyMethod.setAccessible(true);

    } catch (Exception e) {
    throw new RuntimeException(e);
    }
    }

    private final URLStreamHandler delegatee;
    private final Proxy proxy;

    public DelegatingScopedProxyAwareUrlStreamHandler(URLStreamHandler delegatee, Proxy proxy) {

    this.delegatee = delegatee;
    this.proxy = proxy;
    }

    @Override
    protected URLConnection openConnection(URL u) throws IOException {

    try {
    if (isWebKitURLLoaderThread(Thread.currentThread())) {
    return (URLConnection) openConnectionMethod.invoke(delegatee, u);
    }

    return (URLConnection) openConnectionWithProxyMethod.invoke(delegatee, u, proxy);
    } catch (IllegalAccessException | InvocationTargetException e) {
    throw new RuntimeException(e);
    }
    }

    private boolean isWebKitURLLoaderThread(Thread thread) {

    StackTraceElement[] st = Thread.currentThread().getStackTrace();
    return st.length > 4 && st[4].getClassName().equals("com.sun.webkit.network");
    }
    }
    }