[haXe] Automatic Proxy Detection
Nicolas Cannasse
ncannasse at motion-twin.com
Mon Jan 8 16:50:31 CET 2007
Hi list,
Some people using HTTP proxies were unable to use some tools such as
haxeLib. Before adding Proxy support to haxe.Http, I would like to get
sure that proxy settings can be retrieved in most of the cases.
Here's a small class that retrieve the Proxy Settings from various
system-specific configurations places. It seems to work for the
following OS/Browsers :
- Windows 2K : Firefox 1.5 Settings and IE 6 Settings
- OSX 10.4 : System/Safari Settings Firefox Settings
- Linux : Firefox Settings
I would like a lot people to test the following :
a) compile using "haxe -main ProxyDetect -neko pdetect.n"
b) run using "neko pdetect.n"
You should get a trace with either "null" (no proxy detected) or a proxy
structure of the kind { host : 127.0.0.1, port : 8080, auth : null }.
If you get an exception or if the printed settings does not correspond
to your system configuration, try watching the sources of the class and
send me some feedback/patch so I can improve it.
Best,
Nicolas
-------------- next part --------------
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) )
throw "Invalid settings '"+settings+"'";
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 ) throw "Invalid Firefox config directory "+basedir;
var profile = null;
for( f in files )
if( f.substr(-8) == ".default" ) {
profile = f;
break;
}
if( profile == null )
throw "Profile not found in "+basedir;
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) )
throw "No http_port in prefs.js";
var port = r.matched(1);
return parseSettings(host+":"+port);
}
static function detectIE() {
var temp = neko.Sys.getEnv("TMP") + "/proxy.txt";
if( neko.Sys.command('regedit /E "'+temp+'" "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"') != 0 )
throw "Failed to call REGEDIT";
var content = neko.io.File.getContent(temp);
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) )
throw "Could not find 'ProxyEnable'";
if( renabled.matched(1) == "0" )
return null;
// value ?
var rproxy = ~/"ProxyServer"="([^"]+)"/;
if( !rproxy.match(content) )
throw "Could not find 'ProxyServer'";
return parseSettings(rproxy.matched(1));
}
static function parseOSXConfiguration(xml : Xml) : Dynamic {
switch( xml.nodeName ) {
case "dict":
var o = Reflect.empty();
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;
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.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;
static function detect() {
if( save == null )
save = { r : detectAll() };
return save.r;
}
static function main() {
trace(detect());
}
}
More information about the Haxe
mailing list