X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2FHTTP.java;h=3dc73da2aec36fb2732dff9c7bc94f947365a320;hb=55c3195af733f3de6b7894f4c4a96f7b50f58c11;hp=44e2f72847e102032b8433812e902e874a1690ed;hpb=e58686eae8a823ed64ed0ec92c2274c41d90ec93;p=org.ibex.core.git diff --git a/src/org/xwt/HTTP.java b/src/org/xwt/HTTP.java index 44e2f72..3dc73da 100644 --- a/src/org/xwt/HTTP.java +++ b/src/org/xwt/HTTP.java @@ -1,4 +1,4 @@ -// Copyright 2002 Adam Megacz, see the COPYING file for licensing [GPL] +// Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL] package org.xwt; import java.net.*; @@ -60,6 +60,9 @@ public class HTTP { /** true iff we are allowed to skip the resolve check (only allowed when we're downloading the PAC script) */ boolean skipResolveCheck = false; + /** true iff we're using a proxy */ + boolean proxied = false; + // Public Methods //////////////////////////////////////////////////////////////////////////////////////// @@ -150,14 +153,11 @@ public class HTTP { // Safeguarded DNS Resolver /////////////////////////////////////////////////////////////////////////// /** - * resolves the hostname and returns it as a string in the form "x.y.z.w", except for the special case "xmlrpc.xwt.org". + * resolves the hostname and returns it as a string in the form "x.y.z.w" * @throws HTTPException if the host falls within a firewalled netblock */ private void resolveAndCheckIfFirewalled(String host) throws HTTPException { - // special case - if (host.equals("xmlrpc.xwt.org")) return; - // cached if (resolvedHosts.get(host) != null) return; @@ -175,19 +175,7 @@ public class HTTP { return; } catch (UnknownHostException uhe) { } - // resolve using xmlrpc.xwt.org if (Platform.detectProxy() == null) throw new HTTPException("could not resolve hostname \"" + host + "\" and no proxy configured"); - if (Log.on) Log.log(this, " could not resolve host " + host + "; using xmlrpc.xwt.org to ensure security"); - try { - JS.Array args = new JS.Array(); - args.addElement(host); - Object ret = new XMLRPC("http://xmlrpc.xwt.org/RPC2/", "dns.resolve").call(args); - if (ret == null || !(ret instanceof String)) throw new Exception(" xmlrpc.xwt.org returned non-String: " + ret); - resolvedHosts.put(host, ret); - return; - } catch (Throwable e) { - throw new HTTPException("exception while attempting to use xmlrpc.xwt.org to resolve " + host + ": " + e); - } } @@ -281,14 +269,14 @@ public class HTTP { } /** executes the PAC script and dispatches a call to one of the other attempt methods based on the result */ - public Socket attemptPAC(org.xwt.js.JS.Function pacFunc) { - throw new Error("not implemented"); - // FIXME - /* + public Socket attemptPAC(org.xwt.js.JS.Callable pacFunc) { if (Log.verbose) Log.log(this, "evaluating PAC script"); String pac = null; try { - Object obj = pacFunc.call(Proxy.proxyAutoConfigRootScope, null, new Object[] { url.toString(), url.getHost() }); + org.xwt.js.JS.Array args = new org.xwt.js.JS.Array(); + args.addElement(url.toString()); + args.addElement(url.getHost()); + Object obj = pacFunc.call(args); if (Log.verbose) Log.log(this, " PAC script returned \"" + obj + "\""); pac = obj.toString(); } catch (Throwable e) { @@ -317,7 +305,6 @@ public class HTTP { } if (Log.on) Log.log(this, "all PAC results exhausted"); return null; - */ } @@ -359,6 +346,7 @@ public class HTTP { if (sock == null && pi != null && ssl && pi.httpsProxyHost != null) sock = attemptHttpProxy(pi.httpsProxyHost, pi.httpsProxyPort); if (sock == null && pi != null && pi.httpProxyHost != null) sock = attemptHttpProxy(pi.httpProxyHost, pi.httpProxyPort); if (sock == null && pi != null && pi.socksProxyHost != null) sock = attemptSocksProxy(pi.socksProxyHost, pi.socksProxyPort); + proxied = sock != null; if (sock == null) sock = attemptDirect(); if (sock == null) throw new HTTPException("unable to contact host " + host); if (in == null) in = new BufferedInputStream(sock.getInputStream()); @@ -369,9 +357,9 @@ public class HTTP { PrintWriter pw = new PrintWriter(new OutputStreamWriter(sock.getOutputStream())); if (content != null) { pw.print("POST " + path + " HTTP/1.1\r\n"); - int contentLength = content.substring(0, 2).equals("\r\n") ? - content.length() - 2 : - (content.length() - content.indexOf("\r\n\r\n") - 4); + int contentLength = content.substring(0, 2).equals("\r\n") ? + content.length() - 2 : + (content.length() - content.indexOf("\r\n\r\n") - 4); pw.print("Content-Length: " + contentLength + "\r\n"); if (contentType != null) pw.print("Content-Type: " + contentType + "\r\n"); } else { @@ -380,6 +368,7 @@ public class HTTP { pw.print("User-Agent: XWT\r\n"); pw.print("Host: " + (host + (port == 80 ? "" : (":" + port))) + "\r\n"); + if (proxied) pw.print("X-RequestOrigin: " + Main.originHost + "\r\n"); if (Proxy.Authorization.authorization != null) pw.print("Proxy-Authorization: " + Proxy.Authorization.authorization2 + "\r\n"); if (authCache.get(originalUrl) != null) pw.print("Authorization: " + authCache.get(originalUrl) + "\r\n"); @@ -485,6 +474,20 @@ public class HTTP { this.length = length == -1 ? 0 : length; } + public boolean markSupported() { return false; } + public int read(byte[] b) throws IOException { return read(b, 0, b.length); } + public long skip(long n) throws IOException { return read(null, -1, (int)n); } + public int available() throws IOException { + if (contentLength == -1) return java.lang.Math.min(super.available(), length); + return super.available(); + } + + public int read() throws IOException { + byte[] b = new byte[1]; + int ret = read(b, 0, 1); + return ret == -1 ? -1 : b[0] & 0xff; + } + private void readChunk() throws IOException { if (chunkedDone) return; if (!firstChunk) super.skip(2); // CRLF @@ -502,7 +505,7 @@ public class HTTP { chunkLen += (char)i; } } - length = Integer.parseInt(chunkLen, 16); + length = Integer.parseInt(chunkLen.trim(), 16); if (length == 0) chunkedDone = true; } @@ -510,15 +513,17 @@ public class HTTP { boolean good = false; try { if (length == 0 && contentLength == -1) { - readChunk(); - if (chunkedDone) return -1; - } else { - if (length == 0) return -1; - } + readChunk(); + if (chunkedDone) { good = true; return -1; } + } else { + if (length == 0) { good = true; return -1; } + } if (len > length) len = length; - int ret = super.read(b, off, len); - length -= ret; - good = true; + int ret = b == null ? (int)super.skip(len) : super.read(b, off, len); + if (ret >= 0) { + length -= ret; + good = true; + } return ret; } finally { if (!good) invalid = true; @@ -618,4 +623,342 @@ public class HTTP { return ret; } + + // Proxy /////////////////////////////////////////////////////////// + + /** encapsulates most of the proxy logic; some is shared in HTTP.java */ + public static class Proxy { + + public Proxy() { } + + /** the HTTP Proxy host to use */ + public String httpProxyHost = null; + + /** the HTTP Proxy port to use */ + public int httpProxyPort = -1; + + /** if a seperate proxy should be used for HTTPS, this is the hostname; otherwise, httpProxyHost is used */ + public String httpsProxyHost = null; + + /** if a seperate proxy should be used for HTTPS, this is the port */ + public int httpsProxyPort = -1; + + /** the SOCKS Proxy Host to use */ + public String socksProxyHost = null; + + /** the SOCKS Proxy Port to use */ + public int socksProxyPort = -1; + + /** hosts to be excluded from proxy use; wildcards permitted */ + public String[] excluded = null; + + /** the PAC script */ + public JS.Callable proxyAutoConfigFunction = null; + + public static Proxy detectProxyViaManual() { + Proxy ret = new Proxy(); + + ret.httpProxyHost = Platform.getEnv("http_proxy"); + if (ret.httpProxyHost != null) { + if (ret.httpProxyHost.startsWith("http://")) ret.httpProxyHost = ret.httpProxyHost.substring(7); + if (ret.httpProxyHost.endsWith("/")) ret.httpProxyHost = ret.httpProxyHost.substring(0, ret.httpProxyHost.length() - 1); + if (ret.httpProxyHost.indexOf(':') != -1) { + ret.httpProxyPort = Integer.parseInt(ret.httpProxyHost.substring(ret.httpProxyHost.indexOf(':') + 1)); + ret.httpProxyHost = ret.httpProxyHost.substring(0, ret.httpProxyHost.indexOf(':')); + } else { + ret.httpProxyPort = 80; + } + } + + ret.httpsProxyHost = Platform.getEnv("https_proxy"); + if (ret.httpsProxyHost != null) { + if (ret.httpsProxyHost.startsWith("https://")) ret.httpsProxyHost = ret.httpsProxyHost.substring(7); + if (ret.httpsProxyHost.endsWith("/")) ret.httpsProxyHost = ret.httpsProxyHost.substring(0, ret.httpsProxyHost.length() - 1); + if (ret.httpsProxyHost.indexOf(':') != -1) { + ret.httpsProxyPort = Integer.parseInt(ret.httpsProxyHost.substring(ret.httpsProxyHost.indexOf(':') + 1)); + ret.httpsProxyHost = ret.httpsProxyHost.substring(0, ret.httpsProxyHost.indexOf(':')); + } else { + ret.httpsProxyPort = 80; + } + } + + ret.socksProxyHost = Platform.getEnv("socks_proxy"); + if (ret.socksProxyHost != null) { + if (ret.socksProxyHost.startsWith("socks://")) ret.socksProxyHost = ret.socksProxyHost.substring(7); + if (ret.socksProxyHost.endsWith("/")) ret.socksProxyHost = ret.socksProxyHost.substring(0, ret.socksProxyHost.length() - 1); + if (ret.socksProxyHost.indexOf(':') != -1) { + ret.socksProxyPort = Integer.parseInt(ret.socksProxyHost.substring(ret.socksProxyHost.indexOf(':') + 1)); + ret.socksProxyHost = ret.socksProxyHost.substring(0, ret.socksProxyHost.indexOf(':')); + } else { + ret.socksProxyPort = 80; + } + } + + String noproxy = Platform.getEnv("no_proxy"); + if (noproxy != null) { + StringTokenizer st = new StringTokenizer(noproxy, ","); + ret.excluded = new String[st.countTokens()]; + for(int i=0; st.hasMoreTokens(); i++) ret.excluded[i] = st.nextToken(); + } + + if (ret.httpProxyHost == null && ret.socksProxyHost == null) return null; + return ret; + } + + public static JS.Scope proxyAutoConfigRootScope = new ProxyAutoConfigRootScope(); + public static JS.Callable getProxyAutoConfigFunction(String url) { + try { + BufferedReader br = new BufferedReader(new InputStreamReader(new HTTP(url, true).GET())); + String s = null; + String script = ""; + while((s = br.readLine()) != null) script += s + "\n"; + if (Log.on) Log.log(Proxy.class, "successfully retrieved WPAD PAC:"); + if (Log.on) Log.log(Proxy.class, script); + + // MS CARP hack + Vector carpHosts = new Vector(); + for(int i=0; i= arr.length) return true; + for(int i=0; i= d1 && day <= d2) || + (d1 > d2 && (day >= d1 || day <= d2))) ? + Boolean.TRUE : Boolean.FALSE; + } + }; + + private static final JS.Callable dateRange = new JS.Callable() { + public Object call(org.xwt.js.JS.Array args) throws JS.Exn { + throw new JS.Exn("XWT does not support dateRange() in PAC scripts"); + } + }; + + private static final JS.Callable timeRange = new JS.Callable() { + public Object call(org.xwt.js.JS.Array args) throws JS.Exn { + throw new JS.Exn("XWT does not support timeRange() in PAC scripts"); + } + }; + + } + + } + }