Hi All, So the plot thickens - under JDK 1.4.1 the behaviour is as expected:
java version "1.3.1": 2. code is 0 3. code is text/html; charset=iso-8859-1 4. code is 404 1. code is [EMAIL PROTECTED] java version "1.4.1_03": 2. code is 0 3. code is text/html; charset=iso-8859-1 4. code is 404 Exception in thread "main" java.io.FileNotFoundException: http://localhost/broken/something/somewhere/ at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:713) at sun.net.www.protocol.http.HttpURLConnection.getHeaderField(HttpURLConnection.java:1178) at java.net.HttpURLConnection.getHeaderFieldDate(HttpURLConnection.java:309) So, something's changed inbetween JDK versions. I'll make some updates to the patch to take this into account. Cheers, Marcus On Fri, Jun 27, 2003 at 06:53:01PM +0200, Marcus Crafter wrote: > Hi All, > > Hope all is well! > > Have been experiencing some interesting behaviour with the source resolver > today, and in particular the java.net.HttpURLConnection implementation. > > Have a look at this code: > > URL url = new URL("http://localhost:8080/something/somewhere/"); > URLConnection conn = url.openConnection(); > HttpURLConnection c = (HttpURLConnection) conn; > > System.out.println("1." + c.getInputStream()); > System.out.println("2." + c.getLastModified()); > System.out.println("3." + c.getContentType()); > System.out.println("4." + c.getResponseCode()); > > Assuming that the URL points to a valid server, but a bogus path - then the > following code raises a FileNotFoundException. However, if you move the > call to getInputStream() to be after getResponseCode() then no exception is > raised and and you'll receive a valid InputStream containing the error > page from the server. > > This behaviour currently causes the SourceResolver to return server error > pages as valid data when resolving a particular URI. From what I can tell, > other than examine the content returned, there's currently no easy way to > tell whether the SourceResolver resolved the document correctly or not. > > I've attached a patch that examines the return code of the > HttpURLConnection and throws a SourceException if the code is not within > the valid range of 200-206 as defined by the HTTP RFC. > > This fixes the problem, but prevents people from parsing error pages as > Source objects (if anyone did that before?). Perhaps someone could take a > look at the patch as maybe there's a better solution? Any ideas? If not > let me know, and I'll apply the patch attached. > > Cheers, > > Marcus > > > -- > ..... > ,,$$$$$$$$$, Marcus Crafter > ;$' '$$$$: Computer Systems Engineer > $: $$$$: ManageSoft GmbH > $ o_)$$$: 82-84 Mainzer Landstrasse > ;$, _/\ &&:' 60327 Frankfurt Germany > ' /( &&& > \_&&&&' > &&&&. > &&&&&&&: > Index: src/java/org/apache/excalibur/source/impl/URLSource.java > =================================================================== > RCS file: > /home/cvs/avalon-excalibur/sourceresolve/src/java/org/apache/excalibur/source/impl/URLSource.java,v > retrieving revision 1.24 > diff -u -r1.24 URLSource.java > --- src/java/org/apache/excalibur/source/impl/URLSource.java 4 Apr 2003 16:36:51 > -0000 1.24 > +++ src/java/org/apache/excalibur/source/impl/URLSource.java 27 Jun 2003 16:33:57 > -0000 > @@ -54,8 +54,10 @@ > */ > package org.apache.excalibur.source.impl; > > +import java.io.BufferedReader; > import java.io.IOException; > import java.io.InputStream; > +import java.io.InputStreamReader; > import java.lang.reflect.Method; > import java.net.HttpURLConnection; > import java.net.URL; > @@ -278,9 +280,77 @@ > return input; > } > } > + if (m_connection instanceof HttpURLConnection) { > + validateConnection((HttpURLConnection)m_connection); > + } > input = m_connection.getInputStream(); > m_connection = null; // make sure a new m_connection is created next time > return input; > + } > + > + /** > + * Method which ascertains whether a given [EMAIL PROTECTED] HttpURLConnection} > is > + * able to return valid data or not. > + * > + * <p>Valid return codes from HTTP servers are defined > + * <a > href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2">here</a> > + * to be in the range 200-206 (inclusive)</p> > + * > + * <p>This method checks that the given connection object has a return code > + * within this range, and if not, raises a [EMAIL PROTECTED] SourceException} > with the return > + * code and any data sent by the server</p> > + * > + * @param conn a [EMAIL PROTECTED] HttpURLConnection} instance > + * @throws SourceException if the request did not succeed > + * @exception IOException if an error occurs > + */ > + private void validateConnection(final HttpURLConnection conn) > + throws SourceException, IOException { > + final int responseCode = conn.getResponseCode(); > + final int[] SUCCESS_CODES = > + { > + HttpURLConnection.HTTP_OK, > + HttpURLConnection.HTTP_CREATED, > + HttpURLConnection.HTTP_ACCEPTED, > + HttpURLConnection.HTTP_NOT_AUTHORITATIVE, > + HttpURLConnection.HTTP_NO_CONTENT, > + HttpURLConnection.HTTP_RESET, > + HttpURLConnection.HTTP_PARTIAL, > + }; > + > + for (int i = 0; i < SUCCESS_CODES.length; ++i) { > + if (responseCode == SUCCESS_CODES[i]) > + return; > + } > + > + // response from the server was not successful, return an error to the > caller > + final String responseText = readString(conn.getInputStream()); > + > + throw new SourceException( > + "Request for " + conn.getURL() + " was unsuccessful " + > + "(" + responseCode + ")" + ", response from server:\n" + responseText > + ); > + } > + > + /** > + * Helper method to read an [EMAIL PROTECTED] InputStream} into a [EMAIL > PROTECTED] String}. > + * > + * @param stream input [EMAIL PROTECTED] InputStream} > + * @return a contents in the [EMAIL PROTECTED] InputStream} as a [EMAIL > PROTECTED] String} > + * @exception IOException if an error occurs > + */ > + private String readString(final InputStream stream) throws IOException { > + final BufferedReader is = > + new BufferedReader(new InputStreamReader(stream)); > + String line; > + StringBuffer resp = new StringBuffer(); > + > + while ((line = is.readLine()) != null) { > + resp.append(line); > + resp.append('\n'); > + } > + > + return resp.toString(); > } > > private static boolean checkedURLClass = false; > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] -- ..... ,,$$$$$$$$$, Marcus Crafter ;$' '$$$$: Computer Systems Engineer $: $$$$: ManageSoft GmbH $ o_)$$$: 82-84 Mainzer Landstrasse ;$, _/\ &&:' 60327 Frankfurt Germany ' /( &&& \_&&&&' &&&&. &&&&&&&: --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
