summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2008-06-12 21:21:49 +0000
committerStef Walter <stef@memberwebs.com>2008-06-12 21:21:49 +0000
commitd5f13e2ebe4db8fb64a93e26a3b853699e8977b1 (patch)
treeb44e23014d7efef3a44d96573769497a7a2ac1b7
parent3dc8cb104d3392e00514bb829c50390a9598fe3c (diff)
Add the isPristine() method to HttpAuthConnection
-rw-r--r--java/build.xml2
-rw-r--r--java/src/com/memberwebs/httpauth/HttpAuthConnection.java689
2 files changed, 392 insertions, 299 deletions
diff --git a/java/build.xml b/java/build.xml
index a148f6a..5efab1a 100644
--- a/java/build.xml
+++ b/java/build.xml
@@ -2,7 +2,7 @@
<project name="httpauth-client" default="build" basedir=".">
<target name="init">
- <property name="version" value="0.6"/>
+ <property name="version" value="0.9"/>
</target>
<target name="build" depends="init">
diff --git a/java/src/com/memberwebs/httpauth/HttpAuthConnection.java b/java/src/com/memberwebs/httpauth/HttpAuthConnection.java
index 823209c..8a8029c 100644
--- a/java/src/com/memberwebs/httpauth/HttpAuthConnection.java
+++ b/java/src/com/memberwebs/httpauth/HttpAuthConnection.java
@@ -6,16 +6,16 @@
* modification, are permitted provided that the following conditions
* are met:
*
- * * Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the
- * following disclaimer.
- * * Redistributions in binary form must reproduce the
- * above copyright notice, this list of conditions and
- * the following disclaimer in the documentation and/or
- * other materials provided with the distribution.
- * * The names of contributors to this software may not be
- * used to endorse or promote products derived from this
- * software without specific prior written permission.
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -43,6 +43,7 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
+import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
@@ -56,293 +57,385 @@ import java.util.Map;
* @author Stef Walter
*/
public class HttpAuthConnection
- implements HttpAuthConnectionSource
+ implements HttpAuthConnectionSource
{
- /**
- * The option to set the authenticaton handler.
- */
- public static final String OPT_HANDLER = "Handler";
-
- /**
- * The option to set the digest domains.
- */
- public static final String OPT_DOMAIN = "Domain";
-
- private Writer m_output;
- private BufferedReader m_input;
- private Socket m_socket;
- private boolean m_checkedout;
-
- /**
- * Connects to the HttpAuth daemon at the given address and port. The
- * appropriate handler is set.
- *
- * @param hostname The address where the HttpAuth daemon is running.
- * @param port The TCP port for the HttpAuth daemon.
- * @param handler The HttpAuth handler to use.
- */
- public void open(String hostname, int port, String handler)
- throws IOException, HttpAuthException
- {
- HashMap options = new HashMap();
- options.put(OPT_HANDLER, handler);
- open(hostname, port, options);
- }
-
- /**
- * Connects to the HttpAuth daemon at the given address and port. Various
- * options (including the handler) can be set.
- *
- * @param hostname The address where the HttpAuth daemon is running.
- * @param port The TCP port for the HttpAuth daemon.
- * @param options The HttpAuth options to use. This must include {@link #OPT_HANDLER}.
- */
- public void open(String hostname, int port, Map options)
- throws IOException, HttpAuthException
- {
- synchronized(this)
- {
- close();
-
- m_socket = new Socket();
- m_socket.connect(new InetSocketAddress(hostname, port), 60000);
-
- m_input = new BufferedReader(new InputStreamReader(m_socket.getInputStream()));
- m_output = new OutputStreamWriter(m_socket.getOutputStream());
-
- // Okay now read the version number
- Response ver = readResponse(100);
- if(!ver.details.trim().equals("HTTPAUTH/1.0"))
- throw new HttpAuthException("httpauthd speaking wrong version of protocol: " + ver.details);
-
- // Set any options as necessary
- Iterator it = options.keySet().iterator();
- while(it.hasNext())
- {
- String name = (String)it.next();
- String value = (String)options.get(name);
-
- // Set the options request
- sendLine("SET " + name + " " + value);
-
- // This throws an exception if we don't get the right response
- readResponse(202);
- }
- }
- }
-
- /**
- * Closes the connection to the HttpAuth daemon.
- */
- public void close()
- throws IOException
- {
- synchronized(this)
- {
- if(m_socket != null && m_output != null)
- {
- try
- {
- sendLine("QUIT");
- }
- catch(IOException e)
- {
- }
- }
-
- if(m_output != null)
- {
- m_output.close();
- m_output = null;
- }
-
- if(m_input != null)
- {
- m_input.close();
- m_input = null;
- }
-
- if(m_socket != null)
- {
- m_socket.close();
- m_socket = null;
- }
- }
- }
-
- /**
- * Checks whether we're connected to the HttpAuth daemon.
- */
- public boolean isConnected()
- {
- return m_socket != null && m_socket.isConnected()
- && m_input != null && m_output != null;
- }
-
- /**
- * Sends a command string to the HttpAuth daemon.
- *
- * @param string The command to send.
- */
- public void sendLine(String string)
- throws IOException
- {
- synchronized(this)
- {
- m_output.write(string + "\n");
- m_output.flush();
- }
- }
-
- /**
- * Reads a response line from the HttpAuth daemon.
- *
- * @return The response line.
- */
- public String readLine()
- throws IOException
- {
- synchronized(this)
- {
- return m_input.readLine();
- }
- }
-
- /* ---------------------------------------------------------------------------
- * HttpAuthConnectionSource
- *
- * This is a simple implementation which allows a single connection
- * to be used in leu of a connection pool.
- */
-
- /**
- * Treats this single connection as a pool. Checks out the current
- * connection. Use {@link HttpAuthConnectionPool} instead.
- * @return The connection.
- */
- public HttpAuthConnection getOpenConnection()
- throws HttpAuthException
- {
- synchronized(this)
- {
- if(!isConnected() && !m_checkedout)
- return null;
-
- m_checkedout = true;
- return this;
- }
- }
-
- /**
- * Treats this single connection as a pool. Checks in the current
- * connection. Use {@link HttpAuthConnectionPool} instead.
- * @param conn The connection.
- */
- public void doneWithConnection(HttpAuthConnection conn)
- throws HttpAuthException
- {
- synchronized(this)
- {
- m_checkedout = false;
- }
- }
-
- // -----------------------------------------------------------------------------
- // Helper functions
-
- protected Response readResponse(int expected)
- throws HttpAuthException, IOException
- {
- Response resp = new Response();
- String line = readLine();
-
- if(line == null)
- throw new SocketException("Broken Pipe: unexpected end of data from httpauthd");
-
- String word = parseWord(line);
- line = line.substring(word.length());
- word = word.trim();
-
- try
- {
- int code = Integer.parseInt(word, 10);
- if(code < 100 || code > 599)
- throw new NumberFormatException();
-
- resp.code = code;
- }
- catch(NumberFormatException e)
- {
- throw new HttpAuthException("httpauth protocol error. invalid code received: " + word);
- }
-
- if(expected != 0 && resp.code != expected)
- throw new HttpAuthException("httpauth protocol error. expected code '" + expected + "' and got: " + resp.code);
-
- if(resp.code == 200)
- {
- word = parseWord(line);
- line = line.substring(word.length()).trim();
- word = word.trim();
-
- try
- {
- int code = Integer.parseInt(word, 10);
- if(code < 100 || code > 599)
- throw new NumberFormatException();
-
- resp.ccode = code;
- }
- catch(NumberFormatException e)
- {
- throw new HttpAuthException("httpauth protocol error. invalid code received: " + word);
- }
- }
-
- if(line.length() > 0)
- resp.details = line;
-
- return resp;
- }
-
- protected String parseWord(String line)
- {
- int start = -1;
- int end;
- char ch;
-
- while(true)
- {
- if(++start >= line.length())
- return "";
-
- ch = line.charAt(start);
- if(ch != ' ' && ch != '\t')
- break;
- }
-
- end = start - 1;
-
- while(true)
- {
- if(++end >= line.length())
- break;
-
- ch = line.charAt(end);
- if(ch == ' ' || ch == '\t')
- break;
- }
-
- if(end == -1)
- return "";
-
- return line.substring(0, end);
- }
-
- class Response
- {
- int code;
- int ccode;
- String details;
- };
+ /**
+ * The option to set the authenticaton handler.
+ */
+ public static final String OPT_HANDLER = "Handler";
+
+ /**
+ * The option to set the digest domains.
+ */
+ public static final String OPT_DOMAIN = "Domain";
+
+ private Writer m_output;
+ private BufferedReader m_input;
+ private Socket m_socket;
+ private boolean m_checkedout;
+ private boolean m_isPristine = true;
+
+ /**
+ * Connects to the HttpAuth daemon at the given address and port. The
+ * appropriate handler is set.
+ *
+ * @param address The address where the HttpAuth daemon is running.
+ * @param port The TCP port for the HttpAuth daemon.
+ * @param handler The HttpAuth handler to use.
+ */
+ public void open(InetAddress address, int port, String handler)
+ throws IOException, HttpAuthException
+ {
+ HashMap options = new HashMap();
+ options.put(OPT_HANDLER, handler);
+ open(address, port, options);
+ }
+
+ /**
+ * Connects to the HttpAuth daemon at the given address and port. The
+ * appropriate handler is set.
+ *
+ * @param hostname The address where the HttpAuth daemon is running.
+ * @param port The TCP port for the HttpAuth daemon.
+ * @param handler The HttpAuth handler to use.
+ */
+ public void open(String hostname, int port, String handler)
+ throws IOException, HttpAuthException
+ {
+ HashMap options = new HashMap();
+ options.put(OPT_HANDLER, handler);
+ open(InetAddress.getByName(hostname), port, options);
+ }
+
+ /**
+ * Connects to the HttpAuth daemon at the given address and port. Various
+ * options (including the handler) can be set.
+ *
+ * @param hostname The address where the HttpAuth daemon is running.
+ * @param port The TCP port for the HttpAuth daemon.
+ * @param options The HttpAuth options to use. This must include {@link #OPT_HANDLER}.
+ */
+ public void open(String hostname, int port, Map options)
+ throws IOException, HttpAuthException
+ {
+ open(InetAddress.getByName(hostname), port, options);
+ }
+
+ /**
+ * Connects to the HttpAuth daemon at the given address and port. Various
+ * options (including the handler) can be set.
+ *
+ * @param address The address where the HttpAuth daemon is running.
+ * @param port The TCP port for the HttpAuth daemon.
+ * @param options The HttpAuth options to use. This must include {@link #OPT_HANDLER}.
+ */
+ public void open(InetAddress address, int port, Map options)
+ throws IOException, HttpAuthException
+ {
+ synchronized(this)
+ {
+ try
+ {
+ close();
+
+ m_isPristine = true;
+ m_socket = new Socket();
+ m_socket.connect(new InetSocketAddress(address, port), 60000);
+
+ m_input = new BufferedReader(new InputStreamReader(m_socket.getInputStream()));
+ m_output = new OutputStreamWriter(m_socket.getOutputStream());
+
+ // Okay now read the version number
+ Response ver = readResponse(100);
+ if(!ver.details.trim().equals("HTTPAUTH/1.0"))
+ throw new HttpAuthException("httpauthd speaking wrong version of protocol: " + ver.details);
+
+ // Set any options as necessary
+ Iterator it = options.keySet().iterator();
+ while(it.hasNext())
+ {
+ String name = (String)it.next();
+ String value = (String)options.get(name);
+
+ // Set the options request
+ sendLine("SET " + name + " " + value);
+
+ // This throws an exception if we don't get the right response
+ readResponse(202);
+ }
+ }
+ catch(HttpAuthException ex)
+ {
+ m_isPristine = false;
+ throw ex;
+ }
+ catch(IOException ex)
+ {
+ m_isPristine = false;
+ throw ex;
+ }
+ }
+ }
+
+ /**
+ * Closes the connection to the HttpAuth daemon.
+ */
+ public void close()
+ throws IOException
+ {
+ synchronized(this)
+ {
+ if(m_socket != null && m_output != null)
+ {
+ try
+ {
+ sendLine("QUIT");
+ }
+ catch(IOException e)
+ {
+ m_isPristine = false;
+ }
+ }
+
+ try
+ {
+ if(m_output != null)
+ {
+ m_output.close();
+ m_output = null;
+ }
+
+ if(m_input != null)
+ {
+ m_input.close();
+ m_input = null;
+ }
+
+ if(m_socket != null)
+ {
+ m_socket.close();
+ m_socket = null;
+ }
+ }
+ catch(IOException ex)
+ {
+ m_isPristine = false;
+ throw ex;
+ }
+ }
+ }
+
+ /**
+ * Checks whether we're connected to the HttpAuth daemon.
+ */
+ public boolean isConnected()
+ {
+ return m_socket != null && m_socket.isConnected() &&
+ m_input != null && m_output != null;
+ }
+
+ /**
+ * Checks whether the connection has had errors.
+ */
+ public boolean isPristine()
+ {
+ return m_isPristine;
+ }
+
+
+ /**
+ * Sends a command string to the HttpAuth daemon.
+ *
+ * @param string The command to send.
+ */
+ public void sendLine(String string)
+ throws IOException
+ {
+ synchronized(this)
+ {
+ try
+ {
+ m_output.write(string + "\n");
+ m_output.flush();
+ }
+ catch(IOException ex)
+ {
+ m_isPristine = false;
+ throw ex;
+ }
+ }
+ }
+
+ /**
+ * Reads a response line from the HttpAuth daemon.
+ *
+ * @return The response line.
+ */
+ public String readLine()
+ throws IOException
+ {
+ synchronized(this)
+ {
+ try
+ {
+ return m_input.readLine();
+ }
+ catch(IOException ex)
+ {
+ m_isPristine = false;
+ throw ex;
+ }
+ }
+ }
+
+ /* ---------------------------------------------------------------------------
+ * HttpAuthConnectionSource
+ *
+ * This is a simple implementation which allows a single connection
+ * to be used in leu of a connection pool.
+ */
+
+ /**
+ * Treats this single connection as a pool. Checks out the current
+ * connection. Use {@link HttpAuthConnectionPool} instead.
+ * @return The connection.
+ */
+ public HttpAuthConnection getOpenConnection()
+ throws HttpAuthException
+ {
+ synchronized(this)
+ {
+ if(!isConnected() && !m_checkedout)
+ return null;
+
+ m_checkedout = true;
+ return this;
+ }
+ }
+
+ /**
+ * Treats this single connection as a pool. Checks in the current
+ * connection. Use {@link HttpAuthConnectionPool} instead.
+ * @param conn The connection.
+ */
+ public void doneWithConnection(HttpAuthConnection conn)
+ throws HttpAuthException
+ {
+ synchronized(this)
+ {
+ m_checkedout = false;
+ }
+ }
+
+ // -----------------------------------------------------------------------------
+ // Helper functions
+
+ protected Response readResponse(int expected)
+ throws HttpAuthException, IOException
+ {
+ try
+ {
+ Response resp = new Response();
+ String line = readLine();
+
+ if(line == null)
+ throw new SocketException("Broken Pipe: unexpected end of data from httpauthd");
+
+ String word = parseWord(line);
+ line = line.substring(word.length());
+ word = word.trim();
+
+ try
+ {
+ int code = Integer.parseInt(word, 10);
+ if(code < 100 || code > 599)
+ throw new NumberFormatException();
+
+ resp.code = code;
+ }
+ catch(NumberFormatException e)
+ {
+ throw new HttpAuthException("httpauth protocol error. invalid code received: " + word);
+ }
+
+ if(expected != 0 && resp.code != expected)
+ throw new HttpAuthException("httpauth protocol error. expected code '" + expected + "' and got: " + resp.code);
+
+ if(resp.code == 200)
+ {
+ word = parseWord(line);
+ line = line.substring(word.length()).trim();
+ word = word.trim();
+
+ try
+ {
+ int code = Integer.parseInt(word, 10);
+ if(code < 100 || code > 599)
+ throw new NumberFormatException();
+
+ resp.ccode = code;
+ }
+ catch(NumberFormatException e)
+ {
+ throw new HttpAuthException("httpauth protocol error. invalid code received: " + word);
+ }
+ }
+
+ if(line.length() > 0)
+ resp.details = line;
+
+ return resp;
+ }
+ catch(HttpAuthException ex)
+ {
+ m_isPristine = false;
+ throw ex;
+ }
+ catch(IOException ex)
+ {
+ m_isPristine = false;
+ throw ex;
+ }
+ }
+
+ protected String parseWord(String line)
+ {
+ int start = -1;
+ int end;
+ char ch;
+
+ while(true)
+ {
+ if(++start >= line.length())
+ return "";
+
+ ch = line.charAt(start);
+ if(ch != ' ' && ch != '\t')
+ break;
+ }
+
+ end = start - 1;
+
+ while(true)
+ {
+ if(++end >= line.length())
+ break;
+
+ ch = line.charAt(end);
+ if(ch == ' ' || ch == '\t')
+ break;
+ }
+
+ if(end == -1)
+ return "";
+
+ return line.substring(0, end);
+ }
+
+ class Response
+ {
+ int code;
+ int ccode;
+ String details;
+ };
}