You are viewing a plain text version of this content. The canonical link for it is here.
Posted to slide-dev@jakarta.apache.org by je...@apache.org on 2001/02/24 10:00:53 UTC
cvs commit: jakarta-slide/src/webdav/client/src/org/apache/webdav/lib WebdavClient.java Cookie.java
jericho 01/02/24 01:00:53
Modified: src/webdav/client/src/org/apache/webdav/lib
WebdavClient.java Cookie.java
Log:
- Fix code layout
- Make sure code error checking
Revision Changes Path
1.23 +256 -247 jakarta-slide/src/webdav/client/src/org/apache/webdav/lib/WebdavClient.java
Index: WebdavClient.java
===================================================================
RCS file: /home/cvs/jakarta-slide/src/webdav/client/src/org/apache/webdav/lib/WebdavClient.java,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- WebdavClient.java 2001/02/24 06:38:17 1.22
+++ WebdavClient.java 2001/02/24 09:00:53 1.23
@@ -1,13 +1,13 @@
/*
- * $Header: /home/cvs/jakarta-slide/src/webdav/client/src/org/apache/webdav/lib/WebdavClient.java,v 1.22 2001/02/24 06:38:17 remm Exp $
- * $Revision: 1.22 $
- * $Date: 2001/02/24 06:38:17 $
+ * $Header: /home/cvs/jakarta-slide/src/webdav/client/src/org/apache/webdav/lib/WebdavClient.java,v 1.23 2001/02/24 09:00:53 jericho Exp $
+ * $Revision: 1.23 $
+ * $Date: 2001/02/24 09:00:53 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
- * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -15,7 +15,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
@@ -23,15 +23,15 @@
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
- * any, must include the following acknowlegement:
- * "This product includes software developed by the
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
- * from this software without prior written permission. For written
+ * from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
@@ -59,7 +59,7 @@
*
* [Additional notices, if required by prior licensing conditions]
*
- */
+ */
package org.apache.webdav.lib;
@@ -78,206 +78,206 @@
/**
* WebDAV client.
- *
+ *
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
*/
public class WebdavClient {
-
-
+
+
// -------------------------------------------------------------- Constants
-
-
+
+
/**
* HTTP Date format pattern (RFC 2068, 822, 1123).
*/
public static final String DATE_FORMAT = "EEE, d MMM yyyy kk:mm:ss z";
-
-
+
+
/**
* User Agent.
*/
- public static final Header USER_AGENT =
+ public static final Header USER_AGENT =
new Header("user-agent", "org.apache.webdav.lib.WebdavClient");
-
-
+
+
/**
* Date formatter.
*/
- protected static final DateFormat formatter =
+ protected static final DateFormat formatter =
new SimpleDateFormat(DATE_FORMAT);
-
-
+
+
// ----------------------------------------------------------- Constructors
-
-
+
+
public WebdavClient() {
startSession();
}
-
-
+
+
public WebdavClient(URL url) {
startSession(url.getHost(), url.getPort() == -1 ? 80 : url.getPort());
}
-
-
+
+
public WebdavClient(URL url, String user, String password) {
this(url);
setCredentials(new Credentials(user, password));
}
-
-
+
+
// ----------------------------------------------------- Instance Variables
-
-
+
+
/**
* Client Socket in use.
*/
protected Socket socket;
-
-
+
+
/**
* Session state.
*/
protected State state;
-
-
+
+
/**
* Credentials to use.
*/
protected Credentials credentials;
-
-
+
+
/**
* Socket input stream.
*/
protected InputStream input;
-
-
+
+
/**
* Socket output stream.
*/
protected OutputStream output;
-
-
+
+
/**
- * The host name specified when the startSession(host, port) method was
+ * The host name specified when the startSession(host, port) method was
* called.
*/
protected String sessionHost = "";
-
-
- /**
+
+
+ /**
* Port number.
*/
protected int sessionPort = -1;
-
-
+
+
/**
* HTTP/1.1 flag.
*/
protected boolean http11 = false;
-
-
+
+
/**
* Debug level.
*/
protected int debug = 0;
-
-
+
+
// ------------------------------------------------------------- Properties
-
-
+
+
/**
* Set the socket to use.
*/
public void setSocket(Socket socket) {
this.socket = socket;
}
-
-
+
+
/**
* Set the credentials to use.
*/
public void setCredentials(Credentials credentials) {
this.credentials = credentials;
}
-
-
+
+
/**
* Set debug level.
*/
public void setDebug(int debug) {
this.debug = debug;
}
-
-
+
+
/**
* Get debug level.
*/
public int getDebug() {
return debug;
}
-
-
+
+
/**
* Get the session host.
*/
public String getHost() {
return sessionHost;
}
-
-
+
+
/**
* Get the session port.
*/
public int getPort() {
return sessionPort;
}
-
-
+
+
/**
* Get the state for lock information.
*/
public State getState() {
return state;
}
-
-
+
+
/**
* Set the client state.
*/
public void setState(State state) {
this.state = state;
}
-
-
+
+
// --------------------------------------------------------- Public Methods
-
-
+
+
/**
* Execute a DAV method.
- *
+ *
* @param method WebDAV method to execute
*/
- public void executeMethod(WebdavMethod method)
+ public void executeMethod(WebdavMethod method)
throws IOException, WebdavException {
-
+
int retries = 0;
-
+
Hashtable responseHeaders = null;
-
+
boolean methodProcessed = false;
-
+
openConnection();
-
+
while ((retries < 5) && (!methodProcessed)) {
-
+
try {
-
+
responseHeaders = null;
-
+
sendRequest(method);
-
+
boolean closeOutput = needToCloseOutput();
if (closeOutput) {
try {
@@ -290,37 +290,37 @@
// Ignore, and hope everything goes right
}
}
-
+
// Parsing response
-
+
// Parse status line
String statusLine = readLine(input);
if (statusLine == null)
throw new IOException("Couldn't parse status line");
parseStatusLine(statusLine, method);
-
+
// Parse headers
responseHeaders = parseHeaders(input);
-
- // Retrieve the authenticate challenge, if any
- // (needed in case of a digest challenge, for which the
+
+ // Retrieve the authenticate challenge, if any
+ // (needed in case of a digest challenge, for which the
// header is not constant)
- Header authenticateChallenge =
+ Header authenticateChallenge =
(Header) responseHeaders.get("www-authenticate");
if (authenticateChallenge != null) {
state.setAuthenticateToken
(authenticateChallenge.getValue());
}
- if ((method.getStatusCode()
+ if ((method.getStatusCode()
== WebdavStatus.SC_MOVED_TEMPORARILY)
- || (method.getStatusCode()
+ || (method.getStatusCode()
== WebdavStatus.SC_MOVED_PERMANENTLY)) {
if (method.followRedirects()) {
// Retrieve the location header
- // NOTE : Redirects across servers are not
+ // NOTE : Redirects across servers are not
// supported yet (and perhaps will never be for
// security reasons)
- Header location =
+ Header location =
(Header) responseHeaders.get("location");
if (location != null) {
String absolutePath = location.getValue();
@@ -340,21 +340,21 @@
methodProcessed = true;
}
}
-
- if ( (method.getStatusCode() != WebdavStatus.SC_UNAUTHORIZED)
- && (method.getStatusCode()
+
+ if ( (method.getStatusCode() != WebdavStatus.SC_UNAUTHORIZED)
+ && (method.getStatusCode()
!= WebdavStatus.SC_MOVED_TEMPORARILY)
- && (method.getStatusCode()
+ && (method.getStatusCode()
!= WebdavStatus.SC_MOVED_PERMANENTLY) ) {
methodProcessed = true;
} else {
if (!methodProcessed) {
// Consume bytes returned (if any)
method.processResponseHeaders(responseHeaders);
- ResponseInputStream responseInputStream =
+ ResponseInputStream responseInputStream =
new ResponseInputStream(input, responseHeaders);
responseInputStream.close();
- if (closeOutput ||
+ if (closeOutput ||
needToCloseConnection(method, responseHeaders)) {
// Disconnect and reconnect if needed
closeConnection();
@@ -362,7 +362,7 @@
}
}
}
-
+
} catch (IOException e) {
if (debug > 1)
e.printStackTrace();
@@ -384,112 +384,121 @@
}
openConnection();
}
-
+
retries++;
-
+
}
-
+
if (retries == 5) {
throw new WebdavException("Unable to process request");
}
-
+
method.processResponseHeaders(responseHeaders);
// Parse response
- ResponseInputStream responseInputStream =
+ ResponseInputStream responseInputStream =
new ResponseInputStream(input, responseHeaders);
method.parseResponse(responseInputStream);
-
+
method.setUsed();
-
+
responseInputStream.close();
-
+
if (needToCloseConnection(method, responseHeaders)) {
closeConnection();
}
-
+
}
-
-
+
+
/**
* Start a session.
*/
public void startSession() {
-
+
state = new State();
this.sessionHost = "localhost";
this.sessionPort = 80;
-
+
}
-
-
+
+
/**
* Start a session.
*/
public void startSession(String host, int port) {
-
+
if (debug > 0)
- System.out.println("Start session : Host:" + host
+ System.out.println("Start session : Host:" + host
+ " Port:" + port);
-
+
state = new State();
this.sessionHost = host;
this.sessionPort = port;
-
+
}
-
-
+
+
/**
* End a session.
*/
- public void endSession()
+ public void endSession()
throws IOException {
-
+
if (debug > 0)
System.out.println("End session");
-
+
closeConnection();
-
+
state = null;
this.sessionHost = "";
this.sessionPort = -1;
-
+
}
-
-
+
+
// ------------------------------------------------------ Protected Methods
-
-
+
+
protected void openConnection() throws IOException, UnknownHostException {
-
- if (socket == null) {
- if (debug > 0)
- System.out.println("Reopen connection : Host:" + sessionHost
- + " Port:" + sessionPort);
- socket = new Socket(this.sessionHost, this.sessionPort);
- }
+
try {
+ if (socket == null) {
+ if (debug > 0)
+ System.out.println("Reopen connection : Host:" + sessionHost
+ + " Port:" + sessionPort);
+ socket = new Socket(this.sessionHost, this.sessionPort);
+ }
input = socket.getInputStream();
output = socket.getOutputStream();
} catch (IOException e) {
// Connection is probably half closed
// Closing the connection and trying again
- socket.close();
+ if (socket != null)
+ socket.close();
+
+ if (debug > 0)
+ System.out.println("Reopen connection after IOException: Host:"
+ + sessionHost + " Port:" + sessionPort);
socket = new Socket(this.sessionHost, this.sessionPort);
input = socket.getInputStream();
output = socket.getOutputStream();
}
-
+
}
-
-
+
+
protected void closeConnection() throws IOException {
-
+
if (debug > 0)
System.out.println("Closing connection");
-
+
// Close socket
- input.close();
- output.close();
+ if (input != null)
+ input.close();
+ input = null;
+ if (output != null)
+ output.close();
+ output = null;
if (socket != null)
socket.close();
socket = null;
@@ -497,41 +506,41 @@
Thread.sleep(1);
} catch (Exception ex) {
}
-
+
}
-
-
+
+
/**
* Send a WebDAV request.
- *
+ *
* @param method WebDAV method to execute
*/
protected void sendRequest(WebdavMethod method)
throws IOException, WebdavException {
-
+
if (method.hasBeenUsed())
throw new WebdavException("Method has already been used");
-
+
if (!method.validate())
throw new WebdavException("Invalid method");
-
+
String requestLine = method.generateRequestLine();
-
+
if (debug > 0)
System.out.print("Request: " + requestLine);
-
+
String hostName = sessionHost;
if (sessionPort != 80)
hostName = hostName + ":" + sessionPort;
-
+
method.generateHeaders(hostName, state);
Enumeration headersList = method.getHeaders();
-
+
// Sending request line
if (debug > 1)
System.out.print(requestLine);
output.write(requestLine.getBytes());
-
+
// Sending headers
String query = null;
if (!method.isStreamedQuery()) {
@@ -539,10 +548,10 @@
if (query == null)
query = new String();
if (debug > 1)
- System.out.print("Content-Length: "
+ System.out.print("Content-Length: "
+ query.length() + "\r\n");
if (method.needContentLength())
- output.write(("Content-Length: "
+ output.write(("Content-Length: "
+ query.length() + "\r\n").getBytes());
} else {
// Chunking
@@ -552,38 +561,38 @@
output.write(("Transfer-Encoding: chunked\r\n").getBytes());
}
}
-
+
if (state.getAuthenticateToken() != null) {
-
+
String challengeResponse = Authenticator.challengeResponse
(state, credentials);
if (debug > 1)
- System.out.print("Authorization: "
+ System.out.print("Authorization: "
+ challengeResponse + "\r\n");
if (challengeResponse != null)
- output.write(("Authorization: "
+ output.write(("Authorization: "
+ challengeResponse + "\r\n").getBytes());
-
+
}
-
+
// Writing HTTP headers
-
+
while (headersList.hasMoreElements()) {
Header header = (Header) headersList.nextElement();
if (debug > 1)
System.out.print(header.toString());
output.write(header.toString().getBytes());
}
-
+
if (debug > 1)
System.out.print("\r\n");
output.write("\r\n".getBytes());
-
+
// Writing request body
-
- RequestOutputStream requestOutputStream =
+
+ RequestOutputStream requestOutputStream =
new RequestOutputStream(output);
-
+
if (method.isStreamedQuery()) {
if ((http11) && (method.getHeader("Content-Length") == null)) {
requestOutputStream.setUseChunking(true);
@@ -592,26 +601,26 @@
} else {
requestOutputStream.write(query.getBytes());
}
-
+
// Closing wrapped output stream
requestOutputStream.close();
-
+
}
-
-
+
+
/**
- * Reads the input stream, one line at a time. Reads bytes into an array,
+ * Reads the input stream, one line at a time. Reads bytes into an array,
* until it reads a certain number of bytes or reaches a newline character,
* which it reads into the array as well.
- *
+ *
* @param input Input stream on which the bytes are read
* @return The line that was read, or <code>null</code> if end-of-file
* was encountered
* @exception IOException if an input or output exception has occurred
*/
- protected String readLine(InputStream input)
+ protected String readLine(InputStream input)
throws IOException {
-
+
StringBuffer sb = new StringBuffer();
while (true) {
int ch = input.read();
@@ -631,39 +640,39 @@
if (debug > 1)
System.out.println(sb.toString());
return (sb.toString());
-
+
}
-
-
+
+
/**
* Parse status line.
- *
+ *
* @param statusLine String representing the HTTP status line
* @param method Webdav method
*/
protected void parseStatusLine(String statusLine, WebdavMethod method)
throws IOException, WebdavException {
-
+
if (debug > 0)
System.out.println("Response: " + statusLine);
-
+
StringTokenizer st = new StringTokenizer(statusLine);
-
- String protocol = null;
- try {
- protocol = st.nextToken();
- } catch (NoSuchElementException e) {
- }
- if ((protocol == null) ||
+
+ String protocol = null;
+ try {
+ protocol = st.nextToken();
+ } catch (NoSuchElementException e) {
+ }
+ if ((protocol == null) ||
(!protocol.equals("HTTP/1.1") && !protocol.equals("HTTP/1.0")))
- throw new WebdavException("Incorrect server protocol : "
+ throw new WebdavException("Incorrect server protocol : "
+ protocol);
if (protocol.equals("HTTP/1.1")) {
http11 = true;
} else {
http11 = false;
}
-
+
int statusCode = -1;
try {
statusCode = Integer.parseInt(st.nextToken());
@@ -671,58 +680,58 @@
}
if (statusCode == -1)
throw new WebdavException("Status not specified");
-
+
method.setStatusCode(statusCode);
-
+
String statusText = null;
- try {
- statusText = st.nextToken();
- } catch (NoSuchElementException e) {
- }
+ try {
+ statusText = st.nextToken();
+ } catch (NoSuchElementException e) {
+ }
if (statusText != null)
method.setStatusText(statusText);
-
+
}
-
-
+
+
/**
* Parse headers.
- *
+ *
* @param input Input stream on which the bytes are read
*/
protected Hashtable parseHeaders(InputStream input)
throws IOException, WebdavException {
-
+
Hashtable result = new Hashtable();
-
- while (true) {
-
- // Read the next header line
- String line = readLine(input);
- if ((line == null) || (line.length() < 1))
- break;
-
- // Parse the header name and value
- int colon = line.indexOf(":");
- if (colon < 0)
- throw new WebdavException("Incorrect headers");
- String name = line.substring(0, colon).trim();
- String match = name.toLowerCase();
- String value = line.substring(colon + 1).trim();
- Header header = new Header(match, value);
+
+ while (true) {
+
+ // Read the next header line
+ String line = readLine(input);
+ if ((line == null) || (line.length() < 1))
+ break;
+
+ // Parse the header name and value
+ int colon = line.indexOf(":");
+ if (colon < 0)
+ throw new WebdavException("Incorrect headers");
+ String name = line.substring(0, colon).trim();
+ String match = name.toLowerCase();
+ String value = line.substring(colon + 1).trim();
+ Header header = new Header(name, value);
result.put(match, header);
-
+
}
-
+
// should we set cookies?
Header header = (Header) result.get("set-cookie2");
-
- // if the server doesn't support new cookies,
+
+ // if the server doesn't support new cookies,
// we'll use the old cookies
if (header == null) {
header = (Header) result.get("set-cookie");
}
-
+
if (header != null) {
try {
Cookie[] cookies = Cookie.parse(sessionHost, header);
@@ -731,52 +740,52 @@
e.printStackTrace();
}
}
-
+
return result;
-
+
}
-
-
+
+
/**
* Return true if the connection should be closed after processing.
*/
- protected boolean needToCloseConnection(WebdavMethod method,
+ protected boolean needToCloseConnection(WebdavMethod method,
Hashtable responseHeaders) {
if (!http11)
return true;
-
+
Header connectionHeader = (Header) responseHeaders.get("connection");
-
- if ((connectionHeader != null)
+
+ if ((connectionHeader != null)
&& (connectionHeader.getValue().equals("close")))
return true;
-
+
Header teHeader = (Header) responseHeaders.get("transfer-encoding");
- boolean chunk = (teHeader != null)
+ boolean chunk = (teHeader != null)
&& (teHeader.getValue().indexOf("chunked") != -1);
- Header contentLengthHeader =
+ Header contentLengthHeader =
(Header) responseHeaders.get("content-length");
int contentLength = -1;
if (contentLengthHeader != null) {
try {
- contentLength =
+ contentLength =
Integer.parseInt(contentLengthHeader.getValue());
} catch (Exception e) {
}
}
-
- if ((method.needContentLength()) && (contentLength == -1)
+
+ if ((method.needContentLength()) && (contentLength == -1)
&& (!chunk)) {
// Non compliant server ???
return true;
}
-
+
return false;
}
-
-
+
+
/**
- * Return true if the connection should be closed after sending the
+ * Return true if the connection should be closed after sending the
* request.
*/
protected boolean needToCloseOutput() {
@@ -785,6 +794,6 @@
else
return false;
}
-
-
+
+
}
1.5 +8 -4 jakarta-slide/src/webdav/client/src/org/apache/webdav/lib/Cookie.java
Index: Cookie.java
===================================================================
RCS file: /home/cvs/jakarta-slide/src/webdav/client/src/org/apache/webdav/lib/Cookie.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- Cookie.java 2001/02/23 01:19:23 1.4
+++ Cookie.java 2001/02/24 09:00:53 1.5
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-slide/src/webdav/client/src/org/apache/webdav/lib/Cookie.java,v 1.4 2001/02/23 01:19:23 jericho Exp $
- * $Revision: 1.4 $
- * $Date: 2001/02/23 01:19:23 $
+ * $Header: /home/cvs/jakarta-slide/src/webdav/client/src/org/apache/webdav/lib/Cookie.java,v 1.5 2001/02/24 09:00:53 jericho Exp $
+ * $Revision: 1.5 $
+ * $Date: 2001/02/24 09:00:53 $
*
* ====================================================================
*
@@ -355,6 +355,10 @@
// cycle through the parameters
NameValuePair[] parameters = headerElements[i].getParameters();
+ // could be null. In case only a header element and no parameters.
+ if (parameters == null)
+ // go to the next header element.
+ continue;
boolean discard_set = false, secure_set = false;
for (int j = 0; j < parameters.length; j++) {
String name = parameters[j].getName().toLowerCase();
@@ -413,7 +417,7 @@
* In the RFC 2109 for the cookies,
* the Expires date format is "Wdy, DD-Mon-YY HH:MM:SS GMT".
* There might be one more? Wdy, DD-Mon-YYYY HH:MM:SS GMT
- */
+ */
SimpleDateFormat formatter
= new SimpleDateFormat ("EEE, dd-MMM-yyyy HH:mm:ss z");
String expiryDate = parameters[j].getValue();