classpath-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[cp-patches] [PATCH] Fix PR classpath/24086, PR classpath/24091, PR clas


From: David Daney
Subject: [cp-patches] [PATCH] Fix PR classpath/24086, PR classpath/24091, PR classpath/24104 et al. ...
Date: Tue, 11 Oct 2005 17:19:37 -0700
User-agent: Mozilla Thunderbird 1.0.7-1.1.fc3 (X11/20050929)

This is the new version of my HTTP patch. It keeps promoting (near) silence from the approvers, and I keep finding and fixing new bugs. Also it has been about a week and I fixed another bug, so I thought I would post the current version.

This patch is a partial rewrite of the gnu/java/net/protocol/http package.

It fixes:
* classpath/24086 - HttpURLConnection broken for large response bodies.
* classpath/24091 - HttpURLConnection sends too much data on POST.
* classpath/24104 - HttpUrlConnection header map screwed up.
* Failure on unsolicited 100 Continue response.
* Broken logic for connection re-use.
* Unexpected close by server of re-used connections throws IOException.

The main problem was that response bodies were being buffered in memory with ResponseBodyReader and friends.

The patch gets rid of the buffering of response body data and controls access to the connection socket with a new class (LimitedLengthInputStream). The LimitedLengthInputStream prevents the client from reading too much from or closing the connection's socket. If connection keep-alives are enabled, the LimitedLengthInputStream also controls returning the connection to the connection pool when it is idle.

I also got rid of the gnu/java/net/protocol/http/event package as it is not used for anything.

The rest of the fixes are quite intertwined with the rest of the rewrite so so I threw them in as well.

Tested with gcj(20050927)+mauve+jacks on i686-pc-linux-gnu with no regressions. Additional ad hoc testing to verify connection re-use with Connection: keep-alive for multiple GET and POST requests.

OK to commit?

2005-10-1  David Daney  <address@hidden>

        PR classpath/24086, PR classpath/24091, PR classpath/24104:
        * gnu/java/net/protocol/http/ByteArrayResponseBodyReader.java: Removed.
        * gnu/java/net/protocol/http/ResponseBodyReader.java: Removed.
        * gnu/java/net/protocol/http/event/ConnectionEvent.java: Removed.
        * gnu/java/net/protocol/http/event/ConnectionListener.java: Removed.
        * gnu/java/net/protocol/http/event/RequestEvent.java: Removed.
        * gnu/java/net/protocol/http/event/RequestListener.java: Removed.
        * gnu/java/net/protocol/http/event/package.html: Removed.
        * gnu/java/net/protocol/http/HTTPConnection.java: Cleaned up imports.
        (connectionListeners): Removed.
        (requestListeners): Removed.
        (pool): New field.
        (Constructor): Don't initialize connectionListeners or
        requestListeners.
        (useCount): New field.
        (getPoolKey): New method.
        (setPool): New method.
        (release): New method.
        (newRequest): Don't call fireRequestEvent. Use StringBuilder instead
        of StringBuffer.
        (close): Don't call fireConnectionEvent.
        (getURI):Use StringBuilder instead of StringBuffer.
        (addConnectionListener): Removed.
        (removeConnectionListener): Removed.
        (fireConnectionEvent): Removed.
        (addRequestListener): Removed.
        (removeRequestListener): Removed.
        (fireRequestEvent): Removed.
        * gnu/java/net/protocol/http/HTTPURLConnection.java:Cleaned up imports.
        (connectionPool): Changed type to LinkedHashMap.
        (maxConnections): Made static.
        (responseSink): Changed type to InputStream.
        (errorSink): Likewise.
        (connect): Eliminate reader.  Get responseSink from response.
        (getConnection): Rewrote.
        (getHeaderFields): Use null as key for status line.  Return
        unmodifiable Map.
        * gnu/java/net/protocol/http/Headers.java: Extend LinkedHashMap,
        instead of implement Map.
        (headers): Removed.
        (Constructor): Do not initialize headers.
        (size): Removed.
        (isEmpth): Removed.
        (containsKey): Rewrote.
        (containsValue): Removed.
        (get): Call super.get().
        (getValue): Likewise.
        (getLongValue): New method.
        (put): Call super.put().
        (remove): Call super.remove().
        (putAll): Rewrote.
        (clear): Removed.
        (keySet): Call super.keySet().
        (values): Removed.
        (entrySet): Call super.entrySet().
        (equals): Removed.
        (hashCode): Removed.
        (parse): Use StringBuilder instead of StringBuffer.
        (addValue): Call super.* instead of headers.*.
        * gnu/java/net/protocol/http/LimitedLengthInputStream.java: New class.
        * gnu/java/net/protocol/http/Request.java: Cleaned up imports.
        (responseBodyReader): Removed.
        (setResponseBodyReader): Removed.
        (dispatch): Don't create LineInputStream.  Don't call fireRequestEvent.
        Don't append CRLF to Request body.  Handle unsolicited 100 Continue
        response.
        (readResponse): Rewrote.
        (readResponseBody): Renamed to ...
        (createResponseBodyStream): ... And rewritten.
        (parseAuthParams): Use StringBuilder instead of StringBuffer.
        (getNonceCount): Likewise.
        (handleSetCookie): Likewise.
        * gnu/java/net/protocol/http/Response.java: Cleaned up imports.
        (codeClass): Removed.
        (body): New field.
        (Constructor): Don't initialize codeClass.  Initialize body.
        (getCodeClass): Rewrote.
        (getLongHeader): New method.
        (getBody): New method.
        * gnu/java/net/protocol/http/ChunkedInputStream.java (read): Use
        StringBuilder instead of StringBuffer.
        * gnu/java/net/protocol/http/Cookie.java (toString): Use StringBuilder
        instead of StringBuffer.
