X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2FHTTP.java;h=cc476cbec9df2428363e48f560c860df09c4240d;hb=f4ff7c16a3b69784da7f66f6ff1be899b4a5f508;hp=3dc73da2aec36fb2732dff9c7bc94f947365a320;hpb=55c3195af733f3de6b7894f4c4a96f7b50f58c11;p=org.ibex.core.git diff --git a/src/org/xwt/HTTP.java b/src/org/xwt/HTTP.java index 3dc73da..cc476cb 100644 --- a/src/org/xwt/HTTP.java +++ b/src/org/xwt/HTTP.java @@ -54,9 +54,6 @@ public class HTTP { /** cache for resolveAndCheckIfFirewalled() */ static Hashtable resolvedHosts = new Hashtable(); - /** if any request encounters an IOException, the entire HTTP connection is invalidated */ - boolean invalid = false; - /** true iff we are allowed to skip the resolve check (only allowed when we're downloading the PAC script) */ boolean skipResolveCheck = false; @@ -73,27 +70,27 @@ 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; Semaphore releaseMe = null; synchronized(this) { - if (invalid) throw new HTTPException("connection failed on a previous pipelined call"); try { connect(); sendRequest(contentType, content); } catch (IOException e) { - invalid = true; + sock = null; + in = null; throw e; } blockOn = okToRecieve; @@ -104,7 +101,12 @@ public class HTTP { boolean doRelease = true; try { if (blockOn != null) blockOn.block(); - if (invalid) throw new HTTPException("connection failed on a previous pipelined call"); + + // previous call wrecked the socket connection, but we already sent our request, so we can't just retry -- + // this could cause the server to receive the request twice, which could be bad (think of the case where the + // server call causes Amazon.com to ship you an item with one-click purchasing). + if (sock == null) + throw new HTTPException("a previous pipelined call messed up the socket"); Hashtable h = in == null ? null : parseHeaders(in); if (h == null) { @@ -135,7 +137,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; @@ -144,7 +147,7 @@ public class HTTP { } - } catch (IOException e) { invalid = true; throw e; + } catch (IOException e) { sock = null; in = null; throw e; } finally { if (doRelease) releaseMe.release(); } } @@ -176,6 +179,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); + } } @@ -311,6 +325,10 @@ public class HTTP { // Everything Else //////////////////////////////////////////////////////////////////////////// private synchronized void connect() throws IOException { + if (originalUrl.equals("stdio:")) { + in = new BufferedInputStream(System.in); + return; + } if (sock != null) { if (in == null) in = new BufferedInputStream(sock.getInputStream()); return; @@ -342,10 +360,15 @@ public class HTTP { if (Log.verbose) Log.log(this, "creating HTTP object for connection to " + host + ":" + port); Proxy pi = Platform.detectProxy(); - if (sock == null && pi != null && pi.proxyAutoConfigFunction != null) sock = attemptPAC(pi.proxyAutoConfigFunction); - 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); + OUTER: do { + if (pi != null) { + for(int i=0; i