Lines 1-7
Link Here
|
1 |
/* |
1 |
/* |
2 |
* $Header: /home/cvspublic/jakarta-slide/src/webdav/server/org/apache/slide/webdav/util/WebdavUtils.java,v 1.26 2004/09/08 04:14:31 ozeigermann Exp $ |
2 |
* $Header: /home/cvspublic/jakarta-slide/src/webdav/server/org/apache/slide/webdav/util/WebdavUtils.java,v 1.25 2004/09/01 10:34:48 unico Exp $ |
3 |
* $Revision: 1.26 $ |
3 |
* $Revision: 1.25 $ |
4 |
* $Date: 2004/09/08 04:14:31 $ |
4 |
* $Date: 2004/09/01 10:34:48 $ |
5 |
* |
5 |
* |
6 |
* ==================================================================== |
6 |
* ==================================================================== |
7 |
* |
7 |
* |
Lines 26-31
Link Here
|
26 |
import java.security.Principal; |
26 |
import java.security.Principal; |
27 |
|
27 |
|
28 |
import java.io.UnsupportedEncodingException; |
28 |
import java.io.UnsupportedEncodingException; |
|
|
29 |
import java.net.URLDecoder; |
30 |
import java.net.URLEncoder; |
29 |
|
31 |
|
30 |
import javax.servlet.http.HttpServletRequest; |
32 |
import javax.servlet.http.HttpServletRequest; |
31 |
import javax.servlet.http.HttpSession; |
33 |
import javax.servlet.http.HttpSession; |
Lines 62-143
Link Here
|
62 |
|
64 |
|
63 |
private static final String CREDENTIALS_ATTRIBUTE = |
65 |
private static final String CREDENTIALS_ATTRIBUTE = |
64 |
"org.apache.slide.webdav.method.credentials"; |
66 |
"org.apache.slide.webdav.method.credentials"; |
65 |
|
|
|
66 |
|
67 |
// --------------------------------------------------------- Public Methods |
68 |
|
69 |
private static byte convertHexDigitToByte(byte b) { |
70 |
if(b >= 48 && b <= 57) |
71 |
return (byte)(b - 48); |
72 |
if(b >= 97 && b <= 102) |
73 |
return (byte)((b - 97) + 10); |
74 |
if(b >= 65 && b <= 70) |
75 |
return (byte)((b - 65) + 10); |
76 |
else |
77 |
return 0; |
78 |
} |
79 |
|
67 |
|
80 |
public static String URLDecode(String string, String enc) { |
68 |
|
|
|
69 |
/** |
70 |
* Constructs a new String based on bytes sequence contained |
71 |
* in the |
72 |
* Non-ASCII parts of the sequence will be decoded with UTF-8 |
73 |
* if possible, or with the specified encoding. |
74 |
* |
75 |
* @param string A "String" returned by tomcat getPathInfo() |
76 |
* @param enc Encoding to use if non UTF-8 |
77 |
* @return A properly encoded String object |
78 |
*/ |
79 |
public static String decodeString(String string, String enc) |
80 |
throws UnsupportedEncodingException { |
81 |
if(string == null) |
81 |
if(string == null) |
82 |
return null; |
82 |
return null; |
83 |
byte bytes[] = string.getBytes(); |
83 |
StringBuffer sb = null; |
84 |
int len = bytes.length; |
84 |
int j = 0; |
85 |
int ix = 0; |
85 |
int sf = 0; |
86 |
int ox = 0; |
86 |
sb = new StringBuffer(); |
87 |
boolean isUtf8 = true; |
87 |
byte utf8buffer[] = new byte[5]; |
88 |
int shouldFollow = 0; |
88 |
// Get bytes without any decoding |
89 |
while(ix < len) { |
89 |
byte bytes[] = string.getBytes("ISO-8859-1"); |
90 |
byte b = bytes[ix++]; |
90 |
for (int i = 0; i < bytes.length; i+=1) { |
91 |
if(b == 37) { // % character found, followed by hex digit |
91 |
byte b = bytes[i]; |
92 |
b = (byte)((convertHexDigitToByte(bytes[ix++]) << 4) + convertHexDigitToByte(bytes[ix++])); |
92 |
int bb = (b >= 0) ? b : b+256; |
93 |
int i = 256+b; |
93 |
// System.out.print("0x"+Integer.toHexString(bb)+ " "); |
94 |
if (shouldFollow == 0) { |
94 |
utf8buffer[j++] = b; |
95 |
if (i<256) |
95 |
boolean ok = false; |
96 |
if (i>191) |
96 |
// First test if non-ascii |
97 |
if (i>223) |
97 |
if (bb >= 128) { |
98 |
if (i>239) |
98 |
// No ongoing UTF-8 decoding ? |
99 |
if (i>247) |
99 |
if (sf==0) { |
100 |
if (i>251) |
100 |
// Now test if this can be a UTF-8 first byte |
101 |
isUtf8 = false; |
101 |
if (bb >= 192 && i < 252) { |
102 |
else |
102 |
ok = true; |
103 |
shouldFollow = 4; |
103 |
// Determine UTF-8 size |
104 |
else |
104 |
if (bb >= 224) |
105 |
shouldFollow = 3; |
105 |
if (bb >= 240) |
|
|
106 |
if (bb >= 248) |
107 |
sf = 4; |
106 |
else |
108 |
else |
107 |
shouldFollow = 2; |
109 |
sf = 3; |
108 |
else |
110 |
else |
109 |
shouldFollow = 1; |
111 |
sf = 2; |
110 |
else |
112 |
else |
111 |
isUtf8 = false; |
113 |
sf = 1; |
112 |
else |
114 |
} |
113 |
shouldFollow = 0; |
115 |
} else if (bb >= 128 && bb < 192) { |
114 |
} else { |
116 |
// This is a UTF-8 part |
115 |
shouldFollow --; |
117 |
sf--; |
|
|
118 |
if (sf == 0) { |
119 |
sb.append(new String(utf8buffer,0,j,"UTF-8")); |
120 |
j = 0; |
121 |
} |
122 |
ok = true; |
116 |
} |
123 |
} |
117 |
} else { |
|
|
118 |
if (shouldFollow > 0) // this should have been followed with another hex code |
119 |
isUtf8 = false; |
120 |
if(b == 43) // + is replaced by space |
121 |
b = 32; |
122 |
} |
124 |
} |
123 |
|
125 |
// If there was an error during UTF-8 decoding, decode all remaining chars with default encoding |
124 |
bytes[ox++] = b; |
126 |
if (!ok) { |
125 |
} |
127 |
sb.append(new String(utf8buffer,0,j, enc)); |
126 |
String res; |
128 |
j = 0; |
127 |
try { |
129 |
sf = 0; |
128 |
if(shouldFollow == 0 && isUtf8) { |
|
|
129 |
res = new String(bytes, 0, ox, "UTF-8"); |
130 |
} else { |
131 |
res = new String(bytes, 0, ox, enc); |
132 |
} |
130 |
} |
133 |
return res; |
|
|
134 |
} catch(UnsupportedEncodingException e) { |
135 |
e.printStackTrace(); |
136 |
} |
131 |
} |
137 |
|
132 |
// Remaining chars |
138 |
return null; |
133 |
if (j > 0) { |
|
|
134 |
sb.append(new String(utf8buffer,0,j, enc)); |
135 |
} |
136 |
// System.out.println(); |
137 |
// System.out.println(sb); |
138 |
return sb.toString(); |
139 |
} |
139 |
} |
140 |
|
140 |
|
|
|
141 |
|
141 |
/** |
142 |
/** |
142 |
* Return a context-relative path, beginning with a "/", that represents |
143 |
* Return a context-relative path, beginning with a "/", that represents |
143 |
* the canonical version of the specified path after ".." and "." elements |
144 |
* the canonical version of the specified path after ".." and "." elements |
Lines 147-176
Link Here
|
147 |
* |
148 |
* |
148 |
* @param path the path to be normalized |
149 |
* @param path the path to be normalized |
149 |
**/ |
150 |
**/ |
150 |
public static String decodeURL(String path) { |
151 |
public static String normalizeURL(String path) { |
151 |
return decodeURL(path, Configuration.urlEncoding()); |
|
|
152 |
} |
153 |
|
154 |
/** |
155 |
* Return a context-relative path, beginning with a "/", that represents |
156 |
* the canonical version of the specified path after ".." and "." elements |
157 |
* are resolved out. If the specified path attempts to go outside the |
158 |
* boundaries of the current context (i.e. too many ".." path elements |
159 |
* are present), return <code>null</code> instead. |
160 |
* |
161 |
* @param path the path to be normalized |
162 |
**/ |
163 |
public static String decodeURL(String path, String enc) { |
164 |
|
152 |
|
165 |
if (path == null) |
153 |
if (path == null) |
166 |
return null; |
154 |
return null; |
167 |
|
155 |
|
168 |
// Resolve encoded characters in the normalized path, |
156 |
String normalized = path; |
169 |
// which also handles encoded spaces so we can skip that later. |
157 |
|
170 |
// Placed at the beginning of the chain so that encoded |
|
|
171 |
// bad stuff(tm) can be caught by the later checks |
172 |
String normalized = URLDecode(path, enc); |
173 |
|
174 |
if (normalized == null) |
158 |
if (normalized == null) |
175 |
return (null); |
159 |
return (null); |
176 |
|
160 |
|
Lines 209-215
Link Here
|
209 |
normalized = normalized.substring(0, index2) + |
193 |
normalized = normalized.substring(0, index2) + |
210 |
normalized.substring(index + 3); |
194 |
normalized.substring(index + 3); |
211 |
} |
195 |
} |
212 |
|
196 |
normalized = normalized.replace('?','_'); |
213 |
// Return the normalized path that we have completed |
197 |
// Return the normalized path that we have completed |
214 |
return (normalized); |
198 |
return (normalized); |
215 |
} |
199 |
} |
Lines 221-227
Link Here
|
221 |
* @param path the path to be rewritten |
205 |
* @param path the path to be rewritten |
222 |
**/ |
206 |
**/ |
223 |
public static String encodeURL(String path) { |
207 |
public static String encodeURL(String path) { |
224 |
return URLUtil.URLEncode(path, Configuration.urlEncoding()); |
208 |
return URLUtil.URLEncode(path, Configuration.realUrlEncoding()); |
225 |
} |
209 |
} |
226 |
|
210 |
|
227 |
|
211 |
|
Lines 317-323
Link Here
|
317 |
if (config.isDefaultServlet()) { |
301 |
if (config.isDefaultServlet()) { |
318 |
result = req.getServletPath(); |
302 |
result = req.getServletPath(); |
319 |
} else { |
303 |
} else { |
320 |
result = req.getPathInfo(); |
304 |
result = req.getRequestURI(); |
|
|
305 |
result = result.substring(req.getContextPath().length()+ req.getServletPath().length()); |
321 |
} |
306 |
} |
322 |
|
307 |
|
323 |
// default to the namespace root if no path-info is specified |
308 |
// default to the namespace root if no path-info is specified |
Lines 327-366
Link Here
|
327 |
|
312 |
|
328 |
// prefix the URI with the configured scope |
313 |
// prefix the URI with the configured scope |
329 |
result = config.getScope() + result; |
314 |
result = config.getScope() + result; |
330 |
|
315 |
|
331 |
|
316 |
return normalizeURL(fixTomcatURL(result)); // the request URL is utf-8 encoded |
332 |
|
|
|
333 |
return decodeURL(fixTomcatURL(result, "UTF-8")); // the request URL is utf-8 encoded |
334 |
} |
317 |
} |
335 |
|
318 |
|
336 |
|
|
|
337 |
/** |
319 |
/** |
338 |
* Returns an URL based on input. The input URL is encoded with "fromEncoding". |
320 |
* Returns an URL based on input. The input URL is encoded with "fromEncoding". |
339 |
* The resulting URL is encoded as specified in Configuration.urlEncoding() |
321 |
* The resulting URL is encoded as specified in Configuration.urlEncoding() |
340 |
* |
322 |
* |
341 |
* @param input the input URL |
323 |
* @param input the input URL |
342 |
* @param fromEncoding the used encoding of the input URL |
|
|
343 |
* |
324 |
* |
344 |
* @return a new URL encoded in Configuration.urlEncoding() |
325 |
* @return a new URL encoded in Configuration.urlEncoding() |
345 |
**/ |
326 |
**/ |
346 |
public static String fixTomcatURL(String input, String fromEncoding) { |
327 |
public static String fixTomcatURL(String input) { |
347 |
|
328 |
return fixTomcatHeader(input, "UTF-8"); |
348 |
if (input == null) return null; |
|
|
349 |
|
350 |
String result = null; |
351 |
try { |
352 |
|
353 |
// printString(input.substring(27,input.length())); |
354 |
// byte[] a = input.getBytes("UTF-8"); |
355 |
result = encodeURL(new String(input.getBytes(fromEncoding), Configuration.urlEncoding()), |
356 |
Configuration.urlEncoding()); |
357 |
// printString(result.substring(27,result.length())); |
358 |
// byte[] b = result.getBytes(Configuration.urlEncoding()); |
359 |
// System.out.println("Length b " + b.length); |
360 |
} catch (Exception e) { e.printStackTrace(); } |
361 |
// System.out.println("Length = " + input.length()); |
362 |
// System.out.println("Length = " + result.length()); |
363 |
return result; |
364 |
} |
329 |
} |
365 |
|
330 |
|
366 |
|
331 |
|
Lines 375-387
Link Here
|
375 |
* @return a new header value encoded in toEncoding |
340 |
* @return a new header value encoded in toEncoding |
376 |
**/ |
341 |
**/ |
377 |
public static String fixTomcatHeader(String header, String toEncoding) { |
342 |
public static String fixTomcatHeader(String header, String toEncoding) { |
378 |
|
343 |
// todo: toEncoding parameter not used anymore |
379 |
if (header == null) return null; |
344 |
if (header == null) return null; |
380 |
|
345 |
|
381 |
String result = null; |
346 |
String result = null; |
382 |
try { |
347 |
try { |
383 |
result = URLUtil.URLDecode(new String(header.getBytes("ISO-8859-1"), toEncoding), |
348 |
result = URLUtil.URLDecode(header.getBytes("ISO-8859-1"),"ISO-8859-1"); |
384 |
toEncoding); |
349 |
result = decodeString(result,Configuration.urlEncoding()); |
|
|
350 |
if (!Configuration.useUTF8()) { |
351 |
// Remove unsupported characters |
352 |
result = new String(result.getBytes(Configuration.urlEncoding()),Configuration.urlEncoding()); |
353 |
} |
385 |
} catch (Exception e) { e.printStackTrace(); } |
354 |
} catch (Exception e) { e.printStackTrace(); } |
386 |
return result; |
355 |
return result; |
387 |
} |
356 |
} |