Index: gnu/java/net/protocol/http/ByteArrayResponseBodyReader.java
===================================================================
RCS file: gnu/java/net/protocol/http/ByteArrayResponseBodyReader.java
diff -N gnu/java/net/protocol/http/ByteArrayResponseBodyReader.java
--- gnu/java/net/protocol/http/ByteArrayResponseBodyReader.java 2 Jul 2005 
20:32:13 -0000       1.2
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,123 +0,0 @@
-/* Authenticator.java --ByteArrayResponseBodyReader.java --
-   Copyright (C) 2004 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath 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.
- 
-GNU Classpath 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 GNU Classpath; 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 gnu.java.net.protocol.http;
-
-/**
- * Simple response body reader that stores content in a byte array.
- *
- * @author Chris Burdess (address@hidden)
- */
-public class ByteArrayResponseBodyReader
-  implements ResponseBodyReader
-{
-
-  /**
-   * The content.
-   */
-  protected byte[] content;
-
-  /**
-   * The position in the content at which the next write will occur.
-   */
-  protected int pos;
-
-  /**
-   * The length of the buffer.
-   */
-  protected int len;
-
-  /**
-   * Constructs a new byte array response body reader.
-   */
-  public ByteArrayResponseBodyReader()
-  {
-    this(4096);
-  }
-  
-  /**
-   * Constructs a new byte array response body reader with the specified
-   * initial buffer size.
-   * @param size the initial buffer size
-   */
-  public ByteArrayResponseBodyReader(int size)
-  {
-    content = new byte[size];
-    pos = len = 0;
-  }
-
-  /**
-   * This reader accepts all responses.
-   */ 
-  public boolean accept(Request request, Response response)
-  {
-    return true;
-  }
-
-  public void read(byte[] buffer, int offset, int length)
-  {
-    int l = length - offset;
-    if (pos + l > content.length)
-      {
-        byte[] tmp = new byte[content.length * 2];
-        System.arraycopy(content, 0, tmp, 0, pos);
-        content = tmp;
-      }
-    System.arraycopy(buffer, offset, content, pos, l);
-    pos += l;
-    len = pos;
-  }
-
-  public void close()
-  {
-    pos = 0;
-  }
-
-  /**
-   * Retrieves the content of this reader as a byte array.
-   * The size of the returned array is the number of bytes read.
-   */
-  public byte[] toByteArray()
-  {
-    byte[] ret = new byte[len];
-    System.arraycopy(content, 0, ret, 0, len);
-    return ret;
-  }
-  
-}
-
Index: gnu/java/net/protocol/http/ChunkedInputStream.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/gnu/java/net/protocol/http/ChunkedInputStream.java,v
retrieving revision 1.3
diff -u -p -r1.3 ChunkedInputStream.java
--- gnu/java/net/protocol/http/ChunkedInputStream.java  2 Jul 2005 20:32:13 
-0000       1.3
+++ gnu/java/net/protocol/http/ChunkedInputStream.java  11 Oct 2005 23:55:38 
-0000
@@ -110,7 +110,7 @@ public class ChunkedInputStream
         // Read chunk header
         int c, last = 0;
         boolean seenSemi = false;
