Java authentification (Was Getting the http username/password for a part)
Koos Vriezen
koos.vriezen at xs4all.nl
Sat May 3 18:49:28 BST 2003
On Sat, 3 May 2003, Koos Vriezen wrote:
> For cookie based authentication the only way seems to
> implement a HttpURLConnection and create it in a URLStreamHandlerFactory
> set by java.net.URL.setURLStreamHandlerFactory.
> For this, I revamped the KJavaDownloader. It was used for the
> KJASClassLoader a long time ago. I changed it for use of HttpURLConnection.
> It already seems to work nicely, though lot is not implemented yet (like
> POST's). Benefit are caching over jvm sessions and finally got webmin
> applets to work.
It's quite easy now to support other protocols as well. Attached one that
allows opening a html page from a ftp site that contains applets (smb/fish
should be added as well).
Using java default URLStreamHandlerFactory or the one that uses kio, is
just one call. A good candidate for a config option imo.
>
> Comments?
>
> Koos
>
-------------- next part --------------
package org.kde.kjas.server;
import java.net.*;
import java.io.*;
import java.util.*;
import java.security.*;
/**
* ClassLoader used to download and instantiate Applets.
*/
class KIOConnection
{
final static int DATA = 0;
final static int FINISHED = 1;
final static int ERRORCODE = 2;
protected static int id = 0;
static Hashtable jobs = new Hashtable();
Thread thread = null;
protected boolean connected = false;
protected String jobid = null;
protected LinkedList data = new LinkedList ();
protected int errorcode = 0;
protected boolean finished = false;
protected URL url;
void checkConnected() throws IOException {
if (!connected)
throw new IOException("not connected");
}
protected boolean haveError() {
return errorcode != 0;
}
class KJASOutputStream extends OutputStream {
KJASOutputStream() {
}
public void write(int b) throws IOException {
throw new IOException("not implemented");
}
public void close() throws IOException {
checkConnected();
disconnect();
}
public void flush() throws IOException {
checkConnected();
throw new IOException("not implemented");
}
}
class KJASInputStream extends InputStream {
private byte [] buf = null;
private int bufpos = 0;
private boolean eof = false;
KJASInputStream() {
}
private boolean getData() throws IOException {
if (eof)
return false;
checkConnected();
if (haveError()) {
disconnect();
throw new IOException("i/o error " + errorcode);
}
if (buf != null && bufpos < buf.length)
return true;
synchronized (jobs) {
if (data.size() > 0) {
buf = (byte []) data.removeFirst();
bufpos = 0;
return true;
}
}
if (finished) {
eof = true;
synchronized (jobs) {
jobs.remove(jobid);
}
return false;
}
thread = Thread.currentThread();
try {
Thread.currentThread().sleep(10000);
} catch (InterruptedException ie) {
thread = null;
return getData();
}
thread = null;
disconnect();
throw new IOException("timeout");
}
public int read() throws IOException {
if (getData())
return 0x00ff & buf[bufpos++];
return -1;
}
public int read(byte[] b, int off, int len) throws IOException {
if (!getData())
return -1;
int nr = buf.length - bufpos;
if (nr > len)
nr = len;
System.arraycopy(buf, bufpos, b, off, nr);
bufpos += nr;
return nr;
}
public int read(byte[] b) throws IOException {
return read(b, 0, b.length);
}
public int available() throws IOException {
if (eof)
return 0;
checkConnected();
return buf == null ? 0 : buf.length - bufpos;
}
public boolean markSupported() {
return false;
}
public void close() throws IOException {
checkConnected();
disconnect();
}
}
private KJASOutputStream out = null;
private KJASInputStream in = null;
KIOConnection(URL u) {
url = u;
}
public void setData(int code, byte [] d) {
// this method is synchronized on jobs in processCommand
switch (code) {
case FINISHED:
finished = true;
break;
case DATA:
if (d.length > 0)
data.addLast(d);
Main.debug ("XXXXXXX DATA " + data.size());
break;
case ERRORCODE:
String codestr = new String(d);
errorcode = Integer.parseInt(codestr);
Main.debug ("ERRORECODE " + errorcode);
break;
}
}
synchronized void connect(boolean doInput) throws IOException {
Main.debug ("XXXXXX connect " + url);
if (connected)
throw new IOException("already connected");
errorcode = 0;
synchronized (jobs) {
jobid = String.valueOf(id++);
thread = Thread.currentThread();
jobs.put(jobid, this);
}
if (doInput)
Main.protocol.sendGetURLDataCmd(jobid, url.toExternalForm());
try {
Thread.currentThread().sleep(20000);
} catch (InterruptedException ie) {
connected = true;
if (doInput)
in = new KJASInputStream();
else
out = new KJASOutputStream();
if (!haveError()) {
thread = null;
return;
}
}
synchronized (jobs) {
jobs.remove(jobid);
}
thread = null;
if (connected) {
connected = false;
Main.debug ("XXXXXXX connect error");
throw new IOException("connection failed (not found)");
}
Main.debug ("XXXXXXX connect timeout");
throw new IOException("connection failed (timeout)");
}
void disconnect() {
(new Exception()).printStackTrace();
if (!connected)
return;
synchronized (jobs) {
jobs.remove(jobid);
}
connected = false;
out = null;
in = null;
}
InputStream getInputStream() throws IOException {
Main.debug ("XXXXXXX getInputStream " + url);
//(new Exception()).printStackTrace();
if (!connected)
connect(true);
return in;
}
OutputStream getOutputStream() throws IOException {
Main.debug ("XXXXXXX getOutputStream " + url);
if (!connected)
connect(false);
return out;
}
}
final class KIOHttpConnection extends KIOConnection
{
final static int HEADERS = 3;
final static int REDIRECT = 4;
final static int MIMETYPE = 5;
Vector headers = new Vector();
Hashtable headersmap = new Hashtable();
KIOHttpConnection(URL u) {
super(u);
}
protected boolean haveError() {
return errorcode >= 400;
}
public void setData(int code, byte [] d) {
// this method is synchronized on jobs in processCommand
switch (code) {
case HEADERS:
StringTokenizer tokenizer = new StringTokenizer(new String(d), "\n");
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
int pos = token.indexOf(":");
String [] entry = {
token.substring(0, pos > -1 ? pos : token.length()).toLowerCase(), token.substring(pos > -1 ? pos+1: token.length())
};
headers.add(entry);
headersmap.put(entry[0], entry[1]);
Main.debug ("XXXXXXX header " + entry[0] + "=" + entry[1]);
}
default:
super.setData(code, d);
}
}
}
final class KIOFtpConnection extends KIOConnection
{
KIOFtpConnection(URL u) {
super(u);
}
}
final class KJASHttpURLConnection extends HttpURLConnection
{
private KIOHttpConnection kioconnection;
KJASHttpURLConnection(URL u) {
super(u);
kioconnection = new KIOHttpConnection(u);
}
public Map getHeaderFields() {
Main.debug ("XXXXXXX getHeaderFields");
return kioconnection.headersmap;
}
public String getHeaderField(String name) {
Main.debug ("XXXXXXX getHeaderField " + name);
return (String) kioconnection.headersmap.get(name);
}
public String getHeaderField(int n) {
if (n >= kioconnection.headersmap.size())
return null;
String [] entry = (String []) kioconnection.headers.get(n);
String line = entry[0];
if (entry[1].length() > 0)
line += ":" + entry[1];
Main.debug ("XXXXXXX getHeaderField " + line);
return line;
}
public String getHeaderFieldKey(int n) {
Main.debug ("XXXXXXX getHeaderFieldKey " + n);
if (n >= kioconnection.headersmap.size())
return null;
return ((String []) kioconnection.headers.get(n))[0];
}
public boolean usingProxy() {
return false; // FIXME
}
public synchronized void connect() throws IOException {
kioconnection.connect(doInput);
Main.debug ("XXXXXXX connect responsecode=" + getResponseCode());
String token = getHeaderField(0);
do {
if (!token.startsWith("HTTP/1.")) break;
int spos = token.indexOf(' ');
if (spos < 0) break;
int epos = token.indexOf(' ', spos + 1);
if (epos < 0) break;
responseCode = Integer.parseInt(token.substring(spos+1, epos));
responseMessage = token.substring(epos);
} while (false);
}
public void disconnect() {
kioconnection.disconnect();
}
public InputStream getInputStream() throws IOException {
return kioconnection.getInputStream();
}
public OutputStream getOutputStream() throws IOException {
return kioconnection.getOutputStream();
}
}
final class KJASFtpURLConnection extends URLConnection
{
private KIOFtpConnection kioconnection;
KJASFtpURLConnection(URL u) {
super(u);
kioconnection = new KIOFtpConnection(u);
}
public boolean usingProxy() {
return false; // FIXME
}
public synchronized void connect() throws IOException {
kioconnection.connect(doInput);
}
public void disconnect() {
kioconnection.disconnect();
}
public InputStream getInputStream() throws IOException {
return kioconnection.getInputStream();
}
public OutputStream getOutputStream() throws IOException {
return kioconnection.getOutputStream();
}
}
final class KJASHttpURLStreamHandler extends URLStreamHandler
{
KJASHttpURLStreamHandler() {
}
protected URLConnection openConnection(URL u) throws IOException {
Main.debug ("XXXXXXX openConnection " + u);
return new KJASHttpURLConnection(u);
}
protected int getDefaultPort() {
return 80;
}
}
final class KJASFtpURLStreamHandler extends URLStreamHandler
{
KJASFtpURLStreamHandler() {
}
protected URLConnection openConnection(URL u) throws IOException {
Main.debug ("XXXXXXX KJASFtpURLStreamHandler.openConnection " + u);
return new KJASFtpURLConnection(u);
}
protected int getDefaultPort() {
return 21;
}
}
public final class KJASURLStreamHandlerFactory
implements URLStreamHandlerFactory
{
public URLStreamHandler createURLStreamHandler(String protocol) {
Main.debug ("XXXXXXX createURLStreamHandler " + protocol);
if (protocol.equals("http"))
return new KJASHttpURLStreamHandler();
else if (protocol.equals("ftp"))
return new KJASFtpURLStreamHandler();
return null;
}
}
More information about the kfm-devel
mailing list