diff options
author | Jiri Vanek <[email protected]> | 2013-05-02 16:00:17 +0200 |
---|---|---|
committer | Jiri Vanek <[email protected]> | 2013-05-02 16:00:17 +0200 |
commit | c01de86b76ad014e30534ba879478c579e748fa9 (patch) | |
tree | eb83e7fa79f2059ef740ad9243989ad3c1bb5f87 | |
parent | 5c3d81c1620b814a3883909f4a37d71e9742a602 (diff) |
Fix for portalbank.no (trying get after failed head requests) and tests
-rw-r--r-- | ChangeLog | 33 | ||||
-rw-r--r-- | netx/net/sourceforge/jnlp/Version.java | 38 | ||||
-rw-r--r-- | netx/net/sourceforge/jnlp/cache/Resource.java | 2 | ||||
-rw-r--r-- | netx/net/sourceforge/jnlp/cache/ResourceTracker.java | 69 | ||||
-rw-r--r-- | netx/net/sourceforge/jnlp/util/HttpUtils.java | 76 | ||||
-rw-r--r-- | netx/net/sourceforge/jnlp/util/StreamUtils.java | 13 | ||||
-rw-r--r-- | tests/netx/unit/net/sourceforge/jnlp/VersionTest.java | 98 | ||||
-rw-r--r-- | tests/netx/unit/net/sourceforge/jnlp/cache/ResourceTrackerTest.java | 320 | ||||
-rw-r--r-- | tests/netx/unit/net/sourceforge/jnlp/util/HttpUtilsTest.java | 248 | ||||
-rw-r--r-- | tests/netx/unit/net/sourceforge/jnlp/util/UrlUtilsTest.java | 37 | ||||
-rw-r--r-- | tests/test-extensions/net/sourceforge/jnlp/ServerLauncher.java | 17 | ||||
-rw-r--r-- | tests/test-extensions/net/sourceforge/jnlp/TinyHttpdImpl.java | 30 |
12 files changed, 850 insertions, 131 deletions
@@ -1,5 +1,38 @@ 2013-05-02 Jiri Vanek <[email protected]> + Added various tests related to portalbank.no fixes + * netx/net/sourceforge/jnlp/cache/Resource.java: added fixme to warn + before wrong url comparator + * netx/net/sourceforge/jnlp/Version.java: removed useless main. Its + purpose moved to new + * tests/netx/unit/net/sourceforge/jnlp/VersionTest: some small tests to + version class + * tests/netx/unit/net/sourceforge/jnlp/cache/ResourceTrackerTest.java: + added tests to (getUrlResponseCode) and (findBestUrl) + * tests/netx/unit/net/sourceforge/jnlp/util/HttpUtilsTest.java: added tests for + (consumeAndCloseConnectionSilently) and (consumeAndCloseConnection) + * tests/netx/unit/net/sourceforge/jnlp/util/UrlUtilsTest: added license header + * tests/test-extensions/net/sourceforge/jnlp/ServerLauncher.java: and + * tests/test-extensions/net/sourceforge/jnlp/TinyHttpdImpl.java: added + support for simulation of not working HEAD request. + +2013-05-02 Jiri Vanek <[email protected]> + + Fix for portalbank.no (trying get after failed head requests) + * net/sourceforge/jnlp/cache/ResourceTracker : (findBestUrl) + now trying GET after each error request of HEAD type. Changed and + added debug messages. (getUrlResponseCode) closing of stream + moved to separate method HttpUtils.consumeAndCloseConnectionSilently + * net/sourceforge/jnlp/util/HttpUtils.java: new file designed for + http utils. Now contains (consumeAndCloseConnection) and + (consumeAndCloseConnectionSilently) which calls consumeAndCloseConnection + but do not rethrow exception + * netx/net/sourceforge/jnlp/util/StreamUtils.java: removed + (consumeAndCloseInputStream) now improved and moved to HttpUtils + + +2013-05-02 Jiri Vanek <[email protected]> + Renamed cz locales to be more general * netx/net/sourceforge/jnlp/resources/Messages_cs_CZ.properties: renamed to * netx/net/sourceforge/jnlp/resources/Messages_cs.properties: new file diff --git a/netx/net/sourceforge/jnlp/Version.java b/netx/net/sourceforge/jnlp/Version.java index 99e7cd6..a1732ab 100644 --- a/netx/net/sourceforge/jnlp/Version.java +++ b/netx/net/sourceforge/jnlp/Version.java @@ -308,42 +308,6 @@ public class Version { public String toString() { return versionString; - } - - /** - * Test. - */ - /* - public static void main(String args[]) { - Version jvms[] = { - new Version("1.1* 1.3*"), - new Version("1.2+"), - }; - - Version versions[] = { - new Version("1.1"), - new Version("1.1.8"), - new Version("1.2"), - new Version("1.3"), - new Version("2.0"), - new Version("1.3.1"), - new Version("1.2.1"), - new Version("1.3.1-beta"), - new Version("1.1 1.2"), - new Version("1.2 1.3"), - }; - - for (int j = 0; j < jvms.length; j++) { - for (int v = 0; v < versions.length; v++) { - System.out.print( jvms[j].toString() + " " ); - if (!jvms[j].matches(versions[v])) - System.out.print( "!" ); - System.out.println( "matches " + versions[v].toString() ); - } - } - - System.out.println("Test completed"); - } - */ + } } diff --git a/netx/net/sourceforge/jnlp/cache/Resource.java b/netx/net/sourceforge/jnlp/cache/Resource.java index 00d411b..c4c6bbf 100644 --- a/netx/net/sourceforge/jnlp/cache/Resource.java +++ b/netx/net/sourceforge/jnlp/cache/Resource.java @@ -109,6 +109,8 @@ public class Resource { synchronized (resources) { Resource resource = new Resource(location, requestVersion, updatePolicy); + //FIXME - url ignores port during its comparison + //this may affect test-suites int index = resources.indexOf(resource); if (index >= 0) { // return existing object Resource result = resources.get(index); diff --git a/netx/net/sourceforge/jnlp/cache/ResourceTracker.java b/netx/net/sourceforge/jnlp/cache/ResourceTracker.java index 7b6a772..e8f4235 100644 --- a/netx/net/sourceforge/jnlp/cache/ResourceTracker.java +++ b/netx/net/sourceforge/jnlp/cache/ResourceTracker.java @@ -24,14 +24,10 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; import java.net.URL; import java.net.URLConnection; -import java.net.URLDecoder; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; @@ -49,7 +45,7 @@ import net.sourceforge.jnlp.Version; import net.sourceforge.jnlp.event.DownloadEvent; import net.sourceforge.jnlp.event.DownloadListener; import net.sourceforge.jnlp.runtime.JNLPRuntime; -import net.sourceforge.jnlp.util.StreamUtils; +import net.sourceforge.jnlp.util.HttpUtils; import net.sourceforge.jnlp.util.UrlUtils; import net.sourceforge.jnlp.util.WeakList; @@ -118,6 +114,9 @@ public class ResourceTracker { /** max threads */ private static final int maxThreads = 5; + + /** methods used to try individual URLs when choosing best*/ + private static final String[] requestMethods = {"HEAD", "GET"}; /** running threads */ private static int threads = 0; @@ -859,7 +858,7 @@ public class ResourceTracker { * @return the response code if HTTP connection, or HttpURLConnection.HTTP_OK if not. * @throws IOException */ - private static int getUrlResponseCode(URL url, Map<String, String> requestProperties, String requestMethod) throws IOException { + static int getUrlResponseCode(URL url, Map<String, String> requestProperties, String requestMethod) throws IOException { URLConnection connection = url.openConnection(); for (Map.Entry<String, String> property : requestProperties.entrySet()){ @@ -874,7 +873,7 @@ public class ResourceTracker { /* Fully consuming current request helps with connection re-use * See http://docs.oracle.com/javase/1.5.0/docs/guide/net/http-keepalive.html */ - StreamUtils.consumeAndCloseInputStream(httpConnection.getInputStream()); + HttpUtils.consumeAndCloseConnectionSilently(httpConnection); return responseCode; } @@ -891,7 +890,7 @@ public class ResourceTracker { * @param resource the resource * @return the best URL, or null if all failed to resolve */ - private URL findBestUrl(Resource resource) { + URL findBestUrl(Resource resource) { DownloadOptions options = downloadOptions.get(resource); if (options == null) { options = new DownloadOptions(false, false); @@ -903,33 +902,33 @@ public class ResourceTracker { resource.toString() + " : " + urls); } - for (URL url : urls) { - try { - Map<String, String> requestProperties = new HashMap<String, String>(); - requestProperties.put("Accept-Encoding", "pack200-gzip, gzip"); - - int responseCode = getUrlResponseCode(url, requestProperties, "HEAD"); - - if (responseCode == HttpURLConnection.HTTP_NOT_IMPLEMENTED ) { - System.err.println("NOTE: The server does not appear to support HEAD requests, falling back to GET requests."); - /* Fallback: use GET request in the rare case the server does not support HEAD requests */ - responseCode = getUrlResponseCode(url, requestProperties, "GET"); - } - - /* Check if within valid response code range */ - if (responseCode >= 200 && responseCode < 300) { - if (JNLPRuntime.isDebug()) { - System.err.println("best url for " + resource.toString() + " is " + url.toString()); - } - return url; /* This is the best URL */ - } - } catch (IOException e) { - // continue to next candidate - if (JNLPRuntime.isDebug()) { - System.err.println("While processing " + url.toString() + " for resource " + resource.toString() + " got " + e); - } - } - } + for (String requestMethod : requestMethods) { + for (URL url : urls) { + try { + Map<String, String> requestProperties = new HashMap<String, String>(); + requestProperties.put("Accept-Encoding", "pack200-gzip, gzip"); + + int responseCode = getUrlResponseCode(url, requestProperties, requestMethod); + + if (responseCode < 200 || responseCode >= 300) { + if (JNLPRuntime.isDebug()) { + System.err.println("For "+resource.toString()+" the server returned " + responseCode + " code for "+requestMethod+" request for " + url.toExternalForm()); + } + }else { + if (JNLPRuntime.isDebug()) { + System.out.println("best url for " + resource.toString() + " is " + url.toString() + " by " + requestMethod); + } + return url; /* This is the best URL */ + } + } catch (IOException e) { + // continue to next candidate + if (JNLPRuntime.isDebug()) { + System.err.println("While processing " + url.toString() + " by " + requestMethod + " for resource " + resource.toString() + " got " + e + ": "); + e.printStackTrace(); + } + } + } + } /* No valid URL, return null */ return null; diff --git a/netx/net/sourceforge/jnlp/util/HttpUtils.java b/netx/net/sourceforge/jnlp/util/HttpUtils.java new file mode 100644 index 0000000..5bbfa69 --- /dev/null +++ b/netx/net/sourceforge/jnlp/util/HttpUtils.java @@ -0,0 +1,76 @@ +/* + Copyright (C) 2011 Red Hat, Inc. + + This file is part of IcedTea. + + IcedTea is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as published by + the Free Software Foundation, version 2. + + IcedTea is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with IcedTea; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. + */ +package net.sourceforge.jnlp.util; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; + +public class HttpUtils { + + /** + * Ensure a HttpURLConnection is fully read, required for correct behavior. + * Captured IOException is consumed and printed + */ + public static void consumeAndCloseConnectionSilently(HttpURLConnection c) { + try { + consumeAndCloseConnection(c); + } catch (IOException ex) { + ex.printStackTrace(System.err); + } + } + + /** + * Ensure a HttpURLConnection is fully read, required for correct behavior + * + * @throws IOException + */ + public static void consumeAndCloseConnection(HttpURLConnection c) throws IOException { + InputStream in = null; + try { + in = c.getInputStream(); + byte[] throwAwayBuffer = new byte[256]; + while (in.read(throwAwayBuffer) > 0) { + /* ignore contents */ + } + } finally { + if (in != null) { + in.close(); + } + } + } +} diff --git a/netx/net/sourceforge/jnlp/util/StreamUtils.java b/netx/net/sourceforge/jnlp/util/StreamUtils.java index 6692d1c..c498b7b 100644 --- a/netx/net/sourceforge/jnlp/util/StreamUtils.java +++ b/netx/net/sourceforge/jnlp/util/StreamUtils.java @@ -45,19 +45,6 @@ import java.io.InputStreamReader; public class StreamUtils { - /** - * Ensure a stream is fully read, required for correct behaviour in some - * APIs, namely HttpURLConnection. - * @throws IOException - */ - public static void consumeAndCloseInputStream(InputStream in) throws IOException { - byte[] throwAwayBuffer = new byte[256]; - while (in.read(throwAwayBuffer) > 0) { - /* ignore contents */ - } - in.close(); - } - /*** * Closes a stream, without throwing IOException. * In case of IOException, prints the stack trace to System.err. diff --git a/tests/netx/unit/net/sourceforge/jnlp/VersionTest.java b/tests/netx/unit/net/sourceforge/jnlp/VersionTest.java new file mode 100644 index 0000000..efe38ea --- /dev/null +++ b/tests/netx/unit/net/sourceforge/jnlp/VersionTest.java @@ -0,0 +1,98 @@ +/* + Copyright (C) 2011 Red Hat, Inc. + + This file is part of IcedTea. + + IcedTea is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as published by + the Free Software Foundation, version 2. + + IcedTea is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with IcedTea; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. + */ +package net.sourceforge.jnlp; + +import org.junit.Assert; +import org.junit.Test; + +public class VersionTest { + + private static boolean[] results = {true, + true, + false, + true, + false, + true, + false, + true, + false, + false, + false, + false, + true, + true, + true, + true, + true, + true, + false, + true}; + private static Version jvms[] = { + new Version("1.1* 1.3*"), + new Version("1.2+"),}; + private static Version versions[] = { + new Version("1.1"), + new Version("1.1.8"), + new Version("1.2"), + new Version("1.3"), + new Version("2.0"), + new Version("1.3.1"), + new Version("1.2.1"), + new Version("1.3.1-beta"), + new Version("1.1 1.2"), + new Version("1.2 1.3"),}; + + @Test + public void testMatches() { + + int i = 0; + for (int j = 0; j < jvms.length; j++) { + for (int v = 0; v < versions.length; v++) { + i++; + String debugOutput = i + " " + jvms[j].toString() + " "; + if (!jvms[j].matches(versions[v])) { + debugOutput += "!"; + } + debugOutput += "matches " + versions[v].toString(); + ServerAccess.logOutputReprint(debugOutput); + Assert.assertEquals(results[i - 1], jvms[j].matches(versions[v])); + } + } + + + } +} diff --git a/tests/netx/unit/net/sourceforge/jnlp/cache/ResourceTrackerTest.java b/tests/netx/unit/net/sourceforge/jnlp/cache/ResourceTrackerTest.java index 29f372b..0b19668 100644 --- a/tests/netx/unit/net/sourceforge/jnlp/cache/ResourceTrackerTest.java +++ b/tests/netx/unit/net/sourceforge/jnlp/cache/ResourceTrackerTest.java @@ -1,54 +1,70 @@ /* ResourceTrackerTest.java -Copyright (C) 2012 Red Hat, Inc. - -This file is part of IcedTea. - -IcedTea is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License as published by -the Free Software Foundation, version 2. - -IcedTea is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with IcedTea; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. + Copyright (C) 2012 Red Hat, Inc. + + This file is part of IcedTea. + + IcedTea is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as published by + the Free Software Foundation, version 2. + + IcedTea is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with IcedTea; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ package net.sourceforge.jnlp.cache; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.PrintStream; import java.io.UnsupportedEncodingException; +import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; - +import java.util.HashMap; +import net.sourceforge.jnlp.ServerAccess; +import net.sourceforge.jnlp.ServerLauncher; +import net.sourceforge.jnlp.Version; +import net.sourceforge.jnlp.runtime.JNLPRuntime; import net.sourceforge.jnlp.util.UrlUtils; - +import org.junit.AfterClass; import org.junit.Assert; +import org.junit.BeforeClass; import org.junit.Test; -/** Test various corner cases of the parser */ public class ResourceTrackerTest { + public static ServerLauncher testServer; + public static ServerLauncher testServerWithBrokenHead; + private static PrintStream backedUpStream; + private static ByteArrayOutputStream currentErrorStream; + private static final String nameStub1 = "itw-server"; + private static final String nameStub2 = "test-file"; + @Test public void testNormalizeUrl() throws Exception { URL[] u = getUrls(); @@ -58,13 +74,12 @@ public class ResourceTrackerTest { Assert.assertNull("first url should be null", u[0]); Assert.assertNull("first normalized url should be null", n[0]); for (int i = 1; i < CHANGE_BORDER; i++) { - Assert.assertTrue("url " + i + " must be equals too normlaized url " + i, u[i].equals(n[i])); + Assert.assertTrue("url " + i + " must be equals too normalized url " + i, u[i].equals(n[i])); } for (int i = CHANGE_BORDER; i < n.length; i++) { - Assert.assertFalse("url " + i + " must be normalized (and so not equals) too normlaized url " + i, u[i].equals(n[i])); + Assert.assertFalse("url " + i + " must be normalized (and so not equals) too normalized url " + i, u[i].equals(n[i])); } } - public static final int CHANGE_BORDER = 6; public static URL[] getUrls() throws MalformedURLException { @@ -97,4 +112,229 @@ public class ResourceTrackerTest { return n; } + + @BeforeClass + public static void redirectErr() { + if (backedUpStream == null) { + backedUpStream = System.err; + } + currentErrorStream = new ByteArrayOutputStream(); + System.setErr(new PrintStream(currentErrorStream)); + + } + + @AfterClass + public static void redirectErrBack() throws UnsupportedEncodingException { + ServerAccess.logErrorReprint(currentErrorStream.toString("utf-8")); + System.setErr(backedUpStream); + + } + + @BeforeClass + public static void onDebug() { + JNLPRuntime.setDebug(true); + } + + @AfterClass + public static void offDebug() { + JNLPRuntime.setDebug(false); + } + + @BeforeClass + public static void startServer() throws IOException { + testServer = ServerAccess.getIndependentInstance(System.getProperty("java.io.tmpdir"), ServerAccess.findFreePort()); + } + + @BeforeClass + public static void startServer2() throws IOException { + testServerWithBrokenHead = ServerAccess.getIndependentInstance(System.getProperty("java.io.tmpdir"), ServerAccess.findFreePort()); + testServerWithBrokenHead.setSupportingHeadRequest(false); + } + + @AfterClass + public static void stopServer() { + testServer.stop(); + } + + @AfterClass + public static void stopServer2() { + testServerWithBrokenHead.stop(); + } + + @Test + public void getUrlResponseCodeTestWorkingHeadRequest() throws IOException { + redirectErr(); + try { + File f = File.createTempFile(nameStub1, nameStub2); + int i = ResourceTracker.getUrlResponseCode(testServer.getUrl(f.getName()), new HashMap<String, String>(), "HEAD"); + Assert.assertEquals(HttpURLConnection.HTTP_OK, i); + f.delete(); + i = ResourceTracker.getUrlResponseCode(testServer.getUrl(f.getName()), new HashMap<String, String>(), "HEAD"); + Assert.assertEquals(HttpURLConnection.HTTP_NOT_FOUND, i); + } finally { + redirectErrBack(); + } + } + + @Test + public void getUrlResponseCodeTestNotWorkingHeadRequest() throws IOException { + redirectErr(); + try { + File f = File.createTempFile(nameStub1, nameStub2); + int i = ResourceTracker.getUrlResponseCode(testServerWithBrokenHead.getUrl(f.getName()), new HashMap<String, String>(), "HEAD"); + Assert.assertEquals(HttpURLConnection.HTTP_NOT_IMPLEMENTED, i); + f.delete(); + i = ResourceTracker.getUrlResponseCode(testServerWithBrokenHead.getUrl(f.getName()), new HashMap<String, String>(), "HEAD"); + Assert.assertEquals(HttpURLConnection.HTTP_NOT_IMPLEMENTED, i); + } finally { + redirectErrBack(); + } + } + + @Test + public void getUrlResponseCodeTestGetRequestOnNotWorkingHeadRequest() throws IOException { + redirectErr(); + try { + File f = File.createTempFile(nameStub1, nameStub2); + int i = ResourceTracker.getUrlResponseCode(testServerWithBrokenHead.getUrl(f.getName()), new HashMap<String, String>(), "GET"); + Assert.assertEquals(HttpURLConnection.HTTP_OK, i); + f.delete(); + i = ResourceTracker.getUrlResponseCode(testServerWithBrokenHead.getUrl(f.getName()), new HashMap<String, String>(), "GET"); + Assert.assertEquals(HttpURLConnection.HTTP_NOT_FOUND, i); + } finally { + redirectErrBack(); + } + } + + @Test + public void getUrlResponseCodeTestGetRequest() throws IOException { + redirectErr(); + try { + File f = File.createTempFile(nameStub1, nameStub2); + int i = ResourceTracker.getUrlResponseCode(testServer.getUrl(f.getName()), new HashMap<String, String>(), "GET"); + Assert.assertEquals(HttpURLConnection.HTTP_OK, i); + f.delete(); + i = ResourceTracker.getUrlResponseCode(testServer.getUrl(f.getName()), new HashMap<String, String>(), "GET"); + Assert.assertEquals(HttpURLConnection.HTTP_NOT_FOUND, i); + } finally { + redirectErrBack(); + } + } + + @Test + public void getUrlResponseCodeTestWrongRequest() throws IOException { + redirectErr(); + try { + File f = File.createTempFile(nameStub1, nameStub2); + Exception exception = null; + try { + ResourceTracker.getUrlResponseCode(testServer.getUrl(f.getName()), new HashMap<String, String>(), "SomethingWrong"); + } catch (Exception ex) { + exception = ex; + } + Assert.assertNotNull(exception); + exception = null; + f.delete(); + try { + ResourceTracker.getUrlResponseCode(testServer.getUrl(f.getName()), new HashMap<String, String>(), "SomethingWrong"); + } catch (Exception ex) { + exception = ex; + } + Assert.assertNotNull(exception);; + } finally { + redirectErrBack(); + } + + } + + @Test + public void findBestUrltest() throws IOException { + redirectErr(); + try { + File fileForServerWithHeader = File.createTempFile(nameStub1, nameStub2); + File versionedFileForServerWithHeader = new File(fileForServerWithHeader.getParentFile(), fileForServerWithHeader.getName() + "-2.0"); + versionedFileForServerWithHeader.createNewFile(); + + File fileForServerWithoutHeader = File.createTempFile(nameStub1, nameStub2); + File versionedFileForServerWithoutHeader = new File(fileForServerWithoutHeader.getParentFile(), fileForServerWithoutHeader.getName() + "-2.0"); + versionedFileForServerWithoutHeader.createNewFile(); + + ResourceTracker rt = new ResourceTracker(); + Resource r1 = Resource.getResource(testServer.getUrl(fileForServerWithHeader.getName()), null, UpdatePolicy.NEVER); + Resource r2 = Resource.getResource(testServerWithBrokenHead.getUrl(fileForServerWithoutHeader.getName()), null, UpdatePolicy.NEVER); + Resource r3 = Resource.getResource(testServer.getUrl(versionedFileForServerWithHeader.getName()), new Version("1.0"), UpdatePolicy.NEVER); + Resource r4 = Resource.getResource(testServerWithBrokenHead.getUrl(versionedFileForServerWithoutHeader.getName()), new Version("1.0"), UpdatePolicy.NEVER); + assertOnServerWithHeader(rt.findBestUrl(r1)); + assertVersionedOneOnServerWithHeader(rt.findBestUrl(r3)); + assertOnServerWithoutHeader(rt.findBestUrl(r2)); + assertVersionedOneOnServerWithoutHeader(rt.findBestUrl(r4)); + + fileForServerWithHeader.delete(); + Assert.assertNull(rt.findBestUrl(r1)); + assertVersionedOneOnServerWithHeader(rt.findBestUrl(r3)); + assertOnServerWithoutHeader(rt.findBestUrl(r2)); + assertVersionedOneOnServerWithoutHeader(rt.findBestUrl(r4)); + + versionedFileForServerWithHeader.delete(); + Assert.assertNull(rt.findBestUrl(r1)); + Assert.assertNull(rt.findBestUrl(r3)); + assertOnServerWithoutHeader(rt.findBestUrl(r2)); + assertVersionedOneOnServerWithoutHeader(rt.findBestUrl(r4)); + + versionedFileForServerWithoutHeader.delete(); + Assert.assertNull(rt.findBestUrl(r1)); + Assert.assertNull(rt.findBestUrl(r3)); + assertOnServerWithoutHeader(rt.findBestUrl(r2)); + Assert.assertNull(rt.findBestUrl(r4)); + + + fileForServerWithoutHeader.delete(); + Assert.assertNull(rt.findBestUrl(r1)); + Assert.assertNull(rt.findBestUrl(r3)); + Assert.assertNull(rt.findBestUrl(r2)); + Assert.assertNull(rt.findBestUrl(r4)); + } finally { + redirectErrBack(); + } + + } + + private void assertOnServerWithHeader(URL u) { + assertCommonComponentsOfUrl(u); + assertPort(u, testServer.getPort()); + } + + private void assertVersionedOneOnServerWithHeader(URL u) { + assertCommonComponentsOfUrl(u); + assertPort(u, testServer.getPort()); + assertVersion(u); + } + + private void assertOnServerWithoutHeader(URL u) { + assertCommonComponentsOfUrl(u); + assertPort(u, testServerWithBrokenHead.getPort()); + } + + private void assertVersionedOneOnServerWithoutHeader(URL u) { + assertCommonComponentsOfUrl(u); + assertPort(u, testServerWithBrokenHead.getPort()); + assertVersion(u); + } + + private void assertCommonComponentsOfUrl(URL u) { + Assert.assertTrue(u.getProtocol().equals("http")); + Assert.assertTrue(u.getHost().equals("localhost")); + Assert.assertTrue(u.getPath().contains(nameStub1)); + Assert.assertTrue(u.getPath().contains(nameStub2)); + ServerAccess.logOutputReprint(u.toExternalForm()); + } + + private void assertPort(URL u, int port) { + Assert.assertTrue(u.getPort() == port); + } + + private void assertVersion(URL u) { + Assert.assertTrue(u.getPath().contains("-2.0")); + Assert.assertTrue(u.getQuery().contains("version-id=1.0")); + } } diff --git a/tests/netx/unit/net/sourceforge/jnlp/util/HttpUtilsTest.java b/tests/netx/unit/net/sourceforge/jnlp/util/HttpUtilsTest.java new file mode 100644 index 0000000..08a6060 --- /dev/null +++ b/tests/netx/unit/net/sourceforge/jnlp/util/HttpUtilsTest.java @@ -0,0 +1,248 @@ +/* + Copyright (C) 2012 Red Hat, Inc. + + This file is part of IcedTea. + + IcedTea is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + IcedTea is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with IcedTea; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ +package net.sourceforge.jnlp.util; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.io.UnsupportedEncodingException; +import java.net.HttpURLConnection; +import java.net.URL; +import net.sourceforge.jnlp.ServerAccess; +import net.sourceforge.jnlp.ServerLauncher; +import org.junit.Assert; +import org.junit.Test; + +public class HttpUtilsTest { + + private static PrintStream backedUpStream; + private static ByteArrayOutputStream nwErrorStream; + + public static void redirectErr() { + if (backedUpStream == null) { + backedUpStream = System.err; + } + nwErrorStream = new ByteArrayOutputStream(); + System.setErr(new PrintStream(nwErrorStream)); + + } + + + public static void redirectErrBack() throws UnsupportedEncodingException { + ServerAccess.logErrorReprint(nwErrorStream.toString("utf-8")); + System.setErr(backedUpStream); + + } + + @Test + public void consumeAndCloseConnectionSilentlyTest() throws IOException { + redirectErr(); + try{ + Exception exception = null; + try { + HttpUtils.consumeAndCloseConnectionSilently(new HttpURLConnection(null) { + @Override + public void disconnect() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean usingProxy() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void connect() throws IOException { + throw new UnsupportedOperationException("Not supported yet."); + } + }); + } catch (Exception ex) { + ServerAccess.logException(ex); + exception = ex; + } + Assert.assertNull("no exception expected - was" + exception, exception); + + + + try { + HttpUtils.consumeAndCloseConnectionSilently(new HttpURLConnection(new URL("http://localhost/blahblah")) { + @Override + public void disconnect() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean usingProxy() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void connect() throws IOException { + throw new UnsupportedOperationException("Not supported yet."); + } + }); + } catch (Exception ex) { + ServerAccess.logException(ex); + exception = ex; + } + Assert.assertNull("no exception expected - was" + exception, exception); + + ServerLauncher serverLauncher =ServerAccess.getIndependentInstance(System.getProperty("user.dir"), ServerAccess.findFreePort()); + try{ + try { + HttpUtils.consumeAndCloseConnectionSilently(new HttpURLConnection(serverLauncher.getUrl("definitelyNotExisitnfFileInHappyMemoryOfAdam")) { //:) + @Override + public void disconnect() { + + } + + @Override + public boolean usingProxy() { + return false; + } + + @Override + public void connect() throws IOException { + + } + }); + } catch (Exception ex) { + ServerAccess.logException(ex); + exception = ex; + } + Assert.assertNull("no exception expected - was" + exception, exception); + }finally{ + try{ + serverLauncher.stop(); + }catch(Exception ex){ + ServerAccess.logException(ex); + } + } + }finally{ + redirectErrBack(); + } + } + + @Test + public void consumeAndCloseConnectionTest() throws IOException { + redirectErr(); + try{ + Exception exception = null; + try { + HttpUtils.consumeAndCloseConnection(new HttpURLConnection(null) { + @Override + public void disconnect() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean usingProxy() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void connect() throws IOException { + throw new UnsupportedOperationException("Not supported yet."); + } + }); + } catch (Exception ex) { + ServerAccess.logException(ex); + exception = ex; + } + Assert.assertNotNull("exception expected - wasnt" + exception, exception); + + + + try { + HttpUtils.consumeAndCloseConnection(new HttpURLConnection(new URL("http://localhost/blahblah")) { + @Override + public void disconnect() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public boolean usingProxy() { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void connect() throws IOException { + throw new UnsupportedOperationException("Not supported yet."); + } + }); + } catch (Exception ex) { + ServerAccess.logException(ex); + exception = ex; + } + Assert.assertNotNull("exception expected - wasnt" + exception, exception); + + ServerLauncher s =ServerAccess.getIndependentInstance(System.getProperty("user.dir"), ServerAccess.findFreePort()); + try{ + try { + HttpUtils.consumeAndCloseConnection(new HttpURLConnection(s.getUrl("blahblahblah")) { + @Override + public void disconnect() { + + } + + @Override + public boolean usingProxy() { + return false; + } + + @Override + public void connect() throws IOException { + + } + }); + } catch (Exception ex) { + ServerAccess.logException(ex); + exception = ex; + } + Assert.assertNotNull(" exception expected - wasnt" + exception, exception); + }finally{ + try{ + s.stop(); + }catch(Exception ex){ + ServerAccess.logException(ex); + } + } + }finally{ + redirectErrBack(); + } + } +} diff --git a/tests/netx/unit/net/sourceforge/jnlp/util/UrlUtilsTest.java b/tests/netx/unit/net/sourceforge/jnlp/util/UrlUtilsTest.java index 251dfb2..b6cf760 100644 --- a/tests/netx/unit/net/sourceforge/jnlp/util/UrlUtilsTest.java +++ b/tests/netx/unit/net/sourceforge/jnlp/util/UrlUtilsTest.java @@ -1,3 +1,40 @@ +/* + Copyright (C) 2012 Red Hat, Inc. + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +IcedTea is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + package net.sourceforge.jnlp.util; import static org.junit.Assert.assertEquals; diff --git a/tests/test-extensions/net/sourceforge/jnlp/ServerLauncher.java b/tests/test-extensions/net/sourceforge/jnlp/ServerLauncher.java index 30904b8..b580bb1 100644 --- a/tests/test-extensions/net/sourceforge/jnlp/ServerLauncher.java +++ b/tests/test-extensions/net/sourceforge/jnlp/ServerLauncher.java @@ -57,7 +57,18 @@ public class ServerLauncher implements Runnable { private final Integer port; private final File dir; private ServerSocket serverSocket; + private boolean supportingHeadRequest = true; + public void setSupportingHeadRequest(boolean supportsHead) { + this.supportingHeadRequest = supportsHead; + } + + public boolean isSupportingHeadRequest() { + return supportingHeadRequest; + } + + + public String getServerName() { return serverName; } @@ -102,10 +113,12 @@ public class ServerLauncher implements Runnable { try { serverSocket = new ServerSocket(port); while (running) { - new TinyHttpdImpl(serverSocket.accept(), dir, port); + TinyHttpdImpl server = new TinyHttpdImpl(serverSocket.accept(), dir, port,false); + server.setSupportingHeadRequest(isSupportingHeadRequest()); + server.start(); } } catch (Exception e) { - e.printStackTrace(); + ServerAccess.logException(e); } finally { running = false; } diff --git a/tests/test-extensions/net/sourceforge/jnlp/TinyHttpdImpl.java b/tests/test-extensions/net/sourceforge/jnlp/TinyHttpdImpl.java index 0334d1c..561926a 100644 --- a/tests/test-extensions/net/sourceforge/jnlp/TinyHttpdImpl.java +++ b/tests/test-extensions/net/sourceforge/jnlp/TinyHttpdImpl.java @@ -42,6 +42,7 @@ import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStreamReader; +import java.net.HttpURLConnection; import java.net.Socket; import java.net.SocketException; import java.net.URLDecoder; @@ -55,25 +56,41 @@ import java.util.StringTokenizer; * When resource starts with XslowX prefix, then resouce (without XslowX) * is returned, but its delivery is delayed */ -class TinyHttpdImpl extends Thread { +public class TinyHttpdImpl extends Thread { Socket c; private final File dir; private final int port; private boolean canRun = true; private static final String XSX = "/XslowX"; - + private boolean supportingHeadRequest = true; + public TinyHttpdImpl(Socket s, File f, int port) { + this(s, f, port, true); + } + public TinyHttpdImpl(Socket s, File f, int port, boolean start) { c = s; this.dir = f; this.port = port; - start(); + if (start){ + start(); + } } public void setCanRun(boolean canRun) { this.canRun = canRun; } + public void setSupportingHeadRequest(boolean supportsHead) { + this.supportingHeadRequest = supportsHead; + } + + public boolean isSupportingHeadRequest() { + return supportingHeadRequest; + } + + + public int getPort() { return port; } @@ -92,6 +109,11 @@ class TinyHttpdImpl extends Thread { boolean isGetRequest = s.startsWith("GET"); boolean isHeadRequest = s.startsWith("HEAD"); + + if (isHeadRequest && !isSupportingHeadRequest()){ + o.writeBytes("HTTP/1.0 "+HttpURLConnection.HTTP_NOT_IMPLEMENTED+" Not Implemented\n"); + continue; + } if (isGetRequest || isHeadRequest ) { StringTokenizer t = new StringTokenizer(s, " "); @@ -120,7 +142,7 @@ class TinyHttpdImpl extends Thread { } else if (p.toLowerCase().endsWith(".jar")) { content = ct + "application/x-jar\n"; } - o.writeBytes("HTTP/1.0 200 OK\nContent-Length:" + l + "\n" + content + "\n"); + o.writeBytes("HTTP/1.0 "+HttpURLConnection.HTTP_OK+" OK\nContent-Length:" + l + "\n" + content + "\n"); if (isHeadRequest) { continue; // Skip sending body |