Imported GNU Classpath 0.19 + gcj-import-20051115.
* sources.am: Regenerated. * Makefile.in: Likewise. * scripts/makemake.tcl: Use glob -nocomplain. From-SVN: r107049
This commit is contained in:
parent
02e549bfaa
commit
8f523f3a10
1241 changed files with 97711 additions and 25284 deletions
|
@ -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 (dog@gnu.org)
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.GeneralSecurityException;
|
|||
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);
|
||||
}
|
||||
|
||||
|
@ -331,6 +330,73 @@ public class HTTPConnection
|
|||
return cookieManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
try
|
||||
{
|
||||
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);
|
||||
}
|
||||
ByteArrayResponseBodyReader reader = new ByteArrayResponseBodyReader();
|
||||
request.setResponseBodyReader(reader);
|
||||
if (creds != null)
|
||||
{
|
||||
request.setAuthenticator(new Authenticator() {
|
||||
public Credentials getCredentials(String realm, int attempts)
|
||||
request = connection.newRequest(method, file);
|
||||
if (!keepAlive)
|
||||
{
|
||||
return (attempts < 2) ? creds : null;
|
||||
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();
|
||||
}
|
||||
response = request.dispatch();
|
||||
catch (IOException ioe)
|
||||
{
|
||||
if (connection.useCount > 0)
|
||||
{
|
||||
// Connection re-use failed: Try a new connection.
|
||||
try
|
||||
{
|
||||
connection.close();
|
||||
}
|
||||
catch (IOException _)
|
||||
{
|
||||
// Ignore.
|
||||
}
|
||||
connection = null;
|
||||
retry = true;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// First time the connection was used: Hard failure.
|
||||
throw ioe;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
|
@ -60,7 +60,7 @@ import java.util.Set;
|
|||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -204,6 +186,27 @@ public class Headers
|
|||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,220 @@
|
|||
/* 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 (ddaney@avtrex.com)
|
||||
*/
|
||||
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;
|
||||
|
||||
// If we get to here, the stream was not fully read. Just throw
|
||||
// it away.
|
||||
|
||||
doClose = true;
|
||||
|
||||
handleClose();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
@ -99,11 +98,6 @@ public class Request
|
|||
*/
|
||||
protected int requestBodyNegotiationThreshold;
|
||||
|
||||
/**
|
||||
* The response body reader.
|
||||
*/
|
||||
protected ResponseBodyReader responseBodyReader;
|
||||
|
||||
/**
|
||||
* Map of response header handlers.
|
||||
*/
|
||||
|
@ -235,16 +229,6 @@ public class Request
|
|||
this.requestBodyWriter = requestBodyWriter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -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++)
|
||||
{
|
||||
|
|
|
@ -38,6 +38,7 @@ exception statement from your version. */
|
|||
|
||||
package gnu.java.net.protocol.http;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
|
@ -63,19 +64,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.
|
||||
*/
|
||||
|
@ -86,19 +74,23 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -172,6 +171,15 @@ public class Response
|
|||
return headers.getIntValue(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 (dog@gnu.org)
|
||||
*/
|
||||
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();
|
||||
|
||||
}
|
||||
|
|
@ -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 (dog@gnu.org)
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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 (dog@gnu.org)
|
||||
*/
|
||||
public interface ConnectionListener
|
||||
extends EventListener
|
||||
{
|
||||
|
||||
/**
|
||||
* Callback invoked when the associated connection is closed.
|
||||
*/
|
||||
void connectionClosed(ConnectionEvent event);
|
||||
|
||||
}
|
||||
|
|
@ -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 (dog@gnu.org)
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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 (dog@gnu.org)
|
||||
*/
|
||||
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);
|
||||
|
||||
}
|
||||
|
|
@ -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>
|
|
@ -69,13 +69,17 @@ public final class Connection extends JarURLConnection
|
|||
private static Hashtable cache = new Hashtable();
|
||||
private static final int READBUFSIZE = 4*1024;
|
||||
|
||||
public static synchronized JarFile get (URL url) throws IOException
|
||||
public static synchronized JarFile get (URL url, boolean useCaches)
|
||||
throws IOException
|
||||
{
|
||||
JarFile jf = (JarFile) cache.get (url);
|
||||
JarFile jf;
|
||||
if (useCaches)
|
||||
{
|
||||
jf = (JarFile) cache.get (url);
|
||||
if (jf != null)
|
||||
return jf;
|
||||
}
|
||||
|
||||
if (jf != null)
|
||||
return jf;
|
||||
|
||||
if ("file".equals (url.getProtocol()))
|
||||
{
|
||||
File f = new File (url.getFile());
|
||||
|
@ -100,9 +104,10 @@ public final class Connection extends JarURLConnection
|
|||
jf = new JarFile (f, true,
|
||||
ZipFile.OPEN_READ | ZipFile.OPEN_DELETE);
|
||||
}
|
||||
|
||||
cache.put (url, jf);
|
||||
|
||||
|
||||
if (useCaches)
|
||||
cache.put (url, jf);
|
||||
|
||||
return jf;
|
||||
}
|
||||
}
|
||||
|
@ -120,7 +125,7 @@ public final class Connection extends JarURLConnection
|
|||
return;
|
||||
|
||||
jar_url = getJarFileURL();
|
||||
jar_file = JarFileCache.get (jar_url);
|
||||
jar_file = JarFileCache.get (jar_url, useCaches);
|
||||
String entry_name = getEntryName();
|
||||
|
||||
if (entry_name != null
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue