X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2FHTTP.java;h=681b928a614ec505b71ba822d035431a15e7493e;hb=5c8da8336c1196bda3fd5d21208a17058dab1371;hp=5f89ce3d04947fe473efe20973355e5b669aedbe;hpb=c191f0122fbd24c2df21c41affb0c039d59f16d8;p=org.ibex.core.git diff --git a/src/org/xwt/HTTP.java b/src/org/xwt/HTTP.java index 5f89ce3..681b928 100644 --- a/src/org/xwt/HTTP.java +++ b/src/org/xwt/HTTP.java @@ -1,4 +1,4 @@ -// Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL] +// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL] package org.xwt; import java.net.*; @@ -15,35 +15,41 @@ import org.bouncycastle.crypto.digests.*; */ public class HTTP { - /** the URL as passed to the original constructor; this is never changed */ - final String originalUrl; - /** the URL to connect to; this is munged when the url is parsed */ - URL url = null; + // Public Methods //////////////////////////////////////////////////////////////////////////////////////// + + public HTTP(String url) { this(url, false); } + public HTTP(String url, boolean skipResolveCheck) { originalUrl = url; this.skipResolveCheck = skipResolveCheck; } - /** the host to connect to */ - String host = null; + /** Performs an HTTP GET request */ + public InputStream GET() throws IOException { return makeRequest(null, null); } + + /** Performs an HTTP POST request; content is additional headers, blank line, and body */ + public InputStream POST(String contentType, String content) throws IOException { return makeRequest(contentType, content); } - /** the port to connect on */ - int port = -1; + public static class HTTPException extends IOException { public HTTPException(String s) { super(s); } } - /** true if SSL (HTTPS) should be used */ - boolean ssl = false; - /** the path (URI) to retrieve on the server */ - String path = null; + // Statics /////////////////////////////////////////////////////////////////////////////////////////////// - /** the socket */ - Socket sock = null; + static Hash resolvedHosts = new Hash(); ///< cache for resolveAndCheckIfFirewalled() + private static Hash authCache = new Hash(); ///< cache of userInfo strings, keyed on originalUrl - /** the socket's inputstream */ - InputStream in = null; - /** the username and password portions of the URL */ - String userInfo = null; + // Instance Data /////////////////////////////////////////////////////////////////////////////////////////////// - /** cache of userInfo strings, keyed on originalUrl */ - private static Hashtable authCache = new Hashtable(); + final String originalUrl; ///< the URL as passed to the original constructor; this is never changed + URL url = null; ///< the URL to connect to; this is munged when the url is parsed */ + String host = null; ///< the host to connect to + int port = -1; ///< the port to connect on + boolean ssl = false; ///< true if SSL (HTTPS) should be used + String path = null; ///< the path (URI) to retrieve on the server + Socket sock = null; ///< the socket + InputStream in = null; ///< the socket's inputstream + String userInfo = null; ///< the username and password portions of the URL + boolean firstRequest = true; ///< true iff this is the first request to be made on this socket + boolean skipResolveCheck = false; ///< allowed to skip the resolve check when downloading PAC script + boolean proxied = false; ///< true iff we're using a proxy /** this is null if the current request is the first request on * this HTTP connection; otherwise it is a Semaphore which will be @@ -51,33 +57,6 @@ public class HTTP { */ Semaphore okToRecieve = null; - /** true iff this is the first request to be made on this socket */ - boolean firstRequest = true; - - /** cache for resolveAndCheckIfFirewalled() */ - static Hashtable resolvedHosts = new Hashtable(); - - /** 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 //////////////////////////////////////////////////////////////////////////////////////// - - public HTTP(String url) { this(url, false); } - public HTTP(String url, boolean skipResolveCheck) { - originalUrl = url; - this.skipResolveCheck = skipResolveCheck; - } - - /** Performs an HTTP GET request */ - public InputStream GET() throws IOException { return makeRequest(null, null); } - - /** Performs an HTTP POST request; content is appended to the headers (so it should include a blank line to delimit the beginning of the body) */ - public InputStream POST(String contentType, String content) throws IOException { return makeRequest(contentType, content); } - /** * This method isn't synchronized; however, only one thread can be in the inner synchronized block at a time, and the rest of * the method is protected by in-order one-at-a-time semaphore lock-steps @@ -127,7 +106,7 @@ public class HTTP { else doWebAuth(h, content == null ? "GET" : "POST"); if (h.get("HTTP").equals("1.0") && h.get("content-length") == null) { - if (Log.on) Log.log(this, "proxy returned an HTTP/1.0 reply with no content-length..."); + if (Log.on) Log.info(this, "proxy returned an HTTP/1.0 reply with no content-length..."); reset(); } else { int cl = h.get("content-length") == null ? -1 : Integer.parseInt(h.get("content-length").toString()); @@ -177,7 +156,8 @@ public class HTTP { if ((quadbyte[0] == 10 || (quadbyte[0] == 192 && quadbyte[1] == 168) || (quadbyte[0] == 172 && (quadbyte[1] & 0xF0) == 16)) && !addr.equals(Main.originAddr)) - throw new HTTPException("security violation: " + host + " [" + addr.getHostAddress() + "] is in a firewalled netblock"); + throw new HTTPException("security violation: " + host + " [" + addr.getHostAddress() + + "] is in a firewalled netblock"); return; } catch (UnknownHostException uhe) { } @@ -194,40 +174,41 @@ public class HTTP { return ret; } - /** Attempts a direct connection */ - public Socket attemptDirect() { + private Socket attemptDirect() { try { - if (Log.verbose) Log.log(this, "attempting to create unproxied socket to " + host + ":" + port + (ssl ? " [ssl]" : "")); + if (Log.verbose) Log.info(this, "attempting to create unproxied socket to " + + host + ":" + port + (ssl ? " [ssl]" : "")); return getSocket(host, port, ssl, true); } catch (IOException e) { - if (Log.on) Log.log(this, "exception in attemptDirect(): " + e); + if (Log.on) Log.info(this, "exception in attemptDirect(): " + e); return null; } } /** Attempts to use an HTTP proxy, employing the CONNECT method if HTTPS is requested */ - public Socket attemptHttpProxy(String proxyHost, int proxyPort) { + private Socket attemptHttpProxy(String proxyHost, int proxyPort) { try { - if (Log.verbose) Log.log(this, "attempting to create HTTP proxied socket using proxy " + proxyHost + ":" + proxyPort); - + if (Log.verbose) Log.info(this, "attempting to create HTTP proxied socket using proxy " + proxyHost + ":" + proxyPort); Socket sock = getSocket(proxyHost, proxyPort, ssl, false); + if (!ssl) { if (!path.startsWith("http://")) path = "http://" + host + ":" + port + path; - } else { - PrintWriter pw = new PrintWriter(new OutputStreamWriter(sock.getOutputStream())); - BufferedReader br = new BufferedReader(new InputStreamReader(sock.getInputStream())); - pw.print("CONNECT " + host + ":" + port + " HTTP/1.1\r\n\r\n"); - pw.flush(); - String s = br.readLine(); - if (s.charAt(9) != '2') throw new HTTPException("proxy refused CONNECT method: \"" + s + "\""); - while (br.readLine().length() > 0) { }; - ((SSL)sock).negotiate(); + return sock; } + + PrintWriter pw = new PrintWriter(new OutputStreamWriter(sock.getOutputStream())); + BufferedReader br = new BufferedReader(new InputStreamReader(sock.getInputStream())); + pw.print("CONNECT " + host + ":" + port + " HTTP/1.1\r\n\r\n"); + pw.flush(); + String s = br.readLine(); + if (s.charAt(9) != '2') throw new HTTPException("proxy refused CONNECT method: \"" + s + "\""); + while (br.readLine().length() > 0) { }; + ((SSL)sock).negotiate(); return sock; } catch (IOException e) { - if (Log.on) Log.log(this, "exception in attemptHttpProxy(): " + e); + if (Log.on) Log.info(this, "exception in attemptHttpProxy(): " + e); return null; } } @@ -237,13 +218,13 @@ public class HTTP { * @see http://www.socks.nec.com/protocol/socks4.protocol * @see http://www.socks.nec.com/protocol/socks4a.protocol */ - public Socket attemptSocksProxy(String proxyHost, int proxyPort) { + private Socket attemptSocksProxy(String proxyHost, int proxyPort) { // even if host is already a "x.y.z.w" string, we use this to parse it into bytes InetAddress addr = null; try { addr = InetAddress.getByName(host); } catch (Exception e) { } - if (Log.verbose) Log.log(this, "attempting to create SOCKSv4" + (addr == null ? "" : "a") + + if (Log.verbose) Log.info(this, "attempting to create SOCKSv4" + (addr == null ? "" : "a") + " proxied socket using proxy " + proxyHost + ":" + proxyPort); try { @@ -273,33 +254,33 @@ public class HTTP { if (ssl) ((SSL)sock).negotiate(); return sock; } - if (Log.on) Log.log(this, "SOCKS server denied access, code " + (success & 0xff)); + if (Log.on) Log.info(this, "SOCKS server denied access, code " + (success & 0xff)); return null; } catch (IOException e) { - if (Log.on) Log.log(this, "exception in attemptSocksProxy(): " + e); + if (Log.on) Log.info(this, "exception in attemptSocksProxy(): " + e); return null; } } /** 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 pacFunc) { - if (Log.verbose) Log.log(this, "evaluating PAC script"); + private Socket attemptPAC(org.xwt.js.JS pacFunc) { + if (Log.verbose) Log.info(this, "evaluating PAC script"); String pac = null; try { org.xwt.js.JSArray args = new org.xwt.js.JSArray(); Object obj = pacFunc.call(url.toString(), url.getHost(), null, null, 2); - if (Log.verbose) Log.log(this, " PAC script returned \"" + obj + "\""); + if (Log.verbose) Log.info(this, " PAC script returned \"" + obj + "\""); pac = obj.toString(); } catch (Throwable e) { - if (Log.on) Log.log(this, "PAC script threw exception " + e); + if (Log.on) Log.info(this, "PAC script threw exception " + e); return null; } StringTokenizer st = new StringTokenizer(pac, ";", false); while (st.hasMoreTokens()) { String token = st.nextToken().trim(); - if (Log.verbose) Log.log(this, " trying \"" + token + "\"..."); + if (Log.verbose) Log.info(this, " trying \"" + token + "\"..."); try { Socket ret = null; if (token.startsWith("DIRECT")) @@ -312,10 +293,10 @@ public class HTTP { Integer.parseInt(token.substring(token.indexOf(':') + 1))); if (ret != null) return ret; } catch (Throwable e) { - if (Log.on) Log.log(this, "attempt at \"" + token + "\" failed due to " + e + "; trying next token"); + if (Log.on) Log.info(this, "attempt at \"" + token + "\" failed due to " + e + "; trying next token"); } } - if (Log.on) Log.log(this, "all PAC results exhausted"); + if (Log.on) Log.info(this, "all PAC results exhausted"); return null; } @@ -323,10 +304,7 @@ public class HTTP { // Everything Else //////////////////////////////////////////////////////////////////////////// private synchronized void connect() throws IOException { - if (originalUrl.equals("stdio:")) { - in = new BufferedInputStream(System.in); - return; - } + if (originalUrl.equals("stdio:")) { in = new BufferedInputStream(System.in); return; } if (sock != null) { if (in == null) in = new BufferedInputStream(sock.getInputStream()); return; @@ -355,14 +333,14 @@ public class HTTP { path = this.url.getFile(); if (port == -1) port = ssl ? 443 : 80; host = this.url.getHost(); - if (Log.verbose) Log.log(this, "creating HTTP object for connection to " + host + ":" + port); + if (Log.verbose) Log.info(this, "creating HTTP object for connection to " + host + ":" + port); Proxy pi = Platform.detectProxy(); OUTER: do { if (pi != null) { for(int i=0; i= 4 && buf[buflen - 4] == '\r' && buf[buflen - 3] == '\n' && buf[buflen - 2] == '\r' && buf[buflen - 1] == '\n') break; + if (buflen >= 4 && buf[buflen - 4] == '\r' && buf[buflen - 3] == '\n' && + buf[buflen - 2] == '\r' && buf[buflen - 1] == '\n') + break; if (buflen == buf.length) { byte[] newbuf = new byte[buf.length * 2]; System.arraycopy(buf, 0, newbuf, 0, buflen); @@ -682,29 +651,14 @@ public class HTTP { 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 String httpProxyHost = null; ///< the HTTP Proxy host to use + public int httpProxyPort = -1; ///< the HTTP Proxy port to use + public String httpsProxyHost = null; ///< seperate proxy for HTTPS 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 proxyAutoConfigJSFunction = null; + public String socksProxyHost = null; ///< the SOCKS Proxy Host to use + public int socksProxyPort = -1; ///< the SOCKS Proxy Port to use + public String[] excluded = new String[] { }; ///< hosts to be excluded from proxy use; wildcards permitted + public JS proxyAutoConfigFunction = null; ///< the PAC script public static Proxy detectProxyViaManual() { Proxy ret = new Proxy(); @@ -712,7 +666,8 @@ public class HTTP { 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.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(':')); @@ -724,7 +679,8 @@ public class HTTP { 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.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(':')); @@ -736,7 +692,8 @@ public class HTTP { 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.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(':')); @@ -756,22 +713,22 @@ public class HTTP { return ret; } - public static JSScope proxyAutoConfigRootJSScope = new ProxyAutoConfigRootJSScope(); - public static JS getProxyAutoConfigJSFunction(String url) { + public static JSScope proxyAutoConfigRootScope = new ProxyAutoConfigRootScope(); + public static JS 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); + if (Log.on) Log.info(Proxy.class, "successfully retrieved WPAD PAC:"); + if (Log.on) Log.info(Proxy.class, script); // MS CARP hack Vector carpHosts = new Vector(); for(int i=0; i= d1 && day <= d2) || (d1 > d2 && (day >= d1 || day <= d2))) ? T : F; + + case "dateRange": throw new JSExn("XWT does not support dateRange() in PAC scripts"); + case "timeRange": throw new JSExn("XWT does not support timeRange() in PAC scripts"); + //#end + return super.callMethod(method, a0, a1, a2, rest, nargs); + } private static boolean match(String[] arr, String s, int index) { if (index >= 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 dateRange = new JS() { - public Object call(org.xwt.js.JSArray args) throws JSExn { - throw new JSExn("XWT does not support dateRange() in PAC scripts"); - } - }; - - private static final JS timeRange = new JS() { - public Object call(org.xwt.js.JSArray args) throws JSExn { - throw new JSExn("XWT does not support timeRange() in PAC scripts"); - } - }; - } + /** * An implementation of Microsoft's proprietary NTLM authentication protocol. This code was derived from Eric * Glass's work, and is copyright as follows: