use of org.glassfish.grizzly.http.util.CharChunk in project Payara by payara.
the class CoyoteAdapter method normalizeChars.
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;
// 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--;
}
}
}
}
// 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;
}
use of org.glassfish.grizzly.http.util.CharChunk in project Payara by payara.
the class VirtualServerPipeline method redirectIfNecessary.
/**
* Checks to see if the given request needs to be redirected.
*
* @param request The request to process
* @param response The response to return
*
* @return true if redirect has occurred, false otherwise
*/
private boolean redirectIfNecessary(Request request, Response response) throws IOException {
if (redirects == null) {
return false;
}
HttpServletRequest hreq = (HttpServletRequest) request.getRequest();
HttpServletResponse hres = (HttpServletResponse) request.getResponse();
String requestURI = hreq.getRequestURI();
RedirectParameters redirectMatch = null;
// Determine the longest 'from' URI prefix match
int size = redirects.size();
for (int i = 0; i < size; i++) {
RedirectParameters elem = redirects.get(i);
String elemFromWithTrailingSlash = elem.from;
if (!elemFromWithTrailingSlash.endsWith("/")) {
elemFromWithTrailingSlash += "/";
}
if (requestURI.equals(elem.from) || requestURI.startsWith(elemFromWithTrailingSlash)) {
if (redirectMatch != null) {
if (elem.from.length() > redirectMatch.from.length()) {
redirectMatch = elem;
}
} else {
redirectMatch = elem;
}
}
}
if (redirectMatch != null) {
// Redirect prefix match found, need to redirect
String location = null;
String uriSuffix = requestURI.substring(redirectMatch.from.length());
if ("/".equals(redirectMatch.from)) {
uriSuffix = "/" + uriSuffix;
// START 6810361
if (redirectMatch.urlPrefixPath != null && uriSuffix.startsWith(redirectMatch.urlPrefixPath)) {
return false;
}
// END 6810361
}
// Implements welcome page only redirection
if ("".equals(redirectMatch.from)) {
if (!("/".equals(requestURI)))
return false;
}
// END 6810361
if (redirectMatch.urlPrefix != null) {
// Replace 'from' URI prefix with URL prefix
location = redirectMatch.urlPrefix + uriSuffix;
} else {
// Replace 'from' URI prefix with complete URL
location = redirectMatch.url;
}
String queryString = hreq.getQueryString();
if (queryString != null) {
location += "?" + queryString;
}
CharChunk locationCC = null;
if (redirectMatch.isEscape) {
try {
URL url = new URL(location);
locationCC = locations.poll();
if (locationCC == null) {
locationCC = new CharChunk();
}
locationCC.append(url.getProtocol());
locationCC.append("://");
locationCC.append(url.getHost());
if (url.getPort() != -1) {
locationCC.append(":");
locationCC.append(String.valueOf(url.getPort()));
}
locationCC.append(response.encode(url.getPath()));
if (queryString != null) {
locationCC.append("?");
locationCC.append(url.getQuery());
}
location = locationCC.toString();
} catch (MalformedURLException mue) {
if (redirectMatch.validURI) {
logger.log(Level.WARNING, LogFacade.INVALID_REDIRECTION_LOCATION, location);
} else {
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, LogFacade.INVALID_REDIRECTION_LOCATION, location);
}
}
} finally {
if (locationCC != null) {
locationCC.recycle();
locations.offer(locationCC);
}
}
}
hres.sendRedirect(location);
return true;
}
return false;
}
use of org.glassfish.grizzly.http.util.CharChunk in project Payara by payara.
the class Request method convertURI.
// START CR 6309511
/**
* Character conversion of the URI.
*/
protected void convertURI(MessageBytes uri) throws Exception {
ByteChunk bc = uri.getByteChunk();
CharChunk cc = uri.getCharChunk();
int length = bc.getLength();
cc.allocate(length, -1);
String enc = connector.getURIEncoding();
if (enc != null && !enc.isEmpty() && !Globals.ISO_8859_1_ENCODING.equalsIgnoreCase(enc)) {
B2CConverter conv = getURIConverter();
try {
if (conv == null) {
conv = new B2CConverter(enc);
setURIConverter(conv);
}
} catch (IOException e) {
// Ignore
log.log(Level.SEVERE, LogFacade.INVALID_URI_ENCODING);
connector.setURIEncoding(null);
}
if (conv != null) {
try {
conv.convert(bc, cc, cc.getBuffer().length - cc.getEnd());
uri.setChars(cc.getBuffer(), cc.getStart(), cc.getLength());
return;
} catch (IOException e) {
log.log(Level.SEVERE, LogFacade.INVALID_URI_CHAR_ENCODING);
cc.recycle();
}
}
}
// Default encoding: fast conversion
byte[] bbuf = bc.getBuffer();
char[] cbuf = cc.getBuffer();
int start = bc.getStart();
for (int i = 0; i < length; i++) {
cbuf[i] = (char) (bbuf[i + start] & 0xff);
}
uri.setChars(cbuf, 0, length);
}
use of org.glassfish.grizzly.http.util.CharChunk in project Payara by payara.
the class StandardContext method getRequestDispatcher.
/**
* Return a <code>RequestDispatcher</code> instance that acts as a
* wrapper for the resource at the given path. The path must begin
* with a "/" and is interpreted as relative to the current context root.
*/
@Override
public RequestDispatcher getRequestDispatcher(String path) {
// Validate the path argument
if (path == null) {
return null;
}
if (!path.startsWith("/") && !path.isEmpty()) {
String msg = MessageFormat.format(rb.getString(LogFacade.INCORRECT_OR_NOT_EMPTY_PATH), path);
throw new IllegalArgumentException(msg);
}
// Get query string
String queryString = null;
int pos = path.indexOf('?');
if (pos >= 0) {
queryString = path.substring(pos + 1);
path = path.substring(0, pos);
}
path = RequestUtil.normalize(path);
if (path == null)
return (null);
pos = path.length();
// Use the thread local URI and mapping data
DispatchData dd = dispatchData.get();
if (dd == null) {
dd = new DispatchData();
dispatchData.set(dd);
}
MessageBytes uriMB = dd.uriMB;
uriMB.recycle();
// Retrieve the thread local mapping data
MappingData mappingData = dd.mappingData;
// Map the URI
CharChunk uriCC = uriMB.getCharChunk();
try {
uriCC.append(getPath(), 0, getPath().length());
/*
* Ignore any trailing path params (separated by ';') for mapping
* purposes
*/
int semicolon = path.indexOf(';');
if (pos >= 0 && semicolon > pos) {
semicolon = -1;
}
uriCC.append(path, 0, semicolon > 0 ? semicolon : pos);
getMapper().map(uriMB, mappingData);
if (mappingData.wrapper == null) {
return (null);
}
/*
* Append any trailing path params (separated by ';') that were
* ignored for mapping purposes, so that they're reflected in the
* RequestDispatcher's requestURI
*/
if (semicolon > 0) {
uriCC.append(path, semicolon, pos - semicolon);
}
} catch (Exception e) {
// Should never happen
log.log(Level.WARNING, LogFacade.MAPPING_ERROR_EXCEPTION, e);
return (null);
}
Wrapper wrapper = (Wrapper) mappingData.wrapper;
String wrapperPath = mappingData.wrapperPath.toString();
String pathInfo = mappingData.pathInfo.toString();
HttpServletMapping mappingForDispatch = new MappingImpl(mappingData);
mappingData.recycle();
// Construct a RequestDispatcher to process this request
return new ApplicationDispatcher(wrapper, mappingForDispatch, uriCC.toString(), wrapperPath, pathInfo, queryString, null);
}
use of org.glassfish.grizzly.http.util.CharChunk in project Payara by payara.
the class ContainerMapper method mapUriWithSemicolon.
/**
* Maps the decodedURI to the corresponding Adapter, considering that URI
* may have a semicolon with extra data followed, which shouldn't be a part
* of mapping process.
*
* @param req HTTP request
* @param decodedURI URI
* @param semicolonPos semicolon position. Might be <tt>0</tt> if position wasn't resolved yet (so it will be resolved in the method), or <tt>-1</tt> if there is no semicolon in the URI.
* @param mappingData
* @return
* @throws Exception
*/
final HttpHandler mapUriWithSemicolon(final Request req, final DataChunk decodedURI, int semicolonPos, final MappingData mappingData) throws Exception {
mapperLock.readLock().lock();
try {
final CharChunk charChunk = decodedURI.getCharChunk();
final int oldStart = charChunk.getStart();
final int oldEnd = charChunk.getEnd();
if (semicolonPos == 0) {
semicolonPos = decodedURI.indexOf(';', 0);
}
DataChunk localDecodedURI = decodedURI;
if (semicolonPos >= 0) {
charChunk.setEnd(semicolonPos);
// duplicate the URI path, because Mapper may corrupt the attributes,
// which follow the path
localDecodedURI = req.getNote(DATA_CHUNK);
if (localDecodedURI == null) {
localDecodedURI = DataChunk.newInstance();
req.setNote(DATA_CHUNK, localDecodedURI);
}
localDecodedURI.duplicate(decodedURI);
}
try {
return map(req, localDecodedURI, mappingData);
} finally {
charChunk.setStart(oldStart);
charChunk.setEnd(oldEnd);
}
} finally {
mapperLock.readLock().unlock();
}
}
Aggregations