X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2FHTTP.java;h=fed6e6e852931746412e214e66e1719884663d6c;hb=6b010667b40641fdb82925e56466f847f721ef1f;hp=b7a3eb8283a5b40e781141aa5cb24eed6cc5880e;hpb=6833b92bd60998e0c08a9e4f83dbc2712faa8aa3;p=org.ibex.core.git diff --git a/src/org/xwt/HTTP.java b/src/org/xwt/HTTP.java index b7a3eb8..fed6e6e 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.*; @@ -73,16 +73,16 @@ public class HTTP { } /** Performs an HTTP GET request */ - public HTTPInputStream GET() throws IOException { return makeRequest(null, null); } + 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 HTTPInputStream POST(String contentType, String content) throws IOException { return makeRequest(contentType, content); } + 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 */ - private HTTPInputStream makeRequest(String contentType, String content) throws IOException { + private InputStream makeRequest(String contentType, String content) throws IOException { // Step 1: send the request and establish a semaphore to stop any requests that pipeline after us Semaphore blockOn = null; @@ -135,7 +135,8 @@ public class HTTP { if (h.get("HTTP").equals("1.0") && h.get("content-length") == null) throw new HTTPException("XWT does not support HTTP/1.0 servers which fail to return the Content-Length header"); int cl = h.get("content-length") == null ? -1 : Integer.parseInt(h.get("content-length").toString()); - HTTPInputStream ret = new HTTPInputStream(in, cl, releaseMe); + InputStream ret = new HTTPInputStream(in, cl, releaseMe); + if ("gzip".equals(h.get("content-encoding"))) ret = new java.util.zip.GZIPInputStream(ret); doRelease = false; return ret; @@ -176,6 +177,17 @@ public class HTTP { } catch (UnknownHostException uhe) { } 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); + } } @@ -367,6 +379,7 @@ public class HTTP { } pw.print("User-Agent: XWT\r\n"); + pw.print("Accept-encoding: gzip\r\n"); pw.print("Host: " + (host + (port == 80 ? "" : (":" + port))) + "\r\n"); if (proxied) pw.print("X-RequestOrigin: " + Main.originHost + "\r\n"); @@ -467,7 +480,7 @@ public class HTTP { private int contentLength = 0; public int getContentLength() { return contentLength; } - HTTPInputStream(InputStream in, int length, Semaphore releaseMe) { + HTTPInputStream(InputStream in, int length, Semaphore releaseMe) throws IOException { super(in); this.releaseMe = releaseMe; this.contentLength = length; @@ -497,7 +510,7 @@ public class HTTP { int i = super.read(); if (i == -1) throw new HTTPException("encountered end of stream while reading chunk length"); - // FIXME: handle chunking extensions + // FEATURE: handle chunking extensions if (i == '\r') { super.read(); // LF break; @@ -623,4 +636,339 @@ 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"); + } + }; + + } + + } + }