Initial revision
From-SVN: r102074
This commit is contained in:
parent
6f4434b39b
commit
f911ba985a
4557 changed files with 1000262 additions and 0 deletions
190
libjava/classpath/gnu/java/net/BASE64.java
Normal file
190
libjava/classpath/gnu/java/net/BASE64.java
Normal file
|
@ -0,0 +1,190 @@
|
|||
/* BASE.java --
|
||||
Copyright (C) 2003, 2004, 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;
|
||||
|
||||
/**
|
||||
* Encodes and decodes text according to the BASE64 encoding.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public final class BASE64
|
||||
{
|
||||
private static final byte[] src = {
|
||||
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
|
||||
0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54,
|
||||
0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64,
|
||||
0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
|
||||
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
|
||||
0x79, 0x7a, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x2b, 0x2f
|
||||
};
|
||||
|
||||
private static final byte[] dst;
|
||||
static
|
||||
{
|
||||
dst = new byte[0x100];
|
||||
for (int i = 0x0; i < 0xff; i++)
|
||||
{
|
||||
dst[i] = -1;
|
||||
}
|
||||
for (int i = 0; i < src.length; i++)
|
||||
{
|
||||
dst[src[i]] = (byte) i;
|
||||
}
|
||||
}
|
||||
|
||||
private BASE64()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the specified byte array using the BASE64 algorithm.
|
||||
*
|
||||
* @param bs the source byte array
|
||||
*/
|
||||
public static byte[] encode(byte[] bs)
|
||||
{
|
||||
int si = 0, ti = 0; // source/target array indices
|
||||
byte[] bt = new byte[((bs.length + 2) * 4) / 3]; // target byte array
|
||||
for (; si < bs.length; si += 3)
|
||||
{
|
||||
int buflen = bs.length - si;
|
||||
if (buflen == 1)
|
||||
{
|
||||
byte b = bs[si];
|
||||
int i = 0;
|
||||
bt[ti++] = src[b >>> 2 & 0x3f];
|
||||
bt[ti++] = src[(b << 4 & 0x30) + (i >>> 4 & 0xf)];
|
||||
}
|
||||
else if (buflen == 2)
|
||||
{
|
||||
byte b1 = bs[si], b2 = bs[si + 1];
|
||||
int i = 0;
|
||||
bt[ti++] = src[b1 >>> 2 & 0x3f];
|
||||
bt[ti++] = src[(b1 << 4 & 0x30) + (b2 >>> 4 & 0xf)];
|
||||
bt[ti++] = src[(b2 << 2 & 0x3c) + (i >>> 6 & 0x3)];
|
||||
}
|
||||
else
|
||||
{
|
||||
byte b1 = bs[si], b2 = bs[si + 1], b3 = bs[si + 2];
|
||||
bt[ti++] = src[b1 >>> 2 & 0x3f];
|
||||
bt[ti++] = src[(b1 << 4 & 0x30) + (b2 >>> 4 & 0xf)];
|
||||
bt[ti++] = src[(b2 << 2 & 0x3c) + (b3 >>> 6 & 0x3)];
|
||||
bt[ti++] = src[b3 & 0x3f];
|
||||
}
|
||||
}
|
||||
if (ti < bt.length)
|
||||
{
|
||||
byte[] tmp = new byte[ti];
|
||||
System.arraycopy(bt, 0, tmp, 0, ti);
|
||||
bt = tmp;
|
||||
}
|
||||
/*while (ti < bt.length)
|
||||
{
|
||||
bt[ti++] = 0x3d;
|
||||
}*/
|
||||
return bt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the specified byte array using the BASE64 algorithm.
|
||||
*
|
||||
* @param bs the source byte array
|
||||
*/
|
||||
public static byte[] decode(byte[] bs)
|
||||
{
|
||||
int srclen = bs.length;
|
||||
while (srclen > 0 && bs[srclen - 1] == 0x3d)
|
||||
{
|
||||
srclen--; /* strip padding character */
|
||||
}
|
||||
byte[] buffer = new byte[srclen];
|
||||
int buflen = 0;
|
||||
int si = 0;
|
||||
int len = srclen - si;
|
||||
while (len > 0)
|
||||
{
|
||||
byte b0 = dst[bs[si++] & 0xff];
|
||||
byte b2 = dst[bs[si++] & 0xff];
|
||||
buffer[buflen++] = (byte) (b0 << 2 & 0xfc | b2 >>> 4 & 0x3);
|
||||
if (len > 2)
|
||||
{
|
||||
b0 = b2;
|
||||
b2 = dst[bs[si++] & 0xff];
|
||||
buffer[buflen++] = (byte) (b0 << 4 & 0xf0 | b2 >>> 2 & 0xf);
|
||||
if (len > 3)
|
||||
{
|
||||
b0 = b2;
|
||||
b2 = dst[bs[si++] & 0xff];
|
||||
buffer[buflen++] = (byte) (b0 << 6 & 0xc0 | b2 & 0x3f);
|
||||
}
|
||||
}
|
||||
len = srclen - si;
|
||||
}
|
||||
byte[] bt = new byte[buflen];
|
||||
System.arraycopy(buffer, 0, bt, 0, buflen);
|
||||
return bt;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
boolean decode = false;
|
||||
for (int i = 0; i < args.length; i++)
|
||||
{
|
||||
if (args[i].equals("-d"))
|
||||
{
|
||||
decode = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] in = args[i].getBytes("US-ASCII");
|
||||
byte[] out = decode ? decode(in) : encode(in);
|
||||
System.out.println(args[i] + " = " +
|
||||
new String(out, "US-ASCII"));
|
||||
}
|
||||
catch (java.io.UnsupportedEncodingException e)
|
||||
{
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
174
libjava/classpath/gnu/java/net/CRLFInputStream.java
Normal file
174
libjava/classpath/gnu/java/net/CRLFInputStream.java
Normal file
|
@ -0,0 +1,174 @@
|
|||
/* CRLFInputStream.java --
|
||||
Copyright (C) 2002, 2003, 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;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* An input stream that filters out CR/LF pairs into LFs.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public class CRLFInputStream
|
||||
extends FilterInputStream
|
||||
{
|
||||
/**
|
||||
* The CR octet.
|
||||
*/
|
||||
public static final int CR = 13;
|
||||
|
||||
/**
|
||||
* The LF octet.
|
||||
*/
|
||||
public static final int LF = 10;
|
||||
|
||||
private boolean doReset;
|
||||
|
||||
/**
|
||||
* Constructs a CR/LF input stream connected to the specified input
|
||||
* stream.
|
||||
*/
|
||||
public CRLFInputStream(InputStream in)
|
||||
{
|
||||
super(in.markSupported() ? in : new BufferedInputStream(in));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next byte of data from this input stream.
|
||||
* Returns -1 if the end of the stream has been reached.
|
||||
* @exception IOException if an I/O error occurs
|
||||
*/
|
||||
public int read()
|
||||
throws IOException
|
||||
{
|
||||
int c = in.read();
|
||||
if (c == CR)
|
||||
{
|
||||
in.mark(1);
|
||||
int d = in.read();
|
||||
if (d == LF)
|
||||
{
|
||||
c = d;
|
||||
}
|
||||
else
|
||||
{
|
||||
in.reset();
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads up to b.length bytes of data from this input stream into
|
||||
* an array of bytes.
|
||||
* Returns -1 if the end of the stream has been reached.
|
||||
* @exception IOException if an I/O error occurs
|
||||
*/
|
||||
public int read(byte[] b)
|
||||
throws IOException
|
||||
{
|
||||
return read(b, 0, b.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads up to len bytes of data from this input stream into an
|
||||
* array of bytes, starting at the specified offset.
|
||||
* Returns -1 if the end of the stream has been reached.
|
||||
* @exception IOException if an I/O error occurs
|
||||
*/
|
||||
public int read(byte[] b, int off, int len)
|
||||
throws IOException
|
||||
{
|
||||
in.mark(len + 1);
|
||||
int l = in.read(b, off, len);
|
||||
if (l > 0)
|
||||
{
|
||||
int i = indexOfCRLF(b, off, l);
|
||||
if (doReset)
|
||||
{
|
||||
in.reset();
|
||||
if (i != -1)
|
||||
{
|
||||
l = in.read(b, off, i + 1); // read to CR
|
||||
in.read(); // skip LF
|
||||
b[i] = LF; // fix CR as LF
|
||||
}
|
||||
else
|
||||
{
|
||||
l = in.read(b, off, len); // CR(s) but no LF
|
||||
}
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
private int indexOfCRLF(byte[] b, int off, int len)
|
||||
throws IOException
|
||||
{
|
||||
doReset = false;
|
||||
int lm1 = len - 1;
|
||||
for (int i = off; i < len; i++)
|
||||
{
|
||||
if (b[i] == CR)
|
||||
{
|
||||
int d;
|
||||
if (i == lm1)
|
||||
{
|
||||
d = in.read();
|
||||
doReset = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
d = b[i + 1];
|
||||
}
|
||||
if (d == LF)
|
||||
{
|
||||
doReset = true;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
183
libjava/classpath/gnu/java/net/CRLFOutputStream.java
Normal file
183
libjava/classpath/gnu/java/net/CRLFOutputStream.java
Normal file
|
@ -0,0 +1,183 @@
|
|||
/* CRLFOutputStream.java --
|
||||
Copyright (C) 2002, 2003, 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;
|
||||
|
||||
import java.io.FilterOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
/**
|
||||
* An output stream that filters LFs into CR/LF pairs.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public class CRLFOutputStream
|
||||
extends FilterOutputStream
|
||||
{
|
||||
static final String US_ASCII = "US-ASCII";
|
||||
|
||||
/**
|
||||
* The CR octet.
|
||||
*/
|
||||
public static final int CR = 13;
|
||||
|
||||
/**
|
||||
* The LF octet.
|
||||
*/
|
||||
public static final int LF = 10;
|
||||
|
||||
/**
|
||||
* The CR/LF pair.
|
||||
*/
|
||||
public static final byte[] CRLF = { CR, LF };
|
||||
|
||||
/**
|
||||
* The last byte read.
|
||||
*/
|
||||
protected int last;
|
||||
|
||||
/**
|
||||
* Constructs a CR/LF output stream connected to the specified output stream.
|
||||
*/
|
||||
public CRLFOutputStream(OutputStream out)
|
||||
{
|
||||
super(out);
|
||||
last = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a character to the underlying stream.
|
||||
* @exception IOException if an I/O error occurred
|
||||
*/
|
||||
public void write(int ch) throws IOException
|
||||
{
|
||||
if (ch == CR)
|
||||
{
|
||||
out.write(CRLF);
|
||||
}
|
||||
else if (ch == LF)
|
||||
{
|
||||
if (last != CR)
|
||||
{
|
||||
out.write(CRLF);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
out.write(ch);
|
||||
}
|
||||
last = ch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a byte array to the underlying stream.
|
||||
* @exception IOException if an I/O error occurred
|
||||
*/
|
||||
public void write(byte[] b)
|
||||
throws IOException
|
||||
{
|
||||
write(b, 0, b.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a portion of a byte array to the underlying stream.
|
||||
* @exception IOException if an I/O error occurred
|
||||
*/
|
||||
public void write(byte[] b, int off, int len)
|
||||
throws IOException
|
||||
{
|
||||
int d = off;
|
||||
len += off;
|
||||
for (int i = off; i < len; i++)
|
||||
{
|
||||
switch (b[i])
|
||||
{
|
||||
case CR:
|
||||
out.write (b, d, i - d);
|
||||
out.write (CRLF, 0, 2);
|
||||
d = i + 1;
|
||||
break;
|
||||
case LF:
|
||||
if (last != CR)
|
||||
{
|
||||
out.write (b, d, i - d);
|
||||
out.write (CRLF, 0, 2);
|
||||
}
|
||||
d = i + 1;
|
||||
break;
|
||||
}
|
||||
last = b[i];
|
||||
}
|
||||
if (len - d > 0)
|
||||
{
|
||||
out.write (b, d, len - d);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the specified ASCII string to the underlying stream.
|
||||
* @exception IOException if an I/O error occurred
|
||||
*/
|
||||
public void write(String text)
|
||||
throws IOException
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] bytes = text.getBytes(US_ASCII);
|
||||
write(bytes, 0, bytes.length);
|
||||
}
|
||||
catch (UnsupportedEncodingException e)
|
||||
{
|
||||
throw new IOException("The US-ASCII encoding is not supported " +
|
||||
"on this system");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a newline to the underlying stream.
|
||||
* @exception IOException if an I/O error occurred
|
||||
*/
|
||||
public void writeln()
|
||||
throws IOException
|
||||
{
|
||||
out.write(CRLF, 0, 2);
|
||||
}
|
||||
}
|
||||
|
70
libjava/classpath/gnu/java/net/EmptyX509TrustManager.java
Normal file
70
libjava/classpath/gnu/java/net/EmptyX509TrustManager.java
Normal file
|
@ -0,0 +1,70 @@
|
|||
/* EmptyX509TrustManager.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;
|
||||
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
/**
|
||||
* Empty implementation of an X509 trust manager.
|
||||
* This implementation does not check any certificates in the chain.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public class EmptyX509TrustManager
|
||||
implements X509TrustManager
|
||||
{
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType)
|
||||
throws CertificateException
|
||||
{
|
||||
}
|
||||
|
||||
public void checkServerTrusted(X509Certificate[] chain, String authType)
|
||||
throws CertificateException
|
||||
{
|
||||
}
|
||||
|
||||
public X509Certificate[] getAcceptedIssuers()
|
||||
{
|
||||
return new X509Certificate[0];
|
||||
}
|
||||
}
|
||||
|
65
libjava/classpath/gnu/java/net/GetLocalHostAction.java
Normal file
65
libjava/classpath/gnu/java/net/GetLocalHostAction.java
Normal file
|
@ -0,0 +1,65 @@
|
|||
/* GetLocalHostAction.java --
|
||||
Copyright (C) 2003, 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;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
/**
|
||||
* Privileged action to retrieve the local host InetAddress.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public class GetLocalHostAction
|
||||
implements PrivilegedAction
|
||||
{
|
||||
public Object run()
|
||||
{
|
||||
try
|
||||
{
|
||||
return InetAddress.getLocalHost();
|
||||
}
|
||||
catch (UnknownHostException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
138
libjava/classpath/gnu/java/net/HeaderFieldHelper.java
Normal file
138
libjava/classpath/gnu/java/net/HeaderFieldHelper.java
Normal file
|
@ -0,0 +1,138 @@
|
|||
/* HeaderFieldHelper.java -- Helps manage headers fields
|
||||
Copyright (C) 1998, 2003 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;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* This class manages header field keys and values.
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
*/
|
||||
public class HeaderFieldHelper
|
||||
{
|
||||
private Vector headerFieldKeys;
|
||||
private Vector headerFieldValues;
|
||||
|
||||
public HeaderFieldHelper()
|
||||
{
|
||||
this (10);
|
||||
}
|
||||
|
||||
public HeaderFieldHelper (int size)
|
||||
{
|
||||
headerFieldKeys = new Vector (size);
|
||||
headerFieldValues = new Vector (size);
|
||||
}
|
||||
|
||||
public void addHeaderField (String key, String value)
|
||||
{
|
||||
headerFieldKeys.addElement (key);
|
||||
headerFieldValues.addElement (value);
|
||||
}
|
||||
|
||||
public String getHeaderFieldKeyByIndex (int index)
|
||||
{
|
||||
String key = null;
|
||||
|
||||
try
|
||||
{
|
||||
key = (String) headerFieldKeys.elementAt (index);
|
||||
}
|
||||
catch (ArrayIndexOutOfBoundsException e)
|
||||
{
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
public String getHeaderFieldValueByIndex(int index)
|
||||
{
|
||||
String value = null;
|
||||
|
||||
try
|
||||
{
|
||||
value = (String) headerFieldValues.elementAt (index);
|
||||
}
|
||||
catch (ArrayIndexOutOfBoundsException e)
|
||||
{
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getHeaderFieldValueByKey(String key)
|
||||
{
|
||||
String value = null;
|
||||
|
||||
try
|
||||
{
|
||||
value = (String) headerFieldValues.elementAt
|
||||
(headerFieldKeys.indexOf(key));
|
||||
}
|
||||
catch (ArrayIndexOutOfBoundsException e)
|
||||
{
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public Map getHeaderFields()
|
||||
{
|
||||
HashMap headers = new HashMap();
|
||||
int max = headerFieldKeys.size();
|
||||
|
||||
for (int index = 0; index < max; index++)
|
||||
{
|
||||
headers.put(headerFieldKeys.elementAt(index),
|
||||
headerFieldValues.elementAt(index));
|
||||
}
|
||||
|
||||
return headers;
|
||||
}
|
||||
|
||||
public int getNumberOfEntries()
|
||||
{
|
||||
return headerFieldKeys.size();
|
||||
}
|
||||
|
||||
} // class HeaderFieldHelper
|
||||
|
198
libjava/classpath/gnu/java/net/LineInputStream.java
Normal file
198
libjava/classpath/gnu/java/net/LineInputStream.java
Normal file
|
@ -0,0 +1,198 @@
|
|||
/* LineInputStream.java --
|
||||
Copyright (C) 2002, 2003, 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;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* An input stream that can read lines of input.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public class LineInputStream
|
||||
extends FilterInputStream
|
||||
{
|
||||
/*
|
||||
* Line buffer.
|
||||
*/
|
||||
private ByteArrayOutputStream buf;
|
||||
|
||||
/*
|
||||
* Encoding to use when translating bytes to characters.
|
||||
*/
|
||||
private String encoding;
|
||||
|
||||
/*
|
||||
* End-of-stream flag.
|
||||
*/
|
||||
private boolean eof;
|
||||
|
||||
/**
|
||||
* Whether we can use block reads.
|
||||
*/
|
||||
private final boolean blockReads;
|
||||
|
||||
/**
|
||||
* Constructor using the US-ASCII character encoding.
|
||||
* @param in the underlying input stream
|
||||
*/
|
||||
public LineInputStream(InputStream in)
|
||||
{
|
||||
this(in, "US-ASCII");
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param in the underlying input stream
|
||||
* @param encoding the character encoding to use
|
||||
*/
|
||||
public LineInputStream(InputStream in, String encoding)
|
||||
{
|
||||
super(in);
|
||||
buf = new ByteArrayOutputStream();
|
||||
this.encoding = encoding;
|
||||
eof = false;
|
||||
blockReads = in.markSupported();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a line of input.
|
||||
*/
|
||||
public String readLine()
|
||||
throws IOException
|
||||
{
|
||||
if (eof)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
do
|
||||
{
|
||||
if (blockReads)
|
||||
{
|
||||
// Use mark and reset to read chunks of bytes
|
||||
final int MIN_LENGTH = 1024;
|
||||
int len, pos;
|
||||
|
||||
len = in.available();
|
||||
len = (len < MIN_LENGTH) ? MIN_LENGTH : len;
|
||||
byte[] b = new byte[len];
|
||||
in.mark(len);
|
||||
// Read into buffer b
|
||||
len = in.read(b, 0, len);
|
||||
// Handle EOF
|
||||
if (len == -1)
|
||||
{
|
||||
eof = true;
|
||||
if (buf.size() == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We don't care about resetting buf
|
||||
return buf.toString(encoding);
|
||||
}
|
||||
}
|
||||
// Get index of LF in b
|
||||
pos = indexOf(b, len, (byte) 0x0a);
|
||||
if (pos != -1)
|
||||
{
|
||||
// Write pos bytes to buf
|
||||
buf.write(b, 0, pos);
|
||||
// Reset stream, and read pos + 1 bytes
|
||||
in.reset();
|
||||
pos += 1;
|
||||
while (pos > 0)
|
||||
{
|
||||
len = in.read(b, 0, pos);
|
||||
pos = (len == -1) ? -1 : pos - len;
|
||||
}
|
||||
// Return line
|
||||
String ret = buf.toString(encoding);
|
||||
buf.reset();
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Append everything to buf and fall through to re-read.
|
||||
buf.write(b, 0, len);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We must use character reads in order not to read too much
|
||||
// from the underlying stream.
|
||||
int c = in.read();
|
||||
switch (c)
|
||||
{
|
||||
case -1:
|
||||
eof = true;
|
||||
if (buf.size() == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
// Fall through and return contents of buffer.
|
||||
case 0x0a: // LF
|
||||
String ret = buf.toString(encoding);
|
||||
buf.reset();
|
||||
return ret;
|
||||
default:
|
||||
buf.write(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
while (true);
|
||||
}
|
||||
|
||||
private int indexOf(byte[] b, int len, byte c)
|
||||
{
|
||||
for (int pos = 0; pos < len; pos++)
|
||||
{
|
||||
if (b[pos] == c)
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
321
libjava/classpath/gnu/java/net/PlainDatagramSocketImpl.java
Normal file
321
libjava/classpath/gnu/java/net/PlainDatagramSocketImpl.java
Normal file
|
@ -0,0 +1,321 @@
|
|||
/* PlainDatagramSocketImpl.java -- Default DatagramSocket implementation
|
||||
Copyright (C) 1998, 1999, 2001, 2003, 2004, 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;
|
||||
|
||||
import gnu.classpath.Configuration;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocketImpl;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketException;
|
||||
|
||||
/**
|
||||
* Written using on-line Java Platform 1.2 API Specification, as well
|
||||
* as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
|
||||
* Status: Believed complete and correct.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is the default socket implementation for datagram sockets.
|
||||
* It makes native calls to C routines that implement BSD style
|
||||
* SOCK_DGRAM sockets in the AF_INET family.
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
* @author Warren Levy (warrenl@cygnus.com)
|
||||
*/
|
||||
public final class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||
{
|
||||
// Static initializer to load native library
|
||||
static
|
||||
{
|
||||
if (Configuration.INIT_LOAD_LIBRARY)
|
||||
{
|
||||
System.loadLibrary("javanet");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Option id for the IP_TTL (time to live) value.
|
||||
*/
|
||||
private static final int IP_TTL = 0x1E61; // 7777
|
||||
|
||||
/**
|
||||
* This is the actual underlying file descriptor
|
||||
*/
|
||||
int native_fd = -1;
|
||||
|
||||
/**
|
||||
* Lock object to serialize threads wanting to receive
|
||||
*/
|
||||
private final Object RECEIVE_LOCK = new Object();
|
||||
|
||||
/**
|
||||
* Lock object to serialize threads wanting to send
|
||||
*/
|
||||
private final Object SEND_LOCK = new Object();
|
||||
|
||||
/**
|
||||
* Default do nothing constructor
|
||||
*/
|
||||
public PlainDatagramSocketImpl()
|
||||
{
|
||||
}
|
||||
|
||||
protected void finalize() throws Throwable
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (native_fd != -1)
|
||||
close();
|
||||
}
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
public int getNativeFD()
|
||||
{
|
||||
return native_fd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds this socket to a particular port and interface
|
||||
*
|
||||
* @param port The port to bind to
|
||||
* @param addr The address to bind to
|
||||
*
|
||||
* @exception SocketException If an error occurs
|
||||
*/
|
||||
protected synchronized native void bind(int port, InetAddress addr)
|
||||
throws SocketException;
|
||||
|
||||
/**
|
||||
* Creates a new datagram socket
|
||||
*
|
||||
* @exception SocketException If an error occurs
|
||||
*/
|
||||
protected synchronized native void create() throws SocketException;
|
||||
|
||||
/**
|
||||
* Sets the Time to Live value for the socket
|
||||
*
|
||||
* @param ttl The new TTL value
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
protected synchronized void setTimeToLive(int ttl) throws IOException
|
||||
{
|
||||
setOption(IP_TTL, new Integer(ttl));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Time to Live value for the socket
|
||||
*
|
||||
* @return The TTL value
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
protected synchronized int getTimeToLive() throws IOException
|
||||
{
|
||||
Object obj = getOption(IP_TTL);
|
||||
|
||||
if (! (obj instanceof Integer))
|
||||
throw new IOException("Internal Error");
|
||||
|
||||
return ((Integer) obj).intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a packet of data to a remote host
|
||||
*
|
||||
* @param addr The address to send to
|
||||
* @param port The port to send to
|
||||
* @param buf The buffer to send
|
||||
* @param offset The offset of the data in the buffer to send
|
||||
* @param len The length of the data to send
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
private native void sendto (InetAddress addr, int port,
|
||||
byte[] buf, int offset, int len)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Sends a packet of data to a remote host
|
||||
*
|
||||
* @param packet The packet to send
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
protected void send(DatagramPacket packet) throws IOException
|
||||
{
|
||||
synchronized(SEND_LOCK)
|
||||
{
|
||||
sendto(packet.getAddress(), packet.getPort(), packet.getData(),
|
||||
packet.getOffset(), packet.getLength());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Receives a UDP packet from the network
|
||||
*
|
||||
* @param packet The packet to fill in with the data received
|
||||
*
|
||||
* @exception IOException IOException If an error occurs
|
||||
*/
|
||||
protected void receive(DatagramPacket packet)
|
||||
throws IOException
|
||||
{
|
||||
synchronized(RECEIVE_LOCK)
|
||||
{
|
||||
receive0(packet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Native call to receive a UDP packet from the network
|
||||
*
|
||||
* @param packet The packet to fill in with the data received
|
||||
*
|
||||
* @exception IOException IOException If an error occurs
|
||||
*/
|
||||
private native void receive0(DatagramPacket packet) throws IOException;
|
||||
|
||||
/**
|
||||
* Sets the value of an option on the socket
|
||||
*
|
||||
* @param option_id The identifier of the option to set
|
||||
* @param val The value of the option to set
|
||||
*
|
||||
* @exception SocketException If an error occurs
|
||||
*/
|
||||
public synchronized native void setOption(int option_id, Object val)
|
||||
throws SocketException;
|
||||
|
||||
/**
|
||||
* Retrieves the value of an option on the socket
|
||||
*
|
||||
* @param option_id The identifier of the option to retrieve
|
||||
*
|
||||
* @return The value of the option
|
||||
*
|
||||
* @exception SocketException If an error occurs
|
||||
*/
|
||||
public synchronized native Object getOption(int option_id)
|
||||
throws SocketException;
|
||||
|
||||
/**
|
||||
* Closes the socket
|
||||
*/
|
||||
protected synchronized native void close();
|
||||
|
||||
/**
|
||||
* Gets the Time to Live value for the socket
|
||||
*
|
||||
* @return The TTL value
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*
|
||||
* @deprecated 1.2
|
||||
*/
|
||||
protected synchronized byte getTTL() throws IOException
|
||||
{
|
||||
return (byte) getTimeToLive();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Time to Live value for the socket
|
||||
*
|
||||
* @param ttl The new TTL value
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*
|
||||
* @deprecated 1.2
|
||||
*/
|
||||
protected synchronized void setTTL(byte ttl) throws IOException
|
||||
{
|
||||
setTimeToLive(((int) ttl) & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins a multicast group
|
||||
*
|
||||
* @param addr The group to join
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
protected synchronized native void join(InetAddress addr) throws IOException;
|
||||
|
||||
/**
|
||||
* Leaves a multicast group
|
||||
*
|
||||
* @param addr The group to leave
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
protected synchronized native void leave(InetAddress addr) throws IOException;
|
||||
|
||||
/**
|
||||
* What does this method really do?
|
||||
*/
|
||||
protected synchronized int peek(InetAddress addr) throws IOException
|
||||
{
|
||||
throw new IOException("Not Implemented Yet");
|
||||
}
|
||||
|
||||
public int peekData(DatagramPacket packet)
|
||||
{
|
||||
throw new InternalError
|
||||
("PlainDatagramSocketImpl::peekData is not implemented");
|
||||
}
|
||||
|
||||
public void joinGroup(SocketAddress address, NetworkInterface netIf)
|
||||
{
|
||||
throw new InternalError
|
||||
("PlainDatagramSocketImpl::joinGroup is not implemented");
|
||||
}
|
||||
|
||||
public void leaveGroup(SocketAddress address, NetworkInterface netIf)
|
||||
{
|
||||
throw new InternalError
|
||||
("PlainDatagramSocketImpl::leaveGroup is not implemented");
|
||||
}
|
||||
}
|
498
libjava/classpath/gnu/java/net/PlainSocketImpl.java
Normal file
498
libjava/classpath/gnu/java/net/PlainSocketImpl.java
Normal file
|
@ -0,0 +1,498 @@
|
|||
/* PlainSocketImpl.java -- Default socket implementation
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 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;
|
||||
|
||||
import gnu.classpath.Configuration;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketImpl;
|
||||
import java.net.SocketOptions;
|
||||
|
||||
/**
|
||||
* Written using on-line Java Platform 1.2 API Specification, as well
|
||||
* as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
|
||||
* Status: Believed complete and correct.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Unless the application installs its own SocketImplFactory, this is the
|
||||
* default socket implemetation that will be used. It simply uses a
|
||||
* combination of Java and native routines to implement standard BSD
|
||||
* style sockets of family AF_INET and types SOCK_STREAM and SOCK_DGRAM
|
||||
*
|
||||
* @author Per Bothner (bothner@cygnus.com)
|
||||
* @author Nic Ferrier (nferrier@tapsellferrier.co.uk)
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
*/
|
||||
public final class PlainSocketImpl extends SocketImpl
|
||||
{
|
||||
// Static initializer to load native library.
|
||||
static
|
||||
{
|
||||
if (Configuration.INIT_LOAD_LIBRARY)
|
||||
{
|
||||
System.loadLibrary("javanet");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The OS file handle representing the socket.
|
||||
* This is used for reads and writes to/from the socket and
|
||||
* to close it.
|
||||
*
|
||||
* When the socket is closed this is reset to -1.
|
||||
*/
|
||||
int native_fd = -1;
|
||||
|
||||
/**
|
||||
* A cached copy of the in stream for reading from the socket.
|
||||
*/
|
||||
private InputStream in;
|
||||
|
||||
/**
|
||||
* A cached copy of the out stream for writing to the socket.
|
||||
*/
|
||||
private OutputStream out;
|
||||
|
||||
/**
|
||||
* Indicates whether a channel initiated whatever operation
|
||||
* is being invoked on this socket.
|
||||
*/
|
||||
private boolean inChannelOperation;
|
||||
|
||||
/**
|
||||
* Indicates whether we should ignore whether any associated
|
||||
* channel is set to non-blocking mode. Certain operations
|
||||
* throw an <code>IllegalBlockingModeException</code> if the
|
||||
* associated channel is in non-blocking mode, <i>except</i>
|
||||
* if the operation is invoked by the channel itself.
|
||||
*/
|
||||
public final boolean isInChannelOperation()
|
||||
{
|
||||
return inChannelOperation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets our indicator of whether an I/O operation is being
|
||||
* initiated by a channel.
|
||||
*/
|
||||
public final void setInChannelOperation(boolean b)
|
||||
{
|
||||
inChannelOperation = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default do nothing constructor
|
||||
*/
|
||||
public PlainSocketImpl()
|
||||
{
|
||||
}
|
||||
|
||||
protected void finalize() throws Throwable
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (native_fd != -1)
|
||||
try
|
||||
{
|
||||
close();
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
public int getNativeFD()
|
||||
{
|
||||
return native_fd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the specified option on a socket to the passed in object. For
|
||||
* options that take an integer argument, the passed in object is an
|
||||
* Integer. The option_id parameter is one of the defined constants in
|
||||
* this interface.
|
||||
*
|
||||
* @param option_id The identifier of the option
|
||||
* @param val The value to set the option to
|
||||
*
|
||||
* @exception SocketException If an error occurs
|
||||
*/
|
||||
public native void setOption(int optID, Object value) throws SocketException;
|
||||
|
||||
/**
|
||||
* Returns the current setting of the specified option. The Object returned
|
||||
* will be an Integer for options that have integer values. The option_id
|
||||
* is one of the defined constants in this interface.
|
||||
*
|
||||
* @param option_id The option identifier
|
||||
*
|
||||
* @return The current value of the option
|
||||
*
|
||||
* @exception SocketException If an error occurs
|
||||
*/
|
||||
public native Object getOption(int optID) throws SocketException;
|
||||
|
||||
/**
|
||||
* Flushes the input stream and closes it. If you read from the input stream
|
||||
* after calling this method a <code>IOException</code> will be thrown.
|
||||
*
|
||||
* @throws IOException if an error occurs
|
||||
*/
|
||||
public native void shutdownInput() throws IOException;
|
||||
|
||||
/**
|
||||
* Flushes the output stream and closes it. If you write to the output stream
|
||||
* after calling this method a <code>IOException</code> will be thrown.
|
||||
*
|
||||
* @throws IOException if an error occurs
|
||||
*/
|
||||
public native void shutdownOutput() throws IOException;
|
||||
|
||||
/**
|
||||
* Creates a new socket that is not bound to any local address/port and
|
||||
* is not connected to any remote address/port. This will be created as
|
||||
* a stream socket if the stream parameter is true, or a datagram socket
|
||||
* if the stream parameter is false.
|
||||
*
|
||||
* @param stream true for a stream socket, false for a datagram socket
|
||||
*/
|
||||
protected synchronized native void create(boolean stream) throws IOException;
|
||||
|
||||
/**
|
||||
* Connects to the remote hostname and port specified as arguments.
|
||||
*
|
||||
* @param hostname The remote hostname to connect to
|
||||
* @param port The remote port to connect to
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
protected synchronized void connect(String host, int port) throws IOException
|
||||
{
|
||||
connect(InetAddress.getByName(host), port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to the remote address and port specified as arguments.
|
||||
*
|
||||
* @param addr The remote address to connect to
|
||||
* @param port The remote port to connect to
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
protected native void connect(InetAddress addr, int port) throws IOException;
|
||||
|
||||
/**
|
||||
* Connects to the remote socket address with a specified timeout.
|
||||
*
|
||||
* @param timeout The timeout to use for this connect, 0 means infinite.
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
protected synchronized void connect(SocketAddress address, int timeout) throws IOException
|
||||
{
|
||||
InetSocketAddress sockAddr = (InetSocketAddress) address;
|
||||
InetAddress addr = sockAddr.getAddress();
|
||||
|
||||
if (addr == null)
|
||||
throw new IllegalArgumentException("address is unresolved: " + sockAddr);
|
||||
|
||||
int port = sockAddr.getPort();
|
||||
|
||||
if (timeout < 0)
|
||||
throw new IllegalArgumentException("negative timeout");
|
||||
|
||||
Object oldTimeoutObj = null;
|
||||
|
||||
try
|
||||
{
|
||||
oldTimeoutObj = this.getOption (SocketOptions.SO_TIMEOUT);
|
||||
this.setOption (SocketOptions.SO_TIMEOUT, new Integer (timeout));
|
||||
connect (addr, port);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (oldTimeoutObj != null)
|
||||
this.setOption (SocketOptions.SO_TIMEOUT, oldTimeoutObj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds to the specified port on the specified addr. Note that this addr
|
||||
* must represent a local IP address. **** How bind to INADDR_ANY? ****
|
||||
*
|
||||
* @param addr The address to bind to
|
||||
* @param port The port number to bind to
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
protected synchronized native void bind(InetAddress addr, int port)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Starts listening for connections on a socket. The queuelen parameter
|
||||
* is how many pending connections will queue up waiting to be serviced
|
||||
* before being accept'ed. If the queue of pending requests exceeds this
|
||||
* number, additional connections will be refused.
|
||||
*
|
||||
* @param queuelen The length of the pending connection queue
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
protected synchronized native void listen(int queuelen)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Accepts a new connection on this socket and returns in in the
|
||||
* passed in SocketImpl.
|
||||
*
|
||||
* @param impl The SocketImpl object to accept this connection.
|
||||
*/
|
||||
protected synchronized native void accept(SocketImpl impl)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Returns the number of bytes that the caller can read from this socket
|
||||
* without blocking.
|
||||
*
|
||||
* @return The number of readable bytes before blocking
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
protected native int available() throws IOException;
|
||||
|
||||
/**
|
||||
* Closes the socket. This will cause any InputStream or OutputStream
|
||||
* objects for this Socket to be closed as well.
|
||||
* <p>
|
||||
* Note that if the SO_LINGER option is set on this socket, then the
|
||||
* operation could block.
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
protected native void close() throws IOException;
|
||||
|
||||
public void sendUrgentData(int data)
|
||||
{
|
||||
throw new InternalError ("PlainSocketImpl::sendUrgentData not implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method used by SocketInputStream for reading data from
|
||||
* the connection. Reads up to len bytes of data into the buffer
|
||||
* buf starting at offset bytes into the buffer.
|
||||
*
|
||||
* @return The actual number of bytes read or -1 if end of stream.
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
protected native int read(byte[] buf, int offset, int len)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Internal method used by SocketOuputStream for writing data to
|
||||
* the connection. Writes up to len bytes of data from the buffer
|
||||
* buf starting at offset bytes into the buffer.
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
protected native void write(byte[] buf, int offset, int len)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Returns an InputStream object for reading from this socket. This will
|
||||
* be an instance of SocketInputStream.
|
||||
*
|
||||
* @return An input stream attached to the socket.
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
protected synchronized InputStream getInputStream() throws IOException
|
||||
{
|
||||
if (in == null)
|
||||
in = new SocketInputStream();
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an OutputStream object for writing to this socket. This will
|
||||
* be an instance of SocketOutputStream.
|
||||
*
|
||||
* @return An output stream attached to the socket.
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
protected synchronized OutputStream getOutputStream() throws IOException
|
||||
{
|
||||
if (out == null)
|
||||
out = new SocketOutputStream();
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class contains an implementation of <code>InputStream</code> for
|
||||
* sockets. It in an internal only class used by <code>PlainSocketImpl</code>.
|
||||
*
|
||||
* @author Nic Ferrier (nferrier@tapsellferrier.co.uk)
|
||||
*/
|
||||
final class SocketInputStream
|
||||
extends InputStream
|
||||
{
|
||||
/**
|
||||
* Returns the number of bytes available to be read before blocking
|
||||
*/
|
||||
public int available() throws IOException
|
||||
{
|
||||
return PlainSocketImpl.this.available();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method not only closes the stream, it closes the underlying socket
|
||||
* (and thus any connection) and invalidates any other Input/Output streams
|
||||
* for the underlying impl object
|
||||
*/
|
||||
public void close() throws IOException
|
||||
{
|
||||
PlainSocketImpl.this.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next byte of data and returns it as an int.
|
||||
*
|
||||
* @return The byte read (as an int) or -1 if end of stream);
|
||||
*
|
||||
* @exception IOException If an error occurs.
|
||||
*/
|
||||
public int read() throws IOException
|
||||
{
|
||||
byte buf[] = new byte [1];
|
||||
int bytes_read = read(buf, 0, 1);
|
||||
|
||||
if (bytes_read == -1)
|
||||
return -1;
|
||||
|
||||
return buf[0] & 0xFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads up to len bytes of data into the caller supplied buffer starting
|
||||
* at offset bytes from the start of the buffer
|
||||
*
|
||||
* @param buf The buffer
|
||||
* @param offset Offset into the buffer to start reading from
|
||||
* @param len The number of bytes to read
|
||||
*
|
||||
* @return The number of bytes actually read or -1 if end of stream
|
||||
*
|
||||
* @exception IOException If an error occurs.
|
||||
*/
|
||||
public int read (byte[] buf, int offset, int len) throws IOException
|
||||
{
|
||||
int bytes_read = PlainSocketImpl.this.read (buf, offset, len);
|
||||
|
||||
if (bytes_read == 0)
|
||||
return -1;
|
||||
|
||||
return bytes_read;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is used internally by <code>PlainSocketImpl</code> to be the
|
||||
* <code>OutputStream</code> subclass returned by its
|
||||
* <code>getOutputStream method</code>. It expects only to be used in that
|
||||
* context.
|
||||
*
|
||||
* @author Nic Ferrier (nferrier@tapsellferrier.co.uk)
|
||||
*/
|
||||
final class SocketOutputStream
|
||||
extends OutputStream
|
||||
{
|
||||
/**
|
||||
* This method closes the stream and the underlying socket connection. This
|
||||
* action also effectively closes any other InputStream or OutputStream
|
||||
* object associated with the connection.
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
public void close() throws IOException
|
||||
{
|
||||
PlainSocketImpl.this.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a byte (passed in as an int) to the given output stream
|
||||
*
|
||||
* @param b The byte to write
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
public void write(int b) throws IOException
|
||||
{
|
||||
byte buf[] = { (byte) b };
|
||||
write(buf, 0, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes len number of bytes from the array buf to the stream starting
|
||||
* at offset bytes into the buffer.
|
||||
*
|
||||
* @param buf The buffer
|
||||
* @param offset Offset into the buffer to start writing from
|
||||
* @param len The number of bytes to write
|
||||
*
|
||||
* @exception IOException If an error occurs.
|
||||
*/
|
||||
public void write (byte[] buf, int offset, int len) throws IOException
|
||||
{
|
||||
PlainSocketImpl.this.write (buf, offset, len);
|
||||
}
|
||||
}
|
||||
}
|
57
libjava/classpath/gnu/java/net/URLParseError.java
Normal file
57
libjava/classpath/gnu/java/net/URLParseError.java
Normal file
|
@ -0,0 +1,57 @@
|
|||
/* URLParseError.java -- Helps bypassing the exception limitation for
|
||||
URLStreamHandler.parseURL().
|
||||
Copyright (C) 2003 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;
|
||||
|
||||
/**
|
||||
* This class helps the people writing protocols to report URL parse
|
||||
* errors in parseUrl as this method cannot report other exceptions
|
||||
* than Errors.
|
||||
*
|
||||
* The main drawback is that it uses the Error mechanism which should not
|
||||
* be used for that type of error reporting.
|
||||
*
|
||||
* @author Guilhem Lavaux (guilhem@kaffe.org)
|
||||
*/
|
||||
public class URLParseError extends Error
|
||||
{
|
||||
public URLParseError(String msg)
|
||||
{
|
||||
super(msg);
|
||||
}
|
||||
}
|
46
libjava/classpath/gnu/java/net/package.html
Normal file
46
libjava/classpath/gnu/java/net/package.html
Normal file
|
@ -0,0 +1,46 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<!-- package.html - describes classes in gnu.java.net 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</title></head>
|
||||
|
||||
<body>
|
||||
<p></p>
|
||||
|
||||
</body>
|
||||
</html>
|
319
libjava/classpath/gnu/java/net/protocol/file/Connection.java
Normal file
319
libjava/classpath/gnu/java/net/protocol/file/Connection.java
Normal file
|
@ -0,0 +1,319 @@
|
|||
/* FileURLConnection.java -- URLConnection class for "file" protocol
|
||||
Copyright (C) 1998, 1999, 2003 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.file;
|
||||
|
||||
import gnu.classpath.SystemProperties;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FilePermission;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.net.ProtocolException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.security.Permission;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* This subclass of java.net.URLConnection models a URLConnection via
|
||||
* the "file" protocol.
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
* @author Nic Ferrier (nferrier@tapsellferrier.co.uk)
|
||||
* @author Warren Levy (warrenl@cygnus.com)
|
||||
*/
|
||||
public class Connection extends URLConnection
|
||||
{
|
||||
/**
|
||||
* Default permission for a file
|
||||
*/
|
||||
private static final String DEFAULT_PERMISSION = "read";
|
||||
|
||||
private static class StaticData
|
||||
{
|
||||
/**
|
||||
* HTTP-style DateFormat, used to format the last-modified header.
|
||||
*/
|
||||
static SimpleDateFormat dateFormat
|
||||
= new SimpleDateFormat("EEE, dd MMM yyyy hh:mm:ss 'GMT'",
|
||||
new Locale ("En", "Us", "Unix"));
|
||||
|
||||
static String lineSeparator =
|
||||
SystemProperties.getProperty("line.separator");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is a File object for this connection
|
||||
*/
|
||||
private File file;
|
||||
|
||||
/**
|
||||
* If a directory, contains a list of files in the directory.
|
||||
*/
|
||||
private byte[] directoryListing;
|
||||
|
||||
/**
|
||||
* InputStream if we are reading from the file
|
||||
*/
|
||||
private InputStream inputStream;
|
||||
|
||||
/**
|
||||
* OutputStream if we are writing to the file
|
||||
*/
|
||||
private OutputStream outputStream;
|
||||
|
||||
/**
|
||||
* FilePermission to read the file
|
||||
*/
|
||||
private FilePermission permission;
|
||||
|
||||
/**
|
||||
* Calls superclass constructor to initialize.
|
||||
*/
|
||||
public Connection(URL url)
|
||||
{
|
||||
super (url);
|
||||
|
||||
permission = new FilePermission(getURL().getFile(), DEFAULT_PERMISSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* "Connects" to the file by opening it.
|
||||
*/
|
||||
public void connect() throws IOException
|
||||
{
|
||||
// Call is ignored if already connected.
|
||||
if (connected)
|
||||
return;
|
||||
|
||||
// If not connected, then file needs to be openned.
|
||||
file = new File (getURL().getFile());
|
||||
|
||||
if (! file.isDirectory())
|
||||
{
|
||||
if (doInput)
|
||||
inputStream = new BufferedInputStream(new FileInputStream(file));
|
||||
|
||||
if (doOutput)
|
||||
outputStream = new BufferedOutputStream(new FileOutputStream(file));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (doInput)
|
||||
{
|
||||
inputStream = new ByteArrayInputStream(getDirectoryListing());
|
||||
}
|
||||
|
||||
if (doOutput)
|
||||
throw new ProtocolException
|
||||
("file: protocol does not support output on directories");
|
||||
}
|
||||
|
||||
connected = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the <code>directoryListing</code> field with a byte array
|
||||
* containing a representation of the directory listing.
|
||||
*/
|
||||
byte[] getDirectoryListing()
|
||||
throws IOException
|
||||
{
|
||||
if (directoryListing == null)
|
||||
{
|
||||
ByteArrayOutputStream sink = new ByteArrayOutputStream();
|
||||
// NB uses default character encoding for this system
|
||||
Writer writer = new OutputStreamWriter(sink);
|
||||
|
||||
String[] files = file.list();
|
||||
|
||||
for (int i = 0; i < files.length; i++)
|
||||
{
|
||||
writer.write(files[i]);
|
||||
writer.write(StaticData.lineSeparator);
|
||||
}
|
||||
|
||||
directoryListing = sink.toByteArray();
|
||||
}
|
||||
return directoryListing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the file for reading and returns a stream for it.
|
||||
*
|
||||
* @return An InputStream for this connection.
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
public InputStream getInputStream()
|
||||
throws IOException
|
||||
{
|
||||
if (!doInput)
|
||||
throw new ProtocolException("Can't open InputStream if doInput is false");
|
||||
|
||||
if (!connected)
|
||||
connect();
|
||||
|
||||
return inputStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the file for writing and returns a stream for it.
|
||||
*
|
||||
* @return An OutputStream for this connection.
|
||||
*
|
||||
* @exception IOException If an error occurs.
|
||||
*/
|
||||
public OutputStream getOutputStream()
|
||||
throws IOException
|
||||
{
|
||||
if (!doOutput)
|
||||
throw new
|
||||
ProtocolException("Can't open OutputStream if doOutput is false");
|
||||
|
||||
if (!connected)
|
||||
connect();
|
||||
|
||||
return outputStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last modified time of the resource.
|
||||
*
|
||||
* @return the time since epoch that the resource was modified.
|
||||
*/
|
||||
public long getLastModified()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!connected)
|
||||
connect();
|
||||
|
||||
return file.lastModified();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an http-style header field. Just handle a few common ones.
|
||||
*/
|
||||
public String getHeaderField(String field)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!connected)
|
||||
connect();
|
||||
|
||||
if (field.equals("content-type"))
|
||||
return guessContentTypeFromName(file.getName());
|
||||
else if (field.equals("content-length"))
|
||||
{
|
||||
if (file.isDirectory())
|
||||
{
|
||||
return Integer.toString(getContentLength());
|
||||
}
|
||||
return Long.toString(file.length());
|
||||
}
|
||||
else if (field.equals("last-modified"))
|
||||
{
|
||||
synchronized (StaticData.dateFormat)
|
||||
{
|
||||
return StaticData.dateFormat.format(
|
||||
new Date(file.lastModified()));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// Fall through.
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the length of content.
|
||||
*
|
||||
* @return the length of the content.
|
||||
*/
|
||||
public int getContentLength()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!connected)
|
||||
connect();
|
||||
|
||||
if (file.isDirectory())
|
||||
{
|
||||
return getDirectoryListing().length;
|
||||
}
|
||||
return (int) file.length();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a <code>Permission</code> object representing the
|
||||
* permissions required to access this URL. This method returns a
|
||||
* <code>java.io.FilePermission</code> for the file's path with a read
|
||||
* permission.
|
||||
*
|
||||
* @return A Permission object
|
||||
*/
|
||||
public Permission getPermission() throws IOException
|
||||
{
|
||||
return permission;
|
||||
}
|
||||
}
|
91
libjava/classpath/gnu/java/net/protocol/file/Handler.java
Normal file
91
libjava/classpath/gnu/java/net/protocol/file/Handler.java
Normal file
|
@ -0,0 +1,91 @@
|
|||
/* Handler.java -- "file" protocol handler for java.net
|
||||
Copyright (C) 1998, 1999, 2000, 2002, 2003, 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.file;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLStreamHandler;
|
||||
|
||||
/**
|
||||
* This is the protocol handler for the "file" protocol.
|
||||
* It implements the abstract openConnection() method from
|
||||
* URLStreamHandler by returning a new FileURLConnection object (from
|
||||
* this package). All other methods are inherited
|
||||
*
|
||||
* @author Aaron M. Renn (arenn@urbanophile.com)
|
||||
* @author Warren Levy (warrenl@cygnus.com)
|
||||
*/
|
||||
public class Handler extends URLStreamHandler
|
||||
{
|
||||
/**
|
||||
* A do nothing constructor
|
||||
*/
|
||||
public Handler()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returs a new FileURLConnection for the specified URL
|
||||
*
|
||||
* @param url The URL to return a connection for
|
||||
*
|
||||
* @return The URLConnection
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
protected URLConnection openConnection(URL url) throws IOException
|
||||
{
|
||||
// If a hostname is set, then we need to switch protocols to ftp
|
||||
// in order to transfer this from the remote host.
|
||||
String host = url.getHost();
|
||||
if ((host != null) && (! host.equals("")))
|
||||
{
|
||||
// Reset the protocol (and implicitly the handler) for this URL.
|
||||
// Then have the URL attempt the connection again, as it will
|
||||
// get the changed handler the next time around.
|
||||
// If the ftp protocol handler is not installed, an
|
||||
// exception will be thrown from the new openConnection() call.
|
||||
setURL (url, "ftp", url.getHost(), url.getPort(), url.getFile(),
|
||||
url.getRef());
|
||||
return url.openConnection();
|
||||
}
|
||||
|
||||
return new Connection(url);
|
||||
}
|
||||
} // class Handler
|
46
libjava/classpath/gnu/java/net/protocol/file/package.html
Normal file
46
libjava/classpath/gnu/java/net/protocol/file/package.html
Normal file
|
@ -0,0 +1,46 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<!-- package.html - describes classes in gnu.java.net.protocol.file 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.file</title></head>
|
||||
|
||||
<body>
|
||||
<p></p>
|
||||
|
||||
</body>
|
||||
</html>
|
251
libjava/classpath/gnu/java/net/protocol/ftp/ActiveModeDTP.java
Normal file
251
libjava/classpath/gnu/java/net/protocol/ftp/ActiveModeDTP.java
Normal file
|
@ -0,0 +1,251 @@
|
|||
/* ActiveModeDTP.java --
|
||||
Copyright (C) 2003, 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.ftp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
|
||||
/**
|
||||
* An active mode FTP data transfer process.
|
||||
* This starts a server on the specified port listening for a data
|
||||
* connection. It converts the socket input into a file stream for reading.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
final class ActiveModeDTP
|
||||
implements DTP, Runnable
|
||||
{
|
||||
|
||||
ServerSocket server;
|
||||
Socket socket;
|
||||
DTPInputStream in;
|
||||
DTPOutputStream out;
|
||||
boolean completed;
|
||||
boolean inProgress;
|
||||
int transferMode;
|
||||
IOException exception;
|
||||
Thread acceptThread;
|
||||
int connectionTimeout;
|
||||
|
||||
ActiveModeDTP(InetAddress localhost, int port,
|
||||
int connectionTimeout, int timeout)
|
||||
throws IOException
|
||||
{
|
||||
completed = false;
|
||||
inProgress = false;
|
||||
server = new ServerSocket(port, 1, localhost);
|
||||
if (timeout > 0)
|
||||
{
|
||||
server.setSoTimeout(timeout);
|
||||
}
|
||||
if (connectionTimeout <= 0)
|
||||
{
|
||||
connectionTimeout = 20000;
|
||||
}
|
||||
this.connectionTimeout = connectionTimeout;
|
||||
acceptThread = new Thread(this, "ActiveModeDTP");
|
||||
acceptThread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start listening.
|
||||
*/
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
socket = server.accept();
|
||||
//System.err.println("Accepted connection from "+socket.getInetAddress()+":"+socket.getPort());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
exception = e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits until a client has connected.
|
||||
*/
|
||||
public void waitFor()
|
||||
throws IOException
|
||||
{
|
||||
try
|
||||
{
|
||||
acceptThread.join(connectionTimeout);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
}
|
||||
if (exception != null)
|
||||
{
|
||||
throw exception;
|
||||
}
|
||||
if (socket == null)
|
||||
{
|
||||
server.close();
|
||||
throw new IOException("client did not connect before timeout");
|
||||
}
|
||||
acceptThread = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an input stream from which a remote file can be read.
|
||||
*/
|
||||
public InputStream getInputStream()
|
||||
throws IOException
|
||||
{
|
||||
if (inProgress)
|
||||
{
|
||||
throw new IOException("Transfer in progress");
|
||||
}
|
||||
if (acceptThread != null)
|
||||
{
|
||||
waitFor();
|
||||
}
|
||||
switch (transferMode)
|
||||
{
|
||||
case FTPConnection.MODE_STREAM:
|
||||
in = new StreamInputStream(this, socket.getInputStream());
|
||||
break;
|
||||
case FTPConnection.MODE_BLOCK:
|
||||
in = new BlockInputStream(this, socket.getInputStream());
|
||||
break;
|
||||
case FTPConnection.MODE_COMPRESSED:
|
||||
in = new CompressedInputStream(this, socket.getInputStream());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("invalid transfer mode");
|
||||
}
|
||||
in.setTransferComplete(false);
|
||||
return in;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an output stream to which a local file can be written for
|
||||
* upload.
|
||||
*/
|
||||
public OutputStream getOutputStream() throws IOException
|
||||
{
|
||||
if (inProgress)
|
||||
{
|
||||
throw new IOException("Transfer in progress");
|
||||
}
|
||||
if (acceptThread != null)
|
||||
{
|
||||
waitFor();
|
||||
}
|
||||
switch (transferMode)
|
||||
{
|
||||
case FTPConnection.MODE_STREAM:
|
||||
out = new StreamOutputStream(this, socket.getOutputStream());
|
||||
break;
|
||||
case FTPConnection.MODE_BLOCK:
|
||||
out = new BlockOutputStream(this, socket.getOutputStream());
|
||||
break;
|
||||
case FTPConnection.MODE_COMPRESSED:
|
||||
out = new CompressedOutputStream(this, socket.getOutputStream());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("invalid transfer mode");
|
||||
}
|
||||
out.setTransferComplete(false);
|
||||
return out;
|
||||
}
|
||||
|
||||
public void setTransferMode(int mode)
|
||||
{
|
||||
transferMode = mode;
|
||||
}
|
||||
|
||||
public void complete()
|
||||
{
|
||||
completed = true;
|
||||
if (!inProgress)
|
||||
{
|
||||
transferComplete();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean abort()
|
||||
{
|
||||
completed = true;
|
||||
transferComplete();
|
||||
return inProgress;
|
||||
}
|
||||
|
||||
public void transferComplete()
|
||||
{
|
||||
if (socket == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (in != null)
|
||||
{
|
||||
in.setTransferComplete(true);
|
||||
}
|
||||
if (out != null)
|
||||
{
|
||||
out.setTransferComplete(true);
|
||||
}
|
||||
completed = completed || (transferMode == FTPConnection.MODE_STREAM);
|
||||
if (completed && socket != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
socket.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
}
|
||||
try
|
||||
{
|
||||
server.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
/* BlockInputStream.java --
|
||||
Copyright (C) 2003, 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.ftp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* A DTP input stream that implements the FTP block transfer mode.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
class BlockInputStream
|
||||
extends DTPInputStream
|
||||
{
|
||||
|
||||
static final int EOF = 64;
|
||||
|
||||
int descriptor;
|
||||
int max = -1;
|
||||
int count = -1;
|
||||
|
||||
BlockInputStream(DTP dtp, InputStream in)
|
||||
{
|
||||
super(dtp, in);
|
||||
}
|
||||
|
||||
public int read()
|
||||
throws IOException
|
||||
{
|
||||
if (transferComplete)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (count == -1)
|
||||
{
|
||||
readHeader();
|
||||
}
|
||||
if (max < 1)
|
||||
{
|
||||
close();
|
||||
return -1;
|
||||
}
|
||||
int c = in.read();
|
||||
if (c == -1)
|
||||
{
|
||||
dtp.transferComplete();
|
||||
}
|
||||
count++;
|
||||
if (count >= max)
|
||||
{
|
||||
count = -1;
|
||||
if (descriptor == EOF)
|
||||
{
|
||||
close();
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
public int read(byte[] buf)
|
||||
throws IOException
|
||||
{
|
||||
return read(buf, 0, buf.length);
|
||||
}
|
||||
|
||||
public int read(byte[] buf, int off, int len)
|
||||
throws IOException
|
||||
{
|
||||
if (transferComplete)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (count == -1)
|
||||
{
|
||||
readHeader();
|
||||
}
|
||||
if (max < 1)
|
||||
{
|
||||
close();
|
||||
return -1;
|
||||
}
|
||||
int l = in.read(buf, off, len);
|
||||
if (l == -1)
|
||||
{
|
||||
dtp.transferComplete();
|
||||
}
|
||||
count += l;
|
||||
if (count >= max)
|
||||
{
|
||||
count = -1;
|
||||
if (descriptor == EOF)
|
||||
{
|
||||
close();
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the block header.
|
||||
*/
|
||||
void readHeader()
|
||||
throws IOException
|
||||
{
|
||||
descriptor = in.read();
|
||||
int max_hi = in.read();
|
||||
int max_lo = in.read();
|
||||
max = (max_hi << 8) | max_lo;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
/* BlockOutputStream.java --
|
||||
Copyright (C) 2003, 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.ftp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* A DTP output stream that implements the FTP block transfer mode.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
class BlockOutputStream
|
||||
extends DTPOutputStream
|
||||
{
|
||||
|
||||
static final byte RECORD = -128; // 0x80
|
||||
static final byte EOF = 64; // 0x40
|
||||
|
||||
BlockOutputStream(DTP dtp, OutputStream out)
|
||||
{
|
||||
super(dtp, out);
|
||||
}
|
||||
|
||||
public void write(int c)
|
||||
throws IOException
|
||||
{
|
||||
if (transferComplete)
|
||||
{
|
||||
return;
|
||||
}
|
||||
byte[] buf = new byte[]
|
||||
{
|
||||
RECORD, /* record descriptor */
|
||||
0x00, 0x01, /* one byte */
|
||||
(byte) c /* the byte */
|
||||
};
|
||||
out.write(buf, 0, 4);
|
||||
}
|
||||
|
||||
public void write(byte[] b)
|
||||
throws IOException
|
||||
{
|
||||
write(b, 0, b.length);
|
||||
}
|
||||
|
||||
public void write(byte[] b, int off, int len)
|
||||
throws IOException
|
||||
{
|
||||
if (transferComplete)
|
||||
{
|
||||
return;
|
||||
}
|
||||
byte[] buf = new byte[len + 3];
|
||||
buf[0] = RECORD; /* record descriptor */
|
||||
buf[1] = (byte) ((len & 0x00ff) >> 8); /* high byte of bytecount */
|
||||
buf[2] = (byte) (len & 0xff00); /* low byte of bytecount */
|
||||
System.arraycopy(b, off, buf, 3, len);
|
||||
out.write(buf, 0, len);
|
||||
}
|
||||
|
||||
public void close()
|
||||
throws IOException
|
||||
{
|
||||
byte[] buf = new byte[]
|
||||
{
|
||||
EOF, /* eof descriptor */
|
||||
0x00, 0x00 /* no bytes */
|
||||
};
|
||||
out.write(buf, 0, 3);
|
||||
super.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,215 @@
|
|||
/* CompressedInputStream.java --
|
||||
Copyright (C) 2003, 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.ftp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.ProtocolException;
|
||||
|
||||
/**
|
||||
* A DTP input stream that implements the FTP compressed transfer mode.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
class CompressedInputStream
|
||||
extends DTPInputStream
|
||||
{
|
||||
|
||||
static final int EOF = 64;
|
||||
|
||||
static final int RAW = 0x00;
|
||||
static final int COMPRESSED = 0x80;
|
||||
static final int FILLER = 0xc0;
|
||||
|
||||
int descriptor;
|
||||
int max = -1;
|
||||
int count = -1;
|
||||
|
||||
int state = RAW; // RAW | STATE | FILLER
|
||||
int rep; // the compressed byte
|
||||
int n = 0; // the number of compressed or raw bytes
|
||||
|
||||
CompressedInputStream(DTP dtp, InputStream in)
|
||||
{
|
||||
super(dtp, in);
|
||||
}
|
||||
|
||||
public int read()
|
||||
throws IOException
|
||||
{
|
||||
if (transferComplete)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (count == -1)
|
||||
{
|
||||
readHeader();
|
||||
}
|
||||
if (max < 1)
|
||||
{
|
||||
close();
|
||||
return -1;
|
||||
}
|
||||
if (n > 0 && (state == COMPRESSED || state == FILLER))
|
||||
{
|
||||
n--;
|
||||
return rep;
|
||||
}
|
||||
int c = in.read();
|
||||
if (c == -1)
|
||||
{
|
||||
close();
|
||||
}
|
||||
count++;
|
||||
if (count >= max)
|
||||
{
|
||||
count = -1;
|
||||
if (descriptor == EOF)
|
||||
{
|
||||
close();
|
||||
}
|
||||
}
|
||||
if (c == -1)
|
||||
{
|
||||
return c;
|
||||
}
|
||||
while (n == 0) // read code header
|
||||
{
|
||||
state = (c & 0xc0);
|
||||
n = (c & 0x3f);
|
||||
c = in.read();
|
||||
if (c == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
switch (state)
|
||||
{
|
||||
case RAW:
|
||||
break;
|
||||
case COMPRESSED:
|
||||
case FILLER:
|
||||
rep = c;
|
||||
break;
|
||||
default:
|
||||
throw new ProtocolException("Illegal state: " + state);
|
||||
}
|
||||
n--;
|
||||
return c;
|
||||
}
|
||||
|
||||
public int read(byte[] buf)
|
||||
throws IOException
|
||||
{
|
||||
return read(buf, 0, buf.length);
|
||||
}
|
||||
|
||||
public int read(byte[] buf, int off, int len)
|
||||
throws IOException
|
||||
{
|
||||
if (transferComplete)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (count == -1)
|
||||
{
|
||||
readHeader();
|
||||
}
|
||||
if (max < 1)
|
||||
{
|
||||
close();
|
||||
return -1;
|
||||
}
|
||||
// TODO improve performance
|
||||
for (int i = off; i < len; i++)
|
||||
{
|
||||
int c = read();
|
||||
if (c == -1)
|
||||
{
|
||||
close();
|
||||
return i;
|
||||
}
|
||||
buf[i] = (byte) c;
|
||||
}
|
||||
return len;
|
||||
/*
|
||||
int l = in.read (buf, off, len);
|
||||
if (l==-1)
|
||||
{
|
||||
close ();
|
||||
}
|
||||
count += l;
|
||||
if (count>=max)
|
||||
{
|
||||
count = -1;
|
||||
if (descriptor==EOF)
|
||||
{
|
||||
close ();
|
||||
}
|
||||
}
|
||||
return l;
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the block header.
|
||||
*/
|
||||
void readHeader()
|
||||
throws IOException
|
||||
{
|
||||
descriptor = in.read();
|
||||
int max_hi = in.read();
|
||||
int max_lo = in.read();
|
||||
max = (max_hi << 8) | max_lo;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the code header.
|
||||
*/
|
||||
void readCodeHeader()
|
||||
throws IOException
|
||||
{
|
||||
int code = in.read();
|
||||
state = (code & 0xc0);
|
||||
n = (code & 0x3f);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,228 @@
|
|||
/* CompressedOutputStream.java --
|
||||
Copyright (C) 2003, 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.ftp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* A DTP output stream that implements the FTP compressed transfer mode.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
class CompressedOutputStream
|
||||
extends DTPOutputStream
|
||||
{
|
||||
|
||||
static final byte RECORD = -128; // 0x80
|
||||
static final byte EOF = 64; // 0x40
|
||||
|
||||
CompressedOutputStream(DTP dtp, OutputStream out)
|
||||
{
|
||||
super(dtp, out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Just one byte cannot be compressed.
|
||||
* It takes 5 bytes to transmit - hardly very compressed!
|
||||
*/
|
||||
public void write(int c)
|
||||
throws IOException
|
||||
{
|
||||
if (transferComplete)
|
||||
{
|
||||
return;
|
||||
}
|
||||
byte[] buf = new byte[]
|
||||
{
|
||||
RECORD, /* record descriptor */
|
||||
0x00, 0x01, /* one byte */
|
||||
0x01, /* one uncompressed byte */
|
||||
(byte) c /* the byte */
|
||||
};
|
||||
out.write(buf, 0, 5);
|
||||
}
|
||||
|
||||
public void write(byte[] b)
|
||||
throws IOException
|
||||
{
|
||||
write(b, 0, b.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* The larger len is, the better.
|
||||
*/
|
||||
public void write(byte[] b, int off, int len)
|
||||
throws IOException
|
||||
{
|
||||
if (transferComplete)
|
||||
{
|
||||
return;
|
||||
}
|
||||
byte[] buf = compress(b, off, len);
|
||||
len = buf.length;
|
||||
buf[0] = RECORD; /* record descriptor */
|
||||
buf[1] = (byte) ((len & 0x00ff) >> 8); /* high byte of bytecount */
|
||||
buf[2] = (byte) (len & 0xff00); /* low byte of bytecount */
|
||||
out.write(buf, 0, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the compressed form of the given byte array.
|
||||
* The first 3 bytes are left free for header information.
|
||||
*/
|
||||
byte[] compress(byte[] b, int off, int len)
|
||||
{
|
||||
byte[] buf = new byte[len];
|
||||
byte last = 0;
|
||||
int pos = 0, raw_count = 0, rep_count = 1;
|
||||
for (int i = off; i < len; i++)
|
||||
{
|
||||
byte c = b[i];
|
||||
if (i > off && c == last) // compress
|
||||
{
|
||||
if (raw_count > 0) // flush raw bytes to buf
|
||||
{
|
||||
// need to add raw_count+1 bytes
|
||||
if (pos + (raw_count + 1) > buf.length)
|
||||
{
|
||||
buf = realloc(buf, len);
|
||||
}
|
||||
pos = flush_raw(buf, pos, b, (i - raw_count) - 1,
|
||||
raw_count);
|
||||
raw_count = 0;
|
||||
}
|
||||
rep_count++; // keep looking for same byte
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rep_count > 1) // flush compressed bytes to buf
|
||||
{
|
||||
// need to add 2 bytes
|
||||
if (pos + 2 > buf.length)
|
||||
{
|
||||
buf = realloc(buf, len);
|
||||
}
|
||||
pos = flush_compressed(buf, pos, rep_count, last);
|
||||
rep_count = 1;
|
||||
}
|
||||
raw_count++; // keep looking for raw bytes
|
||||
}
|
||||
if (rep_count == 127) // flush compressed bytes
|
||||
{
|
||||
// need to add 2 bytes
|
||||
if (pos + 2 > buf.length)
|
||||
{
|
||||
buf = realloc(buf, len);
|
||||
}
|
||||
pos = flush_compressed(buf, pos, rep_count, last);
|
||||
rep_count = 1;
|
||||
}
|
||||
if (raw_count == 127) // flush raw bytes
|
||||
{
|
||||
// need to add raw_count+1 bytes
|
||||
if (pos + (raw_count + 1) > buf.length)
|
||||
{
|
||||
buf = realloc(buf, len);
|
||||
}
|
||||
pos = flush_raw(buf, pos, b, (i - raw_count), raw_count);
|
||||
raw_count = 0;
|
||||
}
|
||||
last = c;
|
||||
}
|
||||
if (rep_count > 1) // flush compressed bytes
|
||||
{
|
||||
// need to add 2 bytes
|
||||
if (pos + 2 > buf.length)
|
||||
{
|
||||
buf = realloc(buf, len);
|
||||
}
|
||||
pos = flush_compressed(buf, pos, rep_count, last);
|
||||
rep_count = 1;
|
||||
}
|
||||
if (raw_count > 0) // flush raw bytes
|
||||
{
|
||||
// need to add raw_count+1 bytes
|
||||
if (pos + (raw_count + 1) > buf.length)
|
||||
{
|
||||
buf = realloc(buf, len);
|
||||
}
|
||||
pos = flush_raw(buf, pos, b, (len - raw_count), raw_count);
|
||||
raw_count = 0;
|
||||
}
|
||||
byte[] ret = new byte[pos + 3];
|
||||
System.arraycopy(buf, 0, ret, 3, pos);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int flush_compressed(byte[] buf, int pos, int count, byte c)
|
||||
{
|
||||
buf[pos++] = (byte) (0x80 | count);
|
||||
buf[pos++] = c;
|
||||
return pos;
|
||||
}
|
||||
|
||||
int flush_raw(byte[] buf, int pos, byte[] src, int off, int len)
|
||||
{
|
||||
buf[pos++] = (byte) len;
|
||||
System.arraycopy(src, off, buf, pos, len);
|
||||
return pos + len;
|
||||
}
|
||||
|
||||
byte[] realloc(byte[] buf, int len)
|
||||
{
|
||||
byte[] ret = new byte[buf.length + len];
|
||||
System.arraycopy(buf, 0, ret, 0, buf.length);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void close()
|
||||
throws IOException
|
||||
{
|
||||
byte[] buf = new byte[]
|
||||
{
|
||||
EOF, /* eof descriptor */
|
||||
0x00, 0x00 /* no bytes */
|
||||
};
|
||||
out.write(buf, 0, 3);
|
||||
out.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
92
libjava/classpath/gnu/java/net/protocol/ftp/DTP.java
Normal file
92
libjava/classpath/gnu/java/net/protocol/ftp/DTP.java
Normal file
|
@ -0,0 +1,92 @@
|
|||
/* DTP.java --
|
||||
Copyright (C) 2003, 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.ftp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* An FTP data transfer process.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
interface DTP
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns an input stream from which a remote file can be read.
|
||||
*/
|
||||
InputStream getInputStream()
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Returns an output stream to which a local file can be written for
|
||||
* upload.
|
||||
*/
|
||||
OutputStream getOutputStream()
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Sets the transfer mode to be used with this DTP.
|
||||
*/
|
||||
void setTransferMode(int mode);
|
||||
|
||||
/**
|
||||
* Marks this DTP completed.
|
||||
* When the current transfer has finished, any resources will be released.
|
||||
*/
|
||||
void complete();
|
||||
|
||||
/**
|
||||
* Aborts any current transfer and releases all resources held by this
|
||||
* DTP.
|
||||
* @return true if a transfer was interrupted, false otherwise
|
||||
*/
|
||||
boolean abort();
|
||||
|
||||
/**
|
||||
* Used to notify the DTP that its current transfer is complete.
|
||||
* This occurs either when end-of-stream is reached or a 226 response is
|
||||
* received.
|
||||
*/
|
||||
void transferComplete();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
/* DTPInputStream.java --
|
||||
Copyright (C) 2003, 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.ftp;
|
||||
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* An input stream that notifies a DTP on completion.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
abstract class DTPInputStream
|
||||
extends FilterInputStream
|
||||
{
|
||||
|
||||
DTP dtp;
|
||||
boolean transferComplete;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param dtp the controlling data transfer process
|
||||
* @param in the underlying socket stream
|
||||
*/
|
||||
DTPInputStream (DTP dtp, InputStream in)
|
||||
{
|
||||
super(in);
|
||||
this.dtp = dtp;
|
||||
transferComplete = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks this input stream complete.
|
||||
* This is called by the DTP.
|
||||
*/
|
||||
void setTransferComplete(boolean flag)
|
||||
{
|
||||
transferComplete = flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the controlling DTP that this stream has completed transfer.
|
||||
*/
|
||||
public void close()
|
||||
throws IOException
|
||||
{
|
||||
dtp.transferComplete();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/* DTPOutputStream.java --
|
||||
Copyright (C) 2003, 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.ftp;
|
||||
|
||||
import java.io.FilterOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* An output stream that notifies a DTP on end of stream.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
abstract class DTPOutputStream extends FilterOutputStream
|
||||
{
|
||||
|
||||
DTP dtp;
|
||||
boolean transferComplete;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param dtp the controlling data transfer process
|
||||
* @param out the socket output stream
|
||||
*/
|
||||
DTPOutputStream (DTP dtp, OutputStream out)
|
||||
{
|
||||
super (out);
|
||||
this.dtp = dtp;
|
||||
transferComplete = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells this stream whether transfer has completed or not.
|
||||
* @param flag true if the process has completed, false otherwise
|
||||
*/
|
||||
void setTransferComplete (boolean flag)
|
||||
{
|
||||
transferComplete = flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the controlling DTP that this stream has been terminated.
|
||||
*/
|
||||
public void close () throws IOException
|
||||
{
|
||||
dtp.transferComplete ();
|
||||
}
|
||||
|
||||
}
|
1348
libjava/classpath/gnu/java/net/protocol/ftp/FTPConnection.java
Normal file
1348
libjava/classpath/gnu/java/net/protocol/ftp/FTPConnection.java
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,76 @@
|
|||
/* FTPException.java --
|
||||
Copyright (C) 2003. 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.ftp;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* An FTP control exception.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public class FTPException
|
||||
extends IOException
|
||||
{
|
||||
|
||||
/**
|
||||
* The response that provoked this exception.
|
||||
*/
|
||||
protected final FTPResponse response;
|
||||
|
||||
/**
|
||||
* Constructs a new FTP exception.
|
||||
* @param response the response that provoked this exception
|
||||
*/
|
||||
public FTPException(FTPResponse response)
|
||||
{
|
||||
super(response.getMessage());
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the response that provoked this exception.
|
||||
*/
|
||||
public FTPResponse getResponse()
|
||||
{
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
||||
|
112
libjava/classpath/gnu/java/net/protocol/ftp/FTPResponse.java
Normal file
112
libjava/classpath/gnu/java/net/protocol/ftp/FTPResponse.java
Normal file
|
@ -0,0 +1,112 @@
|
|||
/* FTPResponse.java --
|
||||
Copyright (C) 2003, 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.ftp;
|
||||
|
||||
/**
|
||||
* An FTP control response.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public final class FTPResponse
|
||||
{
|
||||
|
||||
/**
|
||||
* The 3-digit status code.
|
||||
*/
|
||||
protected final int code;
|
||||
|
||||
/**
|
||||
* The human-readable message.
|
||||
*/
|
||||
protected final String message;
|
||||
|
||||
/**
|
||||
* Multiline data, if present.
|
||||
*/
|
||||
protected final String data;
|
||||
|
||||
/**
|
||||
* Constructs a new FTP response.
|
||||
* @param code the status code
|
||||
* @param message the message
|
||||
*/
|
||||
public FTPResponse(int code, String message)
|
||||
{
|
||||
this(code, message, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new multiline FTP response.
|
||||
* @param code the status code
|
||||
* @param message the message
|
||||
* @param data multiline data
|
||||
*/
|
||||
public FTPResponse(int code, String message, String data)
|
||||
{
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the 3-digit status code.
|
||||
*/
|
||||
public int getCode()
|
||||
{
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the human-readable message.
|
||||
*/
|
||||
public String getMessage()
|
||||
{
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the multiline data, or null if there was no such data.
|
||||
*/
|
||||
public String getData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,398 @@
|
|||
/* FTPURLConnection.java --
|
||||
Copyright (C) 2003, 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.ftp;
|
||||
|
||||
import gnu.java.net.GetLocalHostAction;
|
||||
import gnu.java.security.action.GetPropertyAction;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.FilterOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* An FTP URL connection.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public class FTPURLConnection
|
||||
extends URLConnection
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection managing the protocol exchange.
|
||||
*/
|
||||
protected FTPConnection connection;
|
||||
|
||||
protected boolean passive;
|
||||
protected int representationType;
|
||||
protected int fileStructure;
|
||||
protected int transferMode;
|
||||
|
||||
/**
|
||||
* Constructs an FTP connection to the specified URL.
|
||||
* @param url the URL
|
||||
*/
|
||||
public FTPURLConnection(URL url)
|
||||
{
|
||||
super(url);
|
||||
passive = true;
|
||||
representationType = FTPConnection.TYPE_BINARY;
|
||||
fileStructure = -1;
|
||||
transferMode = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Establishes the connection.
|
||||
*/
|
||||
public void connect()
|
||||
throws IOException
|
||||
{
|
||||
if (connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
String host = url.getHost();
|
||||
int port = url.getPort();
|
||||
String username = url.getUserInfo();
|
||||
String password = null;
|
||||
if (username != null)
|
||||
{
|
||||
int ci = username.indexOf(':');
|
||||
if (ci != -1)
|
||||
{
|
||||
password = username.substring(ci + 1);
|
||||
username = username.substring(0, ci);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
username = "anonymous";
|
||||
PrivilegedAction a = new GetPropertyAction("user.name");
|
||||
String systemUsername =(String) AccessController.doPrivileged(a);
|
||||
a = new GetLocalHostAction();
|
||||
InetAddress localhost =(InetAddress) AccessController.doPrivileged(a);
|
||||
password = systemUsername + "@" +
|
||||
((localhost == null) ? "localhost" : localhost.getHostName());
|
||||
}
|
||||
connection = new FTPConnection(host, port);
|
||||
if (!connection.authenticate(username, password))
|
||||
{
|
||||
throw new SecurityException("Authentication failed");
|
||||
}
|
||||
connection.setPassive(passive);
|
||||
if (representationType != -1)
|
||||
{
|
||||
connection.setRepresentationType(representationType);
|
||||
}
|
||||
if (fileStructure != -1)
|
||||
{
|
||||
connection.setFileStructure(fileStructure);
|
||||
}
|
||||
if (transferMode != -1)
|
||||
{
|
||||
connection.setTransferMode(transferMode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This connection supports doInput.
|
||||
*/
|
||||
public void setDoInput(boolean doinput)
|
||||
{
|
||||
doInput = doinput;
|
||||
}
|
||||
|
||||
/**
|
||||
* This connection supports doOutput.
|
||||
*/
|
||||
public void setDoOutput(boolean dooutput)
|
||||
{
|
||||
doOutput = dooutput;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an input stream that reads from this open connection.
|
||||
*/
|
||||
public InputStream getInputStream()
|
||||
throws IOException
|
||||
{
|
||||
if (!connected)
|
||||
{
|
||||
connect();
|
||||
}
|
||||
String path = url.getPath();
|
||||
String filename = null;
|
||||
int lsi = path.lastIndexOf('/');
|
||||
if (lsi != -1)
|
||||
{
|
||||
filename = path.substring(lsi + 1);
|
||||
path = path.substring(0, lsi);
|
||||
if (!connection.changeWorkingDirectory(path))
|
||||
{
|
||||
throw new FileNotFoundException(path);
|
||||
}
|
||||
}
|
||||
if (filename != null && filename.length() > 0)
|
||||
{
|
||||
return this.new ClosingInputStream(connection.retrieve(filename));
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.new ClosingInputStream(connection.list(null));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an output stream that writes to this connection.
|
||||
*/
|
||||
public OutputStream getOutputStream()
|
||||
throws IOException
|
||||
{
|
||||
if (!connected)
|
||||
{
|
||||
connect();
|
||||
}
|
||||
String dir = url.getPath();
|
||||
String filename = url.getFile();
|
||||
if (!connection.changeWorkingDirectory(dir))
|
||||
{
|
||||
throw new FileNotFoundException(dir);
|
||||
}
|
||||
if (filename != null)
|
||||
{
|
||||
return this.new ClosingOutputStream(connection.store(filename));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new FileNotFoundException(filename);
|
||||
}
|
||||
}
|
||||
|
||||
public String getRequestProperty(String key)
|
||||
{
|
||||
if ("passive".equals(key))
|
||||
{
|
||||
return Boolean.toString(passive);
|
||||
}
|
||||
else if ("representationType".equals(key))
|
||||
{
|
||||
switch (representationType)
|
||||
{
|
||||
case FTPConnection.TYPE_ASCII:
|
||||
return "ASCII";
|
||||
case FTPConnection.TYPE_EBCDIC:
|
||||
return "EBCDIC";
|
||||
case FTPConnection.TYPE_BINARY:
|
||||
return "BINARY";
|
||||
}
|
||||
}
|
||||
else if ("fileStructure".equals(key))
|
||||
{
|
||||
switch (fileStructure)
|
||||
{
|
||||
case FTPConnection.STRUCTURE_FILE:
|
||||
return "FILE";
|
||||
case FTPConnection.STRUCTURE_RECORD:
|
||||
return "RECORD";
|
||||
case FTPConnection.STRUCTURE_PAGE:
|
||||
return "PAGE";
|
||||
}
|
||||
}
|
||||
else if ("transferMode".equals(key))
|
||||
{
|
||||
switch (transferMode)
|
||||
{
|
||||
case FTPConnection.MODE_STREAM:
|
||||
return "STREAM";
|
||||
case FTPConnection.MODE_BLOCK:
|
||||
return "BLOCK";
|
||||
case FTPConnection.MODE_COMPRESSED:
|
||||
return "COMPRESSED";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Map getRequestProperties()
|
||||
{
|
||||
Map map = new HashMap();
|
||||
addRequestPropertyValue(map, "passive");
|
||||
addRequestPropertyValue(map, "representationType");
|
||||
addRequestPropertyValue(map, "fileStructure");
|
||||
addRequestPropertyValue(map, "transferMode");
|
||||
return map;
|
||||
}
|
||||
|
||||
private void addRequestPropertyValue(Map map, String key)
|
||||
{
|
||||
String value = getRequestProperty(key);
|
||||
map.put(key, value);
|
||||
}
|
||||
|
||||
public void setRequestProperty(String key, String value)
|
||||
{
|
||||
if (connected)
|
||||
{
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
if ("passive".equals(key))
|
||||
{
|
||||
passive = Boolean.valueOf(value).booleanValue();
|
||||
}
|
||||
else if ("representationType".equals(key))
|
||||
{
|
||||
if ("A".equalsIgnoreCase(value) ||
|
||||
"ASCII".equalsIgnoreCase(value))
|
||||
{
|
||||
representationType = FTPConnection.TYPE_ASCII;
|
||||
}
|
||||
else if ("E".equalsIgnoreCase(value) ||
|
||||
"EBCDIC".equalsIgnoreCase(value))
|
||||
{
|
||||
representationType = FTPConnection.TYPE_EBCDIC;
|
||||
}
|
||||
else if ("I".equalsIgnoreCase(value) ||
|
||||
"BINARY".equalsIgnoreCase(value))
|
||||
{
|
||||
representationType = FTPConnection.TYPE_BINARY;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalArgumentException(value);
|
||||
}
|
||||
}
|
||||
else if ("fileStructure".equals(key))
|
||||
{
|
||||
if ("F".equalsIgnoreCase(value) ||
|
||||
"FILE".equalsIgnoreCase(value))
|
||||
{
|
||||
fileStructure = FTPConnection.STRUCTURE_FILE;
|
||||
}
|
||||
else if ("R".equalsIgnoreCase(value) ||
|
||||
"RECORD".equalsIgnoreCase(value))
|
||||
{
|
||||
fileStructure = FTPConnection.STRUCTURE_RECORD;
|
||||
}
|
||||
else if ("P".equalsIgnoreCase(value) ||
|
||||
"PAGE".equalsIgnoreCase(value))
|
||||
{
|
||||
fileStructure = FTPConnection.STRUCTURE_PAGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalArgumentException(value);
|
||||
}
|
||||
}
|
||||
else if ("transferMode".equals(key))
|
||||
{
|
||||
if ("S".equalsIgnoreCase(value) ||
|
||||
"STREAM".equalsIgnoreCase(value))
|
||||
{
|
||||
transferMode = FTPConnection.MODE_STREAM;
|
||||
}
|
||||
else if ("B".equalsIgnoreCase(value) ||
|
||||
"BLOCK".equalsIgnoreCase(value))
|
||||
{
|
||||
transferMode = FTPConnection.MODE_BLOCK;
|
||||
}
|
||||
else if ("C".equalsIgnoreCase(value) ||
|
||||
"COMPRESSED".equalsIgnoreCase(value))
|
||||
{
|
||||
transferMode = FTPConnection.MODE_COMPRESSED;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalArgumentException(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addRequestProperty(String key, String value)
|
||||
{
|
||||
setRequestProperty(key, value);
|
||||
}
|
||||
|
||||
class ClosingInputStream
|
||||
extends FilterInputStream
|
||||
{
|
||||
|
||||
ClosingInputStream(InputStream in)
|
||||
{
|
||||
super(in);
|
||||
}
|
||||
|
||||
public void close()
|
||||
throws IOException
|
||||
{
|
||||
super.close();
|
||||
connection.logout();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ClosingOutputStream
|
||||
extends FilterOutputStream
|
||||
{
|
||||
|
||||
ClosingOutputStream(OutputStream out)
|
||||
{
|
||||
super(out);
|
||||
}
|
||||
|
||||
public void close()
|
||||
throws IOException
|
||||
{
|
||||
super.close();
|
||||
connection.logout();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
70
libjava/classpath/gnu/java/net/protocol/ftp/Handler.java
Normal file
70
libjava/classpath/gnu/java/net/protocol/ftp/Handler.java
Normal file
|
@ -0,0 +1,70 @@
|
|||
/* Handler.java --
|
||||
Copyright (C) 2003, 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.ftp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLStreamHandler;
|
||||
|
||||
/**
|
||||
* An FTP URL stream handler.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public class Handler
|
||||
extends URLStreamHandler
|
||||
{
|
||||
|
||||
protected int getDefaultPort()
|
||||
{
|
||||
return FTPConnection.FTP_PORT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an FTPURLConnection for the given URL.
|
||||
*/
|
||||
public URLConnection openConnection(URL url)
|
||||
throws IOException
|
||||
{
|
||||
return new FTPURLConnection(url);
|
||||
}
|
||||
|
||||
}
|
||||
|
201
libjava/classpath/gnu/java/net/protocol/ftp/PassiveModeDTP.java
Normal file
201
libjava/classpath/gnu/java/net/protocol/ftp/PassiveModeDTP.java
Normal file
|
@ -0,0 +1,201 @@
|
|||
/* PassiveModeDTP.java --
|
||||
Copyright (C) 2003, 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.ftp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
|
||||
/**
|
||||
* A passive mode FTP data transfer process.
|
||||
* This connects to the host specified and proxies the resulting socket's
|
||||
* input and output streams.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
final class PassiveModeDTP
|
||||
implements DTP
|
||||
{
|
||||
|
||||
final String address;
|
||||
final int port;
|
||||
Socket socket;
|
||||
DTPInputStream in;
|
||||
DTPOutputStream out;
|
||||
boolean completed;
|
||||
boolean inProgress;
|
||||
int transferMode;
|
||||
|
||||
PassiveModeDTP(String address, int port, InetAddress localhost,
|
||||
int connectionTimeout, int timeout)
|
||||
throws IOException
|
||||
{
|
||||
this.address = address;
|
||||
this.port = port;
|
||||
completed = false;
|
||||
inProgress = false;
|
||||
socket = new Socket();
|
||||
InetSocketAddress remote = new InetSocketAddress(address, port);
|
||||
InetSocketAddress local = new InetSocketAddress(localhost, port + 1);
|
||||
socket.bind(local);
|
||||
if (connectionTimeout > 0)
|
||||
{
|
||||
socket.connect(remote, connectionTimeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
socket.connect(remote);
|
||||
}
|
||||
if (timeout > 0)
|
||||
{
|
||||
socket.setSoTimeout(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an input stream from which a remote file can be read.
|
||||
*/
|
||||
public InputStream getInputStream()
|
||||
throws IOException
|
||||
{
|
||||
if (inProgress)
|
||||
{
|
||||
throw new IOException("Transfer in progress");
|
||||
}
|
||||
switch (transferMode)
|
||||
{
|
||||
case FTPConnection.MODE_STREAM:
|
||||
in = new StreamInputStream(this, socket.getInputStream());
|
||||
break;
|
||||
case FTPConnection.MODE_BLOCK:
|
||||
in = new BlockInputStream(this, socket.getInputStream());
|
||||
break;
|
||||
case FTPConnection.MODE_COMPRESSED:
|
||||
in = new CompressedInputStream(this, socket.getInputStream());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Invalid transfer mode");
|
||||
}
|
||||
in.setTransferComplete(false);
|
||||
return in;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an output stream to which a local file can be written for
|
||||
* upload.
|
||||
*/
|
||||
public OutputStream getOutputStream()
|
||||
throws IOException
|
||||
{
|
||||
if (inProgress)
|
||||
{
|
||||
throw new IOException("Transfer in progress");
|
||||
}
|
||||
switch (transferMode)
|
||||
{
|
||||
case FTPConnection.MODE_STREAM:
|
||||
out = new StreamOutputStream(this, socket.getOutputStream());
|
||||
break;
|
||||
case FTPConnection.MODE_BLOCK:
|
||||
out = new BlockOutputStream(this, socket.getOutputStream());
|
||||
break;
|
||||
case FTPConnection.MODE_COMPRESSED:
|
||||
out = new CompressedOutputStream(this, socket.getOutputStream());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Invalid transfer mode");
|
||||
}
|
||||
out.setTransferComplete(false);
|
||||
return out;
|
||||
}
|
||||
|
||||
public void setTransferMode(int mode)
|
||||
{
|
||||
transferMode = mode;
|
||||
}
|
||||
|
||||
public void complete()
|
||||
{
|
||||
completed = true;
|
||||
if (!inProgress)
|
||||
{
|
||||
transferComplete();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean abort()
|
||||
{
|
||||
completed = true;
|
||||
transferComplete();
|
||||
return inProgress;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by DTPInputStream or DTPOutputStream when end of
|
||||
* stream is reached.
|
||||
*/
|
||||
public void transferComplete()
|
||||
{
|
||||
if (in != null)
|
||||
{
|
||||
in.setTransferComplete(true);
|
||||
}
|
||||
if (out != null)
|
||||
{
|
||||
out.setTransferComplete(true);
|
||||
}
|
||||
inProgress = false;
|
||||
completed = completed ||(transferMode == FTPConnection.MODE_STREAM);
|
||||
if (completed && socket != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
socket.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
/* StreamInputStream.java --
|
||||
Copyright (C) 2003, 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.ftp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* A DTP input stream that implements the FTP stream data transfer mode.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
class StreamInputStream
|
||||
extends DTPInputStream
|
||||
{
|
||||
|
||||
StreamInputStream(DTP dtp, InputStream in)
|
||||
{
|
||||
super(dtp, in);
|
||||
}
|
||||
|
||||
public int read()
|
||||
throws IOException
|
||||
{
|
||||
if (transferComplete)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int c = in.read();
|
||||
if (c == -1)
|
||||
{
|
||||
close();
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
public int read(byte[] buf)
|
||||
throws IOException
|
||||
{
|
||||
return read(buf, 0, buf.length);
|
||||
}
|
||||
|
||||
public int read(byte[] buf, int off, int len)
|
||||
throws IOException
|
||||
{
|
||||
if (transferComplete)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int l = in.read(buf, off, len);
|
||||
if (l == -1)
|
||||
{
|
||||
close();
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/* StreamOutputStream.java --
|
||||
Copyright (C) 2003, 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.ftp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* A DTP output stream that implements the FTP stream transfer mode.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
class StreamOutputStream
|
||||
extends DTPOutputStream
|
||||
{
|
||||
|
||||
StreamOutputStream(DTP dtp, OutputStream out)
|
||||
{
|
||||
super(dtp, out);
|
||||
}
|
||||
|
||||
public void write(int c)
|
||||
throws IOException
|
||||
{
|
||||
if (transferComplete)
|
||||
{
|
||||
return;
|
||||
}
|
||||
out.write(c);
|
||||
}
|
||||
|
||||
public void write(byte[] b)
|
||||
throws IOException
|
||||
{
|
||||
write(b, 0, b.length);
|
||||
}
|
||||
|
||||
public void write(byte[] b, int off, int len)
|
||||
throws IOException
|
||||
{
|
||||
if (transferComplete)
|
||||
{
|
||||
return;
|
||||
}
|
||||
out.write(b, off, len);
|
||||
}
|
||||
|
||||
}
|
||||
|
60
libjava/classpath/gnu/java/net/protocol/ftp/package.html
Normal file
60
libjava/classpath/gnu/java/net/protocol/ftp/package.html
Normal file
|
@ -0,0 +1,60 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<!-- package.html - describes classes in gnu.java.net.protocol.ftp package.
|
||||
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. -->
|
||||
|
||||
<html>
|
||||
<head><title>GNU Classpath - gnu.java.net.protocol.ftp</title></head>
|
||||
|
||||
<body>
|
||||
|
||||
<p>
|
||||
This package contains an FTP client. It can handle both active and passive
|
||||
mode connections and the various transfer modes and representation types.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Interaction with the server is via a simple stream interface. Only one
|
||||
concurrent stream (input or output) is supported.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The control connection to the server can be protected using TLS
|
||||
(the starttls method).
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,59 @@
|
|||
/* Authenticator.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 managing authentication.
|
||||
* @see Request#setAuthenticator
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public interface Authenticator
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns the credentials to supply for the given realm.
|
||||
* @param realm the authentication realm
|
||||
* @param attempt zero on first authentication attempt, increments on each
|
||||
* unsuccessful attempt
|
||||
*/
|
||||
Credentials getCredentials(String realm, int attempt);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
/* ByteArrayRequestBodyWriter.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;
|
||||
|
||||
/**
|
||||
* A simple request body writer using a byte array.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public class ByteArrayRequestBodyWriter
|
||||
implements RequestBodyWriter
|
||||
{
|
||||
|
||||
/**
|
||||
* The content.
|
||||
*/
|
||||
protected byte[] content;
|
||||
|
||||
/**
|
||||
* The position within the content at which the next read will occur.
|
||||
*/
|
||||
protected int pos;
|
||||
|
||||
/**
|
||||
* Constructs a new byte array request body writer with the specified
|
||||
* content.
|
||||
* @param content the content buffer
|
||||
*/
|
||||
public ByteArrayRequestBodyWriter(byte[] content)
|
||||
{
|
||||
this.content = content;
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total number of bytes that will be written in a single pass
|
||||
* by this writer.
|
||||
*/
|
||||
public int getContentLength()
|
||||
{
|
||||
return content.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises the writer.
|
||||
* This will be called before each pass.
|
||||
*/
|
||||
public void reset()
|
||||
{
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes body content to the supplied buffer.
|
||||
* @param buffer the content buffer
|
||||
* @return the number of bytes written
|
||||
*/
|
||||
public int write(byte[] buffer)
|
||||
{
|
||||
int len = content.length - pos;
|
||||
len = (buffer.length < len) ? buffer.length : len;
|
||||
if (len > -1)
|
||||
{
|
||||
System.arraycopy(content, pos, buffer, 0, len);
|
||||
pos += len;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
/* 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
/* ChunkedInputStream.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;
|
||||
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.ProtocolException;
|
||||
|
||||
/**
|
||||
* Input stream wrapper for the "chunked" transfer-coding.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public class ChunkedInputStream
|
||||
extends FilterInputStream
|
||||
{
|
||||
|
||||
private static final byte CR = 0x0d;
|
||||
private static final byte LF = 0x0a;
|
||||
|
||||
int size;
|
||||
int count;
|
||||
boolean meta;
|
||||
boolean eof;
|
||||
Headers headers;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param in the response socket input stream
|
||||
* @param headers the headers to receive additional header lines
|
||||
*/
|
||||
public ChunkedInputStream(InputStream in, Headers headers)
|
||||
{
|
||||
super(in);
|
||||
this.headers = headers;
|
||||
size = -1;
|
||||
count = 0;
|
||||
meta = true;
|
||||
}
|
||||
|
||||
public int read()
|
||||
throws IOException
|
||||
{
|
||||
byte[] buf = new byte[1];
|
||||
int len = read(buf, 0, 1);
|
||||
if (len == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int ret = (int) buf[0];
|
||||
if (ret < 0)
|
||||
{
|
||||
ret += 0x100;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int read(byte[] buffer)
|
||||
throws IOException
|
||||
{
|
||||
return read(buffer, 0, buffer.length);
|
||||
}
|
||||
|
||||
public int read(byte[] buffer, int offset, int length)
|
||||
throws IOException
|
||||
{
|
||||
if (eof)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (meta)
|
||||
{
|
||||
// Read chunk header
|
||||
int c, last = 0;
|
||||
boolean seenSemi = false;
|
||||
StringBuffer buf = new StringBuffer();
|
||||
do
|
||||
{
|
||||
c = in.read();
|
||||
if (c == 0x3b) // ;
|
||||
{
|
||||
seenSemi = true;
|
||||
}
|
||||
else if (c == 0x0a && last == 0x0d) // CRLF
|
||||
{
|
||||
size = Integer.parseInt(buf.toString(), 16);
|
||||
break;
|
||||
}
|
||||
else if (!seenSemi && c >= 0x30)
|
||||
{
|
||||
buf.append ((char) c);
|
||||
}
|
||||
last = c;
|
||||
}
|
||||
while(c != -1);
|
||||
count = 0;
|
||||
meta = false;
|
||||
}
|
||||
if (size == 0)
|
||||
{
|
||||
// Read trailer
|
||||
headers.parse(in);
|
||||
eof = true;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int diff = length - offset;
|
||||
int max = size - count;
|
||||
max = (diff < max) ? diff : max;
|
||||
int len = (max > 0) ? in.read(buffer, offset, max) : 0;
|
||||
count += len;
|
||||
if (count == size)
|
||||
{
|
||||
// Read CRLF
|
||||
int c1 = in.read();
|
||||
int c2 = in.read();
|
||||
if (c1 == -1 && c2 == -1)
|
||||
{
|
||||
// EOF before CRLF: bad, but ignore
|
||||
eof = true;
|
||||
return -1;
|
||||
}
|
||||
if (c1 != 0x0d || c2 != 0x0a)
|
||||
{
|
||||
throw new ProtocolException("expecting CRLF: " + c1 + "," + c2);
|
||||
}
|
||||
meta = true;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
160
libjava/classpath/gnu/java/net/protocol/http/Cookie.java
Normal file
160
libjava/classpath/gnu/java/net/protocol/http/Cookie.java
Normal file
|
@ -0,0 +1,160 @@
|
|||
/* Cookie.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;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* An HTTP cookie, as specified in RFC 2109.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public class Cookie
|
||||
{
|
||||
|
||||
/**
|
||||
* The name of the cookie.
|
||||
*/
|
||||
protected final String name;
|
||||
|
||||
/**
|
||||
* The value of the cookie.
|
||||
*/
|
||||
protected final String value;
|
||||
|
||||
/**
|
||||
* Optional documentation of the intended use of the cookie.
|
||||
*/
|
||||
protected final String comment;
|
||||
|
||||
/**
|
||||
* The domain for which the cookie is valid.
|
||||
*/
|
||||
protected final String domain;
|
||||
|
||||
/**
|
||||
* Optional subset of URL paths within the domain for which the cookie is
|
||||
* valid.
|
||||
*/
|
||||
protected final String path;
|
||||
|
||||
/**
|
||||
* Indicates that the user-agent should only use secure means to transmit
|
||||
* this cookie to the server.
|
||||
*/
|
||||
protected final boolean secure;
|
||||
|
||||
/**
|
||||
* The date at which this cookie expires.
|
||||
*/
|
||||
protected final Date expires;
|
||||
|
||||
public Cookie(String name, String value, String comment, String domain,
|
||||
String path, boolean secure, Date expires)
|
||||
{
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
this.comment = comment;
|
||||
this.domain = domain;
|
||||
this.path = path;
|
||||
this.secure = secure;
|
||||
this.expires = expires;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getComment()
|
||||
{
|
||||
return comment;
|
||||
}
|
||||
|
||||
public String getDomain()
|
||||
{
|
||||
return domain;
|
||||
}
|
||||
|
||||
public String getPath()
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
public boolean isSecure()
|
||||
{
|
||||
return secure;
|
||||
}
|
||||
|
||||
public Date getExpiryDate()
|
||||
{
|
||||
return expires;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return toString(true, true);
|
||||
}
|
||||
|
||||
public String toString(boolean showPath, boolean showDomain)
|
||||
{
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append(name);
|
||||
buf.append('=');
|
||||
buf.append(value);
|
||||
if (showPath)
|
||||
{
|
||||
buf.append("; $Path=");
|
||||
buf.append(path);
|
||||
}
|
||||
if (showDomain)
|
||||
{
|
||||
buf.append("; $Domain=");
|
||||
buf.append(domain);
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/* CookieManager.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;
|
||||
|
||||
/**
|
||||
* Cookie manager interface.
|
||||
* If an application wants to handle cookies, they should implement this
|
||||
* interface and register the instance with each HTTPConnection they use.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public interface CookieManager
|
||||
{
|
||||
|
||||
/**
|
||||
* Stores a cookie in the cookie manager.
|
||||
* @param cookie the cookie to store
|
||||
*/
|
||||
void setCookie(Cookie cookie);
|
||||
|
||||
/**
|
||||
* Retrieves the cookies matching the specified criteria.
|
||||
* @param host the host name
|
||||
* @param secure whether the connection is secure
|
||||
* @param path the path to access
|
||||
*/
|
||||
Cookie[] getCookies(String host, boolean secure, String path);
|
||||
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/* Credentials.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;
|
||||
|
||||
/**
|
||||
* Represents a username/password combination that can be used to
|
||||
* authenticate to an HTTP server.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public class Credentials
|
||||
{
|
||||
|
||||
/**
|
||||
* The username.
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* The password.
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param username the username
|
||||
* @param password the password
|
||||
*/
|
||||
public Credentials(String username, String password)
|
||||
{
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the username.
|
||||
*/
|
||||
public String getUsername()
|
||||
{
|
||||
return username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the password.
|
||||
*/
|
||||
public String getPassword()
|
||||
{
|
||||
return password;
|
||||
}
|
||||
|
||||
}
|
||||
|
681
libjava/classpath/gnu/java/net/protocol/http/HTTPConnection.java
Normal file
681
libjava/classpath/gnu/java/net/protocol/http/HTTPConnection.java
Normal file
|
@ -0,0 +1,681 @@
|
|||
/* HTTPConnection.java --
|
||||
Copyright (C) 2004, 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 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;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.net.ssl.HandshakeCompletedListener;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.TrustManager;
|
||||
|
||||
/**
|
||||
* A connection to an HTTP server.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public class HTTPConnection
|
||||
{
|
||||
|
||||
/**
|
||||
* The default HTTP port.
|
||||
*/
|
||||
public static final int HTTP_PORT = 80;
|
||||
|
||||
/**
|
||||
* The default HTTPS port.
|
||||
*/
|
||||
public static final int HTTPS_PORT = 443;
|
||||
|
||||
private static final String userAgent = SystemProperties.getProperty("http.agent");
|
||||
|
||||
/**
|
||||
* The host name of the server to connect to.
|
||||
*/
|
||||
protected final String hostname;
|
||||
|
||||
/**
|
||||
* The port to connect to.
|
||||
*/
|
||||
protected final int port;
|
||||
|
||||
/**
|
||||
* Whether the connection should use transport level security (HTTPS).
|
||||
*/
|
||||
protected final boolean secure;
|
||||
|
||||
/**
|
||||
* The connection timeout for connecting the underlying socket.
|
||||
*/
|
||||
protected final int connectionTimeout;
|
||||
|
||||
/**
|
||||
* The read timeout for reads on the underlying socket.
|
||||
*/
|
||||
protected final int timeout;
|
||||
|
||||
/**
|
||||
* The host name of the proxy to connect to.
|
||||
*/
|
||||
protected String proxyHostname;
|
||||
|
||||
/**
|
||||
* The port on the proxy to connect to.
|
||||
*/
|
||||
protected int proxyPort;
|
||||
|
||||
/**
|
||||
* The major version of HTTP supported by this client.
|
||||
*/
|
||||
protected int majorVersion;
|
||||
|
||||
/**
|
||||
* The minor version of HTTP supported by this client.
|
||||
*/
|
||||
protected int minorVersion;
|
||||
|
||||
private final List connectionListeners;
|
||||
private final List requestListeners;
|
||||
private final List handshakeCompletedListeners;
|
||||
|
||||
/**
|
||||
* The socket this connection communicates on.
|
||||
*/
|
||||
protected Socket socket;
|
||||
|
||||
/**
|
||||
* The SSL socket factory to use.
|
||||
*/
|
||||
private SSLSocketFactory sslSocketFactory;
|
||||
|
||||
/**
|
||||
* The socket input stream.
|
||||
*/
|
||||
protected InputStream in;
|
||||
|
||||
/**
|
||||
* The socket output stream.
|
||||
*/
|
||||
protected OutputStream out;
|
||||
|
||||
/**
|
||||
* Nonce values seen by this connection.
|
||||
*/
|
||||
private Map nonceCounts;
|
||||
|
||||
/**
|
||||
* The cookie manager for this connection.
|
||||
*/
|
||||
protected CookieManager cookieManager;
|
||||
|
||||
/**
|
||||
* Creates a new HTTP connection.
|
||||
* @param hostname the name of the host to connect to
|
||||
*/
|
||||
public HTTPConnection(String hostname)
|
||||
{
|
||||
this(hostname, HTTP_PORT, false, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new HTTP or HTTPS connection.
|
||||
* @param hostname the name of the host to connect to
|
||||
* @param secure whether to use a secure connection
|
||||
*/
|
||||
public HTTPConnection(String hostname, boolean secure)
|
||||
{
|
||||
this(hostname, secure ? HTTPS_PORT : HTTP_PORT, secure, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new HTTP or HTTPS connection on the specified port.
|
||||
* @param hostname the name of the host to connect to
|
||||
* @param secure whether to use a secure connection
|
||||
* @param connectionTimeout the connection timeout
|
||||
* @param timeout the socket read timeout
|
||||
*/
|
||||
public HTTPConnection(String hostname, boolean secure,
|
||||
int connectionTimeout, int timeout)
|
||||
{
|
||||
this(hostname, secure ? HTTPS_PORT : HTTP_PORT, secure,
|
||||
connectionTimeout, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new HTTP connection on the specified port.
|
||||
* @param hostname the name of the host to connect to
|
||||
* @param port the port on the host to connect to
|
||||
*/
|
||||
public HTTPConnection(String hostname, int port)
|
||||
{
|
||||
this(hostname, port, false, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new HTTP or HTTPS connection on the specified port.
|
||||
* @param hostname the name of the host to connect to
|
||||
* @param port the port on the host to connect to
|
||||
* @param secure whether to use a secure connection
|
||||
*/
|
||||
public HTTPConnection(String hostname, int port, boolean secure)
|
||||
{
|
||||
this(hostname, port, secure, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new HTTP or HTTPS connection on the specified port.
|
||||
* @param hostname the name of the host to connect to
|
||||
* @param port the port on the host to connect to
|
||||
* @param secure whether to use a secure connection
|
||||
* @param connectionTimeout the connection timeout
|
||||
* @param timeout the socket read timeout
|
||||
*/
|
||||
public HTTPConnection(String hostname, int port, boolean secure,
|
||||
int connectionTimeout, int timeout)
|
||||
{
|
||||
this.hostname = hostname;
|
||||
this.port = port;
|
||||
this.secure = secure;
|
||||
this.connectionTimeout = connectionTimeout;
|
||||
this.timeout = timeout;
|
||||
majorVersion = minorVersion = 1;
|
||||
connectionListeners = new ArrayList(4);
|
||||
requestListeners = new ArrayList(4);
|
||||
handshakeCompletedListeners = new ArrayList(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the host to connect to.
|
||||
*/
|
||||
public String getHostName()
|
||||
{
|
||||
return hostname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the port on the host to connect to.
|
||||
*/
|
||||
public int getPort()
|
||||
{
|
||||
return port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether to use a secure connection or not.
|
||||
*/
|
||||
public boolean isSecure()
|
||||
{
|
||||
return secure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTTP version string supported by this connection.
|
||||
* @see #version
|
||||
*/
|
||||
public String getVersion()
|
||||
{
|
||||
return "HTTP/" + majorVersion + '.' + minorVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the HTTP version supported by this connection.
|
||||
* @param majorVersion the major version
|
||||
* @param minorVersion the minor version
|
||||
*/
|
||||
public void setVersion(int majorVersion, int minorVersion)
|
||||
{
|
||||
if (majorVersion != 1)
|
||||
{
|
||||
throw new IllegalArgumentException("major version not supported: " +
|
||||
majorVersion);
|
||||
}
|
||||
if (minorVersion < 0 || minorVersion > 1)
|
||||
{
|
||||
throw new IllegalArgumentException("minor version not supported: " +
|
||||
minorVersion);
|
||||
}
|
||||
this.majorVersion = majorVersion;
|
||||
this.minorVersion = minorVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Directs this connection to use the specified proxy.
|
||||
* @param hostname the proxy host name
|
||||
* @param port the port on the proxy to connect to
|
||||
*/
|
||||
public void setProxy(String hostname, int port)
|
||||
{
|
||||
proxyHostname = hostname;
|
||||
proxyPort = port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this connection is using an HTTP proxy.
|
||||
*/
|
||||
public boolean isUsingProxy()
|
||||
{
|
||||
return (proxyHostname != null && proxyPort > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cookie manager to use for this connection.
|
||||
* @param cookieManager the cookie manager
|
||||
*/
|
||||
public void setCookieManager(CookieManager cookieManager)
|
||||
{
|
||||
this.cookieManager = cookieManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cookie manager in use for this connection.
|
||||
*/
|
||||
public CookieManager getCookieManager()
|
||||
{
|
||||
return cookieManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* optional query part
|
||||
*/
|
||||
public Request newRequest(String method, String path)
|
||||
{
|
||||
if (method == null || method.length() == 0)
|
||||
{
|
||||
throw new IllegalArgumentException("method must have non-zero length");
|
||||
}
|
||||
if (path == null || path.length() == 0)
|
||||
{
|
||||
path = "/";
|
||||
}
|
||||
Request ret = new Request(this, method, path);
|
||||
if ((secure && port != HTTPS_PORT) ||
|
||||
(!secure && port != HTTP_PORT))
|
||||
{
|
||||
ret.setHeader("Host", hostname + ":" + port);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.setHeader("Host", hostname);
|
||||
}
|
||||
ret.setHeader("User-Agent", userAgent);
|
||||
ret.setHeader("Connection", "keep-alive");
|
||||
ret.setHeader("Accept-Encoding",
|
||||
"chunked;q=1.0, gzip;q=0.9, deflate;q=0.8, " +
|
||||
"identity;q=0.6, *;q=0");
|
||||
if (cookieManager != null)
|
||||
{
|
||||
Cookie[] cookies = cookieManager.getCookies(hostname, secure, path);
|
||||
if (cookies != null && cookies.length > 0)
|
||||
{
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("$Version=1");
|
||||
for (int i = 0; i < cookies.length; i++)
|
||||
{
|
||||
buf.append(',');
|
||||
buf.append(' ');
|
||||
buf.append(cookies[i].toString());
|
||||
}
|
||||
ret.setHeader("Cookie", buf.toString());
|
||||
}
|
||||
}
|
||||
fireRequestEvent(RequestEvent.REQUEST_CREATED, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this connection.
|
||||
*/
|
||||
public void close()
|
||||
throws IOException
|
||||
{
|
||||
try
|
||||
{
|
||||
closeConnection();
|
||||
}
|
||||
finally
|
||||
{
|
||||
fireConnectionEvent(ConnectionEvent.CONNECTION_CLOSED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the socket associated with this connection.
|
||||
* This creates the socket if necessary.
|
||||
*/
|
||||
protected synchronized Socket getSocket()
|
||||
throws IOException
|
||||
{
|
||||
if (socket == null)
|
||||
{
|
||||
String connectHostname = hostname;
|
||||
int connectPort = port;
|
||||
if (isUsingProxy())
|
||||
{
|
||||
connectHostname = proxyHostname;
|
||||
connectPort = proxyPort;
|
||||
}
|
||||
socket = new Socket();
|
||||
InetSocketAddress address =
|
||||
new InetSocketAddress(connectHostname, connectPort);
|
||||
if (connectionTimeout > 0)
|
||||
{
|
||||
socket.connect(address, connectionTimeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
socket.connect(address);
|
||||
}
|
||||
if (timeout > 0)
|
||||
{
|
||||
socket.setSoTimeout(timeout);
|
||||
}
|
||||
if (secure)
|
||||
{
|
||||
try
|
||||
{
|
||||
SSLSocketFactory factory = getSSLSocketFactory();
|
||||
SSLSocket ss =
|
||||
(SSLSocket) factory.createSocket(socket, connectHostname,
|
||||
connectPort, true);
|
||||
String[] protocols = { "TLSv1", "SSLv3" };
|
||||
ss.setEnabledProtocols(protocols);
|
||||
ss.setUseClientMode(true);
|
||||
synchronized (handshakeCompletedListeners)
|
||||
{
|
||||
if (!handshakeCompletedListeners.isEmpty())
|
||||
{
|
||||
for (Iterator i =
|
||||
handshakeCompletedListeners.iterator();
|
||||
i.hasNext(); )
|
||||
{
|
||||
HandshakeCompletedListener l =
|
||||
(HandshakeCompletedListener) i.next();
|
||||
ss.addHandshakeCompletedListener(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
ss.startHandshake();
|
||||
socket = ss;
|
||||
}
|
||||
catch (GeneralSecurityException e)
|
||||
{
|
||||
throw new IOException(e.getMessage());
|
||||
}
|
||||
}
|
||||
in = socket.getInputStream();
|
||||
in = new BufferedInputStream(in);
|
||||
out = socket.getOutputStream();
|
||||
out = new BufferedOutputStream(out);
|
||||
}
|
||||
return socket;
|
||||
}
|
||||
|
||||
SSLSocketFactory getSSLSocketFactory()
|
||||
throws GeneralSecurityException
|
||||
{
|
||||
if (sslSocketFactory == null)
|
||||
{
|
||||
TrustManager tm = new EmptyX509TrustManager();
|
||||
SSLContext context = SSLContext.getInstance("SSL");
|
||||
TrustManager[] trust = new TrustManager[] { tm };
|
||||
context.init(null, trust, null);
|
||||
sslSocketFactory = context.getSocketFactory();
|
||||
}
|
||||
return sslSocketFactory;
|
||||
}
|
||||
|
||||
void setSSLSocketFactory(SSLSocketFactory factory)
|
||||
{
|
||||
sslSocketFactory = factory;
|
||||
}
|
||||
|
||||
protected synchronized InputStream getInputStream()
|
||||
throws IOException
|
||||
{
|
||||
if (socket == null)
|
||||
{
|
||||
getSocket();
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
protected synchronized OutputStream getOutputStream()
|
||||
throws IOException
|
||||
{
|
||||
if (socket == null)
|
||||
{
|
||||
getSocket();
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the underlying socket, if any.
|
||||
*/
|
||||
protected synchronized void closeConnection()
|
||||
throws IOException
|
||||
{
|
||||
if (socket != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
socket.close();
|
||||
}
|
||||
finally
|
||||
{
|
||||
socket = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a URI representing the connection.
|
||||
* This does not include any request path component.
|
||||
*/
|
||||
protected String getURI()
|
||||
{
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append(secure ? "https://" : "http://");
|
||||
buf.append(hostname);
|
||||
if (secure)
|
||||
{
|
||||
if (port != HTTPConnection.HTTPS_PORT)
|
||||
{
|
||||
buf.append(':');
|
||||
buf.append(port);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (port != HTTPConnection.HTTP_PORT)
|
||||
{
|
||||
buf.append(':');
|
||||
buf.append(port);
|
||||
}
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of times the specified nonce has been seen by this
|
||||
* connection.
|
||||
*/
|
||||
int getNonceCount(String nonce)
|
||||
{
|
||||
if (nonceCounts == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return((Integer) nonceCounts.get(nonce)).intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the number of times the specified nonce has been seen.
|
||||
*/
|
||||
void incrementNonce(String nonce)
|
||||
{
|
||||
int current = getNonceCount(nonce);
|
||||
if (nonceCounts == null)
|
||||
{
|
||||
nonceCounts = new HashMap();
|
||||
}
|
||||
nonceCounts.put(nonce, new Integer(current + 1));
|
||||
}
|
||||
|
||||
// -- 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)
|
||||
{
|
||||
handshakeCompletedListeners.add(l);
|
||||
}
|
||||
}
|
||||
void removeHandshakeCompletedListener(HandshakeCompletedListener l)
|
||||
{
|
||||
synchronized (handshakeCompletedListeners)
|
||||
{
|
||||
handshakeCompletedListeners.remove(l);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
441
libjava/classpath/gnu/java/net/protocol/http/HTTPDateFormat.java
Normal file
441
libjava/classpath/gnu/java/net/protocol/http/HTTPDateFormat.java
Normal file
|
@ -0,0 +1,441 @@
|
|||
/* HTTPDateFormat.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;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.FieldPosition;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParsePosition;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* HTTP date formatter and parser.
|
||||
* Formats dates according to RFC 822 (updated by RFC 1123).
|
||||
* Parses dates according to the above, <i>or</i> RFC 1036, <i>or</i> the
|
||||
* ANSI C <code>asctime()</code> format.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public class HTTPDateFormat
|
||||
extends DateFormat
|
||||
{
|
||||
|
||||
static final String[] DAYS_OF_WEEK = {
|
||||
null, "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
|
||||
};
|
||||
|
||||
static final String[] MONTHS = {
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
|
||||
public HTTPDateFormat()
|
||||
{
|
||||
calendar = new GregorianCalendar(TimeZone.getTimeZone ("GMT"));
|
||||
numberFormat = new DecimalFormat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the textual value for the specified field to the given string
|
||||
* buffer. This method should be avoided, use <code>format(Date)</code>
|
||||
* instead.
|
||||
* @param date the Date object
|
||||
* @param buf the buffer to append to
|
||||
* @param field the current field position
|
||||
* @return the modified buffer
|
||||
*/
|
||||
public StringBuffer format(Date date, StringBuffer buf,
|
||||
FieldPosition field)
|
||||
{
|
||||
calendar.clear();
|
||||
calendar.setTime(date);
|
||||
buf.setLength(0);
|
||||
|
||||
// Day of week
|
||||
buf.append(DAYS_OF_WEEK[calendar.get(Calendar.DAY_OF_WEEK)]);
|
||||
buf.append(',');
|
||||
buf.append(' ');
|
||||
|
||||
// Day of month
|
||||
int day = calendar.get(Calendar.DAY_OF_MONTH);
|
||||
buf.append(Character.forDigit(day / 10, 10));
|
||||
buf.append(Character.forDigit(day % 10, 10));
|
||||
buf.append(' ');
|
||||
|
||||
// Month
|
||||
buf.append(MONTHS[calendar.get(Calendar.MONTH)]);
|
||||
buf.append(' ');
|
||||
|
||||
// Year
|
||||
int year = calendar.get(Calendar.YEAR);
|
||||
if (year < 1000)
|
||||
{
|
||||
buf.append('0');
|
||||
if (year < 100)
|
||||
{
|
||||
buf.append('0');
|
||||
if (year < 10)
|
||||
{
|
||||
buf.append('0');
|
||||
}
|
||||
}
|
||||
}
|
||||
buf.append(Integer.toString(year));
|
||||
buf.append(' ');
|
||||
|
||||
// Hour
|
||||
int hour = calendar.get(Calendar.HOUR_OF_DAY);
|
||||
buf.append(Character.forDigit(hour / 10, 10));
|
||||
buf.append(Character.forDigit(hour % 10, 10));
|
||||
buf.append(':');
|
||||
|
||||
// Minute
|
||||
int minute = calendar.get(Calendar.MINUTE);
|
||||
buf.append(Character.forDigit(minute / 10, 10));
|
||||
buf.append(Character.forDigit(minute % 10, 10));
|
||||
buf.append(':');
|
||||
|
||||
// Second
|
||||
int second = calendar.get(Calendar.SECOND);
|
||||
buf.append(Character.forDigit(second / 10, 10));
|
||||
buf.append(Character.forDigit(second % 10, 10));
|
||||
buf.append(' ');
|
||||
|
||||
// Timezone
|
||||
// Get time offset in minutes
|
||||
int zoneOffset =(calendar.get(Calendar.ZONE_OFFSET) +
|
||||
calendar.get(Calendar.DST_OFFSET)) / 60000;
|
||||
|
||||
// Apply + or - appropriately
|
||||
if (zoneOffset < 0)
|
||||
{
|
||||
zoneOffset = -zoneOffset;
|
||||
buf.append('-');
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.append('+');
|
||||
}
|
||||
|
||||
// Set the 2 2-char fields as specified above
|
||||
int tzhours = zoneOffset / 60;
|
||||
buf.append(Character.forDigit(tzhours / 10, 10));
|
||||
buf.append(Character.forDigit(tzhours % 10, 10));
|
||||
int tzminutes = zoneOffset % 60;
|
||||
buf.append(Character.forDigit(tzminutes / 10, 10));
|
||||
buf.append(Character.forDigit(tzminutes % 10, 10));
|
||||
|
||||
field.setBeginIndex(0);
|
||||
field.setEndIndex(buf.length());
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given date in the current TimeZone.
|
||||
* @param text the formatted date to be parsed
|
||||
* @param pos the current parse position
|
||||
*/
|
||||
public Date parse(String text, ParsePosition pos)
|
||||
{
|
||||
int date, month, year, hour, minute, second;
|
||||
String monthText;
|
||||
int start = 0, end = -1;
|
||||
int len = text.length();
|
||||
calendar.clear();
|
||||
pos.setIndex(start);
|
||||
try
|
||||
{
|
||||
// Advance to date
|
||||
if (Character.isLetter(text.charAt(start)))
|
||||
{
|
||||
start = skipNonWhitespace(text, start);
|
||||
}
|
||||
// Determine mode
|
||||
switch(start)
|
||||
{
|
||||
case 3:
|
||||
// asctime
|
||||
start = skipWhitespace(text, start);
|
||||
pos.setIndex(start);
|
||||
end = skipNonWhitespace(text, start + 1);
|
||||
monthText = text.substring(start, end);
|
||||
month = -1;
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
if (MONTHS[i].equals(monthText))
|
||||
{
|
||||
month = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (month == -1)
|
||||
{
|
||||
pos.setErrorIndex(end);
|
||||
return null;
|
||||
}
|
||||
// Advance to date
|
||||
start = skipWhitespace(text, end + 1);
|
||||
pos.setIndex(start);
|
||||
end = skipNonWhitespace(text, start + 1);
|
||||
date = Integer.parseInt(text.substring(start, end));
|
||||
// Advance to hour
|
||||
start = skipWhitespace(text, end + 1);
|
||||
pos.setIndex(start);
|
||||
end = skipTo(text, start + 1, ':');
|
||||
hour = Integer.parseInt(text.substring(start, end));
|
||||
// Advance to minute
|
||||
start = end + 1;
|
||||
pos.setIndex(start);
|
||||
end = skipTo(text, start + 1, ':');
|
||||
minute = Integer.parseInt(text.substring(start, end));
|
||||
// Advance to second
|
||||
start = end + 1;
|
||||
pos.setIndex(start);
|
||||
end = skipNonWhitespace(text, start + 1);
|
||||
second = Integer.parseInt(text.substring(start, end));
|
||||
// Advance to year
|
||||
start = skipWhitespace(text, end + 1);
|
||||
pos.setIndex(start);
|
||||
end = skipNonWhitespace(text, start + 1);
|
||||
year = Integer.parseInt(text.substring(start, end));
|
||||
break;
|
||||
case 0:
|
||||
case 4:
|
||||
// rfc822
|
||||
start = skipWhitespace(text, start);
|
||||
pos.setIndex(start);
|
||||
end = skipNonWhitespace(text, start + 1);
|
||||
date = Integer.parseInt(text.substring(start, end));
|
||||
// Advance to month
|
||||
start = skipWhitespace(text, end + 1);
|
||||
pos.setIndex(start);
|
||||
end = skipNonWhitespace(text, start + 1);
|
||||
monthText = text.substring(start, end);
|
||||
month = -1;
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
if (MONTHS[i].equals(monthText))
|
||||
{
|
||||
month = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (month == -1)
|
||||
{
|
||||
pos.setErrorIndex(end);
|
||||
return null;
|
||||
}
|
||||
// Advance to year
|
||||
start = skipWhitespace(text, end + 1);
|
||||
pos.setIndex(start);
|
||||
end = skipNonWhitespace(text, start + 1);
|
||||
year = Integer.parseInt(text.substring(start, end));
|
||||
// Advance to hour
|
||||
start = skipWhitespace(text, end + 1);
|
||||
pos.setIndex(start);
|
||||
end = skipTo(text, start + 1, ':');
|
||||
hour = Integer.parseInt(text.substring(start, end));
|
||||
// Advance to minute
|
||||
start = end + 1;
|
||||
pos.setIndex(start);
|
||||
end = skipTo(text, start + 1, ':');
|
||||
minute = Integer.parseInt(text.substring(start, end));
|
||||
// Advance to second
|
||||
start = end + 1;
|
||||
pos.setIndex(start);
|
||||
end = start + 1;
|
||||
while (end < len && !Character.isWhitespace(text.charAt(end)))
|
||||
{
|
||||
end++;
|
||||
}
|
||||
second = Integer.parseInt(text.substring(start, end));
|
||||
break;
|
||||
default:
|
||||
// rfc850(obsolete)
|
||||
start = skipWhitespace(text, start);
|
||||
pos.setIndex(start);
|
||||
end = skipTo(text, start + 1, '-');
|
||||
date = Integer.parseInt(text.substring(start, end));
|
||||
// Advance to month
|
||||
start = end + 1;
|
||||
pos.setIndex(start);
|
||||
end = skipTo(text, start + 1, '-');
|
||||
monthText = text.substring(start, end);
|
||||
month = -1;
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
if (MONTHS[i].equals(monthText))
|
||||
{
|
||||
month = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (month == -1)
|
||||
{
|
||||
pos.setErrorIndex(end);
|
||||
return null;
|
||||
}
|
||||
// Advance to year
|
||||
start = end + 1;
|
||||
pos.setIndex(start);
|
||||
end = skipNonWhitespace(text, start + 1);
|
||||
year = 1900 + Integer.parseInt(text.substring(start, end));
|
||||
// Advance to hour
|
||||
start = skipWhitespace(text, end + 1);
|
||||
pos.setIndex(start);
|
||||
end = skipTo(text, start + 1, ':');
|
||||
hour = Integer.parseInt(text.substring(start, end));
|
||||
// Advance to minute
|
||||
start = end + 1;
|
||||
pos.setIndex(start);
|
||||
end = skipTo(text, start + 1, ':');
|
||||
minute = Integer.parseInt(text.substring(start, end));
|
||||
// Advance to second
|
||||
start = end + 1;
|
||||
pos.setIndex(start);
|
||||
end = start + 1;
|
||||
while (end < len && !Character.isWhitespace(text.charAt(end)))
|
||||
{
|
||||
end++;
|
||||
}
|
||||
second = Integer.parseInt(text.substring(start, end));
|
||||
}
|
||||
|
||||
calendar.set(Calendar.YEAR, year);
|
||||
calendar.set(Calendar.MONTH, month);
|
||||
calendar.set(Calendar.DAY_OF_MONTH, date);
|
||||
calendar.set(Calendar.HOUR, hour);
|
||||
calendar.set(Calendar.MINUTE, minute);
|
||||
calendar.set(Calendar.SECOND, second);
|
||||
|
||||
if (end != len)
|
||||
{
|
||||
// Timezone
|
||||
start = skipWhitespace(text, end + 1);
|
||||
end = start + 1;
|
||||
while (end < len && !Character.isWhitespace(text.charAt(end)))
|
||||
{
|
||||
end++;
|
||||
}
|
||||
char pm = text.charAt(start);
|
||||
if (Character.isLetter(pm))
|
||||
{
|
||||
TimeZone tz =
|
||||
TimeZone.getTimeZone(text.substring(start, end));
|
||||
calendar.set(Calendar.ZONE_OFFSET, tz.getRawOffset());
|
||||
}
|
||||
else
|
||||
{
|
||||
int zoneOffset = 0;
|
||||
zoneOffset += 600 * Character.digit(text.charAt(++start), 10);
|
||||
zoneOffset += 60 * Character.digit(text.charAt(++start), 10);
|
||||
zoneOffset += 10 * Character.digit(text.charAt(++start), 10);
|
||||
zoneOffset += Character.digit(text.charAt(++start), 10);
|
||||
zoneOffset *= 60000; // minutes -> ms
|
||||
if ('-' == pm)
|
||||
{
|
||||
zoneOffset = -zoneOffset;
|
||||
}
|
||||
calendar.set(Calendar.ZONE_OFFSET, zoneOffset);
|
||||
}
|
||||
}
|
||||
pos.setIndex(end);
|
||||
|
||||
return calendar.getTime();
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
pos.setErrorIndex(Math.max(start, end));
|
||||
}
|
||||
catch (StringIndexOutOfBoundsException e)
|
||||
{
|
||||
pos.setErrorIndex(Math.max(start, end));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private int skipWhitespace(String text, int pos)
|
||||
{
|
||||
while(Character.isWhitespace(text.charAt(pos)))
|
||||
{
|
||||
pos++;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
private int skipNonWhitespace(String text, int pos)
|
||||
{
|
||||
while(!Character.isWhitespace(text.charAt(pos)))
|
||||
{
|
||||
pos++;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
private int skipTo(String text, int pos, char c)
|
||||
{
|
||||
while(text.charAt(pos) != c)
|
||||
{
|
||||
pos++;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't allow setting the calendar.
|
||||
*/
|
||||
public void setCalendar(Calendar newCalendar)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't allow setting the NumberFormat.
|
||||
*/
|
||||
public void setNumberFormat(NumberFormat newNumberFormat)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,688 @@
|
|||
/* HTTPURLConnection.java --
|
||||
Copyright (C) 2004, 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.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.ProtocolException;
|
||||
import java.net.URL;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.cert.Certificate;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.net.ssl.HandshakeCompletedEvent;
|
||||
import javax.net.ssl.HandshakeCompletedListener;
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLPeerUnverifiedException;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
|
||||
/**
|
||||
* A URLConnection that uses the HTTPConnection class.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public class HTTPURLConnection
|
||||
extends HttpsURLConnection
|
||||
implements HandshakeCompletedListener
|
||||
{
|
||||
|
||||
/**
|
||||
* Pool of reusable connections, used if keepAlive is true.
|
||||
*/
|
||||
private static final Map connectionPool = new LinkedHashMap();
|
||||
|
||||
/*
|
||||
* The underlying connection.
|
||||
*/
|
||||
private HTTPConnection connection;
|
||||
|
||||
// These are package private for use in anonymous inner classes.
|
||||
String proxyHostname;
|
||||
int proxyPort;
|
||||
String agent;
|
||||
boolean keepAlive;
|
||||
int maxConnections;
|
||||
|
||||
private Request request;
|
||||
private Headers requestHeaders;
|
||||
private ByteArrayOutputStream requestSink;
|
||||
private boolean requestMethodSetExplicitly;
|
||||
|
||||
private Response response;
|
||||
private ByteArrayInputStream responseSink;
|
||||
private ByteArrayInputStream errorSink;
|
||||
|
||||
private HandshakeCompletedEvent handshakeEvent;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param url the URL
|
||||
*/
|
||||
public HTTPURLConnection(URL url)
|
||||
throws IOException
|
||||
{
|
||||
super(url);
|
||||
requestHeaders = new Headers();
|
||||
AccessController.doPrivileged(this.new GetHTTPPropertiesAction());
|
||||
}
|
||||
|
||||
class GetHTTPPropertiesAction
|
||||
implements PrivilegedAction
|
||||
{
|
||||
|
||||
public Object run()
|
||||
{
|
||||
proxyHostname = System.getProperty("http.proxyHost");
|
||||
if (proxyHostname != null && proxyHostname.length() > 0)
|
||||
{
|
||||
String port = System.getProperty("http.proxyPort");
|
||||
if (port != null && port.length() > 0)
|
||||
{
|
||||
proxyPort = Integer.parseInt(port);
|
||||
}
|
||||
else
|
||||
{
|
||||
proxyHostname = null;
|
||||
proxyPort = -1;
|
||||
}
|
||||
}
|
||||
agent = System.getProperty("http.agent");
|
||||
String ka = System.getProperty("http.keepAlive");
|
||||
keepAlive = !(ka != null && "false".equals(ka));
|
||||
String mc = System.getProperty("http.maxConnections");
|
||||
maxConnections = (mc != null && mc.length() > 0) ?
|
||||
Math.max(Integer.parseInt(mc), 1) : 5;
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void connect()
|
||||
throws IOException
|
||||
{
|
||||
if (connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
String protocol = url.getProtocol();
|
||||
boolean secure = "https".equals(protocol);
|
||||
String host = url.getHost();
|
||||
int port = url.getPort();
|
||||
if (port < 0)
|
||||
{
|
||||
port = secure ? HTTPConnection.HTTPS_PORT :
|
||||
HTTPConnection.HTTP_PORT;
|
||||
}
|
||||
String file = url.getFile();
|
||||
String username = url.getUserInfo();
|
||||
String password = null;
|
||||
if (username != null)
|
||||
{
|
||||
int ci = username.indexOf(':');
|
||||
if (ci != -1)
|
||||
{
|
||||
password = username.substring(ci + 1);
|
||||
username = username.substring(0, ci);
|
||||
}
|
||||
}
|
||||
final Credentials creds = (username == null) ? null :
|
||||
new Credentials (username, password);
|
||||
|
||||
boolean retry;
|
||||
do
|
||||
{
|
||||
retry = false;
|
||||
if (connection == null)
|
||||
{
|
||||
connection = getConnection(host, port, secure);
|
||||
if (secure)
|
||||
{
|
||||
SSLSocketFactory factory = getSSLSocketFactory();
|
||||
HostnameVerifier verifier = getHostnameVerifier();
|
||||
if (factory != null)
|
||||
{
|
||||
connection.setSSLSocketFactory(factory);
|
||||
}
|
||||
connection.addHandshakeCompletedListener(this);
|
||||
// TODO verifier
|
||||
}
|
||||
}
|
||||
if (proxyHostname != null)
|
||||
{
|
||||
if (proxyPort < 0)
|
||||
{
|
||||
proxyPort = secure ? HTTPConnection.HTTPS_PORT :
|
||||
HTTPConnection.HTTP_PORT;
|
||||
}
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
return (attempts < 2) ? creds : null;
|
||||
}
|
||||
});
|
||||
}
|
||||
response = request.dispatch();
|
||||
if (response.getCodeClass() == 3 && getInstanceFollowRedirects())
|
||||
{
|
||||
// Follow redirect
|
||||
String location = response.getHeader("Location");
|
||||
if (location != null)
|
||||
{
|
||||
String connectionUri = connection.getURI();
|
||||
int start = connectionUri.length();
|
||||
if (location.startsWith(connectionUri) &&
|
||||
location.charAt(start) == '/')
|
||||
{
|
||||
file = location.substring(start);
|
||||
retry = true;
|
||||
}
|
||||
else if (location.startsWith("http:"))
|
||||
{
|
||||
connection.close();
|
||||
connection = null;
|
||||
secure = false;
|
||||
start = 7;
|
||||
int end = location.indexOf('/', start);
|
||||
host = location.substring(start, end);
|
||||
int ci = host.lastIndexOf(':');
|
||||
if (ci != -1)
|
||||
{
|
||||
port = Integer.parseInt(host.substring (ci + 1));
|
||||
host = host.substring(0, ci);
|
||||
}
|
||||
else
|
||||
{
|
||||
port = HTTPConnection.HTTP_PORT;
|
||||
}
|
||||
file = location.substring(end);
|
||||
retry = true;
|
||||
}
|
||||
else if (location.startsWith("https:"))
|
||||
{
|
||||
connection.close();
|
||||
connection = null;
|
||||
secure = true;
|
||||
start = 8;
|
||||
int end = location.indexOf('/', start);
|
||||
host = location.substring(start, end);
|
||||
int ci = host.lastIndexOf(':');
|
||||
if (ci != -1)
|
||||
{
|
||||
port = Integer.parseInt(host.substring (ci + 1));
|
||||
host = host.substring(0, ci);
|
||||
}
|
||||
else
|
||||
{
|
||||
port = HTTPConnection.HTTPS_PORT;
|
||||
}
|
||||
file = location.substring(end);
|
||||
retry = true;
|
||||
}
|
||||
else if (location.length() > 0)
|
||||
{
|
||||
// Malformed absolute URI, treat as file part of URI
|
||||
if (location.charAt(0) == '/')
|
||||
{
|
||||
// Absolute path
|
||||
file = location;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Relative path
|
||||
int lsi = file.lastIndexOf('/');
|
||||
file = (lsi == -1) ? "/" : file.substring(0, lsi + 1);
|
||||
file += location;
|
||||
}
|
||||
retry = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
responseSink = new ByteArrayInputStream(reader.toByteArray ());
|
||||
if (response.getCode() == 404)
|
||||
{
|
||||
errorSink = responseSink;
|
||||
throw new FileNotFoundException(url.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
while (retry);
|
||||
connected = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a connection, from the pool if necessary.
|
||||
*/
|
||||
HTTPConnection getConnection(String host, int port, boolean secure)
|
||||
throws IOException
|
||||
{
|
||||
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();
|
||||
synchronized (connectionPool)
|
||||
{
|
||||
connection = (HTTPConnection) connectionPool.get(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
connection = new HTTPConnection(host, port, secure);
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
|
||||
public void disconnect()
|
||||
{
|
||||
if (connection != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
connection.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean usingProxy()
|
||||
{
|
||||
return (proxyHostname != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the corresponding method in HttpURLConnection to permit
|
||||
* arbitrary methods, as long as they're valid ASCII alphabetic
|
||||
* characters. This is to permit WebDAV and other HTTP extensions to
|
||||
* function.
|
||||
* @param method the method
|
||||
*/
|
||||
public void setRequestMethod(String method)
|
||||
throws ProtocolException
|
||||
{
|
||||
if (connected)
|
||||
{
|
||||
throw new ProtocolException("Already connected");
|
||||
}
|
||||
// Validate
|
||||
method = method.toUpperCase();
|
||||
int len = method.length();
|
||||
if (len == 0)
|
||||
{
|
||||
throw new ProtocolException("Empty method name");
|
||||
}
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
char c = method.charAt(i);
|
||||
if (c < 0x41 || c > 0x5a)
|
||||
{
|
||||
throw new ProtocolException("Illegal character '" + c +
|
||||
"' at index " + i);
|
||||
}
|
||||
}
|
||||
// OK
|
||||
this.method = method;
|
||||
requestMethodSetExplicitly = true;
|
||||
}
|
||||
|
||||
public String getRequestProperty(String key)
|
||||
{
|
||||
return requestHeaders.getValue(key);
|
||||
}
|
||||
|
||||
public Map getRequestProperties()
|
||||
{
|
||||
return requestHeaders;
|
||||
}
|
||||
|
||||
public void setRequestProperty(String key, String value)
|
||||
{
|
||||
requestHeaders.put(key, value);
|
||||
}
|
||||
|
||||
public void addRequestProperty(String key, String value)
|
||||
{
|
||||
String old = requestHeaders.getValue(key);
|
||||
if (old == null)
|
||||
{
|
||||
requestHeaders.put(key, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
requestHeaders.put(key, old + "," + value);
|
||||
}
|
||||
}
|
||||
|
||||
public OutputStream getOutputStream()
|
||||
throws IOException
|
||||
{
|
||||
if (connected)
|
||||
{
|
||||
throw new ProtocolException("Already connected");
|
||||
}
|
||||
if (!doOutput)
|
||||
{
|
||||
throw new ProtocolException("doOutput is false");
|
||||
}
|
||||
else if (!requestMethodSetExplicitly)
|
||||
{
|
||||
/*
|
||||
* Silently change the method to POST if no method was set
|
||||
* explicitly. This is due to broken applications depending on this
|
||||
* behaviour (Apache XMLRPC for one).
|
||||
*/
|
||||
method = "POST";
|
||||
}
|
||||
if (requestSink == null)
|
||||
{
|
||||
requestSink = new ByteArrayOutputStream();
|
||||
}
|
||||
return requestSink;
|
||||
}
|
||||
|
||||
// -- Response --
|
||||
|
||||
public InputStream getInputStream()
|
||||
throws IOException
|
||||
{
|
||||
if (!connected)
|
||||
{
|
||||
connect();
|
||||
}
|
||||
if (!doInput)
|
||||
{
|
||||
throw new ProtocolException("doInput is false");
|
||||
}
|
||||
return responseSink;
|
||||
}
|
||||
|
||||
public InputStream getErrorStream()
|
||||
{
|
||||
return errorSink;
|
||||
}
|
||||
|
||||
public Map getHeaderFields()
|
||||
{
|
||||
if (!connected)
|
||||
{
|
||||
try
|
||||
{
|
||||
connect();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Map headers = response.getHeaders();
|
||||
Map ret = new LinkedHashMap();
|
||||
ret.put("", Collections.singletonList(getStatusLine(response)));
|
||||
for (Iterator i = headers.entrySet().iterator(); i.hasNext(); )
|
||||
{
|
||||
Map.Entry entry = (Map.Entry) i.next();
|
||||
String key = (String) entry.getKey();
|
||||
String value = (String) entry.getValue();
|
||||
ret.put(key, Collections.singletonList(value));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
String getStatusLine(Response response)
|
||||
{
|
||||
return "HTTP/" + response.getMajorVersion() +
|
||||
"." + response.getMinorVersion() +
|
||||
" " + response.getCode() +
|
||||
" " + response.getMessage();
|
||||
}
|
||||
|
||||
public String getHeaderField(int index)
|
||||
{
|
||||
if (!connected)
|
||||
{
|
||||
try
|
||||
{
|
||||
connect();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (index == 0)
|
||||
{
|
||||
return getStatusLine(response);
|
||||
}
|
||||
Iterator i = response.getHeaders().entrySet().iterator();
|
||||
Map.Entry entry;
|
||||
int count = 1;
|
||||
do
|
||||
{
|
||||
if (!i.hasNext())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
entry = (Map.Entry) i.next();
|
||||
count++;
|
||||
}
|
||||
while (count <= index);
|
||||
return (String) entry.getValue();
|
||||
}
|
||||
|
||||
public String getHeaderFieldKey(int index)
|
||||
{
|
||||
if (!connected)
|
||||
{
|
||||
try
|
||||
{
|
||||
connect();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (index == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
Iterator i = response.getHeaders().entrySet().iterator();
|
||||
Map.Entry entry;
|
||||
int count = 1;
|
||||
do
|
||||
{
|
||||
if (!i.hasNext())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
entry = (Map.Entry) i.next();
|
||||
count++;
|
||||
}
|
||||
while (count <= index);
|
||||
return (String) entry.getKey();
|
||||
}
|
||||
|
||||
public String getHeaderField(String name)
|
||||
{
|
||||
if (!connected)
|
||||
{
|
||||
try
|
||||
{
|
||||
connect();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return (String) response.getHeader(name);
|
||||
}
|
||||
|
||||
public long getHeaderFieldDate(String name, long def)
|
||||
{
|
||||
if (!connected)
|
||||
{
|
||||
try
|
||||
{
|
||||
connect();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
return def;
|
||||
}
|
||||
}
|
||||
Date date = response.getDateHeader(name);
|
||||
return (date == null) ? def : date.getTime();
|
||||
}
|
||||
|
||||
public String getContentType()
|
||||
{
|
||||
return getHeaderField("Content-Type");
|
||||
}
|
||||
|
||||
public int getResponseCode()
|
||||
throws IOException
|
||||
{
|
||||
if (!connected)
|
||||
{
|
||||
connect();
|
||||
}
|
||||
return response.getCode();
|
||||
}
|
||||
|
||||
public String getResponseMessage()
|
||||
throws IOException
|
||||
{
|
||||
if (!connected)
|
||||
{
|
||||
connect();
|
||||
}
|
||||
return response.getMessage();
|
||||
}
|
||||
|
||||
// -- HTTPS specific --
|
||||
|
||||
public String getCipherSuite()
|
||||
{
|
||||
if (!connected)
|
||||
{
|
||||
throw new IllegalStateException("not connected");
|
||||
}
|
||||
return handshakeEvent.getCipherSuite();
|
||||
}
|
||||
|
||||
public Certificate[] getLocalCertificates()
|
||||
{
|
||||
if (!connected)
|
||||
{
|
||||
throw new IllegalStateException("not connected");
|
||||
}
|
||||
return handshakeEvent.getLocalCertificates();
|
||||
}
|
||||
|
||||
public Certificate[] getServerCertificates()
|
||||
throws SSLPeerUnverifiedException
|
||||
{
|
||||
if (!connected)
|
||||
{
|
||||
throw new IllegalStateException("not connected");
|
||||
}
|
||||
return handshakeEvent.getPeerCertificates();
|
||||
}
|
||||
|
||||
// HandshakeCompletedListener
|
||||
|
||||
public void handshakeCompleted(HandshakeCompletedEvent event)
|
||||
{
|
||||
handshakeEvent = event;
|
||||
}
|
||||
|
||||
}
|
||||
|
73
libjava/classpath/gnu/java/net/protocol/http/Handler.java
Normal file
73
libjava/classpath/gnu/java/net/protocol/http/Handler.java
Normal file
|
@ -0,0 +1,73 @@
|
|||
/* Handler.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;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLStreamHandler;
|
||||
|
||||
/**
|
||||
* An HTTP URL stream handler.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public class Handler
|
||||
extends URLStreamHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns the default HTTP port (80).
|
||||
*/
|
||||
protected int getDefaultPort()
|
||||
{
|
||||
return HTTPConnection.HTTP_PORT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an HTTPURLConnection for the given URL.
|
||||
*/
|
||||
public URLConnection openConnection(URL url)
|
||||
throws IOException
|
||||
{
|
||||
return new HTTPURLConnection(url);
|
||||
}
|
||||
|
||||
}
|
||||
|
369
libjava/classpath/gnu/java/net/protocol/http/Headers.java
Normal file
369
libjava/classpath/gnu/java/net/protocol/http/Headers.java
Normal file
|
@ -0,0 +1,369 @@
|
|||
/* Headers.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;
|
||||
|
||||
import gnu.java.net.LineInputStream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A collection of HTTP header names and associated values.
|
||||
* Retrieval of values is case insensitive. An iteration over the keys
|
||||
* returns the header names in the order they were received.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public class Headers
|
||||
implements Map
|
||||
{
|
||||
|
||||
static final DateFormat dateFormat = new HTTPDateFormat();
|
||||
|
||||
static class Header
|
||||
{
|
||||
|
||||
final String name;
|
||||
|
||||
Header(String name)
|
||||
{
|
||||
if (name == null || name.length() == 0)
|
||||
{
|
||||
throw new IllegalArgumentException(name);
|
||||
}
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return name.toLowerCase().hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object other)
|
||||
{
|
||||
if (other instanceof Header)
|
||||
{
|
||||
return ((Header) other).name.equalsIgnoreCase(name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class HeaderEntry
|
||||
implements Map.Entry
|
||||
{
|
||||
|
||||
final Map.Entry entry;
|
||||
|
||||
HeaderEntry(Map.Entry entry)
|
||||
{
|
||||
this.entry = entry;
|
||||
}
|
||||
|
||||
public Object getKey()
|
||||
{
|
||||
return ((Header) entry.getKey()).name;
|
||||
}
|
||||
|
||||
public Object getValue()
|
||||
{
|
||||
return entry.getValue();
|
||||
}
|
||||
|
||||
public Object setValue(Object value)
|
||||
{
|
||||
return entry.setValue(value);
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return entry.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object other)
|
||||
{
|
||||
return entry.equals(other);
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return getKey().toString() + "=" + getValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public Object get(Object key)
|
||||
{
|
||||
return headers.get(new Header((String) key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the specified header as a string.
|
||||
*/
|
||||
public String getValue(String header)
|
||||
{
|
||||
return (String) headers.get(new Header(header));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the specified header as an integer,
|
||||
* or -1 if the header is not present or not an integer.
|
||||
*/
|
||||
public int getIntValue(String header)
|
||||
{
|
||||
String val = getValue(header);
|
||||
if (val == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
try
|
||||
{
|
||||
return Integer.parseInt(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.
|
||||
*/
|
||||
public Date getDateValue(String header)
|
||||
{
|
||||
String val = getValue(header);
|
||||
if (val == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
try
|
||||
{
|
||||
return dateFormat.parse(val);
|
||||
}
|
||||
catch (ParseException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Object put(Object key, Object value)
|
||||
{
|
||||
return headers.put(new Header((String) key), value);
|
||||
}
|
||||
|
||||
public Object remove(Object key)
|
||||
{
|
||||
return headers.remove(new Header((String) key));
|
||||
}
|
||||
|
||||
public void putAll(Map t)
|
||||
{
|
||||
for (Iterator i = t.keySet().iterator(); i.hasNext(); )
|
||||
{
|
||||
String key = (String) i.next();
|
||||
String value = (String) t.get(key);
|
||||
headers.put(new Header(key), value);
|
||||
}
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
headers.clear();
|
||||
}
|
||||
|
||||
public Set keySet()
|
||||
{
|
||||
Set keys = headers.keySet();
|
||||
Set ret = new LinkedHashSet();
|
||||
for (Iterator i = keys.iterator(); i.hasNext(); )
|
||||
{
|
||||
ret.add(((Header) i.next()).name);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Collection values()
|
||||
{
|
||||
return headers.values();
|
||||
}
|
||||
|
||||
public Set entrySet()
|
||||
{
|
||||
Set entries = headers.entrySet();
|
||||
Set ret = new LinkedHashSet();
|
||||
for (Iterator i = entries.iterator(); i.hasNext(); )
|
||||
{
|
||||
Map.Entry entry = (Map.Entry) i.next();
|
||||
ret.add(new HeaderEntry(entry));
|
||||
}
|
||||
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.
|
||||
*/
|
||||
public void parse(InputStream in)
|
||||
throws IOException
|
||||
{
|
||||
LineInputStream lin = (in instanceof LineInputStream) ?
|
||||
(LineInputStream) in : new LineInputStream(in);
|
||||
|
||||
String name = null;
|
||||
StringBuffer value = new StringBuffer();
|
||||
while (true)
|
||||
{
|
||||
String line = lin.readLine();
|
||||
if (line == null)
|
||||
{
|
||||
if (name != null)
|
||||
{
|
||||
addValue(name, value.toString());
|
||||
}
|
||||
break;
|
||||
}
|
||||
int len = line.length();
|
||||
if (len < 2)
|
||||
{
|
||||
if (name != null)
|
||||
{
|
||||
addValue(name, value.toString());
|
||||
}
|
||||
break;
|
||||
}
|
||||
char c1 = line.charAt(0);
|
||||
if (c1 == ' ' || c1 == '\t')
|
||||
{
|
||||
// Continuation
|
||||
int last = len - 1;
|
||||
if (line.charAt(last) != '\r')
|
||||
++last;
|
||||
value.append(line.substring(0, last));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (name != null)
|
||||
{
|
||||
addValue(name, value.toString());
|
||||
}
|
||||
|
||||
int di = line.indexOf(':');
|
||||
name = line.substring(0, di);
|
||||
value.setLength(0);
|
||||
do
|
||||
{
|
||||
di++;
|
||||
}
|
||||
while (di < len && line.charAt(di) == ' ');
|
||||
int last = len - 1;
|
||||
if (line.charAt(last) != '\r')
|
||||
++last;
|
||||
value.append(line.substring(di, last));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addValue(String name, String value)
|
||||
{
|
||||
Header key = new Header(name);
|
||||
String old = (String) headers.get(key);
|
||||
if (old == null)
|
||||
{
|
||||
headers.put(key, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
headers.put(key, old + ", " + value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
915
libjava/classpath/gnu/java/net/protocol/http/Request.java
Normal file
915
libjava/classpath/gnu/java/net/protocol/http/Request.java
Normal file
|
@ -0,0 +1,915 @@
|
|||
/* Request.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;
|
||||
|
||||
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;
|
||||
import java.io.OutputStream;
|
||||
import java.net.ProtocolException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.InflaterInputStream;
|
||||
|
||||
/**
|
||||
* A single HTTP request.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public class Request
|
||||
{
|
||||
|
||||
/**
|
||||
* The connection context in which this request is invoked.
|
||||
*/
|
||||
protected final HTTPConnection connection;
|
||||
|
||||
/**
|
||||
* The HTTP method to invoke.
|
||||
*/
|
||||
protected final String method;
|
||||
|
||||
/**
|
||||
* The path identifying the resource.
|
||||
* This string must conform to the abs_path definition given in RFC2396,
|
||||
* with an optional "?query" part, and must be URI-escaped by the caller.
|
||||
*/
|
||||
protected final String path;
|
||||
|
||||
/**
|
||||
* The headers in this request.
|
||||
*/
|
||||
protected final Headers requestHeaders;
|
||||
|
||||
/**
|
||||
* The request body provider.
|
||||
*/
|
||||
protected RequestBodyWriter requestBodyWriter;
|
||||
|
||||
/**
|
||||
* Request body negotiation threshold for 100-continue expectations.
|
||||
*/
|
||||
protected int requestBodyNegotiationThreshold;
|
||||
|
||||
/**
|
||||
* The response body reader.
|
||||
*/
|
||||
protected ResponseBodyReader responseBodyReader;
|
||||
|
||||
/**
|
||||
* Map of response header handlers.
|
||||
*/
|
||||
protected Map responseHeaderHandlers;
|
||||
|
||||
/**
|
||||
* The authenticator.
|
||||
*/
|
||||
protected Authenticator authenticator;
|
||||
|
||||
/**
|
||||
* Whether this request has been dispatched yet.
|
||||
*/
|
||||
private boolean dispatched;
|
||||
|
||||
/**
|
||||
* Constructor for a new request.
|
||||
* @param connection the connection context
|
||||
* @param method the HTTP method
|
||||
* @param path the resource path including query part
|
||||
*/
|
||||
protected Request(HTTPConnection connection, String method,
|
||||
String path)
|
||||
{
|
||||
this.connection = connection;
|
||||
this.method = method;
|
||||
this.path = path;
|
||||
requestHeaders = new Headers();
|
||||
responseHeaderHandlers = new HashMap();
|
||||
requestBodyNegotiationThreshold = 4096;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the connection associated with this request.
|
||||
* @see #connection
|
||||
*/
|
||||
public HTTPConnection getConnection()
|
||||
{
|
||||
return connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTTP method to invoke.
|
||||
* @see #method
|
||||
*/
|
||||
public String getMethod()
|
||||
{
|
||||
return method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the resource path.
|
||||
* @see #path
|
||||
*/
|
||||
public String getPath()
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full request-URI represented by this request, as specified
|
||||
* by HTTP/1.1.
|
||||
*/
|
||||
public String getRequestURI()
|
||||
{
|
||||
return connection.getURI() + path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the headers in this request.
|
||||
*/
|
||||
public Headers getHeaders()
|
||||
{
|
||||
return requestHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the specified header in this request.
|
||||
* @param name the header name
|
||||
*/
|
||||
public String getHeader(String name)
|
||||
{
|
||||
return requestHeaders.getValue(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the specified header in this request as an integer.
|
||||
* @param name the header name
|
||||
*/
|
||||
public int getIntHeader(String name)
|
||||
{
|
||||
return requestHeaders.getIntValue(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the specified header in this request as a date.
|
||||
* @param name the header name
|
||||
*/
|
||||
public Date getDateHeader(String name)
|
||||
{
|
||||
return requestHeaders.getDateValue(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the specified header in this request.
|
||||
* @param name the header name
|
||||
* @param value the header value
|
||||
*/
|
||||
public void setHeader(String name, String value)
|
||||
{
|
||||
requestHeaders.put(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to set the entire request body.
|
||||
* @param requestBody the request body content
|
||||
*/
|
||||
public void setRequestBody(byte[] requestBody)
|
||||
{
|
||||
setRequestBodyWriter(new ByteArrayRequestBodyWriter(requestBody));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the request body provider.
|
||||
* @param requestBodyWriter the handler used to obtain the request body
|
||||
*/
|
||||
public void setRequestBodyWriter(RequestBodyWriter requestBodyWriter)
|
||||
{
|
||||
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
|
||||
* @param handler the handler to receive the value for the header
|
||||
*/
|
||||
public void setResponseHeaderHandler(String name,
|
||||
ResponseHeaderHandler handler)
|
||||
{
|
||||
responseHeaderHandlers.put(name, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an authenticator that can be used to handle authentication
|
||||
* automatically.
|
||||
* @param authenticator the authenticator
|
||||
*/
|
||||
public void setAuthenticator(Authenticator authenticator)
|
||||
{
|
||||
this.authenticator = authenticator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the request body negotiation threshold.
|
||||
* If this is set, it determines the maximum size that the request body
|
||||
* may be before body negotiation occurs(via the
|
||||
* <code>100-continue</code> expectation). This ensures that a large
|
||||
* request body is not sent when the server wouldn't have accepted it
|
||||
* anyway.
|
||||
* @param threshold the body negotiation threshold, or <=0 to disable
|
||||
* request body negotation entirely
|
||||
*/
|
||||
public void setRequestBodyNegotiationThreshold(int threshold)
|
||||
{
|
||||
requestBodyNegotiationThreshold = threshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches this request.
|
||||
* A request can only be dispatched once; calling this method a second
|
||||
* time results in a protocol exception.
|
||||
* @exception IOException if an I/O error occurred
|
||||
* @return an HTTP response object representing the result of the operation
|
||||
*/
|
||||
public Response dispatch()
|
||||
throws IOException
|
||||
{
|
||||
if (dispatched)
|
||||
{
|
||||
throw new ProtocolException("request already dispatched");
|
||||
}
|
||||
final String CRLF = "\r\n";
|
||||
final String HEADER_SEP = ": ";
|
||||
final String US_ASCII = "US-ASCII";
|
||||
final String version = connection.getVersion();
|
||||
Response response;
|
||||
int contentLength = -1;
|
||||
boolean retry = false;
|
||||
int attempts = 0;
|
||||
boolean expectingContinue = false;
|
||||
if (requestBodyWriter != null)
|
||||
{
|
||||
contentLength = requestBodyWriter.getContentLength();
|
||||
if (contentLength > requestBodyNegotiationThreshold)
|
||||
{
|
||||
expectingContinue = true;
|
||||
setHeader("Expect", "100-continue");
|
||||
}
|
||||
else
|
||||
{
|
||||
setHeader("Content-Length", Integer.toString(contentLength));
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Loop while authentication fails or continue
|
||||
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() &&
|
||||
!"*".equals(requestUri) &&
|
||||
!"CONNECT".equals(method))
|
||||
{
|
||||
requestUri = getRequestURI();
|
||||
}
|
||||
String line = method + ' ' + requestUri + ' ' + version + CRLF;
|
||||
out.write(line.getBytes(US_ASCII));
|
||||
// Request headers
|
||||
for (Iterator i = requestHeaders.keySet().iterator();
|
||||
i.hasNext(); )
|
||||
{
|
||||
String name =(String) i.next();
|
||||
String value =(String) requestHeaders.get(name);
|
||||
line = name + HEADER_SEP + value + CRLF;
|
||||
out.write(line.getBytes(US_ASCII));
|
||||
}
|
||||
out.write(CRLF.getBytes(US_ASCII));
|
||||
// Request body
|
||||
if (requestBodyWriter != null && !expectingContinue)
|
||||
{
|
||||
byte[] buffer = new byte[4096];
|
||||
int len;
|
||||
int count = 0;
|
||||
|
||||
requestBodyWriter.reset();
|
||||
do
|
||||
{
|
||||
len = requestBodyWriter.write(buffer);
|
||||
if (len > 0)
|
||||
{
|
||||
out.write(buffer, 0, len);
|
||||
}
|
||||
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 (retry);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
connection.close();
|
||||
throw e;
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
Response readResponse(LineInputStream in)
|
||||
throws IOException
|
||||
{
|
||||
String line;
|
||||
int len;
|
||||
|
||||
// Read response status line
|
||||
line = in.readLine();
|
||||
if (line == null)
|
||||
{
|
||||
throw new ProtocolException("Peer closed connection");
|
||||
}
|
||||
if (!line.startsWith("HTTP/"))
|
||||
{
|
||||
throw new ProtocolException(line);
|
||||
}
|
||||
len = line.length();
|
||||
int start = 5, end = 6;
|
||||
while (line.charAt(end) != '.')
|
||||
{
|
||||
end++;
|
||||
}
|
||||
int majorVersion = Integer.parseInt(line.substring(start, end));
|
||||
start = end + 1;
|
||||
end = start + 1;
|
||||
while (line.charAt(end) != ' ')
|
||||
{
|
||||
end++;
|
||||
}
|
||||
int minorVersion = Integer.parseInt(line.substring(start, end));
|
||||
start = end + 1;
|
||||
end = start + 3;
|
||||
int code = Integer.parseInt(line.substring(start, end));
|
||||
String message = line.substring(end + 1, len - 1);
|
||||
// Read response headers
|
||||
Headers responseHeaders = new Headers();
|
||||
responseHeaders.parse(in);
|
||||
notifyHeaderHandlers(responseHeaders);
|
||||
// Construct response
|
||||
int codeClass = code / 100;
|
||||
Response ret = new Response(majorVersion, minorVersion, code,
|
||||
codeClass, message, responseHeaders);
|
||||
switch (code)
|
||||
{
|
||||
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);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void notifyHeaderHandlers(Headers headers)
|
||||
{
|
||||
for (Iterator i = headers.entrySet().iterator(); i.hasNext(); )
|
||||
{
|
||||
Map.Entry entry = (Map.Entry) i.next();
|
||||
String name =(String) entry.getKey();
|
||||
// Handle Set-Cookie
|
||||
if ("Set-Cookie".equalsIgnoreCase(name))
|
||||
{
|
||||
String value = (String) entry.getValue();
|
||||
handleSetCookie(value);
|
||||
}
|
||||
ResponseHeaderHandler handler =
|
||||
(ResponseHeaderHandler) responseHeaderHandlers.get(name);
|
||||
if (handler != null)
|
||||
{
|
||||
String value = (String) entry.getValue();
|
||||
handler.setValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void readResponseBody(Response response, InputStream in,
|
||||
boolean notify)
|
||||
throws IOException
|
||||
{
|
||||
byte[] buffer = new byte[4096];
|
||||
int contentLength = -1;
|
||||
Headers trailer = null;
|
||||
|
||||
String transferCoding = response.getHeader("Transfer-Encoding");
|
||||
if ("chunked".equalsIgnoreCase(transferCoding))
|
||||
{
|
||||
trailer = new Headers();
|
||||
in = new ChunkedInputStream(in, trailer);
|
||||
}
|
||||
else
|
||||
{
|
||||
contentLength = response.getIntHeader("Content-Length");
|
||||
}
|
||||
String contentCoding = response.getHeader("Content-Encoding");
|
||||
if (contentCoding != null && !"identity".equals(contentCoding))
|
||||
{
|
||||
if ("gzip".equals(contentCoding))
|
||||
{
|
||||
in = new GZIPInputStream(in);
|
||||
}
|
||||
else if ("deflate".equals(contentCoding))
|
||||
{
|
||||
in = new InflaterInputStream(in);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ProtocolException("Unsupported Content-Encoding: " +
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
boolean authenticate(Response response, int attempts)
|
||||
throws IOException
|
||||
{
|
||||
String challenge = response.getHeader("WWW-Authenticate");
|
||||
if (challenge == null)
|
||||
{
|
||||
challenge = response.getHeader("Proxy-Authenticate");
|
||||
}
|
||||
int si = challenge.indexOf(' ');
|
||||
String scheme = (si == -1) ? challenge : challenge.substring(0, si);
|
||||
if ("Basic".equalsIgnoreCase(scheme))
|
||||
{
|
||||
Properties params = parseAuthParams(challenge.substring(si + 1));
|
||||
String realm = params.getProperty("realm");
|
||||
Credentials creds = authenticator.getCredentials(realm, attempts);
|
||||
String userPass = creds.getUsername() + ':' + creds.getPassword();
|
||||
byte[] b_userPass = userPass.getBytes("US-ASCII");
|
||||
byte[] b_encoded = BASE64.encode(b_userPass);
|
||||
String authorization =
|
||||
scheme + " " + new String(b_encoded, "US-ASCII");
|
||||
setHeader("Authorization", authorization);
|
||||
return true;
|
||||
}
|
||||
else if ("Digest".equalsIgnoreCase(scheme))
|
||||
{
|
||||
Properties params = parseAuthParams(challenge.substring(si + 1));
|
||||
String realm = params.getProperty("realm");
|
||||
String nonce = params.getProperty("nonce");
|
||||
String qop = params.getProperty("qop");
|
||||
String algorithm = params.getProperty("algorithm");
|
||||
String digestUri = getRequestURI();
|
||||
Credentials creds = authenticator.getCredentials(realm, attempts);
|
||||
String username = creds.getUsername();
|
||||
String password = creds.getPassword();
|
||||
connection.incrementNonce(nonce);
|
||||
try
|
||||
{
|
||||
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||
final byte[] COLON = { 0x3a };
|
||||
|
||||
// Calculate H(A1)
|
||||
md5.reset();
|
||||
md5.update(username.getBytes("US-ASCII"));
|
||||
md5.update(COLON);
|
||||
md5.update(realm.getBytes("US-ASCII"));
|
||||
md5.update(COLON);
|
||||
md5.update(password.getBytes("US-ASCII"));
|
||||
byte[] ha1 = md5.digest();
|
||||
if ("md5-sess".equals(algorithm))
|
||||
{
|
||||
byte[] cnonce = generateNonce();
|
||||
md5.reset();
|
||||
md5.update(ha1);
|
||||
md5.update(COLON);
|
||||
md5.update(nonce.getBytes("US-ASCII"));
|
||||
md5.update(COLON);
|
||||
md5.update(cnonce);
|
||||
ha1 = md5.digest();
|
||||
}
|
||||
String ha1Hex = toHexString(ha1);
|
||||
|
||||
// Calculate H(A2)
|
||||
md5.reset();
|
||||
md5.update(method.getBytes("US-ASCII"));
|
||||
md5.update(COLON);
|
||||
md5.update(digestUri.getBytes("US-ASCII"));
|
||||
if ("auth-int".equals(qop))
|
||||
{
|
||||
byte[] hEntity = null; // TODO hash of entity body
|
||||
md5.update(COLON);
|
||||
md5.update(hEntity);
|
||||
}
|
||||
byte[] ha2 = md5.digest();
|
||||
String ha2Hex = toHexString(ha2);
|
||||
|
||||
// Calculate response
|
||||
md5.reset();
|
||||
md5.update(ha1Hex.getBytes("US-ASCII"));
|
||||
md5.update(COLON);
|
||||
md5.update(nonce.getBytes("US-ASCII"));
|
||||
if ("auth".equals(qop) || "auth-int".equals(qop))
|
||||
{
|
||||
String nc = getNonceCount(nonce);
|
||||
byte[] cnonce = generateNonce();
|
||||
md5.update(COLON);
|
||||
md5.update(nc.getBytes("US-ASCII"));
|
||||
md5.update(COLON);
|
||||
md5.update(cnonce);
|
||||
md5.update(COLON);
|
||||
md5.update(qop.getBytes("US-ASCII"));
|
||||
}
|
||||
md5.update(COLON);
|
||||
md5.update(ha2Hex.getBytes("US-ASCII"));
|
||||
String digestResponse = toHexString(md5.digest());
|
||||
|
||||
String authorization = scheme +
|
||||
" username=\"" + username + "\"" +
|
||||
" realm=\"" + realm + "\"" +
|
||||
" nonce=\"" + nonce + "\"" +
|
||||
" uri=\"" + digestUri + "\"" +
|
||||
" response=\"" + digestResponse + "\"";
|
||||
setHeader("Authorization", authorization);
|
||||
return true;
|
||||
}
|
||||
catch (NoSuchAlgorithmException e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Scheme not recognised
|
||||
return false;
|
||||
}
|
||||
|
||||
Properties parseAuthParams(String text)
|
||||
{
|
||||
int len = text.length();
|
||||
String key = null;
|
||||
StringBuffer buf = new StringBuffer();
|
||||
Properties ret = new Properties();
|
||||
boolean inQuote = false;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
char c = text.charAt(i);
|
||||
if (c == '"')
|
||||
{
|
||||
inQuote = !inQuote;
|
||||
}
|
||||
else if (c == '=' && key == null)
|
||||
{
|
||||
key = buf.toString().trim();
|
||||
buf.setLength(0);
|
||||
}
|
||||
else if (c == ' ' && !inQuote)
|
||||
{
|
||||
String value = unquote(buf.toString().trim());
|
||||
ret.put(key, value);
|
||||
key = null;
|
||||
buf.setLength(0);
|
||||
}
|
||||
else if (c != ',' || (i <(len - 1) && text.charAt(i + 1) != ' '))
|
||||
{
|
||||
buf.append(c);
|
||||
}
|
||||
}
|
||||
if (key != null)
|
||||
{
|
||||
String value = unquote(buf.toString().trim());
|
||||
ret.put(key, value);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
String unquote(String text)
|
||||
{
|
||||
int len = text.length();
|
||||
if (len > 0 && text.charAt(0) == '"' && text.charAt(len - 1) == '"')
|
||||
{
|
||||
return text.substring(1, len - 1);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of times the specified nonce value has been seen.
|
||||
* This always returns an 8-byte 0-padded hexadecimal string.
|
||||
*/
|
||||
String getNonceCount(String nonce)
|
||||
{
|
||||
int nc = connection.getNonceCount(nonce);
|
||||
String hex = Integer.toHexString(nc);
|
||||
StringBuffer buf = new StringBuffer();
|
||||
for (int i = 8 - hex.length(); i > 0; i--)
|
||||
{
|
||||
buf.append('0');
|
||||
}
|
||||
buf.append(hex);
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Client nonce value.
|
||||
*/
|
||||
byte[] nonce;
|
||||
|
||||
/**
|
||||
* Generates a new client nonce value.
|
||||
*/
|
||||
byte[] generateNonce()
|
||||
throws IOException, NoSuchAlgorithmException
|
||||
{
|
||||
if (nonce == null)
|
||||
{
|
||||
long time = System.currentTimeMillis();
|
||||
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||
md5.update(Long.toString(time).getBytes("US-ASCII"));
|
||||
nonce = md5.digest();
|
||||
}
|
||||
return nonce;
|
||||
}
|
||||
|
||||
String toHexString(byte[] bytes)
|
||||
{
|
||||
char[] ret = new char[bytes.length * 2];
|
||||
for (int i = 0, j = 0; i < bytes.length; i++)
|
||||
{
|
||||
int c =(int) bytes[i];
|
||||
if (c < 0)
|
||||
{
|
||||
c += 0x100;
|
||||
}
|
||||
ret[j++] = Character.forDigit(c / 0x10, 0x10);
|
||||
ret[j++] = Character.forDigit(c % 0x10, 0x10);
|
||||
}
|
||||
return new String(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the specified cookie list and notify the cookie manager.
|
||||
*/
|
||||
void handleSetCookie(String text)
|
||||
{
|
||||
CookieManager cookieManager = connection.getCookieManager();
|
||||
if (cookieManager == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
String name = null;
|
||||
String value = null;
|
||||
String comment = null;
|
||||
String domain = connection.getHostName();
|
||||
String path = this.path;
|
||||
int lsi = path.lastIndexOf('/');
|
||||
if (lsi != -1)
|
||||
{
|
||||
path = path.substring(0, lsi);
|
||||
}
|
||||
boolean secure = false;
|
||||
Date expires = null;
|
||||
|
||||
int len = text.length();
|
||||
String attr = null;
|
||||
StringBuffer buf = new StringBuffer();
|
||||
boolean inQuote = false;
|
||||
for (int i = 0; i <= len; i++)
|
||||
{
|
||||
char c =(i == len) ? '\u0000' : text.charAt(i);
|
||||
if (c == '"')
|
||||
{
|
||||
inQuote = !inQuote;
|
||||
}
|
||||
else if (!inQuote)
|
||||
{
|
||||
if (c == '=' && attr == null)
|
||||
{
|
||||
attr = buf.toString().trim();
|
||||
buf.setLength(0);
|
||||
}
|
||||
else if (c == ';' || i == len || c == ',')
|
||||
{
|
||||
String val = unquote(buf.toString().trim());
|
||||
if (name == null)
|
||||
{
|
||||
name = attr;
|
||||
value = val;
|
||||
}
|
||||
else if ("Comment".equalsIgnoreCase(attr))
|
||||
{
|
||||
comment = val;
|
||||
}
|
||||
else if ("Domain".equalsIgnoreCase(attr))
|
||||
{
|
||||
domain = val;
|
||||
}
|
||||
else if ("Path".equalsIgnoreCase(attr))
|
||||
{
|
||||
path = val;
|
||||
}
|
||||
else if ("Secure".equalsIgnoreCase(val))
|
||||
{
|
||||
secure = true;
|
||||
}
|
||||
else if ("Max-Age".equalsIgnoreCase(attr))
|
||||
{
|
||||
int delta = Integer.parseInt(val);
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTimeInMillis(System.currentTimeMillis());
|
||||
cal.add(Calendar.SECOND, delta);
|
||||
expires = cal.getTime();
|
||||
}
|
||||
else if ("Expires".equalsIgnoreCase(attr))
|
||||
{
|
||||
DateFormat dateFormat = new HTTPDateFormat();
|
||||
try
|
||||
{
|
||||
expires = dateFormat.parse(val);
|
||||
}
|
||||
catch (ParseException e)
|
||||
{
|
||||
// if this isn't a valid date, it may be that
|
||||
// the value was returned unquoted; in that case, we
|
||||
// want to continue buffering the value
|
||||
buf.append(c);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
attr = null;
|
||||
buf.setLength(0);
|
||||
// case EOL
|
||||
if (i == len || c == ',')
|
||||
{
|
||||
Cookie cookie = new Cookie(name, value, comment, domain,
|
||||
path, secure, expires);
|
||||
cookieManager.setCookie(cookie);
|
||||
}
|
||||
if (c == ',')
|
||||
{
|
||||
// Reset cookie fields
|
||||
name = null;
|
||||
value = null;
|
||||
comment = null;
|
||||
domain = connection.getHostName();
|
||||
path = this.path;
|
||||
if (lsi != -1)
|
||||
{
|
||||
path = path.substring(0, lsi);
|
||||
}
|
||||
secure = false;
|
||||
expires = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.append(c);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.append(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/* RequestBodyWriter.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 writing request body content.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public interface RequestBodyWriter
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns the total number of bytes that will be written in a single pass
|
||||
* by this writer.
|
||||
*/
|
||||
int getContentLength();
|
||||
|
||||
/**
|
||||
* Initialises the writer.
|
||||
* This will be called before each pass.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* Writes body content to the supplied buffer.
|
||||
* @param buffer the content buffer
|
||||
* @return the number of bytes written
|
||||
*/
|
||||
int write(byte[] buffer);
|
||||
|
||||
}
|
||||
|
185
libjava/classpath/gnu/java/net/protocol/http/Response.java
Normal file
185
libjava/classpath/gnu/java/net/protocol/http/Response.java
Normal file
|
@ -0,0 +1,185 @@
|
|||
/* Response.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;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* An HTTP response.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public class Response
|
||||
{
|
||||
|
||||
/**
|
||||
* The HTTP major version of the server issuing the response.
|
||||
*/
|
||||
protected final int majorVersion;
|
||||
|
||||
/**
|
||||
* The HTTP minor version of the server issuing the response.
|
||||
*/
|
||||
protected final int minorVersion;
|
||||
|
||||
/**
|
||||
* The HTTP status code of the 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;
|
||||
|
||||
/**
|
||||
* The response headers.
|
||||
*/
|
||||
protected final Headers headers;
|
||||
|
||||
/**
|
||||
* Constructs a new response with the specified parameters.
|
||||
*/
|
||||
protected Response(int majorVersion, int minorVersion, int code,
|
||||
int codeClass, String message,
|
||||
Headers headers)
|
||||
{
|
||||
this.majorVersion = majorVersion;
|
||||
this.minorVersion = minorVersion;
|
||||
this.code = code;
|
||||
this.codeClass = codeClass;
|
||||
this.message = message;
|
||||
this.headers = headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTTP major version of the server issuing the response.
|
||||
* @see #majorVersion
|
||||
*/
|
||||
public int getMajorVersion()
|
||||
{
|
||||
return majorVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTTP minor version of the server issuing the response.
|
||||
* @see #minorVersion
|
||||
*/
|
||||
public int getMinorVersion()
|
||||
{
|
||||
return minorVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTTP status code of the response.
|
||||
* @see #code
|
||||
*/
|
||||
public int getCode()
|
||||
{
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class of the response.
|
||||
* @see #codeClass
|
||||
*/
|
||||
public int getCodeClass()
|
||||
{
|
||||
return codeClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the human-readable text of the response.
|
||||
* @see #message
|
||||
*/
|
||||
public String getMessage()
|
||||
{
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the headers in the response.
|
||||
*/
|
||||
public Headers getHeaders()
|
||||
{
|
||||
return headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the header value for the specified name.
|
||||
* @param name the header name
|
||||
*/
|
||||
public String getHeader(String name)
|
||||
{
|
||||
return headers.getValue(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the header value for the specified name as an integer.
|
||||
* @param name the header name
|
||||
*/
|
||||
public int getIntHeader(String name)
|
||||
{
|
||||
return headers.getIntValue(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the header value for the specified name as a date.
|
||||
* @param name the header name
|
||||
*/
|
||||
public Date getDateHeader(String name)
|
||||
{
|
||||
return headers.getDateValue(name);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/* 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();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/* ResponseHeaderHandler.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 objects that wish to be notified of response
|
||||
* header values.
|
||||
* @see Request#setHeaderHandler(String)
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public interface ResponseHeaderHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* Sets the value for the header associated with this handler.
|
||||
*/
|
||||
void setValue(String value);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
/* CookieManager.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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A simple non-persistent cookie manager. This class can be extended to
|
||||
* provide cookie persistence.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public class SimpleCookieManager
|
||||
implements CookieManager
|
||||
{
|
||||
|
||||
/**
|
||||
* The cookie cache.
|
||||
* This is a dictionary mapping domains to maps of cookies by name.
|
||||
*/
|
||||
protected Map cookies;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public SimpleCookieManager()
|
||||
{
|
||||
cookies = new HashMap();
|
||||
}
|
||||
|
||||
public void setCookie(Cookie cookie)
|
||||
{
|
||||
String domain = cookie.getDomain();
|
||||
Map map =(Map) cookies.get(domain);
|
||||
if (map == null)
|
||||
{
|
||||
map = new HashMap();
|
||||
cookies.put(domain, map);
|
||||
}
|
||||
String name = cookie.getName();
|
||||
map.put(name, cookie); // will replace a cookie of the same name
|
||||
}
|
||||
|
||||
public Cookie[] getCookies(String host, boolean secure, String path)
|
||||
{
|
||||
List matches = new ArrayList();
|
||||
Date now = new Date();
|
||||
if (Character.isLetter(host.charAt(0)))
|
||||
{
|
||||
int di = host.indexOf('.');
|
||||
while (di != -1)
|
||||
{
|
||||
addCookies(matches, host, secure, path, now);
|
||||
host = host.substring(di);
|
||||
di = host.indexOf('.', 1);
|
||||
}
|
||||
}
|
||||
addCookies(matches, host, secure, path, now);
|
||||
Cookie[] ret = new Cookie[matches.size()];
|
||||
matches.toArray(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private void addCookies(List matches, String domain, boolean secure,
|
||||
String path, Date now)
|
||||
{
|
||||
Map map = (Map) cookies.get(domain);
|
||||
if (map != null)
|
||||
{
|
||||
List expired = new ArrayList();
|
||||
for (Iterator i = map.entrySet().iterator(); i.hasNext(); )
|
||||
{
|
||||
Map.Entry entry = (Map.Entry) i.next();
|
||||
Cookie cookie = (Cookie) entry.getValue();
|
||||
Date expires = cookie.getExpiryDate();
|
||||
if (expires != null && expires.before(now))
|
||||
{
|
||||
expired.add(entry.getKey());
|
||||
continue;
|
||||
}
|
||||
if (secure && !cookie.isSecure())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (path.startsWith(cookie.getPath()))
|
||||
{
|
||||
matches.add(cookie);
|
||||
}
|
||||
}
|
||||
// Good housekeeping
|
||||
for (Iterator i = expired.iterator(); i.hasNext(); )
|
||||
{
|
||||
map.remove(i.next());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/* 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/* 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);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
/* 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/* 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);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
<!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>
|
76
libjava/classpath/gnu/java/net/protocol/http/package.html
Normal file
76
libjava/classpath/gnu/java/net/protocol/http/package.html
Normal file
|
@ -0,0 +1,76 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<!-- package.html - describes classes in gnu.java.net.protocol.http package.
|
||||
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. -->
|
||||
|
||||
<html>
|
||||
<head><title>GNU Classpath - gnu.java.net.protocol.http</title></head>
|
||||
|
||||
<body>
|
||||
|
||||
<p>
|
||||
This package contains an HTTP/1.1 client, as described in RFC 2616.
|
||||
It supports the following features:
|
||||
<ul>
|
||||
<li>Persistent connections</li>
|
||||
<li>Basic and Digest authentication (RFC 2617)</li>
|
||||
<li>HTTPS</li>
|
||||
<li>HTTP proxies</li>
|
||||
<li>HTTP/1.0 compatibility</li>
|
||||
<li>Support for WebDAV methods and other HTTP extensions</li>
|
||||
<li>Automatic decoding of the chunked transfer-coding</li>
|
||||
<li>Parsing of HTTP date headers</li>
|
||||
<li>Support for the 100-continue expectation</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The API is similar to the <a href='http://www.webdav.org/neon/'>neon</a>
|
||||
WebDAV/HTTP library. A logical connection to the server is instantiated,
|
||||
and multiple requests can be issued for this connection. Each request
|
||||
has an atomic <code>dispatch</code> method which returns the response.
|
||||
All I/O, authentication, etc is handled by registering callback objects
|
||||
with the request prior to dispatch, which are notified during the dispatch
|
||||
procedure as necessary. Simple byte-array content callbacks are supplied
|
||||
which can manage any request/response content that fits in available memory.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
An URL stream handler is provided, supporting the full HttpURLConnection
|
||||
specification.
|
||||
</p>
|
||||
|
||||
</body>
|
76
libjava/classpath/gnu/java/net/protocol/https/Handler.java
Normal file
76
libjava/classpath/gnu/java/net/protocol/https/Handler.java
Normal file
|
@ -0,0 +1,76 @@
|
|||
/* Handler.java --
|
||||
Copyright (C) 2004, 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.https;
|
||||
|
||||
import gnu.java.net.protocol.http.HTTPConnection;
|
||||
import gnu.java.net.protocol.http.HTTPURLConnection;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLStreamHandler;
|
||||
|
||||
/**
|
||||
* An HTTPS URL stream handler.
|
||||
*
|
||||
* @author Chris Burdess (dog@gnu.org)
|
||||
*/
|
||||
public class Handler
|
||||
extends URLStreamHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns the default HTTPS port (443).
|
||||
*/
|
||||
protected int getDefaultPort()
|
||||
{
|
||||
return HTTPConnection.HTTPS_PORT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an HTTPURLConnection for the given URL.
|
||||
*/
|
||||
public URLConnection openConnection(URL url)
|
||||
throws IOException
|
||||
{
|
||||
return new HTTPURLConnection(url);
|
||||
}
|
||||
|
||||
}
|
||||
|
170
libjava/classpath/gnu/java/net/protocol/jar/Connection.java
Normal file
170
libjava/classpath/gnu/java/net/protocol/jar/Connection.java
Normal file
|
@ -0,0 +1,170 @@
|
|||
/* Connection - jar url connection for java.net
|
||||
Copyright (C) 1999, 2002, 2003, 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.jar;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.JarURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.ProtocolException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.Hashtable;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
/**
|
||||
* This subclass of java.net.JarURLConnection models a URLConnection via
|
||||
* the "jar" protocol.
|
||||
*
|
||||
* @author Kresten Krab Thorup (krab@gnu.org)
|
||||
*/
|
||||
public final class Connection extends JarURLConnection
|
||||
{
|
||||
private JarFile jar_file;
|
||||
private JarEntry jar_entry;
|
||||
private URL jar_url;
|
||||
|
||||
public static class JarFileCache
|
||||
{
|
||||
private static Hashtable cache = new Hashtable();
|
||||
private static final int READBUFSIZE = 4*1024;
|
||||
|
||||
public static synchronized JarFile get (URL url) throws IOException
|
||||
{
|
||||
JarFile jf = (JarFile) cache.get (url);
|
||||
|
||||
if (jf != null)
|
||||
return jf;
|
||||
|
||||
if ("file".equals (url.getProtocol()))
|
||||
{
|
||||
File f = new File (url.getFile());
|
||||
jf = new JarFile (f, true, ZipFile.OPEN_READ);
|
||||
}
|
||||
else
|
||||
{
|
||||
URLConnection urlconn = url.openConnection();
|
||||
InputStream is = urlconn.getInputStream();
|
||||
byte[] buf = new byte [READBUFSIZE];
|
||||
File f = File.createTempFile ("cache", "jar");
|
||||
FileOutputStream fos = new FileOutputStream (f);
|
||||
int len = 0;
|
||||
|
||||
while ((len = is.read (buf)) != -1)
|
||||
{
|
||||
fos.write (buf, 0, len);
|
||||
}
|
||||
|
||||
fos.close();
|
||||
// Always verify the Manifest, open read only and delete when done.
|
||||
jf = new JarFile (f, true,
|
||||
ZipFile.OPEN_READ | ZipFile.OPEN_DELETE);
|
||||
}
|
||||
|
||||
cache.put (url, jf);
|
||||
|
||||
return jf;
|
||||
}
|
||||
}
|
||||
|
||||
protected Connection(URL url)
|
||||
throws MalformedURLException
|
||||
{
|
||||
super(url);
|
||||
}
|
||||
|
||||
public synchronized void connect() throws IOException
|
||||
{
|
||||
// Call is ignored if already connected.
|
||||
if (connected)
|
||||
return;
|
||||
|
||||
jar_url = getJarFileURL();
|
||||
jar_file = JarFileCache.get (jar_url);
|
||||
String entry_name = getEntryName();
|
||||
|
||||
if (entry_name != null
|
||||
&& !entry_name.equals (""))
|
||||
{
|
||||
jar_entry = (JarEntry) jar_file.getEntry (entry_name);
|
||||
|
||||
if(jar_entry == null)
|
||||
throw new IOException ("No entry for " + entry_name + " exists.");
|
||||
}
|
||||
|
||||
connected = true;
|
||||
}
|
||||
|
||||
public InputStream getInputStream() throws IOException
|
||||
{
|
||||
if (!connected)
|
||||
connect();
|
||||
|
||||
if (! doInput)
|
||||
throw new ProtocolException("Can't open InputStream if doInput is false");
|
||||
|
||||
if (jar_entry == null)
|
||||
throw new IOException (jar_url + " couldn't be found.");
|
||||
|
||||
return jar_file.getInputStream (jar_entry);
|
||||
}
|
||||
|
||||
public synchronized JarFile getJarFile() throws IOException
|
||||
{
|
||||
if (!connected)
|
||||
connect();
|
||||
|
||||
if (! doInput)
|
||||
throw new ProtocolException("Can't open JarFile if doInput is false");
|
||||
|
||||
return jar_file;
|
||||
}
|
||||
|
||||
public int getContentLength()
|
||||
{
|
||||
if (!connected)
|
||||
return -1;
|
||||
|
||||
return (int) jar_entry.getSize();
|
||||
}
|
||||
}
|
173
libjava/classpath/gnu/java/net/protocol/jar/Handler.java
Normal file
173
libjava/classpath/gnu/java/net/protocol/jar/Handler.java
Normal file
|
@ -0,0 +1,173 @@
|
|||
/* gnu.java.net.protocol.jar.Handler - jar protocol handler for java.net
|
||||
Copyright (C) 1999, 2002, 2003, 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.jar;
|
||||
|
||||
import gnu.java.net.URLParseError;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLStreamHandler;
|
||||
|
||||
/**
|
||||
* @author Kresten Krab Thorup (krab@gnu.org)
|
||||
*/
|
||||
public class Handler extends URLStreamHandler
|
||||
{
|
||||
/**
|
||||
* A do nothing constructor
|
||||
*/
|
||||
public Handler()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returs a new JarURLConnection for the specified URL
|
||||
*
|
||||
* @param url The URL to return a connection for
|
||||
*
|
||||
* @return The URLConnection
|
||||
*
|
||||
* @exception IOException If an error occurs
|
||||
*/
|
||||
protected URLConnection openConnection(URL url) throws IOException
|
||||
{
|
||||
return new Connection(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method overrides URLStreamHandler's for parsing url of protocol "jar"
|
||||
*
|
||||
* @param url The URL object in which to store the results
|
||||
* @param url_string The String-ized URL to parse
|
||||
* @param start The position in the string to start scanning from
|
||||
* @param end The position in the string to stop scanning
|
||||
*/
|
||||
protected void parseURL (URL url, String url_string, int start, int end)
|
||||
{
|
||||
// This method does not throw an exception or return a value. Thus our
|
||||
// strategy when we encounter an error in parsing is to return without
|
||||
// doing anything.
|
||||
String file = url.getFile();
|
||||
|
||||
if (!file.equals(""))
|
||||
{ //has context url
|
||||
url_string = url_string.substring (start, end);
|
||||
if (url_string.startsWith("/"))
|
||||
{ //url string is an absolute path
|
||||
int idx = file.lastIndexOf ("!/");
|
||||
|
||||
if (idx < 0)
|
||||
throw new URLParseError("no !/ in spec");
|
||||
|
||||
file = file.substring (0, idx + 1) + url_string;
|
||||
}
|
||||
else if (url_string.length() > 0)
|
||||
{
|
||||
int idx = file.lastIndexOf ("/");
|
||||
if (idx == -1) //context path is weird
|
||||
file = "/" + url_string;
|
||||
else if (idx == (file.length() - 1))
|
||||
//just concatenate two parts
|
||||
file = file + url_string;
|
||||
else
|
||||
// according to Java API Documentation, here is a little different
|
||||
// with URLStreamHandler.parseURL
|
||||
// but JDK seems doesn't handle it well
|
||||
file = file.substring(0, idx + 1) + url_string;
|
||||
}
|
||||
|
||||
setURL (url, "jar", url.getHost(), url.getPort(), file, null);
|
||||
return;
|
||||
}
|
||||
|
||||
// Bunches of things should be true. Make sure.
|
||||
if (end < start)
|
||||
return;
|
||||
if (end - start < 2)
|
||||
return;
|
||||
if (start > url_string.length())
|
||||
return;
|
||||
|
||||
// Skip remains of protocol
|
||||
url_string = url_string.substring (start, end);
|
||||
|
||||
int jar_stop;
|
||||
if ((jar_stop = url_string.indexOf("!/")) < 0)
|
||||
throw new URLParseError("no !/ in spec");
|
||||
|
||||
try
|
||||
{
|
||||
new URL(url_string.substring (0, jar_stop));
|
||||
}
|
||||
catch (MalformedURLException e)
|
||||
{
|
||||
throw new URLParseError("invalid inner URL: " + e.getMessage());
|
||||
}
|
||||
|
||||
if (!url.getProtocol().equals ("jar") )
|
||||
throw new URLParseError("unexpected protocol " + url.getProtocol());
|
||||
|
||||
setURL (url, "jar", url.getHost(), url.getPort(), url_string, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method converts a Jar URL object into a String.
|
||||
*
|
||||
* @param url The URL object to convert
|
||||
*/
|
||||
protected String toExternalForm (URL url)
|
||||
{
|
||||
String file = url.getFile();
|
||||
String ref = url.getRef();
|
||||
|
||||
// return "jar:" + file;
|
||||
// Performance!!:
|
||||
// Do the concatenation manually to avoid resize StringBuffer's
|
||||
// internal buffer. The length of ref is not taken into consideration
|
||||
// as it's a rare path.
|
||||
StringBuffer sb = new StringBuffer (file.length() + 5);
|
||||
sb.append ("jar:");
|
||||
sb.append (file);
|
||||
if (ref != null)
|
||||
sb.append('#').append(ref);
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
46
libjava/classpath/gnu/java/net/protocol/jar/package.html
Normal file
46
libjava/classpath/gnu/java/net/protocol/jar/package.html
Normal file
|
@ -0,0 +1,46 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<!-- package.html - describes classes in gnu.java.net.protocol.jar 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.jar</title></head>
|
||||
|
||||
<body>
|
||||
<p></p>
|
||||
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Add a link
Reference in a new issue