-        StringBuffer buf = new StringBuffer();
+        StringBuilder buf = new StringBuilder();
         do
           {
             c = in.read();
Index: gnu/java/net/protocol/http/Cookie.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/net/protocol/http/Cookie.java,v
retrieving revision 1.3
diff -u -p -r1.3 Cookie.java
--- gnu/java/net/protocol/http/Cookie.java      2 Jul 2005 20:32:13 -0000       
1.3
+++ gnu/java/net/protocol/http/Cookie.java      11 Oct 2005 23:55:38 -0000
@@ -139,7 +139,7 @@ public class Cookie
   
   public String toString(boolean showPath, boolean showDomain)
   {
-    StringBuffer buf = new StringBuffer();
+    StringBuilder buf = new StringBuilder();
     buf.append(name);
     buf.append('=');
     buf.append(value);
Index: gnu/java/net/protocol/http/HTTPConnection.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/gnu/java/net/protocol/http/HTTPConnection.java,v
retrieving revision 1.9
diff -u -p -r1.9 HTTPConnection.java
--- gnu/java/net/protocol/http/HTTPConnection.java      7 Jul 2005 06:29:30 
-0000       1.9
+++ gnu/java/net/protocol/http/HTTPConnection.java      11 Oct 2005 23:55:38 
-0000
@@ -41,10 +41,6 @@ package gnu.java.net.protocol.http;
 import gnu.classpath.Configuration;
 import gnu.classpath.SystemProperties;
 import gnu.java.net.EmptyX509TrustManager;
-import gnu.java.net.protocol.http.event.ConnectionEvent;
-import gnu.java.net.protocol.http.event.ConnectionListener;
-import gnu.java.net.protocol.http.event.RequestEvent;
-import gnu.java.net.protocol.http.event.RequestListener;
 
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
@@ -57,6 +53,7 @@ import java.security.GeneralSecurityExce
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -131,8 +128,6 @@ public class HTTPConnection
    */
   protected int minorVersion;
 
-  private final List connectionListeners;
-  private final List requestListeners;
   private final List handshakeCompletedListeners;
 
   /**
@@ -165,6 +160,12 @@ public class HTTPConnection
    */
   protected CookieManager cookieManager;
 
+
+  /**
+   * The pool that this connection is a member of (if any).
+   */
+  private LinkedHashMap pool;
+
   /**
    * Creates a new HTTP connection.
    * @param hostname the name of the host to connect to
@@ -236,8 +237,6 @@ public class HTTPConnection
     this.connectionTimeout = connectionTimeout;
     this.timeout = timeout;
     majorVersion = minorVersion = 1;
-    connectionListeners = new ArrayList(4);
-    requestListeners = new ArrayList(4);
     handshakeCompletedListeners = new ArrayList(2);
   }
 
@@ -332,6 +331,73 @@ public class HTTPConnection
   }
 
   /**
+   * The number of times this HTTPConnection has be used via keep-alive.
+   */
+  int useCount;
+
+  /**
+   * Generates a key for connections in the connection pool.
+   *
+   * @param h the host name.
+   * @param p the port.
+   * @param sec true if using https.
+   *
+   * @return the key.
+   */
+  static Object getPoolKey(String h, int p, boolean sec)
+  {
+    StringBuilder buf = new StringBuilder(sec ? "https://"; : "http://";);
+    buf.append(h);
+    buf.append(':');
+    buf.append(p);
+    return buf.toString();
+  }
+
+  /**
+   * Set the connection pool that this HTTPConnection is a member of.
+   * If left unset or set to null, it will not be a member of any pool
+   * and will not be a candidate for reuse.
+   *
+   * @param p the pool.
+   */
+  void setPool(LinkedHashMap p)
+  {
+    pool = p;
+  }
+
+  /**
+   * Signal that this HTTPConnection is no longer needed and can be
+   * returned to the connection pool.
+   *
+   */
+  void release()
+  {
+    if (pool != null)
+      {
+        synchronized (pool)
+          {
+            useCount++;
+            Object key = HTTPConnection.getPoolKey(hostname, port, secure);
+            pool.put(key, this);
+            while (pool.size() >= HTTPURLConnection.maxConnections)
+              {
+                // maxConnections must always be >= 1
+                Object lru = pool.keySet().iterator().next();
+                HTTPConnection c = (HTTPConnection)pool.remove(lru);
+                try
+                  {
+                    c.closeConnection();
+                  }
+                catch (IOException ioe)
+                  {
+                      // Ignore it.  We are just cleaning up.
+                  }
+              }
+          }
+      }
+  }
+
+  /**
    * Creates a new request using this connection.
    * @param method the HTTP method to invoke
    * @param path the URI-escaped RFC2396 <code>abs_path</code> with
@@ -367,7 +433,7 @@ public class HTTPConnection
         Cookie[] cookies = cookieManager.getCookies(hostname, secure, path);
         if (cookies != null && cookies.length > 0)
           {
-            StringBuffer buf = new StringBuffer();
+            StringBuilder buf = new StringBuilder();
             buf.append("$Version=1");
             for (int i = 0; i < cookies.length; i++)
               {
@@ -378,7 +444,6 @@ public class HTTPConnection
             ret.setHeader("Cookie", buf.toString());
           }
       }
-    fireRequestEvent(RequestEvent.REQUEST_CREATED, ret);
     return ret;
   }
 
@@ -388,14 +453,7 @@ public class HTTPConnection
   public void close()
     throws IOException
   {
-    try
-      {
-        closeConnection();
-      }
-    finally
-      {
-        fireConnectionEvent(ConnectionEvent.CONNECTION_CLOSED);
-      }
+    closeConnection();
   }
 
   /**
@@ -534,7 +592,7 @@ public class HTTPConnection
    */
   protected String getURI()
   {
-    StringBuffer buf = new StringBuffer();
+    StringBuilder buf = new StringBuilder();
     buf.append(secure ? "https://"; : "http://";);
     buf.append(hostname);
     if (secure)
@@ -584,84 +642,6 @@ public class HTTPConnection
 
   // -- Events --
   
-  public void addConnectionListener(ConnectionListener l)
-  {
-    synchronized (connectionListeners)
-      {
-        connectionListeners.add(l);
-      }
-  }
-
-  public void removeConnectionListener(ConnectionListener l)
-  {
-    synchronized (connectionListeners)
-      {
-        connectionListeners.remove(l);
-      }
-  }
-
-  protected void fireConnectionEvent(int type)
-  {
-    ConnectionEvent event = new ConnectionEvent(this, type);
-    ConnectionListener[] l = null;
-    synchronized (connectionListeners)
-      {
-        l = new ConnectionListener[connectionListeners.size()];
-        connectionListeners.toArray(l);
-      }
-    for (int i = 0; i < l.length; i++)
-      {
-        switch (type)
-          {
-          case ConnectionEvent.CONNECTION_CLOSED:
-            l[i].connectionClosed(event);
-            break;
-          }
-      }
-  }
-
-  public void addRequestListener(RequestListener l)
-  {
-    synchronized (requestListeners)
-      {
-        requestListeners.add(l);
-      }
-  }
-
-  public void removeRequestListener(RequestListener l)
-  {
-    synchronized (requestListeners)
-      {
-        requestListeners.remove(l);
-      }
-  }
-
-  protected void fireRequestEvent(int type, Request request)
-  {
-    RequestEvent event = new RequestEvent(this, type, request);
-    RequestListener[] l = null;
-    synchronized (requestListeners)
-      {
-        l = new RequestListener[requestListeners.size()];
-        requestListeners.toArray(l);
-      }
-    for (int i = 0; i < l.length; i++)
-      {
-        switch (type)
-          {
-          case RequestEvent.REQUEST_CREATED:
-            l[i].requestCreated(event);
-            break;
-          case RequestEvent.REQUEST_SENDING:
-            l[i].requestSent(event);
-            break;
-          case RequestEvent.REQUEST_SENT:
-            l[i].requestSent(event);
-            break;
-          }
-      }
-  }
-
   void addHandshakeCompletedListener(HandshakeCompletedListener l)
   {
     synchronized (handshakeCompletedListeners)
Index: gnu/java/net/protocol/http/HTTPURLConnection.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/gnu/java/net/protocol/http/HTTPURLConnection.java,v
retrieving revision 1.14
diff -u -p -r1.14 HTTPURLConnection.java
--- gnu/java/net/protocol/http/HTTPURLConnection.java   13 Jul 2005 23:22:30 
-0000      1.14
+++ gnu/java/net/protocol/http/HTTPURLConnection.java   11 Oct 2005 23:55:38 
-0000
@@ -38,7 +38,6 @@ exception statement from your version. *
 
 package gnu.java.net.protocol.http;
 
-import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -75,7 +74,8 @@ public class HTTPURLConnection
   /**
    * Pool of reusable connections, used if keepAlive is true.
    */
-  private static final Map connectionPool = new LinkedHashMap();
+  private static final LinkedHashMap connectionPool = new LinkedHashMap();
+  static int maxConnections;
 
   /*
    * The underlying connection.
@@ -87,7 +87,6 @@ public class HTTPURLConnection
   int proxyPort;
   String agent;
   boolean keepAlive;
-  int maxConnections;
 
   private Request request;
   private Headers requestHeaders;
@@ -95,8 +94,8 @@ public class HTTPURLConnection
   private boolean requestMethodSetExplicitly;
 
   private Response response;
-  private ByteArrayInputStream responseSink;
-  private ByteArrayInputStream errorSink;
+  private InputStream responseSink;
+  private InputStream errorSink;
 
   private HandshakeCompletedEvent handshakeEvent;
 
@@ -202,34 +201,59 @@ public class HTTPURLConnection
               }
             connection.setProxy(proxyHostname, proxyPort);
           }
-        request = connection.newRequest(method, file);
-        if (!keepAlive)
-          {
-            request.setHeader("Connection", "close");
-          }
-        if (agent != null)
-          {
-            request.setHeader("User-Agent", agent);
-          }
-        request.getHeaders().putAll(requestHeaders);
-        if (requestSink != null)
+        try
           {
-            byte[] content = requestSink.toByteArray();
-            RequestBodyWriter writer = new ByteArrayRequestBodyWriter(content);
-            request.setRequestBodyWriter(writer);
+            request = connection.newRequest(method, file);
+            if (!keepAlive)
+              {
+                request.setHeader("Connection", "close");
+              }
+            if (agent != null)
+              {
+                request.setHeader("User-Agent", agent);
+              }
+            request.getHeaders().putAll(requestHeaders);
+            if (requestSink != null)
+              {
+                byte[] content = requestSink.toByteArray();
+                RequestBodyWriter writer = new 
ByteArrayRequestBodyWriter(content);
+                request.setRequestBodyWriter(writer);
+              }
+            if (creds != null)
+              {
+                request.setAuthenticator(new Authenticator() {
+                    public Credentials getCredentials(String realm, int 
attempts)
+                    {
+                      return (attempts < 2) ? creds : null;
+                    }
+                  });
+              }
+            response = request.dispatch();
           }
-        ByteArrayResponseBodyReader reader = new ByteArrayResponseBodyReader();
-        request.setResponseBodyReader(reader);
-        if (creds != null)
+        catch (IOException ioe)
           {
-            request.setAuthenticator(new Authenticator() {
-              public Credentials getCredentials(String realm, int attempts)
+            if (connection.useCount > 0)
+              {
+                // Connection re-use failed: Try a new connection.
+                try
+                  {
+                    connection.close();
+                  }
+                catch (IOException _)
+                  {
+                    // Ignore.
+                  }
+                connection = null;
+                retry = true;
+                continue;
+              }
+            else
               {
-                return (attempts < 2) ? creds : null;
+                // First time the connection was used: Hard failure.
+                throw ioe;
               }
-            });
           }
-        response = request.dispatch();
+        
         if (response.getCodeClass() == 3 && getInstanceFollowRedirects())
           {
             // Follow redirect
@@ -307,7 +331,8 @@ public class HTTPURLConnection
           }
         else
           {
-            responseSink = new ByteArrayInputStream(reader.toByteArray ());
+            responseSink = response.getBody();
+            
             if (response.getCode() == 404)
              {
                errorSink = responseSink;
@@ -328,27 +353,14 @@ public class HTTPURLConnection
     HTTPConnection connection;
     if (keepAlive)
       {
-        StringBuffer buf = new StringBuffer(secure ? "https://"; : "http://";);
-        buf.append(Thread.currentThread().hashCode());
-        buf.append('@');
-        buf.append(host);
-        buf.append(':');
-        buf.append(port);
-        String key = buf.toString();
+        Object key = HTTPConnection.getPoolKey(host, port, secure);
         synchronized (connectionPool)
           {
-            connection = (HTTPConnection) connectionPool.get(key);
+            connection = (HTTPConnection) connectionPool.remove(key);
             if (connection == null)
               {
                 connection = new HTTPConnection(host, port, secure);
-                // Good housekeeping
-                if (connectionPool.size() == maxConnections)
-                  {
-                    // maxConnections must always be >= 1
-                    Object lru = connectionPool.keySet().iterator().next();
-                    connectionPool.remove(lru);
-                  }
-                connectionPool.put(key, connection);
+                connection.setPool(connectionPool);
               }
           }
       }
@@ -502,9 +514,9 @@ public class HTTPURLConnection
             return null;
           }
       }
-    Map headers = response.getHeaders();
-    Map ret = new LinkedHashMap();
-    ret.put("", Collections.singletonList(getStatusLine(response)));
+    Headers headers = response.getHeaders();
+    LinkedHashMap ret = new LinkedHashMap();
+    ret.put(null, Collections.singletonList(getStatusLine(response)));
     for (Iterator i = headers.entrySet().iterator(); i.hasNext(); )
       {
         Map.Entry entry = (Map.Entry) i.next();
@@ -512,7 +524,7 @@ public class HTTPURLConnection
         String value = (String) entry.getValue();
         ret.put(key, Collections.singletonList(value));
       }
-    return ret;
+    return Collections.unmodifiableMap(ret);
   }
 
   String getStatusLine(Response response)
Index: gnu/java/net/protocol/http/Headers.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/net/protocol/http/Headers.java,v
retrieving revision 1.4
diff -u -p -r1.4 Headers.java
--- gnu/java/net/protocol/http/Headers.java     2 Jul 2005 20:32:13 -0000       
1.4
+++ gnu/java/net/protocol/http/Headers.java     11 Oct 2005 23:55:38 -0000
@@ -60,7 +60,7 @@ import java.util.Set;
  * @author Chris Burdess (address@hidden)
  */
 public class Headers
-  implements Map
+  extends LinkedHashMap
 {
 
   static final DateFormat dateFormat = new HTTPDateFormat();
@@ -143,36 +143,18 @@ public class Headers
     
   }
 
-  private LinkedHashMap headers;
-
   public Headers()
   {
-    headers = new LinkedHashMap();
-  }
-
-  public int size()
-  {
-    return headers.size();
-  }
-
-  public boolean isEmpty()
-  {
-    return headers.isEmpty();
   }
 
   public boolean containsKey(Object key)
   {
-    return headers.containsKey(new Header((String) key));
-  }
-
-  public boolean containsValue(Object value)
-  {
-    return headers.containsValue(value);
+    return super.containsKey(new Header((String) key));
   }
 
   public Object get(Object key)
   {
-    return headers.get(new Header((String) key));
+    return super.get(new Header((String) key));
   }
 
   /**
@@ -180,7 +162,7 @@ public class Headers
    */
   public String getValue(String header)
   {
-    return (String) headers.get(new Header(header));
+    return (String) super.get(new Header(header));
   }
 
   /**
@@ -205,6 +187,27 @@ public class Headers
   }
 
   /**
+   * Returns the value of the specified header as a long, or -1 if the
+   * header is not present or cannot be parsed as a long.
+   */
+  public long getLongValue(String header)
+  {
+    String val = getValue(header);
+    if (val == null)
+      {
+        return -1;
+      }
+    try
+      {
+        return Long.parseLong(val);
+      }
+    catch (NumberFormatException e)
+      {
+      }
+    return -1;
+  }
+
+  /**
    * Returns the value of the specified header as a date,
    * or <code>null</code> if the header is not present or not a date.
    */
@@ -227,12 +230,12 @@ public class Headers
 
   public Object put(Object key, Object value)
   {
-    return headers.put(new Header((String) key), value);
+    return super.put(new Header((String) key), value);
   }
 
   public Object remove(Object key)
   {
-    return headers.remove(new Header((String) key));
+    return super.remove(new Header((String) key));
   }
 
   public void putAll(Map t)
@@ -241,18 +244,13 @@ public class Headers
       {
         String key = (String) i.next();
         String value = (String) t.get(key);
-        headers.put(new Header(key), value);
+        put(key, value);
       }
   }
   
-  public void clear()
-  {
-    headers.clear();
-  }
-
   public Set keySet()
   {
-    Set keys = headers.keySet();
+    Set keys = super.keySet();
     Set ret = new LinkedHashSet();
     for (Iterator i = keys.iterator(); i.hasNext(); )
       {
@@ -261,14 +259,9 @@ public class Headers
     return ret;
   }
 
-  public Collection values()
-  {
-    return headers.values();
-  }
-
   public Set entrySet()
   {
-    Set entries = headers.entrySet();
+    Set entries = super.entrySet();
     Set ret = new LinkedHashSet();
     for (Iterator i = entries.iterator(); i.hasNext(); )
       {
@@ -278,16 +271,6 @@ public class Headers
     return ret;
   }
 
-  public boolean equals(Object other)
-  {
-    return headers.equals(other);
-  }
-
-  public int hashCode()
-  {
-    return headers.hashCode();
-  }
-
   /**
    * Parse the specified input stream, adding headers to this collection.
    */
@@ -298,7 +281,7 @@ public class Headers
       (LineInputStream) in : new LineInputStream(in);
     
     String name = null;
-    StringBuffer value = new StringBuffer();
+    StringBuilder value = new StringBuilder();
     while (true)
       {
         String line = lin.readLine();
@@ -354,14 +337,14 @@ public class Headers
   private void addValue(String name, String value)
   {
     Header key = new Header(name);
-    String old = (String) headers.get(key);
+    String old = (String) super.get(key);
     if (old == null)
       {
-        headers.put(key, value);
+        super.put(key, value);
       }
     else
       {
-        headers.put(key, old + ", " + value);
+        super.put(key, old + ", " + value);
       }
   }
   
Index: gnu/java/net/protocol/http/LimitedLengthInputStream.java
===================================================================
RCS file: gnu/java/net/protocol/http/LimitedLengthInputStream.java
diff -N gnu/java/net/protocol/http/LimitedLengthInputStream.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gnu/java/net/protocol/http/LimitedLengthInputStream.java    11 Oct 2005 
23:55:38 -0000
@@ -0,0 +1,238 @@
+/* LimitedLengthInputStream.java --
+   Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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.
+ 
+GNU Classpath 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 GNU Classpath; 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 gnu.java.net.protocol.http;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * InputStream that limits the total number of bytes that can be read
+ * from an underlying stream.  In addition to limiting the number of
+ * bytes read, close() is not propagated to the underlying stream.
+ *
+ * @author David Daney (address@hidden)
+ */
+class LimitedLengthInputStream
+  extends InputStream
+{
+  private long remainingLen;
+  private boolean restrictLen;
+  private HTTPConnection connection;
+  private boolean eof;
+  private InputStream in;
+  private boolean doClose;
+  
+  
+  private void handleClose()
+    throws IOException
+  {
+    eof = true;
+    if (doClose)
+      {
+        in.close();
+      }
+    else
+      {
+        connection.release();
+      }
+    in = null;
+    connection = null;
+  }
+
+  /**
+   * Constructor.
+   *
+   * @param in the underlying stream
+   *
+   * @param maxLen the maximum number of bytes to read
+   *
+   * @param restrictLen if true the number of bytes that can be read
+   * from this stream will be limited to maxLen, otherwise the number
+   * of bytes is not restricted.
+   * 
+   * @param con the HTTPConnection associated with this stream
+   *
+   * @param doClose if true con will be closed when finished reading,
+   * else it will be placed back in the connection pool.
+   *
+   */
+  LimitedLengthInputStream(InputStream in,
+                           long maxLen,
+                           boolean restrictLen,
+                           HTTPConnection con,
+                           boolean doClose)
+    throws IOException
+
+  {
+    this.in = in;
+    this.remainingLen = maxLen;
+    this.restrictLen = restrictLen;
+    this.connection = con;
+    this.doClose = doClose;
+
+    if (restrictLen)
+      {
+        if (maxLen < 0)
+          throw new IllegalArgumentException();
+        else if (maxLen == 0)
+          handleClose(); // Nothing to do, release the connection.
+      }
+  }
+
+  public synchronized int read()
+    throws IOException
+  {
+    if (eof)
+      return -1; // EOF
+
+    int r;
+    
+    if (restrictLen)
+      {
+        r = in.read();
+        if (-1 != r)
+          remainingLen--;
+
+        if (0 == remainingLen)
+          handleClose();
+      }
+    else
+      {
+        r = in.read();
+        if (r == -1)
+          handleClose();
+      }
+    
+    return r;
+  }
+
+  public int read(byte[] buffer)
+    throws IOException
+  {
+    return read(buffer, 0, buffer.length);
+  }
+
+  public synchronized int read(byte[] buffer, int offset, int length)
+    throws IOException
+  {
+    if (eof)
+      return -1; // EOF
+
+    if (restrictLen && length > remainingLen)
+      length = (int) remainingLen;
+      
+    int r = in.read(buffer, offset, length);
+    
+    if (-1 == r)
+      handleClose();
+    
+    if (restrictLen && r > 0)
+      {
+        remainingLen -= r;
+        if (0 == remainingLen)
+          handleClose();
+      }
+    return r;
+  }
+
+  public synchronized long skip(long n)
+    throws IOException
+  {
+
+    if (eof)
+      return 0;
+
+    if (restrictLen && n > remainingLen)
+      n = remainingLen;
+
+    long r = in.skip(n);
+    
+    if (restrictLen)
+      {
+        remainingLen -= r;
+        if (0 == remainingLen)
+          handleClose();
+      }
+    return r;
+  }
+
+  public synchronized int available()
+    throws IOException
+  {
+    if (eof)
+      return 0;
+
+    int a = in.available();
+    if (restrictLen && a > remainingLen)
+      a = (int)remainingLen;
+    return a;
+  }
+
+  public synchronized void close()
+    throws IOException
+  {
+    if (eof)
+      return;
+
+    try
+      {
+        while (restrictLen && remainingLen > 0)
+          {
+            long r = in.skip(remainingLen);
+            remainingLen -= r;
+            if (r == 0)
+              doClose = true;  // Something is broken, close the stream.
+          }
+      }
+    catch (IOException ioe)
+      {
+        // Something is broken, close the stream.
+        doClose = true;
+      }
+    
+    handleClose();
+  }
+
+  protected void finalize()
+    throws Throwable
+  {
+    close();
+  }
+  
+}
Index: gnu/java/net/protocol/http/Request.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/net/protocol/http/Request.java,v
retrieving revision 1.5
diff -u -p -r1.5 Request.java
--- gnu/java/net/protocol/http/Request.java     2 Jul 2005 20:32:13 -0000       
1.5
+++ gnu/java/net/protocol/http/Request.java     11 Oct 2005 23:55:38 -0000
@@ -1,5 +1,5 @@
 /* Request.java --
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -40,7 +40,6 @@ package gnu.java.net.protocol.http;
 
 import gnu.java.net.BASE64;
 import gnu.java.net.LineInputStream;
-import gnu.java.net.protocol.http.event.RequestEvent;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -100,11 +99,6 @@ public class Request
   protected int requestBodyNegotiationThreshold;
 
   /**
-   * The response body reader.
-   */
-  protected ResponseBodyReader responseBodyReader;
-
-  /**
    * Map of response header handlers.
    */
   protected Map responseHeaderHandlers;
@@ -236,16 +230,6 @@ public class Request
   }
 
   /**
-   * Sets the response body reader.
-   * @param responseBodyReader the handler to receive notifications of
-   * response body content
-   */
-  public void setResponseBodyReader(ResponseBodyReader responseBodyReader)
-  {
-    this.responseBodyReader = responseBodyReader;
-  }
-
-  /**
    * Sets a callback handler to be invoked for the specified header name.
    * @param name the header name
    * @param handler the handler to receive the value for the header
@@ -324,13 +308,10 @@ public class Request
         do
           {
             retry = false;
-            // Send request
-            connection.fireRequestEvent(RequestEvent.REQUEST_SENDING, this);
             
             // Get socket output and input streams
             OutputStream out = connection.getOutputStream();
-            LineInputStream in =
-              new LineInputStream(connection.getInputStream());
+
             // Request line
             String requestUri = path;
             if (connection.isUsingProxy() &&
@@ -369,28 +350,42 @@ public class Request
                     count += len;
                   }
                 while (len > -1 && count < contentLength);
-                out.write(CRLF.getBytes(US_ASCII));
               }
             out.flush();
-            // Sent event
-            connection.fireRequestEvent(RequestEvent.REQUEST_SENT, this);
             // Get response
-            response = readResponse(in);
-            int sc = response.getCode();
-            if (sc == 401 && authenticator != null)
-              {
-                if (authenticate(response, attempts++))
-                  {
-                    retry = true;
-                  }
-              }
-            else if (sc == 100 && expectingContinue)
-              {
-                requestHeaders.remove("Expect");
-                setHeader("Content-Length", Integer.toString(contentLength));
-                expectingContinue = false;
-                retry = true;
-              }
+            while(true)
+            {
+              response = readResponse(connection.getInputStream());
+              int sc = response.getCode();
+              if (sc == 401 && authenticator != null)
+                {
+                  if (authenticate(response, attempts++))
+                    {
+                      retry = true;
+                    }
+                }
+              else if (sc == 100)
+                {
+                  if (expectingContinue)
+                    {
+                      requestHeaders.remove("Expect");
+                      setHeader("Content-Length",
+                                Integer.toString(contentLength));
+                      expectingContinue = false;
+                      retry = true;
+                    }
+                  else
+                    {
+                      // A conforming server can send an unsoliceted
+                      // Continue response but *should* not (RFC 2616
+                      // sec 8.2.3).  Ignore the bogus Continue
+                      // response and get the real response that
+                      // should follow
+                      continue;
+                    }
+                }
+              break;
+            }
           }
         while (retry);
       }
@@ -402,14 +397,16 @@ public class Request
     return response;
   }
     
-  Response readResponse(LineInputStream in)
+  Response readResponse(InputStream in)
     throws IOException
   {
     String line;
     int len;
     
     // Read response status line
-    line = in.readLine();
+    LineInputStream lis = new LineInputStream(in);
+
+    line = lis.readLine();
     if (line == null)
       {
         throw new ProtocolException("Peer closed connection");
@@ -438,30 +435,25 @@ public class Request
     String message = line.substring(end + 1, len - 1);
     // Read response headers
     Headers responseHeaders = new Headers();
-    responseHeaders.parse(in);
+    responseHeaders.parse(lis);
     notifyHeaderHandlers(responseHeaders);
-    // Construct response
-    int codeClass = code / 100;
-    Response ret = new Response(majorVersion, minorVersion, code,
-                                codeClass, message, responseHeaders);
+    InputStream body = null;
+    
     switch (code)
       {
+      case 100:
       case 204:
       case 205:
       case 304:
         break;
       default:
-        // Does response body reader want body?
-        boolean notify = (responseBodyReader != null);
-        if (notify)
-          {
-            if (!responseBodyReader.accept(this, ret))
-              {
-                notify = false;
-              }
-          }
-        readResponseBody(ret, in, notify);
+        body = createResponseBodyStream(responseHeaders, majorVersion,
+                                        minorVersion, in);
       }
+
+    // Construct response
+    Response ret = new Response(majorVersion, minorVersion, code,
+                                message, responseHeaders, body);
     return ret;
   }
 
@@ -487,25 +479,40 @@ public class Request
       }
   }
 
-  void readResponseBody(Response response, InputStream in,
-                        boolean notify)
+  private InputStream createResponseBodyStream(Headers responseHeaders,
+                                               int majorVersion,
+                                               int minorVersion,
+                                               InputStream in)
     throws IOException
   {
-    byte[] buffer = new byte[4096];
-    int contentLength = -1;
+    long contentLength = -1;
     Headers trailer = null;
     
-    String transferCoding = response.getHeader("Transfer-Encoding");
+    // Persistent connections are the default in HTTP/1.1
+    boolean doClose = "close".equalsIgnoreCase(getHeader("Connection")) ||
+      "close".equalsIgnoreCase(responseHeaders.getValue("Connection")) ||
+      (connection.majorVersion == 1 && connection.minorVersion == 0) ||
+      (majorVersion == 1 && minorVersion == 0);
+
+    String transferCoding = responseHeaders.getValue("Transfer-Encoding");
     if ("chunked".equalsIgnoreCase(transferCoding))
       {
-        trailer = new Headers();
-        in = new ChunkedInputStream(in, trailer);
+        in = new LimitedLengthInputStream(in, -1, false, connection, doClose);
+          
+        in = new ChunkedInputStream(in, responseHeaders);
       } 
     else
       {
-        contentLength = response.getIntHeader("Content-Length");
+        contentLength = responseHeaders.getLongValue("Content-Length");
+
+        if (contentLength < 0)
+          doClose = true;  // No Content-Length, must close.
+
+        in = new LimitedLengthInputStream(in, contentLength,
+                                          contentLength >= 0,
+                                          connection, doClose);
       }
-    String contentCoding = response.getHeader("Content-Encoding");
+    String contentCoding = responseHeaders.getValue("Content-Encoding");
     if (contentCoding != null && !"identity".equals(contentCoding))
       {
         if ("gzip".equals(contentCoding))
@@ -522,51 +529,7 @@ public class Request
                                         contentCoding);
           }
       }
-    
-    // Persistent connections are the default in HTTP/1.1
-    boolean doClose = "close".equalsIgnoreCase(getHeader("Connection")) ||
-      "close".equalsIgnoreCase(response.getHeader("Connection")) ||
-      (connection.majorVersion == 1 && connection.minorVersion == 0) ||
-      (response.majorVersion == 1 && response.minorVersion == 0);
-    
-    int count = contentLength;
-    int len = (count > -1) ? count : buffer.length;
-    len = (len > buffer.length) ? buffer.length : len;
-    while (len > -1)
-      {
-        len = in.read(buffer, 0, len);
-        if (len < 0)
-          {
-            // EOF
-            connection.closeConnection();
-            break;
-          }
-        if (notify)
-          {
-            responseBodyReader.read(buffer, 0, len);
-          }
-        if (count > -1)
-          {
-            count -= len;
-            if (count < 1)
-              {
-                if (doClose)
-                  {
-                    connection.closeConnection();
-                  }
-                break;
-              }
-          }
-      }
-    if (notify)
-      {
-        responseBodyReader.close();
-      }
-    if (trailer != null)
-      {
-        response.getHeaders().putAll(trailer);
-        notifyHeaderHandlers(trailer);
-      }
+    return in;
   }
 
   boolean authenticate(Response response, int attempts)
@@ -686,7 +649,7 @@ public class Request
   {
     int len = text.length();
     String key = null;
-    StringBuffer buf = new StringBuffer();
+    StringBuilder buf = new StringBuilder();
     Properties ret = new Properties();
     boolean inQuote = false;
     for (int i = 0; i < len; i++)
@@ -739,7 +702,7 @@ public class Request
   {
     int nc = connection.getNonceCount(nonce);
     String hex = Integer.toHexString(nc);
-    StringBuffer buf = new StringBuffer();
+    StringBuilder buf = new StringBuilder();
     for (int i = 8 - hex.length(); i > 0; i--)
       {
         buf.append('0');
@@ -810,7 +773,7 @@ public class Request
 
     int len = text.length();
     String attr = null;
-    StringBuffer buf = new StringBuffer();
+    StringBuilder buf = new StringBuilder();
     boolean inQuote = false;
     for (int i = 0; i <= len; i++)
       {
Index: gnu/java/net/protocol/http/Response.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/gnu/java/net/protocol/http/Response.java,v
retrieving revision 1.2
diff -u -p -r1.2 Response.java
--- gnu/java/net/protocol/http/Response.java    2 Jul 2005 20:32:13 -0000       
1.2
+++ gnu/java/net/protocol/http/Response.java    11 Oct 2005 23:55:38 -0000
@@ -38,6 +38,7 @@ exception statement from your version. *
 
 package gnu.java.net.protocol.http;
 
+import java.io.InputStream;
 import java.util.Date;
 
 /**
@@ -64,19 +65,6 @@ public class Response
   protected final int code;
 
   /**
-   * The class of the response. This is the most significant digit of the
-   * status code.
-   * <dl>
-   * <dt><code>1xx</code></dt> <dd>Informational response</dd>
-   * <dt><code>2xx</code></dt> <dd>Success</dd>
-   * <dt><code>3xx</code></dt> <dd>Redirection</dd>
-   * <dt><code>4xx</code></dt> <dd>Client error</dd>
-   * <dt><code>5xx</code></dt> <dd>Server error</dd>
-   * </dl>
-   */
-  protected final int codeClass;
-
-  /**
    * Human-readable text of the response.
    */
   protected final String message;
@@ -87,18 +75,22 @@ public class Response
   protected final Headers headers;
 
   /**
+   * An InputStream that returns the body of the response.
+   */
+  protected final InputStream body;
+
+  /**
    * Constructs a new response with the specified parameters.
    */
   protected Response(int majorVersion, int minorVersion, int code,
-                     int codeClass, String message,
-                     Headers headers)
+                     String message, Headers headers, InputStream body)
   {
     this.majorVersion = majorVersion;
     this.minorVersion = minorVersion;
     this.code = code;
-    this.codeClass = codeClass;
     this.message = message;
     this.headers = headers;
+    this.body = body;
   }
 
   /**
@@ -129,12 +121,19 @@ public class Response
   }
 
   /**
-   * Returns the class of the response.
-   * @see #codeClass
+   * Returns the class of the response.  This is the most significant
+   * digit of the status code.
+   * <dl>
+   * <dt><code>1xx</code></dt> <dd>Informational response</dd>
+   * <dt><code>2xx</code></dt> <dd>Success</dd>
+   * <dt><code>3xx</code></dt> <dd>Redirection</dd>
+   * <dt><code>4xx</code></dt> <dd>Client error</dd>
+   * <dt><code>5xx</code></dt> <dd>Server error</dd>
+   * </dl>
    */
   public int getCodeClass()
   {
-    return codeClass;
+    return code / 100;
   }
 
   /**
@@ -173,6 +172,15 @@ public class Response
   }
 
   /**
+   * Returns the header value for the specified name as a long.
+   * @param name the header name
+   */
+  public long getLongHeader(String name)
+  {
+    return headers.getLongValue(name);
+  }
+
+  /**
    * Returns the header value for the specified name as a date.
    * @param name the header name
    */
@@ -181,5 +189,14 @@ public class Response
     return headers.getDateValue(name);
   }
 
+  /**
+   * Returns an InputStream that returns the body of the response.
+   *
+   * @return the body of the response
+   */
+  public InputStream getBody()
+  {
+    return body;
+  }
 }
 
Index: gnu/java/net/protocol/http/ResponseBodyReader.java
===================================================================
RCS file: gnu/java/net/protocol/http/ResponseBodyReader.java
diff -N gnu/java/net/protocol/http/ResponseBodyReader.java
--- gnu/java/net/protocol/http/ResponseBodyReader.java  2 Jul 2005 20:32:13 
-0000       1.2
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,70 +0,0 @@
-/* ResponseBodyReader.java --
-   Copyright (C) 2004 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath 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.
- 
-GNU Classpath 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 GNU Classpath; 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 gnu.java.net.protocol.http;
-
-/**
- * Callback interface for receiving notification of response body content.
- *
- * @author Chris Burdess (address@hidden)
- */
-public interface ResponseBodyReader
-{
-
-  /**
-   * Indicate whether this reader is interested in the specified response.
-   * If it returns false, it will not receive body content notifications for
-   * that response.
-   */ 
-  boolean accept(Request request, Response response);
-
-  /**
-   * Receive notification of body content.
-   * @param buffer the content buffer
-   * @param offset the offset within the buffer that content starts
-   * @param length the length of the content
-   */
-  void read(byte[] buffer, int offset, int length);
-
-  /**
-   * Notifies the reader that the end of the content was reached.
-   */
-  void close();
-  
-}
-
Index: gnu/java/net/protocol/http/event/ConnectionEvent.java
===================================================================
RCS file: gnu/java/net/protocol/http/event/ConnectionEvent.java
diff -N gnu/java/net/protocol/http/event/ConnectionEvent.java
--- gnu/java/net/protocol/http/event/ConnectionEvent.java       2 Jul 2005 
20:32:13 -0000       1.2
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,81 +0,0 @@
-/* ConnectionEvent.java --
-   Copyright (C) 2004 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath 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.
- 
-GNU Classpath 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 GNU Classpath; 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 gnu.java.net.protocol.http.event;
-
-import java.util.EventObject;
-
-/**
- * A connection event.
- *
- * @author Chris Burdess (address@hidden)
- */
-public class ConnectionEvent
-  extends EventObject
-{
-
-  /**
-   * The connection closed event type.
-   */
-  public static final int CONNECTION_CLOSED = 0;
-  
-  /**
-   * The type of this event.
-   */
-  protected int type;
-
-  /**
-   * Constructs a connection event with the specified source and type.
-   */
-  public ConnectionEvent(Object source, int type)
-  {
-    super(source);
-    this.type = type;
-  }
-
-  /**
-   * Returns the type of this event.
-   * @see #type
-   */
-  public int getType()
-  {
-    return type;
-  }
-  
-}
-
Index: gnu/java/net/protocol/http/event/ConnectionListener.java
===================================================================
RCS file: gnu/java/net/protocol/http/event/ConnectionListener.java
diff -N gnu/java/net/protocol/http/event/ConnectionListener.java
--- gnu/java/net/protocol/http/event/ConnectionListener.java    2 Jul 2005 
20:32:13 -0000       1.2
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,58 +0,0 @@
-/* ConnectionListener.java --
-   Copyright (C) 2004 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath 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.
- 
-GNU Classpath 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 GNU Classpath; 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 gnu.java.net.protocol.http.event;
-
-import java.util.EventListener;
-
-/**
- * A connection listener.
- *
- * @author Chris Burdess (address@hidden)
- */
-public interface ConnectionListener
-  extends EventListener
-{
-
-  /**
-   * Callback invoked when the associated connection is closed.
-   */
-  void connectionClosed(ConnectionEvent event);
-  
-}
-
Index: gnu/java/net/protocol/http/event/RequestEvent.java
===================================================================
RCS file: gnu/java/net/protocol/http/event/RequestEvent.java
diff -N gnu/java/net/protocol/http/event/RequestEvent.java
--- gnu/java/net/protocol/http/event/RequestEvent.java  2 Jul 2005 20:32:13 
-0000       1.2
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,107 +0,0 @@
-/* RequestEvent.java --
-   Copyright (C) 2004 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath 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.
- 
-GNU Classpath 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 GNU Classpath; 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 gnu.java.net.protocol.http.event;
-
-import gnu.java.net.protocol.http.Request;
-
-import java.util.EventObject;
-
-/**
- * A request event.
- *
- * @author Chris Burdess (address@hidden)
- */
-public class RequestEvent
-  extends EventObject
-{
-
-  /**
-   * The request created event type.
-   */
-  public static final int REQUEST_CREATED = 0;
-  
-  /**
-   * The request sending event type.
-   */
-  public static final int REQUEST_SENDING = 1;
-  
-  /**
-   * The request sent event type.
-   */
-  public static final int REQUEST_SENT = 2;
-  
-  /**
-   * The type of this event.
-   */
-  protected int type;
-
-  /**
-   * The request associated with this event.
-   */
-  protected Request request;
-
-  /**
-   * Constructs a request event with the specified source, type, and request.
-   */
-  public RequestEvent(Object source, int type, Request request)
-  {
-    super(source);
-    this.type = type;
-    this.request = request;
-  }
-
-  /**
-   * Returns the type of this event.
-   * @see #type
-   */
-  public int getType()
-  {
-    return type;
-  }
-
-  /**
-   * Returns the request associated with this event.
-   */
-  public Request getRequest()
-  {
-    return request;
-  }
-  
-}
-
Index: gnu/java/net/protocol/http/event/RequestListener.java
===================================================================
RCS file: gnu/java/net/protocol/http/event/RequestListener.java
diff -N gnu/java/net/protocol/http/event/RequestListener.java
--- gnu/java/net/protocol/http/event/RequestListener.java       2 Jul 2005 
20:32:13 -0000       1.2
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,70 +0,0 @@
-/* RequestListener.java --
-   Copyright (C) 2004 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath 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.
- 
-GNU Classpath 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 GNU Classpath; 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 gnu.java.net.protocol.http.event;
-
-import java.util.EventListener;
-
-/**
- * A request listener.
- *
- * @author Chris Burdess (address@hidden)
- */
-public interface RequestListener
-  extends EventListener
-{
-
-  /**
-   * Callback invoked when a request is created from the associated
-   * connection.
-   */
-  void requestCreated(RequestEvent event);
-
-  /**
-   * Callback invoked when the request has been initialised with all data
-   * and before sending this data to the server.
-   */
-  void requestSending(RequestEvent event);
-
-  /**
-   * Callback invoked after all request data has been sent to the server.
-   */
-  void requestSent(RequestEvent event);
-  
-}
-
Index: gnu/java/net/protocol/http/event/package.html
===================================================================
RCS file: gnu/java/net/protocol/http/event/package.html
diff -N gnu/java/net/protocol/http/event/package.html
--- gnu/java/net/protocol/http/event/package.html       2 Jul 2005 20:32:13 
-0000       1.2
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,46 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<!-- package.html - describes classes in gnu.java.net.protocol.http.event 
package.
-   Copyright (C) 2005 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath 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.
-
-GNU Classpath 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 GNU Classpath; 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. -->
-
-<html>
-<head><title>GNU Classpath - gnu.java.net.protocol.http.event</title></head>
-
-<body>
-<p></p>
-
-</body>
-</html>

reply via email to

[Prev in Thread] Current Thread [Next in Thread]