}
private static boolean normalizeChars(MessageBytes uriMB) {
CharChunk uriCC = uriMB.getCharChunk();
char[] c = uriCC.getChars();
int start = uriCC.getStart();
int end = uriCC.getEnd();
// URL * is acceptable
if ((end - start == 1) && c[start] == (char) '*')
return true;
int pos = 0;
int index = 0;
// Replace '\' with '/'
// Check for null char
for (pos = start; pos < end; pos++) {
if (c[pos] == (char) '\\') {
if (ALLOW_BACKSLASH) {
c[pos] = (char) '/';
} else {
return false;
}
}
if (c[pos] == (char) 0) {
return false;
}
}
// The URL must start with '/'
if (c[start] != (char) '/') {
return false;
}
// Replace "//" with "/"
if (COLLAPSE_ADJACENT_SLASHES) {
for (pos = start; pos < (end - 1); pos++) {
if (c[pos] == (char) '/') {
while ((pos + 1 < end) && (c[pos + 1] == (char) '/')) {
copyChars(c, pos, pos + 1, end - pos - 1);
end--;
}
}
}
}
// If the URI ends with "/." or "/..", then we append an extra "/"
// Note: It is possible to extend the URI by 1 without any side effect
// as the next character is a non-significant WS.
if (((end - start) > 2) && (c[end - 1] == (char) '.')) {
if ((c[end - 2] == (char) '/')
|| ((c[end - 2] == (char) '.')
&& (c[end - 3] == (char) '/'))) {
c[end] = (char) '/';
end++;
}
}
uriCC.setEnd(end);
index = 0;
// Resolve occurrences of "/./" in the normalized path
while (true) {
index = uriCC.indexOf("/./", 0, 3, index);
if (index < 0)
break;
copyChars(c, start + index, start + index + 2,
end - start - index - 2);
end = end - 2;
uriCC.setEnd(end);
}
index = 0;
// Resolve occurrences of "/../" in the normalized path
while (true) {
index = uriCC.indexOf("/../", 0, 4, index);
if (index < 0)
break;
// Prevent from going outside our context
if (index == 0)
return false;
int index2 = -1;
for (pos = start + index - 1; (pos >= 0) && (index2 < 0); pos --) {
if (c[pos] == (char) '/') {
index2 = pos;
}
}
copyChars(c, start + index2, start + index + 3,
end - start - index - 3);
end = end + index2 - index - 3;
uriCC.setEnd(end);
index = index2;
}
uriCC.setChars(c, start, end);
return true;
}