123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- /*
- * Copyright (c) 2005, The haXe Project Contributors
- * All rights reserved.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
- package neko.net;
- typedef ProxySettings = {
- var host : String;
- var port : Int;
- var auth : {
- var user : String;
- var pass : String;
- };
- }
- class ProxyDetect {
- static function parseSettings( settings : String ) {
- var r = ~/^([^:]+):([^@]*)@([^:]+):([0-9]+)$/;
- if( r.match(settings) )
- return {
- auth : {
- user : r.matched(1),
- pass : r.matched(2),
- },
- host : r.matched(3),
- port : Std.parseInt(r.matched(4)),
- };
- var r = ~/^([^:]+):([0-9]+)$/;
- if( !r.match(settings) ) {
- var r2 = ~/http=([^:]+):([0-9]+)/;
- if( !r2.match(settings) )
- throw "Invalid settings '"+settings+"'";
- r = r2;
- }
- return {
- host : r.matched(1),
- port : Std.parseInt(r.matched(2)),
- auth : null,
- };
- }
- static function detectFF( basedir : String ) {
- var files = try neko.FileSystem.readDirectory(basedir) catch( e : Dynamic ) return null;
- var profile = null;
- for( f in files )
- if( f.substr(-8) == ".default" ) {
- profile = f;
- break;
- }
- if( profile == null )
- return null;
- var prefs = neko.io.File.getContent(basedir+"/"+profile+"/prefs.js");
- // enabled ?
- var r = ~/user_pref\("network\.proxy\.type", 1\);/;
- if( !r.match(prefs) )
- return null;
- // prefs
- var r = ~/user_pref\("network\.proxy\.http", "([^"]+)"\);/;
- if( !r.match(prefs) )
- return null;
- var host = r.matched(1);
- var r = ~/user_pref\("network\.proxy\.http_port", ([0-9]+)\);/;
- if( !r.match(prefs) )
- return null;
- var port = r.matched(1);
- return parseSettings(host+":"+port);
- }
- static function detectIE() {
- var dir = neko.Sys.getEnv("TMP");
- if( dir == null )
- dir = ".";
- var temp = dir + "/proxy.txt";
- if( neko.Sys.command('regedit /E "'+temp+'" "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"') != 0 ) {
- // might fail without appropriate rights
- return null;
- }
- // it's possible that if registry access was disabled the proxy file is not created
- var content = try neko.io.File.getContent(temp) catch( e : Dynamic ) return null;
- neko.FileSystem.deleteFile(temp);
- // turn 16-bit string into 8-bit one
- var b = new StringBuf();
- var p = 0;
- while( p < content.length ) {
- b.addChar(content.charCodeAt(p));
- p += 2;
- }
- content = b.toString();
- // enabled ?
- var renabled = ~/"ProxyEnable"=dword:0000000(0|1)/;
- if( !renabled.match(content) )
- return null;
- if( renabled.matched(1) == "0" )
- return null;
- // value ?
- var rproxy = ~/"ProxyServer"="([^"]+)"/;
- if( !rproxy.match(content) )
- return null;
- return parseSettings(rproxy.matched(1));
- }
- static function parseOSXConfiguration(xml : Xml) : Dynamic {
- switch( xml.nodeName ) {
- case "dict":
- var o = {};
- var it = xml.elements();
- for( x in it ) {
- if( x.nodeName != "key" ) throw "Missing key";
- var v = x.firstChild().nodeValue;
- var r = parseOSXConfiguration(it.next());
- Reflect.setField(o,v,r);
- }
- return o;
- case "string":
- return xml.firstChild().nodeValue;
- case "integer":
- return Std.parseInt(xml.firstChild().nodeValue);
- case "array":
- var a = new Array();
- for( x in xml.elements() )
- a.push(parseOSXConfiguration(x));
- return a;
- case "true":
- return true;
- case "false":
- return false;
- case "data":
- return xml.firstChild().nodeValue;
- default:
- throw "Invalid value type '"+xml.nodeName+"'";
- }
- }
- static function detectOSX() {
- var prefs = neko.io.File.getContent("/Library/Preferences/SystemConfiguration/preferences.plist");
- var xml = Xml.parse(prefs).firstElement().firstElement(); // plist/dict
- var data : Dynamic = parseOSXConfiguration(xml);
- for( nsname in Reflect.fields(data.NetworkServices) ) {
- var ns : Dynamic = Reflect.field(data.NetworkServices,nsname);
- if( ns.Proxies != null && ns.Proxies.HTTPEnable == 1 )
- return { host : ns.Proxies.HTTPProxy, port : ns.Proxies.HTTPPort, auth : null };
- }
- return null;
- }
- static function detectAll() : ProxySettings {
- switch( neko.Sys.systemName() ) {
- case "Windows":
- try {
- var ffdir = neko.Sys.getEnv("APPDATA")+"/Mozilla/Firefox/Profiles";
- var p = detectFF(ffdir);
- if( p == null )
- throw "No Firefox proxy";
- return p;
- } catch( e : Dynamic ) {
- return detectIE();
- }
- case "Mac":
- var p = detectOSX();
- if( p != null )
- return p;
- var ffdir = neko.Sys.getEnv("HOME")+"/Library/Application Support/Firefox/Profiles";
- return detectFF(ffdir);
- case "Linux":
- var ffdir = neko.Sys.getEnv("HOME")+"/.mozilla/firefox";
- return detectFF(ffdir);
- default:
- throw "This system is not supported";
- }
- }
- static var save : { r : ProxySettings } = null;
- public static function detect() {
- if( save == null )
- save = { r : detectAll() };
- return save.r;
- }
- static function main() {
- trace(detect());
- }
- }
|