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 re...@apache.org on 2001/02/11 21:39:26 UTC
cvs commit: jakarta-slide/src/webdav/server/org/apache/slide/webdav/method CopyMethod.java DeleteMethod.java GetMethod.java LockMethod.java MkcolMethod.java MoveMethod.java PropFindMethod.java PropPatchMethod.java PutMethod.java UnlockMethod.java WebdavMethod.java
remm 01/02/11 12:39:26
Modified: src/webdav/server/org/apache/slide/webdav/method
CopyMethod.java DeleteMethod.java GetMethod.java
LockMethod.java MkcolMethod.java MoveMethod.java
PropFindMethod.java PropPatchMethod.java
PutMethod.java UnlockMethod.java WebdavMethod.java
Added: src/webdav/server/org/apache/slide/webdav/common
RequestUtil.java
Log:
- Add proper URL encoding / decoding based on Catalina code.
- The only supported char encoding is Unicode (UTF-8), but this will eventually be
configurable.
Revision Changes Path
1.1 jakarta-slide/src/webdav/server/org/apache/slide/webdav/common/RequestUtil.java
Index: RequestUtil.java
===================================================================
/*
* $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/common/RequestUtil.java,v 1.1 2001/02/11 20:39:24 remm Exp $
* $Revision: 1.1 $
* $Date: 2001/02/11 20:39:24 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* 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
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* 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
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.webdav.common;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Map;
import java.util.TimeZone;
import javax.servlet.http.Cookie;
/**
* General purpose request parsing and encoding utility methods.
*
* @author Craig R. McClanahan
* @author Tim Tye
* @version $Revision: 1.1 $ $Date: 2001/02/11 20:39:24 $
*/
public final class RequestUtil {
/**
* The DateFormat to use for generating readable dates in cookies.
*/
private static SimpleDateFormat format =
new SimpleDateFormat(" EEEE, dd-MMM-yy kk:mm:ss zz");
static {
format.setTimeZone(TimeZone.getTimeZone("GMT"));
}
/**
* Encode a cookie as per RFC 2109. The resulting string can be used
* as the value for a <code>Set-Cookie</code> header.
*
* @param cookie The cookie to encode.
* @return A string following RFC 2109.
*/
public static String encodeCookie(Cookie cookie) {
StringBuffer buf = new StringBuffer( cookie.getName() );
buf.append("=");
buf.append(cookie.getValue());
if (cookie.getComment() != null) {
buf.append("; Comment=\"");
buf.append(cookie.getComment());
buf.append("\"");
}
if (cookie.getDomain() != null) {
buf.append("; Domain=\"");
buf.append(cookie.getDomain());
buf.append("\"");
}
long age = cookie.getMaxAge();
if (cookie.getMaxAge() >= 0) {
buf.append("; Max-Age=\"");
buf.append(cookie.getMaxAge());
buf.append("\"");
}
if (cookie.getPath() != null) {
buf.append("; Path=\"");
buf.append(cookie.getPath());
buf.append("\"");
}
if (cookie.getSecure()) {
buf.append("; Secure");
}
if (cookie.getVersion() > 0) {
buf.append("; Version=\"");
buf.append(cookie.getVersion());
buf.append("\"");
}
return (buf.toString());
}
/**
* Parse the character encoding from the specified content type header.
* If the content type is null, or there is no explicit character encoding,
* <code>null</code> is returned.
*
* @param contentType a content type header
*/
public static String parseCharacterEncoding(String contentType) {
if (contentType == null)
return (null);
int start = contentType.indexOf("charset=");
if (start < 0)
return (null);
String encoding = contentType.substring(start + 8);
int end = encoding.indexOf(";");
if (end >= 0)
encoding = encoding.substring(0, end);
encoding = encoding.trim();
if ((encoding.length() > 2) && (encoding.startsWith("\""))
&& (encoding.endsWith("\"")))
encoding = encoding.substring(1, encoding.length() - 1);
return (encoding.trim());
}
/**
* Parse a cookie header into an array of cookies according to RFC 2109.
*
* @param header Value of an HTTP "Cookie" header
*/
public static Cookie[] parseCookieHeader(String header) {
if ((header == null) || (header.length() < 1))
return (new Cookie[0]);
ArrayList cookies = new ArrayList();
while (header.length() > 0) {
int semicolon = header.indexOf(";");
if (semicolon < 0)
semicolon = header.length();
if (semicolon == 0)
break;
String token = header.substring(0, semicolon);
if (semicolon < header.length())
header = header.substring(semicolon + 1);
else
header = "";
try {
int equals = token.indexOf("=");
if (equals > 0) {
String name = URLDecode(token.substring(0, equals).trim());
String value = URLDecode(token.substring(equals+1).trim());
cookies.add(new Cookie(name, value));
}
} catch (Throwable e) {
;
}
}
return ((Cookie[]) cookies.toArray(new Cookie[cookies.size()]));
}
/**
* Append request parameters from the specified String to the specified
* Map. It is presumed that the specified Map is not accessed from any
* other thread, so no synchronization is performed.
* <p>
* <strong>IMPLEMENTATION NOTE</strong>: URL decoding is performed
* individually on the parsed name and value elements, rather than on
* the entire query string ahead of time, to properly deal with the case
* where the name or value includes an encoded "=" or "&" character
* that would otherwise be interpreted as a delimiter.
*
* @param map Map that accumulates the resulting parameters
* @param data Input string containing request parameters
* @param urlParameters true if we're parsing parameters on the URL
*
* @exception IllegalArgumentException if the data is malformed
*/
public static void parseParameters(Map map, String data, String encoding)
throws UnsupportedEncodingException {
if ((data != null) && (data.length() > 0)) {
int len = data.length();
byte[] bytes = new byte[len];
data.getBytes(0, len, bytes, 0);
parseParameters(map, bytes, encoding);
}
}
/**
* Decode and return the specified URL-encoded String.
* When the byte array is converted to a string, the system default
* character encoding is used... This may be different than some other
* servers.
*
* @param str The url-encoded string
*
* @exception IllegalArgumentException if a '%' character is not followed
* by a valid 2-digit hexadecimal number
*/
public static String URLDecode(String str) {
return URLDecode(str, null);
}
/**
* Decode and return the specified URL-encoded String.
*
* @param str The url-encoded string
* @param enc The encoding to use; if null, the default encoding is used
* @exception IllegalArgumentException if a '%' character is not followed
* by a valid 2-digit hexadecimal number
*/
public static String URLDecode(String str, String enc) {
if (str == null)
return (null);
int len = str.length();
byte[] bytes = new byte[len];
str.getBytes(0, len, bytes, 0);
return URLDecode(bytes, enc);
}
/**
* Decode and return the specified URL-encoded byte array.
*
* @param bytes The url-encoded byte array
* @exception IllegalArgumentException if a '%' character is not followed
* by a valid 2-digit hexadecimal number
*/
public static String URLDecode(byte[] bytes) {
return URLDecode(bytes, null);
}
/**
* Decode and return the specified URL-encoded byte array.
*
* @param bytes The url-encoded byte array
* @param enc The encoding to use; if null, the default encoding is used
* @exception IllegalArgumentException if a '%' character is not followed
* by a valid 2-digit hexadecimal number
*/
public static String URLDecode(byte[] bytes, String enc) {
if (bytes == null)
return (null);
int len = bytes.length;
int ix = 0;
int ox = 0;
while (ix < len) {
byte b = bytes[ix++]; // Get byte to test
if (b == '+') {
b = (byte)' ';
} else if (b == '%') {
b = (byte) ((convertHexDigit(bytes[ix++]) << 4)
+ convertHexDigit(bytes[ix++]));
}
bytes[ox++] = b;
}
if (enc != null) {
try {
return new String(bytes, 0, ox, enc);
} catch (Exception e) {
e.printStackTrace();
}
}
return new String(bytes, 0, ox);
}
/**
* Convert a byte character value to hexidecimal digit value.
*
* @param b the character value byte
*/
private static byte convertHexDigit( byte b ) {
if ((b >= '0') && (b <= '9')) return (byte)(b - '0');
if ((b >= 'a') && (b <= 'f')) return (byte)(b - 'a' + 10);
if ((b >= 'A') && (b <= 'F')) return (byte)(b - 'A' + 10);
return 0;
}
/**
* Put name value pair in map.
*
* @param b the character value byte
*
* Put name and value pair in map. When name already exist, add value
* to array of values.
*/
private static void putMapEntry( Map map, String name, String value) {
String[] newValues = null;
String[] oldValues = (String[]) map.get(name);
if (oldValues == null) {
newValues = new String[1];
newValues[0] = value;
} else {
newValues = new String[oldValues.length + 1];
System.arraycopy(oldValues, 0, newValues, 0, oldValues.length);
newValues[oldValues.length] = value;
}
map.put(name, newValues);
}
/**
* Append request parameters from the specified String to the specified
* Map. It is presumed that the specified Map is not accessed from any
* other thread, so no synchronization is performed.
* <p>
* <strong>IMPLEMENTATION NOTE</strong>: URL decoding is performed
* individually on the parsed name and value elements, rather than on
* the entire query string ahead of time, to properly deal with the case
* where the name or value includes an encoded "=" or "&" character
* that would otherwise be interpreted as a delimiter.
*
* NOTE: byte array data is modified by this method. Caller beware.
*
* @param map Map that accumulates the resulting parameters
* @param data Input string containing request parameters
* @param urlParameters true if we're parsing parameters on the URL
*
* @exception UnsupportedEncodingException if the data is malformed
*/
public static void parseParameters(Map map, byte[] data, String encoding)
throws UnsupportedEncodingException {
if (data != null && data.length > 0) {
int pos = 0;
int ix = 0;
int ox = 0;
String key = null;
String value = null;
while (ix < data.length) {
byte c = data[ix++];
switch (c) {
case '&':
value = new String(data, 0, ox, encoding);
if (key != null) {
putMapEntry(map, key, value);
key = null;
}
ox = 0;
break;
case '=':
key = new String(data, 0, ox, encoding);
ox = 0;
break;
case '+':
data[ox++] = (byte)' ';
break;
case '%':
data[ox++] = (byte)((convertHexDigit(data[ix++]) << 4)
+ convertHexDigit(data[ix++]));
break;
default:
data[ox++] = c;
}
}
//The last value does not end in '&'. So save it now.
if (key != null) {
value = new String(data, 0, ox, encoding);
putMapEntry(map, key, value);
}
}
}
}
1.5 +4 -4 jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/CopyMethod.java
Index: CopyMethod.java
===================================================================
RCS file: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/CopyMethod.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- CopyMethod.java 2001/01/19 01:26:59 1.4
+++ CopyMethod.java 2001/02/11 20:39:24 1.5
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/CopyMethod.java,v 1.4 2001/01/19 01:26:59 remm Exp $
- * $Revision: 1.4 $
- * $Date: 2001/01/19 01:26:59 $
+ * $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/CopyMethod.java,v 1.5 2001/02/11 20:39:24 remm Exp $
+ * $Revision: 1.5 $
+ * $Date: 2001/02/11 20:39:24 $
*
* ====================================================================
*
@@ -316,7 +316,7 @@
protected void generateStatusText(WebdavXMLPrinter printer, String href,
int statusCode) {
printer.writeElement("d", "href", WebdavXMLPrinter.OPENING);
- printer.writeText(href);
+ printer.writeText(URLEncode(href));
printer.writeElement("d", "href", WebdavXMLPrinter.CLOSING);
printer.writeElement("d", "status", WebdavXMLPrinter.OPENING);
printer.writeText("HTTP/1.1 " + statusCode + " "
1.4 +4 -4 jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/DeleteMethod.java
Index: DeleteMethod.java
===================================================================
RCS file: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/DeleteMethod.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- DeleteMethod.java 2001/01/17 16:48:59 1.3
+++ DeleteMethod.java 2001/02/11 20:39:24 1.4
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/DeleteMethod.java,v 1.3 2001/01/17 16:48:59 juergen Exp $
- * $Revision: 1.3 $
- * $Date: 2001/01/17 16:48:59 $
+ * $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/DeleteMethod.java,v 1.4 2001/02/11 20:39:24 remm Exp $
+ * $Revision: 1.4 $
+ * $Date: 2001/02/11 20:39:24 $
*
* ====================================================================
*
@@ -233,7 +233,7 @@
protected void generateStatusText(WebdavXMLPrinter printer, String href,
int statusCode) {
printer.writeElement("d", "href", WebdavXMLPrinter.OPENING);
- printer.writeText(href);
+ printer.writeText(URLEncode(href));
printer.writeElement("d", "href", WebdavXMLPrinter.CLOSING);
printer.writeElement("d", "status", WebdavXMLPrinter.OPENING);
printer.writeText("HTTP/1.1 " + statusCode + " "
1.3 +5 -29 jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/GetMethod.java
Index: GetMethod.java
===================================================================
RCS file: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/GetMethod.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- GetMethod.java 2000/11/25 01:36:09 1.2
+++ GetMethod.java 2001/02/11 20:39:24 1.3
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/GetMethod.java,v 1.2 2000/11/25 01:36:09 remm Exp $
- * $Revision: 1.2 $
- * $Date: 2000/11/25 01:36:09 $
+ * $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/GetMethod.java,v 1.3 2001/02/11 20:39:24 remm Exp $
+ * $Revision: 1.3 $
+ * $Date: 2001/02/11 20:39:24 $
*
* ====================================================================
*
@@ -391,7 +391,7 @@
String parent = name.substring(0, slash);
writer.print("<tr><td colspan=\"5\" bgcolor=\"#ffffff\">\r\n");
writer.print("<a href=\"");
- writer.print(rewriteUrl(contextPath));
+ writer.print(URLEncode(contextPath));
if (parent.equals(""))
parent = "/";
writer.print(parent);
@@ -507,8 +507,7 @@
writer.print("<td align=\"left\" colspan=\"3\"> \r\n");
writer.print("<a href=\"");
- writer.print(rewriteUrl(contextPath));
- writer.print(rewriteUrl(currentResource));
+ writer.print(URLEncode(contextPath + currentResource));
writer.print("\"><tt>");
writer.print(trimmed);
if (isCollection(currentDescriptor)) {
@@ -802,29 +801,6 @@
rightSide = 1;
return ("" + leftSide + "." + rightSide + " kb");
-
- }
-
-
- /**
- * URL rewriter.
- *
- * @param path Path which has to be rewiten
- */
- private String rewriteUrl(String path) {
-
- String normalized = path;
-
- // Replace " " with "%20"
- while (true) {
- int index = normalized.indexOf(" ");
- if (index < 0)
- break;
- normalized = normalized.substring(0, index) + "%20"
- + normalized.substring(index + 1);
- }
-
- return normalized;
}
1.5 +7 -9 jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/LockMethod.java
Index: LockMethod.java
===================================================================
RCS file: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/LockMethod.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- LockMethod.java 2001/01/29 12:18:04 1.4
+++ LockMethod.java 2001/02/11 20:39:24 1.5
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/LockMethod.java,v 1.4 2001/01/29 12:18:04 juergen Exp $
- * $Revision: 1.4 $
- * $Date: 2001/01/29 12:18:04 $
+ * $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/LockMethod.java,v 1.5 2001/02/11 20:39:24 remm Exp $
+ * $Revision: 1.5 $
+ * $Date: 2001/02/11 20:39:24 $
*
* ====================================================================
*
@@ -678,11 +678,10 @@
generatedXML.writeElement("d", null, "prop",
WebdavXMLPrinter.CLOSING);
+
try {
- System.out.println("Query result");
-
- System.out.println(generatedXML.toString());
-
+ //System.out.println("Query result");
+ //System.out.println(generatedXML.toString());
Writer writer = resp.getWriter();
writer.write(generatedXML.toString());
writer.flush();
@@ -691,17 +690,16 @@
throw new WebdavException(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
}
+
}
-
/**
* Returns true
*/
protected boolean methodNeedsTransactionSupport() {
return true;
}
-
}
1.5 +7 -9 jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/MkcolMethod.java
Index: MkcolMethod.java
===================================================================
RCS file: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/MkcolMethod.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- MkcolMethod.java 2001/01/17 16:49:01 1.4
+++ MkcolMethod.java 2001/02/11 20:39:24 1.5
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/MkcolMethod.java,v 1.4 2001/01/17 16:49:01 juergen Exp $
- * $Revision: 1.4 $
- * $Date: 2001/01/17 16:49:01 $
+ * $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/MkcolMethod.java,v 1.5 2001/02/11 20:39:24 remm Exp $
+ * $Revision: 1.5 $
+ * $Date: 2001/02/11 20:39:24 $
*
* ====================================================================
*
@@ -257,16 +257,14 @@
// TODO : Initialize and create collection's properties.
}
-
-
-
+
+
/**
* Returns true
*/
- protected boolean methodNeedsTransactionSupport() {
- return true;
+ protected boolean methodNeedsTransactionSupport() {
+ return true;
}
-
}
1.5 +8 -10 jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/MoveMethod.java
Index: MoveMethod.java
===================================================================
RCS file: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/MoveMethod.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- MoveMethod.java 2001/01/19 01:27:00 1.4
+++ MoveMethod.java 2001/02/11 20:39:24 1.5
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/MoveMethod.java,v 1.4 2001/01/19 01:27:00 remm Exp $
- * $Revision: 1.4 $
- * $Date: 2001/01/19 01:27:00 $
+ * $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/MoveMethod.java,v 1.5 2001/02/11 20:39:24 remm Exp $
+ * $Revision: 1.5 $
+ * $Date: 2001/02/11 20:39:24 $
*
* ====================================================================
*
@@ -318,23 +318,21 @@
protected void generateStatusText(WebdavXMLPrinter printer, String href,
int statusCode) {
printer.writeElement("d", "href", WebdavXMLPrinter.OPENING);
- printer.writeText(href);
+ printer.writeText(URLEncode(href));
printer.writeElement("d", "href", WebdavXMLPrinter.CLOSING);
printer.writeElement("d", "status", WebdavXMLPrinter.OPENING);
printer.writeText("HTTP/1.1 " + statusCode + " "
+ WebdavStatus.getStatusText(statusCode));
printer.writeElement("d", "status", WebdavXMLPrinter.CLOSING);
}
-
-
-
+
+
/**
* Returns true
*/
- protected boolean methodNeedsTransactionSupport() {
- return true;
+ protected boolean methodNeedsTransactionSupport() {
+ return true;
}
-
}
1.6 +27 -46 jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PropFindMethod.java
Index: PropFindMethod.java
===================================================================
RCS file: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PropFindMethod.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- PropFindMethod.java 2001/01/29 12:18:05 1.5
+++ PropFindMethod.java 2001/02/11 20:39:24 1.6
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PropFindMethod.java,v 1.5 2001/01/29 12:18:05 juergen Exp $
- * $Revision: 1.5 $
- * $Date: 2001/01/29 12:18:05 $
+ * $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PropFindMethod.java,v 1.6 2001/02/11 20:39:24 remm Exp $
+ * $Revision: 1.6 $
+ * $Date: 2001/02/11 20:39:24 $
*
* ====================================================================
*
@@ -207,28 +207,24 @@
msProprietarySupport = isMsProprietarySupport();
- String depthStr = req.getHeader("Depth");
-
- if (depthStr == null) {
- depth = INFINITY;
- } else {
- if (depthStr.equals("0")) {
+ String depthStr = req.getHeader("Depth");
+
+ if (depthStr == null) {
+ depth = INFINITY;
+ } else {
+ if (depthStr.equals("0")) {
depth = 0;
- }
- if (depthStr.equals("1")) {
+ }
+ if (depthStr.equals("1")) {
depth = 1;
- }
- if (depthStr.equals("infinity")) {
+ }
+ if (depthStr.equals("infinity")) {
depth = INFINITY;
+ }
}
- }
-
- if (req.getContentLength() != 0) {
- //Propfind propfind = null;
+ if (req.getContentLength() != 0) {
- // Workaround : Castor doesn't work, so I use DOM in the meantime
-
Node propNode = null;
try {
@@ -287,8 +283,8 @@
}
- }
-
+ }
+
}
@@ -311,8 +307,6 @@
try {
resource = structure.retrieve(slideToken, resourceUri);
} catch (StructureException e) {
- // We silently catch that since we need to generate some XML ...
- e.printStackTrace();
try {
resp.sendError
(WebdavStatus.SC_NOT_FOUND,
@@ -393,20 +387,6 @@
// Send remaining data
generatedXML.sendData();
- /*
- try {
- //System.out.println("Query result");
- //System.out.println(generatedXML.toString());
-
- Writer writer = resp.getWriter();
- writer.write(generatedXML.toString());
- writer.flush();
- } catch (Exception e) {
- e.printStackTrace();
- throw new WebdavException(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
- }
- */
-
}
@@ -460,7 +440,7 @@
}
}
- generatedXML.writeText(absoluteUri + toAppend);
+ generatedXML.writeText(URLEncode(absoluteUri + toAppend));
} catch (RevisionDescriptorNotFoundException e) {
@@ -483,7 +463,7 @@
}
}
- generatedXML.writeText(absoluteUri + toAppend);
+ generatedXML.writeText(URLEncode(absoluteUri + toAppend));
}
@@ -575,9 +555,9 @@
generatedXML.writeElement(null, "propstat",
WebdavXMLPrinter.CLOSING);
- break;
- case FIND_PROPERTY_NAMES :
- // Show properties for current object.
+ break;
+ case FIND_PROPERTY_NAMES :
+ // Show properties for current object.
status = new String("HTTP/1.1 " + WebdavStatus.SC_OK
+ " " + WebdavStatus.getStatusText
@@ -616,9 +596,9 @@
generatedXML.writeElement(null, "propstat",
WebdavXMLPrinter.CLOSING);
- break;
- case FIND_BY_PROPERTY :
- // Show requested properties value.
+ break;
+ case FIND_BY_PROPERTY :
+ // Show requested properties value.
propertyList = propertyVector.elements();
@@ -889,7 +869,8 @@
generatedXML.writeElement(null, "owner", WebdavXMLPrinter.OPENING);
generatedXML.writeElement(null, "href", WebdavXMLPrinter.OPENING);
- generatedXML.writeText(req.getServletPath() + token.getSubjectUri());
+ generatedXML.writeText
+ (URLEncode(req.getServletPath() + token.getSubjectUri()));
generatedXML.writeElement(null, "href", WebdavXMLPrinter.CLOSING);
generatedXML.writeElement(null, "owner", WebdavXMLPrinter.CLOSING);
1.6 +4 -4 jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PropPatchMethod.java
Index: PropPatchMethod.java
===================================================================
RCS file: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PropPatchMethod.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- PropPatchMethod.java 2001/01/29 12:18:06 1.5
+++ PropPatchMethod.java 2001/02/11 20:39:25 1.6
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PropPatchMethod.java,v 1.5 2001/01/29 12:18:06 juergen Exp $
- * $Revision: 1.5 $
- * $Date: 2001/01/29 12:18:06 $
+ * $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PropPatchMethod.java,v 1.6 2001/02/11 20:39:25 remm Exp $
+ * $Revision: 1.6 $
+ * $Date: 2001/02/11 20:39:25 $
*
* ====================================================================
*
@@ -494,7 +494,7 @@
generatedXML.writeElement("d", null, "response",
WebdavXMLPrinter.OPENING);
- generatedXML.writeProperty("d", null, "href", requestUri);
+ generatedXML.writeProperty("d", null, "href", URLEncode(requestUri));
1.6 +7 -9 jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PutMethod.java
Index: PutMethod.java
===================================================================
RCS file: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PutMethod.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- PutMethod.java 2001/01/17 16:49:03 1.5
+++ PutMethod.java 2001/02/11 20:39:25 1.6
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PutMethod.java,v 1.5 2001/01/17 16:49:03 juergen Exp $
- * $Revision: 1.5 $
- * $Date: 2001/01/17 16:49:03 $
+ * $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/PutMethod.java,v 1.6 2001/02/11 20:39:25 remm Exp $
+ * $Revision: 1.6 $
+ * $Date: 2001/02/11 20:39:25 $
*
* ====================================================================
*
@@ -411,16 +411,14 @@
}
-
-
-
+
+
/**
* Returns true
*/
- protected boolean methodNeedsTransactionSupport() {
- return true;
+ protected boolean methodNeedsTransactionSupport() {
+ return true;
}
-
}
1.4 +7 -9 jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/UnlockMethod.java
Index: UnlockMethod.java
===================================================================
RCS file: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/UnlockMethod.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- UnlockMethod.java 2001/01/17 16:49:03 1.3
+++ UnlockMethod.java 2001/02/11 20:39:25 1.4
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/UnlockMethod.java,v 1.3 2001/01/17 16:49:03 juergen Exp $
- * $Revision: 1.3 $
- * $Date: 2001/01/17 16:49:03 $
+ * $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/UnlockMethod.java,v 1.4 2001/02/11 20:39:25 remm Exp $
+ * $Revision: 1.4 $
+ * $Date: 2001/02/11 20:39:25 $
*
* ====================================================================
*
@@ -93,6 +93,7 @@
*/
private String toUnlock;
+
/**
* Id.
*/
@@ -187,17 +188,14 @@
}
}
+
-
-
-
/**
* Returns true
*/
- protected boolean methodNeedsTransactionSupport() {
- return true;
+ protected boolean methodNeedsTransactionSupport() {
+ return true;
}
-
}
1.10 +155 -59 jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/WebdavMethod.java
Index: WebdavMethod.java
===================================================================
RCS file: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/WebdavMethod.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- WebdavMethod.java 2001/02/08 08:02:00 1.9
+++ WebdavMethod.java 2001/02/11 20:39:25 1.10
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/WebdavMethod.java,v 1.9 2001/02/08 08:02:00 remm Exp $
- * $Revision: 1.9 $
- * $Date: 2001/02/08 08:02:00 $
+ * $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/method/WebdavMethod.java,v 1.10 2001/02/11 20:39:25 remm Exp $
+ * $Revision: 1.10 $
+ * $Date: 2001/02/11 20:39:25 $
*
* ====================================================================
*
@@ -233,6 +233,40 @@
protected static String managerServletPath = "/manager/";
+ /**
+ * Array containing the safe characters set.
+ */
+ protected static BitSet safeCharacters;
+
+
+ protected static final char[] hexadecimal =
+ {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'A', 'B', 'C', 'D', 'E', 'F'};
+
+
+ // ----------------------------------------------------- Static Initializer
+
+
+ static {
+ safeCharacters = new BitSet(256);
+ int i;
+ for (i = 'a'; i <= 'z'; i++) {
+ safeCharacters.set(i);
+ }
+ for (i = 'A'; i <= 'Z'; i++) {
+ safeCharacters.set(i);
+ }
+ for (i = '0'; i <= '9'; i++) {
+ safeCharacters.set(i);
+ }
+ safeCharacters.set('-');
+ safeCharacters.set('_');
+ safeCharacters.set('.');
+ safeCharacters.set('*');
+ safeCharacters.set('/');
+ }
+
+
// ----------------------------------------------------------- Constructors
@@ -554,67 +588,129 @@
/**
- * Decode and return the specified URL-encoded String.
- *
- * @param str The url-encoded string
- *
- * @exception IllegalArgumentException if a '%' character is not followed
- * by a valid 2-digit hexadecimal number
- */
- protected static String URLDecode(String str)
- throws IllegalArgumentException {
+ * Return a context-relative path, beginning with a "/", that represents
+ * the canonical version of the specified path after ".." and "." elements
+ * are resolved out. If the specified path attempts to go outside the
+ * boundaries of the current context (i.e. too many ".." path elements
+ * are present), return <code>null</code> instead.
+ *
+ * @param path Path to be normalized
+ */
+ protected static String URLDecode(String path) {
+
+ if (path == null)
+ return null;
+
+ // Resolve encoded characters in the normalized path,
+ // which also handles encoded spaces so we can skip that later.
+ // Placed at the beginning of the chain so that encoded
+ // bad stuff(tm) can be caught by the later checks
+ String normalized = path;
+ if (normalized.indexOf('%') >= 0)
+ // FIXME: Use configurable encoding here.
+ normalized = RequestUtil.URLDecode(normalized, "UTF8");
+ if (normalized == null)
+ return (null);
+
+ // Normalize the slashes and add leading slash if necessary
+ if (normalized.indexOf('\\') >= 0)
+ normalized = normalized.replace('\\', '/');
+ if (!normalized.startsWith("/"))
+ normalized = "/" + normalized;
+
+ // Resolve occurrences of "//" in the normalized path
+ while (true) {
+ int index = normalized.indexOf("//");
+ if (index < 0)
+ break;
+ normalized = normalized.substring(0, index) +
+ normalized.substring(index + 1);
+ }
+
+ // Resolve occurrences of "/./" in the normalized path
+ while (true) {
+ int index = normalized.indexOf("/./");
+ if (index < 0)
+ break;
+ normalized = normalized.substring(0, index) +
+ normalized.substring(index + 2);
+ }
+
+ // Resolve occurrences of "/../" in the normalized path
+ while (true) {
+ int index = normalized.indexOf("/../");
+ if (index < 0)
+ break;
+ if (index == 0)
+ return (null); // Trying to go outside our context
+ int index2 = normalized.lastIndexOf('/', index - 1);
+ normalized = normalized.substring(0, index2) +
+ normalized.substring(index + 3);
+ }
+
+ // Return the normalized path that we have completed
+ return (normalized);
- if (str == null)
- return (null);
+ }
- StringBuffer dec = new StringBuffer();
- int pos = 0;
- int len = str.length();
- dec.ensureCapacity(str.length());
-
- while (pos < len) {
- int lookahead; // Look-ahead position
-
- // Look ahead to the next URLencoded metacharacter, if any
- for (lookahead = pos; lookahead < len; lookahead++) {
- char ch = str.charAt(lookahead);
- if ((ch == '+') || (ch == '%'))
- break;
- }
-
- // If there were non-metacharacters, copy them as a block
- if (lookahead > pos) {
- dec.append(str.substring(pos, lookahead));
- pos = lookahead;
- }
-
- // Shortcut out if we are at the end of the string
- if (pos >= len)
- break;
-
- // Process the next metacharacter
- char meta = str.charAt(pos);
- if (meta == '+') {
- dec.append(' ');
- pos++;
- } else if (meta == '%') {
+
+ /**
+ * URL rewriter.
+ *
+ * @param path Path which has to be rewiten
+ */
+ protected static String URLEncode(String path) {
+
+ /**
+ * Note: This code portion is very similar to URLEncoder.encode.
+ * Unfortunately, there is no way to specify to the URLEncoder which
+ * characters should be encoded. Here, ' ' should be encoded as "%20"
+ * and '/' shouldn't be encoded.
+ */
+
+ int maxBytesPerChar = 10;
+ int caseDiff = ('a' - 'A');
+ StringBuffer rewrittenPath = new StringBuffer(path.length());
+ ByteArrayOutputStream buf = new ByteArrayOutputStream(maxBytesPerChar);
+ OutputStreamWriter writer = null;
try {
- dec.append((char) Integer.parseInt
- (str.substring(pos+1, pos+3), 16));
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException
- ("Invalid hexadecimal '" + str.substring(pos+1, pos+3)
- + " in URLencoded string");
- } catch (StringIndexOutOfBoundsException e) {
- throw new IllegalArgumentException
- ("Invalid unescaped '%' in URLcoded string");
- }
- pos += 3;
+ // FIXME: Use the same encoding as the one specified above
+ writer = new OutputStreamWriter(buf, "UTF8");
+ } catch (Exception e) {
+ e.printStackTrace();
+ writer = new OutputStreamWriter(buf);
}
- }
- return (dec.toString());
- }
+ for (int i = 0; i < path.length(); i++) {
+ int c = (int) path.charAt(i);
+ if (safeCharacters.get(c)) {
+ rewrittenPath.append((char)c);
+ } else {
+ // convert to external encoding before hex conversion
+ try {
+ writer.write(c);
+ writer.flush();
+ } catch(IOException e) {
+ buf.reset();
+ continue;
+ }
+ byte[] ba = buf.toByteArray();
+ for (int j = 0; j < ba.length; j++) {
+ // Converting each byte in the buffer
+ byte toEncode = ba[j];
+ rewrittenPath.append('%');
+ int low = (int) (toEncode & 0x0f);
+ int high = (int) ((toEncode & 0xf0) >> 4);
+ rewrittenPath.append(hexadecimal[high]);
+ rewrittenPath.append(hexadecimal[low]);
+ }
+ buf.reset();
+ }
+ }
+ return rewrittenPath.toString();
+ }
+
+
}