| /******************************************************************************* |
| * Copyright (c) 2007 IBM Corporation and Others |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Takashi ITOH - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.actf.model.flash.proxy; |
| |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| import java.io.OutputStream; |
| import java.io.OutputStreamWriter; |
| import java.io.Reader; |
| import java.net.URL; |
| import java.text.MessageFormat; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| import org.eclipse.actf.model.flash.FlashModelPlugin; |
| import org.eclipse.actf.model.flash.bridge.IWaXcoding; |
| import org.eclipse.actf.model.flash.proxy.internal.INTERNET_PER_CONN_OPTION; |
| import org.eclipse.actf.model.flash.proxy.internal.INTERNET_PER_CONN_OPTION_LIST; |
| import org.eclipse.actf.model.flash.proxy.internal.WSTR; |
| import org.eclipse.actf.model.flash.proxy.internal.WinInet; |
| import org.eclipse.actf.model.flash.proxy.logs.ProxyLogHandler; |
| import org.eclipse.core.runtime.FileLocator; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.swt.internal.win32.OS; |
| |
| |
| |
| |
| public class ProxyManager { |
| |
| public static boolean initLogger = false; |
| public static boolean forceProxy = false; |
| private static String noProxy = Messages.getString("NO_PROXY"); //$NON-NLS-1$ |
| |
| static { |
| String[] temp = Platform.getApplicationArgs(); |
| for( int i=0; i<temp.length; i++ ) { |
| if( "-initLogger".equals(temp[i]) ) { //$NON-NLS-1$ |
| initLogger = true; |
| } |
| else if( "-forceProxy".equals(temp[i]) ) { //$NON-NLS-1$ |
| forceProxy = true; |
| } |
| else if( "-noProxy".equals(temp[i]) ) { //$NON-NLS-1$ |
| if( i < temp.length-1 ) { |
| String nextArg = temp[i+1]; |
| if( nextArg.startsWith("|") && nextArg.endsWith("|") ) { //$NON-NLS-1$ //$NON-NLS-2$ |
| noProxy = nextArg; |
| } |
| } |
| } |
| } |
| if( Platform.inDebugMode() ) { |
| System.out.println("initLogger = "+initLogger); //$NON-NLS-1$ |
| System.out.println("forceProxy = "+forceProxy); //$NON-NLS-1$ |
| System.out.println("noProxy = "+noProxy); //$NON-NLS-1$ |
| } |
| } |
| |
| private INTERNET_PER_CONN_OPTION_LIST savedList; |
| private int savedAddress; |
| private int hSession; |
| private boolean needRestore = false; |
| private int currentPort = 0; |
| private static String PROTCOL_HTTP = "http"; //$NON-NLS-1$ |
| private static String PROTCOL_HTTPS = "https"; //$NON-NLS-1$ |
| private static String PROTCOL_FTP = "ftp"; //$NON-NLS-1$ |
| private static String PROTCOL_GOPHER = "gopher"; //$NON-NLS-1$ |
| // private static String[] PROTCOL_EXTRA = new String[]{"https","ftp","gopher"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| |
| public ProxyManager() { |
| // Save default settings |
| savedList = new INTERNET_PER_CONN_OPTION_LIST(4); |
| savedList.perConnOptions[0].dwOption=INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_FLAGS; |
| savedList.perConnOptions[1].dwOption=INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_PROXY_SERVER; |
| savedList.perConnOptions[2].dwOption=INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_PROXY_BYPASS; |
| savedList.perConnOptions[3].dwOption=INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_AUTOCONFIG_URL; |
| savedAddress = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT, INTERNET_PER_CONN_OPTION_LIST.sizeof); |
| savedList.getData(savedAddress); |
| int[] pInt = new int[]{INTERNET_PER_CONN_OPTION_LIST.sizeof}; |
| WinInet.InternetQueryOptionW(0,WinInet.INTERNET_OPTION_PER_CONNECTION_OPTION,savedAddress,pInt); |
| savedList.setData(savedAddress); |
| WSTR wsAgent = new WSTR("Agent"); //$NON-NLS-1$ |
| hSession = WinInet.InternetOpenW(wsAgent.getAddress(),WinInet.INTERNET_OPEN_TYPE_DIRECT,0,0,0); |
| wsAgent.dispose(); |
| } |
| |
| public void startProxy(int port, int swfVersion, int timeout, |
| boolean swfBootloader, boolean swfTranscoder) { |
| IWaXcoding waXcoding = getIWaXcoding(); |
| waXcoding.setPort(port); |
| waXcoding.setSWFTranscodingMinimumVersion(swfVersion); |
| waXcoding.setTimeout(timeout); |
| waXcoding.setExternalProxyFlag(false); |
| waXcoding.setSWFBootloaderFlag(swfBootloader); |
| waXcoding.setSWFTranscodingFlag(swfTranscoder); |
| String extProxy = getDefaultProxy(PROTCOL_HTTP); |
| if( null != extProxy ) { |
| int pos = extProxy.indexOf(':'); |
| if( -1 != pos ) { |
| try { |
| String extHost = extProxy.substring(0,pos); |
| String portStr = extProxy.substring(pos+1); |
| int extPort = Integer.parseInt(portStr); |
| waXcoding.setExternalProxyFlag(true); |
| waXcoding.setExternalProxy(extHost,extPort); |
| if( Platform.inDebugMode() ) { |
| System.out.println("Using external proxy "+extHost+":"+extPort); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } catch( Exception e ) { |
| } |
| } |
| } |
| ProxyLogHandler.configure(); // Configure our log handler |
| waXcoding.start(initLogger); // Start WaXcoding without log handler |
| if( !initLogger ) { |
| ProxyLogHandler.resetLogLevel(); |
| } |
| currentPort = waXcoding.getPort(); |
| } |
| |
| public void stopProxy() { |
| if( 0 != currentPort ) { |
| getIWaXcoding().stop(); |
| currentPort = 0; |
| } |
| } |
| |
| public void setInternetOptions(boolean isGlobal) { |
| if( 0 != savedAddress ) { |
| if( 0 == currentPort ) { |
| invokeSetOption(hSession,savedAddress); |
| invokeSetOption(0,savedAddress); |
| needRestore = false; |
| } |
| else { |
| // INTERNET_PER_CONN_OPTION_LIST list = new INTERNET_PER_CONN_OPTION_LIST(3); |
| // list.perConnOptions[0].dwOption=INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_FLAGS; |
| // list.perConnOptions[0].dwValue=INTERNET_PER_CONN_OPTION.PROXY_TYPE_PROXY | INTERNET_PER_CONN_OPTION.PROXY_TYPE_DIRECT; |
| // list.perConnOptions[1].dwOption=INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_PROXY_SERVER; |
| // list.perConnOptions[1].strValue.setString(getProxyString()); |
| // list.perConnOptions[2].dwOption=INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_PROXY_BYPASS; |
| // list.perConnOptions[2].strValue.setString(null); |
| INTERNET_PER_CONN_OPTION_LIST list = new INTERNET_PER_CONN_OPTION_LIST(2); |
| list.perConnOptions[0].dwOption=INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_FLAGS; |
| list.perConnOptions[0].dwValue=INTERNET_PER_CONN_OPTION.PROXY_TYPE_AUTO_PROXY_URL | INTERNET_PER_CONN_OPTION.PROXY_TYPE_DIRECT; |
| list.perConnOptions[1].dwOption=INTERNET_PER_CONN_OPTION.INTERNET_PER_CONN_AUTOCONFIG_URL; |
| list.perConnOptions[1].strValue.setString(getAutoConfigURL(isGlobal||forceProxy)); |
| int address = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT, INTERNET_PER_CONN_OPTION_LIST.sizeof); |
| list.getData(address); |
| invokeSetOption(hSession, address); |
| invokeSetOption(0, isGlobal ? address : savedAddress); |
| needRestore = isGlobal; |
| OS.GlobalFree(address); |
| list.dispose(); |
| } |
| } |
| } |
| |
| public void dispose() { |
| ProxyLogHandler.removeHandler(); |
| stopProxy(); |
| if( 0 != hSession ) { |
| WinInet.InternetCloseHandle(hSession); |
| } |
| if( 0 != savedAddress ) { |
| if( needRestore ) { |
| WinInet.InternetSetOptionW(0,WinInet.INTERNET_OPTION_PER_CONNECTION_OPTION,savedAddress,INTERNET_PER_CONN_OPTION_LIST.sizeof); |
| } |
| OS.GlobalFree(savedAddress); |
| savedList.dispose(); |
| } |
| } |
| |
| private void invokeSetOption(int handle, int address) { |
| WinInet.InternetSetOptionW(handle,WinInet.INTERNET_OPTION_PER_CONNECTION_OPTION,address,INTERNET_PER_CONN_OPTION_LIST.sizeof); |
| WinInet.InternetSetOptionW(handle,WinInet.INTERNET_OPTION_SETTINGS_CHANGED,0,0); |
| WinInet.InternetSetOptionW(handle,WinInet.INTERNET_OPTION_REFRESH,0,0); |
| } |
| |
| // private String getProxyString() { |
| // String result = PROTCOL_HTTP+"=localhost:"+currentPort; //$NON-NLS-1$ |
| // for( int i=0; i<PROTCOL_EXTRA.length; i++ ) { |
| // String s = getDefaultProxy(PROTCOL_EXTRA[i]); |
| // if( null!=s && s.length()>0 ) { |
| // result += ";"+PROTCOL_EXTRA[i]+"="+s; //$NON-NLS-1$ //$NON-NLS-2$ |
| // } |
| // } |
| // return result; |
| // } |
| |
| private String getDefaultProxy(String protocol) { |
| if( 0 != (savedList.perConnOptions[0].dwValue & INTERNET_PER_CONN_OPTION.PROXY_TYPE_PROXY) ) { |
| String defaultProxy = savedList.perConnOptions[1].strValue.getString(); |
| if( null != defaultProxy ) { |
| if( -1 == defaultProxy.indexOf('=') ) { |
| return defaultProxy; |
| } |
| Matcher m = Pattern.compile(protocol+"=(.+)").matcher(defaultProxy); //$NON-NLS-1$ |
| if( m.find() ) { |
| String s = m.group(1); |
| if( null != s ) { |
| int sep = s.indexOf(';'); |
| return -1==sep ? s : s.substring(0,sep); |
| } |
| } |
| } |
| } |
| return null; |
| } |
| |
| private IWaXcoding getIWaXcoding() { |
| return FlashModelPlugin.getDefault().getIWaXcoding(); |
| } |
| |
| private String getAutoConfigURL(boolean disableAutoProxy) { |
| String pac = readPluginFile("templates/proxy.pac"); //$NON-NLS-1$ |
| if( null != pac ) { |
| String httpProxy = getProxyString("localhost:"+currentPort); //$NON-NLS-1$ |
| pac = pac.replaceAll("\\$NOPROXY_EXTS\\$", disableAutoProxy ? "" : noProxy) //$NON-NLS-1$ //$NON-NLS-2$ |
| .replaceAll("\\$HTTP_PROXY\\$", httpProxy) //$NON-NLS-1$ |
| .replaceAll("\\$HTTP_DIRECT\\$", getProxyString(getDefaultProxy(PROTCOL_HTTP))) //$NON-NLS-1$ |
| .replaceAll("\\$HTTPS_DIRECT\\$", getProxyString(getDefaultProxy(PROTCOL_HTTPS))) //$NON-NLS-1$ |
| .replaceAll("\\$FTP_DIRECT\\$", getProxyString(getDefaultProxy(PROTCOL_FTP))) //$NON-NLS-1$ |
| .replaceAll("\\$GOPHER_DIRECT\\$", getProxyString(getDefaultProxy(PROTCOL_GOPHER))); //$NON-NLS-1$ |
| // System.out.println(pac); |
| OutputStream os = null; |
| try { |
| IPath pacPath = ProxyPlugin.getDefault().getStateLocation().append("proxy.pac"); //$NON-NLS-1$ |
| os = new FileOutputStream(pacPath.toFile()); |
| OutputStreamWriter writer = new OutputStreamWriter(os, "utf-8"); //$NON-NLS-1$ |
| writer.write(pac); |
| writer.close(); |
| return "file://"+pacPath.toString(); //$NON-NLS-1$ |
| } |
| catch( Exception e ) { |
| e.printStackTrace(); |
| } |
| finally { |
| if( null != os ) { |
| try { |
| os.close(); |
| } |
| catch (IOException e) { |
| } |
| } |
| } |
| } |
| return null; |
| } |
| |
| private static String getProxyString(String defaultProxy) { |
| return null != defaultProxy ? MessageFormat.format("PROXY {0}; DIRECT", new Object[]{defaultProxy}) : "DIRECT"; //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| private static String readPluginFile(String path) { |
| InputStream is = null; |
| try { |
| URL url = FileLocator.resolve(ProxyPlugin.getDefault().getBundle().getEntry(path)); |
| is = url.openStream(); |
| Reader reader = new InputStreamReader(is); |
| StringBuffer sb = new StringBuffer(); |
| char[] buff = new char[4096]; |
| int result; |
| while( -1 != (result=reader.read(buff)) ) { |
| sb.append(buff, 0, result); |
| } |
| return sb.toString(); |
| } |
| catch( Exception e ) { |
| e.printStackTrace(); |
| } |
| finally { |
| if( null != is ) { |
| try { |
| is.close(); |
| } |
| catch (IOException e) { |
| } |
| } |
| } |
| return null; |
| } |
| } |