From mboxrd@z Thu Jan 1 00:00:00 1970 From: francis@ecal.com To: java-gnats@sourceware.cygnus.com Subject: libgcj/1165: HTTP client code treats headers as body Date: Wed, 20 Dec 2000 12:20:00 -0000 Message-id: <20000309185830.30117.qmail@sourceware.cygnus.com> X-SW-Source: 2000-q4/msg00953.html List-Id: >Number: 1165 >Category: libgcj >Synopsis: HTTP client code treats headers as body >Confidential: no >Severity: serious >Priority: medium >Responsible: warrenl >State: closed >Class: sw-bug >Submitter-Id: net >Arrival-Date: Wed Dec 20 12:16:41 PST 2000 >Closed-Date: Thu Aug 10 02:15:05 PDT 2000 >Last-Modified: Thu Aug 10 02:16:02 PDT 2000 >Originator: francis@ecal.com >Release: libgcj-2.95.2 >Organization: >Environment: RedHat 6.1 >Description: If I open an HTTP connection, and read from the input stream, I don't just get the body of the response; I get the headers, too. The only way around this is to ask for the headers first, and then read from the stream. >How-To-Repeat: The attached tarfile contains a patch and a Java source file (DemonstrateChunked.java). Compile and run DemonstrateChunked.java; it will make an HTTP request and then print out what it reads from the input stream; you will see the status line and headers before the body of the resource. >Fix: Apply the patch included in the tarfile. >Release-Note: >Audit-Trail: Formerly PR java.net/170 From: Bryce McKinlay To: francis@ecal.com Cc: java-gnats@sourceware.cygnus.com, warrenl@cygnus.com Subject: Re: java.net/170: HTTP client code treats headers as body Date: Fri, 10 Mar 2000 11:00:51 +1300 Francis, in future could you provide a ChangeLog entry with your patches? Thanks. Otherwise, these look fine to me. What do you think, Warren? [ bryce ] From: Bryce McKinlay To: francis@ecal.com Cc: java-gnats@sourceware.cygnus.com Subject: Re: java.net/170: HTTP client code treats headers as body Date: Fri, 10 Mar 2000 15:21:09 +1300 Actually, the second part of the 170 patch is wrong, I think. The http status line is what is returned by getHeaderField(0), so it shouldn't be skipped. regards [ bryce ] @@ -247,6 +246,9 @@ boolean gotnl = false; byte[] ch = new byte[1]; ch[0] = (byte) '\n'; + + boolean isFirst=true; + while (true) { // Check for leftover byte from non-'\n' after a '\r'. @@ -266,6 +268,13 @@ } } line = line + new String(buf, 0, i); + + if (isFirst) // skip the status line + { + isFirst=false; + line=""; + continue; + } From: John Stracke To: Bryce McKinlay Cc: java-gnats@sourceware.cygnus.com Subject: Re: java.net/170: HTTP client code treats headers as body Date: Thu, 09 Mar 2000 21:45:58 -0500 Bryce McKinlay wrote: > Actually, the second part of the 170 patch is wrong, I think. The http status > line is what is returned by getHeaderField(0), so it shouldn't be skipped. But it's not a header. Hmm...ah, here we are: the status line is accessible through methods of java.net.HttpURLConnection: getResponseCode() and getResponseMessage()...though there's no method to get the protocol version. gcj doesn't currently implement getResponseCode() or getResponseMessage(). I'll write them tonight or tomorrow. -- /===============================================================\ |John Stracke | http://www.ecal.com |My opinions are my own. | |Chief Scientist |==============================================| |eCal Corp. |"This [OLE] isn't an API, this is a shaggy dog| |francis@ecal.com|story in C!" -- Unknown | \===============================================================/ From: John Stracke To: Bryce McKinlay , java-gnats@sourceware.cygnus.com Cc: Subject: Re: java.net/170: HTTP client code treats headers as body Date: Thu, 09 Mar 2000 22:05:30 -0500 John Stracke wrote: > gcj doesn't currently implement getResponseCode() or getResponseMessage(). I'll > write them tonight or tomorrow. Here's the updated patch: --- libgcj-2.95.1-orig/libjava/gnu/gcj/protocol/http/Connection.java Thu Apr 15 17:33:38 1999 +++ libgcj-2.95.1/libjava/gnu/gcj/protocol/http/Connection.java Thu Mar 9 21:58:05 2000 @@ -46,6 +46,18 @@ requestProperties = (Hashtable) defRequestProperties.clone(); } + public int getResponseCode() throws IOException + { + getHttpHeaders(); + return responseCode; + } + + public String getResponseMessage() throws IOException + { + getHttpHeaders(); + return responseMessage; + } + // Override method in URLConnection. public static void setDefaultRequestProperty(String key, String value) { @@ -94,7 +106,7 @@ PrintWriter out = new PrintWriter(sock.getOutputStream()); // Send request including any request properties that were set. - out.print(getRequestMethod() + " " + url.getFile() + " HTTP/1.1\n"); + out.print(getRequestMethod() + " " + url.getFile() + " HTTP/1.0\n"); out.print("Host: " + url.getHost() + ":" + port + "\n"); Enumeration reqKeys = requestProperties.keys(); Enumeration reqVals = requestProperties.elements(); @@ -137,8 +149,7 @@ if (! doInput) throw new ProtocolException("Can't open InputStream if doInput is false"); - if (bufferedIn == null) - bufferedIn = new BufferedInputStream(sock.getInputStream()); + getHttpHeaders(); return bufferedIn; } @@ -247,6 +258,9 @@ boolean gotnl = false; byte[] ch = new byte[1]; ch[0] = (byte) '\n'; + + boolean isFirst=true; + while (true) { // Check for leftover byte from non-'\n' after a '\r'. @@ -266,6 +280,25 @@ } } line = line + new String(buf, 0, i); + + if (isFirst) // parse the status line + { + isFirst=false; + + int space1=line.indexOf(' '); + if (space1<0) + continue; + + int space2=line.indexOf(' ',space1+1); + if (space2<0) + continue; + + String responseCodeStr=line.substring(space1+1,space2); + responseCode=(new Integer(responseCodeStr)).intValue(); + responseMessage=line.substring(space2+1); + line=""; + continue; + } // A '\r' '\n' combo indicates the end of the header entry. // If it wasn't found, cycle back through the loop and append -- /==============================================================\ |John Stracke | http://www.ecal.com |My opinions are my own.| |Chief Scientist |=============================================| |eCal Corp. |Never underestimate the power of human | |francis@ecal.com|stupidity. --I forget who | \==============================================================/ From: Bryce McKinlay To: John Stracke , java-gnats@sourceware.cygnus.com Cc: Subject: Re: java.net/170: HTTP client code treats headers as body Date: Fri, 10 Mar 2000 16:09:52 +1300 John Stracke wrote: > Bryce McKinlay wrote: > > > Actually, the second part of the 170 patch is wrong, I think. The http status > > line is what is returned by getHeaderField(0), so it shouldn't be skipped. > > But it's not a header. Hmm...ah, here we are: the status line is accessible > through methods of java.net.HttpURLConnection: getResponseCode() and > getResponseMessage()...though there's no method to get the protocol version. Sure, its not *really* a header, but if you call getResponseField(0) on the JDK 1.2.2, you'll get back the status line. We usually try to copy the JDK's behaviour in these situations, even if it isnt formally specified in the API documentation. > gcj doesn't currently implement getResponseCode() or getResponseMessage(). I'll write them tonight or > tomorrow. > Cool. A couple of points: 1. Its probibly best to work on the latest version of libgcj (I noticed your patches said 2.95.1 on them). There have been some changes to the URLConnection stuff since 2.95.1, and using cvs makes generating patches a lot easier anyway. 2. Significant changes require a copyrite assignment to be filled out (see http://sourceware.cygnus.com/java/contrib.html ). Best to contact Tom Tromey or Anthony Green about this as the procedure will be changing given the FSF/classpath merger. regards [ bryce ] From: John Stracke To: Bryce McKinlay , java-gnats@sourceware.cygnus.com Cc: Subject: Re: java.net/170: HTTP client code treats headers as body Date: Thu, 09 Mar 2000 22:07:01 -0500 John Stracke wrote: > gcj doesn't currently implement getResponseCode() or > getResponseMessage(). I'll > write them tonight or tomorrow. > Oh, and here's the updated test program that prints the response code & message along with the headers: import java.net.*; import java.io.*; public class DemonstrateChunked { public static void main(String args[]) { URL url; try { url=new URL(" http://impp.research.ecal.com/demonstrate.php3 "); } catch (java.net.MalformedURLException malf) { System.err.println("Malformed URL: "+malf.getMessage()); return; } DataInputStream in; try { URLConnection conn=url.openConnection(); if (conn instanceof HttpURLConnection) { HttpURLConnection httpConn=(HttpURLConnection)conn; int status=httpConn.getResponseCode(); String statusStr=httpConn.getResponseMessage(); System.out.println("status=="+status); System.out.println("statusStr=="+statusStr); } else System.out.println("(Not an HttpURLConnection)"); InputStream _in=conn.getInputStream(); in=new DataInputStream(_in); } catch (IOException io) { System.err.println("Can't fetch URL: "+io.getMessage()); return; } String line; try { while ((line=in.readLine())!=null) System.out.println(line); } catch (IOException io) { System.out.println("Can't read line from URL: "+io.getMessage()); return; } } }; -- /==============================================================\ |John Stracke | http://www.ecal.com |My opinions are my own.| |Chief Scientist |=============================================| |eCal Corp. |They prayed for their fates to be quick, | |francis@ecal.com|painless, and, ideally, someone else's. | \==============================================================/ From: Bryce McKinlay To: John Stracke , java-gnats@sourceware.cygnus.com Cc: Subject: Re: java.net/170: HTTP client code treats headers as body Date: Fri, 10 Mar 2000 16:25:38 +1300 John Stracke wrote: > + public int getResponseCode() throws IOException > + { > + getHttpHeaders(); > + return responseCode; > + } For efficiency we should change all the getHttpHeaders() calls to: if (! gotHeaders) getHttpHeaders(); and remove the gotHeaders check from getHttpHeaders(). This avoids the overhead of the extra method call in the common case. > + responseCode=(new Integer(responseCodeStr)).intValue(); Integer.parseInt(responseCodeStr); would be more efficient here. regards [ bryce ] From: Warren Levy To: Bryce McKinlay , John Stracke Cc: java-gnats@sourceware.cygnus.com Subject: Re: java.net/170: HTTP client code treats headers as body Date: Fri, 10 Mar 2000 02:20:44 -0800 (PST) On Fri, 10 Mar 2000, Bryce McKinlay wrote: > Francis, in future could you provide a ChangeLog entry with your patches? > Thanks. Otherwise, these look fine to me. What do you think, Warren? Sorry, I've been in the middle of something else today and have only been able to give this and java.net/169 a quick glance. I'll check them out on Friday and let you know if I see any further changes needed. Thanks for finding/fixing these! --warrenl From: John Stracke To: Bryce McKinlay Cc: java-gnats@sourceware.cygnus.com Subject: Re: java.net/170: HTTP client code treats headers as body Date: Fri, 10 Mar 2000 09:15:00 -0500 Bryce McKinlay wrote: > Sure, its not *really* a header, but if you call getResponseField(0) on the JDK > 1.2.2, you'll get back the status line. Huh. OK, then. I'm on my way to work now; I'll make the changes when I can. > We usually try to copy the JDK's behaviour > in these situations, even if it isnt formally specified in the API documentation. Right, makes sense. -- /==============================================================\ |John Stracke | http://www.ecal.com |My opinions are my own.| |Chief Scientist |=============================================| |eCal Corp. |This space intentionally left blank. | |francis@ecal.com| | \==============================================================/ State-Changed-From-To: open->closed State-Changed-By: bryce State-Changed-When: Thu Aug 10 02:15:05 2000 State-Changed-Why: Fix checked in to cvs: http://sources.redhat.com/ml/java-patches/2000-q3/msg00096.html From: bryce@albatross.co.nz To: francis@ecal.com, java-gnats@sourceware.cygnus.com, warrenl@cygnus.com Cc: Subject: Re: java.net/170 Date: 10 Aug 2000 09:15:05 -0000 Synopsis: HTTP client code treats headers as body State-Changed-From-To: open->closed State-Changed-By: bryce State-Changed-When: Thu Aug 10 02:15:05 2000 State-Changed-Why: Fix checked in to cvs: http://sources.redhat.com/ml/java-patches/2000-q3/msg00096.html http://sources.redhat.com/cgi-bin/gnatsweb.pl?cmd=view&pr=170&database=java >Unformatted: ----gnatsweb-attachment---- Content-Type: application/x-tar; name="headers.tar.gz" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="headers.tar.gz" H4sICJX0xzgAA2hlYWRlcnMudGFyAO1WbW/bNhDOV+lXXP0l8mzrxbKt2IGBdMmGBmjQYt0+ZcFA S5TFRiYFikoWFPnvO1LyS1q02YZ2wwY+Hyz6jrx77kg91AXdCF4rSRQ9Lxp+SzP/PbkjR18TYRSG s8nkKEQks+1zap6IaDINj8IknEXJLBmPcRxNY3RD+FVZfAZNrYgEOMol4SmrPzvvOf9/FGxTCalA 77nPqfK/O3UPTUxoi1s1q5KlkJakruHikyMDH1xAdLOwoQofd4JlsCGMe++UZHwNRK7r65u+mfrB dX756TU0ssTojpIP2qIdaFlyeg/o9XqFUtUiCJBQ5UtaUyLTwqcpKf1UbIJsz8Oviiru9U9d5xFS otICvF1FV6TMhdzQDEP+8HtKK8UER2Jl3t8mffdQK7rxqZR+hVRVyb3ebpmmsoDeQK/w11Rd0bom a+r1dTq9WlLVSK5zYykXRJFLXjUKi6ZkA4x/VCBGOxec09TQSHG4xJp9UVG+t3vb2IehfmN8qedr Egf23Vx06859xMDDZU8ac/lm3wUmvtiDc8KPFeRUr+u6gAfi2R50+10yTk+f1H5fsJKC52nPknHc U5K9xjHGebHkTVn2XcfpiIhG7Yjo+X+hhsOlXQ06kyEEuRSbP1+M/vvoPp66//Z7+q1QYGOorEeV buw3yvGc/ifjaaf/Wv7RH8VxEln9/ycwGo3wvVit0/ejsT+f+tFISLYO0KQFNFjzJkBfUEmhRCrK QEtysBcq87Hg/Fw08LKSEE0hShZxvIhPIJrP5+5gMHga/W8EvtLbM4coXkxPFmEEYzwy7tkZjKI4 GZ7AQD8SODtzwbytwHLwXkAmjAa2tw1CFVLcg9bHt13GnYJsNUJL8BPBxUhdGGA15KSsqb5jRtss qybPqaTZJYflElr9GrXpDl0m6/c7w16Za5HefiLmmGCgI6D9FbbkVft+apGHvTYdxDd2FCrTkvEk Gc5gMJ7MhnPTEsNFiJISDmuheIl0TCFduNWDotc3gJra0jT/o5vOmxbX4Q16PG3uw/Gv/BjZtfy2 UVn9I5O1WirZUO2EA6HXtt0O4DeCEwRwXtD0FvBqhZLmStxRaZK2uswFH+ksQHKFDoIp5bHfljab mdJmJ8MoNrU5bdxHM9K/Rt+XrcwPTDntTaQ3agjhEFjf0Hf05nW8+4Cc6ltW4Qmh5tOlqU0EnNay HjjOtsauc2gxN1ivZ8Z4JyvGTfVOR6gt9aWhb9qGF/1mJfCKzhheYbQ22SjPQORm2MowWvC29NvV lzkwBfekNnewaHg2hPQhxb6uCHZQH+hmXZjVpRAVEIxGKjzD2f/2srKwsLCwsLCwsLCwsLCwsLCw sLCwsLCwsLCwsPgi/gAFPIQeACgAAA==