use of org.apache.tomcat.util.buf.MessageBytes in project tomcat by apache.
the class ApplicationContext method getRequestDispatcher.
@Override
public RequestDispatcher getRequestDispatcher(String path) {
// Validate the path argument
if (path == null)
return (null);
if (!path.startsWith("/"))
throw new IllegalArgumentException(sm.getString("applicationContext.requestDispatcher.iae", path));
// Get query string
String queryString = null;
String normalizedPath = path;
int pos = normalizedPath.indexOf('?');
if (pos >= 0) {
queryString = normalizedPath.substring(pos + 1);
normalizedPath = normalizedPath.substring(0, pos);
}
normalizedPath = RequestUtil.normalize(normalizedPath);
if (normalizedPath == null)
return (null);
if (getContext().getDispatchersUseEncodedPaths()) {
// Decode
String decodedPath;
try {
decodedPath = URLDecoder.decode(normalizedPath, "UTF-8");
} catch (UnsupportedEncodingException e) {
// Impossible
return null;
}
// Security check to catch attempts to encode /../ sequences
normalizedPath = RequestUtil.normalize(decodedPath);
if (!decodedPath.equals(normalizedPath)) {
getContext().getLogger().warn(sm.getString("applicationContext.illegalDispatchPath", path), new IllegalArgumentException());
return null;
}
}
pos = normalizedPath.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();
// Use the thread local mapping data
MappingData mappingData = dd.mappingData;
// Map the URI
CharChunk uriCC = uriMB.getCharChunk();
try {
uriCC.append(context.getPath(), 0, context.getPath().length());
/*
* Ignore any trailing path params (separated by ';') for mapping
* purposes
*/
int semicolon = normalizedPath.indexOf(';');
if (pos >= 0 && semicolon > pos) {
semicolon = -1;
}
uriCC.append(normalizedPath, 0, semicolon > 0 ? semicolon : pos);
service.getMapper().map(context, 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(normalizedPath, semicolon, pos - semicolon);
}
} catch (Exception e) {
// Should never happen
log(sm.getString("applicationContext.mapping.error"), e);
return (null);
}
Wrapper wrapper = mappingData.wrapper;
String wrapperPath = mappingData.wrapperPath.toString();
String pathInfo = mappingData.pathInfo.toString();
ServletMapping mapping = (new ApplicationMapping(mappingData)).getServletMapping();
mappingData.recycle();
String encodedUri = URLEncoder.DEFAULT.encode(uriCC.toString(), "UTF-8");
// Construct a RequestDispatcher to process this request
return new ApplicationDispatcher(wrapper, encodedUri, wrapperPath, pathInfo, queryString, mapping, null);
}
use of org.apache.tomcat.util.buf.MessageBytes in project tomcat by apache.
the class ApplicationContext method getContext.
@Override
public ServletContext getContext(String uri) {
// Validate the format of the specified argument
if (uri == null || !uri.startsWith("/")) {
return null;
}
Context child = null;
try {
// Look for an exact match
Container host = context.getParent();
child = (Context) host.findChild(uri);
// Non-running contexts should be ignored.
if (child != null && !child.getState().isAvailable()) {
child = null;
}
// Remove any version information and use the mapper
if (child == null) {
int i = uri.indexOf("##");
if (i > -1) {
uri = uri.substring(0, i);
}
// Note: This could be more efficient with a dedicated Mapper
// method but such an implementation would require some
// refactoring of the Mapper to avoid copy/paste of
// existing code.
MessageBytes hostMB = MessageBytes.newInstance();
hostMB.setString(host.getName());
MessageBytes pathMB = MessageBytes.newInstance();
pathMB.setString(uri);
MappingData mappingData = new MappingData();
((Engine) host.getParent()).getService().getMapper().map(hostMB, pathMB, null, mappingData);
child = mappingData.context;
}
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
return null;
}
if (child == null) {
return null;
}
if (context.getCrossContext()) {
// If crossContext is enabled, can always return the context
return child.getServletContext();
} else if (child == context) {
// Can still return the current context
return context.getServletContext();
} else {
// Nothing to return
return null;
}
}
use of org.apache.tomcat.util.buf.MessageBytes in project tomcat by apache.
the class RewriteValve method invoke.
@Override
public void invoke(Request request, Response response) throws IOException, ServletException {
if (!getEnabled() || rules == null || rules.length == 0) {
getNext().invoke(request, response);
return;
}
if (Boolean.TRUE.equals(invoked.get())) {
try {
getNext().invoke(request, response);
} finally {
invoked.set(null);
}
return;
}
try {
Resolver resolver = new ResolverImpl(request);
invoked.set(Boolean.TRUE);
// As long as MB isn't a char sequence or affiliated, this has to be
// converted to a string
String uriEncoding = request.getConnector().getURIEncoding();
String originalQueryStringEncoded = request.getQueryString();
MessageBytes urlMB = context ? request.getRequestPathMB() : request.getDecodedRequestURIMB();
urlMB.toChars();
CharSequence urlDecoded = urlMB.getCharChunk();
CharSequence host = request.getServerName();
boolean rewritten = false;
boolean done = false;
boolean qsa = false;
for (int i = 0; i < rules.length; i++) {
RewriteRule rule = rules[i];
CharSequence test = (rule.isHost()) ? host : urlDecoded;
CharSequence newtest = rule.evaluate(test, resolver);
if (newtest != null && !test.equals(newtest.toString())) {
if (containerLog.isDebugEnabled()) {
containerLog.debug("Rewrote " + test + " as " + newtest + " with rule pattern " + rule.getPatternString());
}
if (rule.isHost()) {
host = newtest;
} else {
urlDecoded = newtest;
}
rewritten = true;
}
// Check QSA before the final reply
if (!qsa && newtest != null && rule.isQsappend()) {
// TODO: This logic will need some tweaks if we add QSD
// support
qsa = true;
}
// - forbidden
if (rule.isForbidden() && newtest != null) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
done = true;
break;
}
// - gone
if (rule.isGone() && newtest != null) {
response.sendError(HttpServletResponse.SC_GONE);
done = true;
break;
}
// - redirect (code)
if (rule.isRedirect() && newtest != null) {
// Append the query string to the url if there is one and it
// hasn't been rewritten
String urlStringDecoded = urlDecoded.toString();
int index = urlStringDecoded.indexOf("?");
String rewrittenQueryStringDecoded;
if (index == -1) {
rewrittenQueryStringDecoded = null;
} else {
rewrittenQueryStringDecoded = urlStringDecoded.substring(index + 1);
urlStringDecoded = urlStringDecoded.substring(0, index);
}
StringBuffer urlStringEncoded = new StringBuffer(ENCODER.encode(urlStringDecoded, uriEncoding));
if (originalQueryStringEncoded != null && originalQueryStringEncoded.length() > 0) {
if (rewrittenQueryStringDecoded == null) {
urlStringEncoded.append('?');
urlStringEncoded.append(originalQueryStringEncoded);
} else {
if (qsa) {
// if qsa is specified append the query
urlStringEncoded.append('?');
urlStringEncoded.append(ENCODER.encode(rewrittenQueryStringDecoded, uriEncoding));
urlStringEncoded.append('&');
urlStringEncoded.append(originalQueryStringEncoded);
} else if (index == urlStringEncoded.length() - 1) {
// if the ? is the last character delete it, its only purpose was to
// prevent the rewrite module from appending the query string
urlStringEncoded.deleteCharAt(index);
} else {
urlStringEncoded.append('?');
urlStringEncoded.append(ENCODER.encode(rewrittenQueryStringDecoded, uriEncoding));
}
}
} else if (rewrittenQueryStringDecoded != null) {
urlStringEncoded.append('?');
urlStringEncoded.append(ENCODER.encode(rewrittenQueryStringDecoded, uriEncoding));
}
// 3. the url isn't absolute
if (context && urlStringEncoded.charAt(0) == '/' && !UriUtil.hasScheme(urlStringEncoded)) {
urlStringEncoded.insert(0, request.getContext().getEncodedPath());
}
if (rule.isNoescape()) {
response.sendRedirect(URLDecoder.decode(urlStringEncoded.toString(), uriEncoding));
} else {
response.sendRedirect(urlStringEncoded.toString());
}
response.setStatus(rule.getRedirectCode());
done = true;
break;
}
// - cookie
if (rule.isCookie() && newtest != null) {
Cookie cookie = new Cookie(rule.getCookieName(), rule.getCookieResult());
cookie.setDomain(rule.getCookieDomain());
cookie.setMaxAge(rule.getCookieLifetime());
cookie.setPath(rule.getCookiePath());
cookie.setSecure(rule.isCookieSecure());
cookie.setHttpOnly(rule.isCookieHttpOnly());
response.addCookie(cookie);
}
// - env (note: this sets a request attribute)
if (rule.isEnv() && newtest != null) {
for (int j = 0; j < rule.getEnvSize(); j++) {
request.setAttribute(rule.getEnvName(j), rule.getEnvResult(j));
}
}
// to do that)
if (rule.isType() && newtest != null) {
request.setContentType(rule.getTypeValue());
}
// - chain (skip remaining chained rules if this one does not match)
if (rule.isChain() && newtest == null) {
for (int j = i; j < rules.length; j++) {
if (!rules[j].isChain()) {
i = j;
break;
}
}
continue;
}
// - last (stop rewriting here)
if (rule.isLast() && newtest != null) {
break;
}
// - next (redo again)
if (rule.isNext() && newtest != null) {
i = 0;
continue;
}
// - skip (n rules)
if (newtest != null) {
i += rule.getSkip();
}
}
if (rewritten) {
if (!done) {
// See if we need to replace the query string
String urlStringDecoded = urlDecoded.toString();
String queryStringDecoded = null;
int queryIndex = urlStringDecoded.indexOf('?');
if (queryIndex != -1) {
queryStringDecoded = urlStringDecoded.substring(queryIndex + 1);
urlStringDecoded = urlStringDecoded.substring(0, queryIndex);
}
// Save the current context path before re-writing starts
String contextPath = null;
if (context) {
contextPath = request.getContextPath();
}
// Populated the encoded (i.e. undecoded) requestURI
request.getCoyoteRequest().requestURI().setString(null);
CharChunk chunk = request.getCoyoteRequest().requestURI().getCharChunk();
chunk.recycle();
if (context) {
// This is neither decoded nor normalized
chunk.append(contextPath);
}
chunk.append(ENCODER.encode(urlStringDecoded, uriEncoding));
request.getCoyoteRequest().requestURI().toChars();
// Decoded and normalized URI
// Rewriting may have denormalized the URL
urlStringDecoded = RequestUtil.normalize(urlStringDecoded);
request.getCoyoteRequest().decodedURI().setString(null);
chunk = request.getCoyoteRequest().decodedURI().getCharChunk();
chunk.recycle();
if (context) {
// This is decoded and normalized
chunk.append(request.getServletContext().getContextPath());
}
chunk.append(urlStringDecoded);
request.getCoyoteRequest().decodedURI().toChars();
// Set the new Query if there is one
if (queryStringDecoded != null) {
request.getCoyoteRequest().queryString().setString(null);
chunk = request.getCoyoteRequest().queryString().getCharChunk();
chunk.recycle();
chunk.append(ENCODER.encode(queryStringDecoded, uriEncoding));
if (qsa && originalQueryStringEncoded != null && originalQueryStringEncoded.length() > 0) {
chunk.append('&');
chunk.append(originalQueryStringEncoded);
}
if (!chunk.isNull()) {
request.getCoyoteRequest().queryString().toChars();
}
}
// Set the new host if it changed
if (!host.equals(request.getServerName())) {
request.getCoyoteRequest().serverName().setString(null);
chunk = request.getCoyoteRequest().serverName().getCharChunk();
chunk.recycle();
chunk.append(host.toString());
request.getCoyoteRequest().serverName().toChars();
}
request.getMappingData().recycle();
// Reinvoke the whole request recursively
try {
Connector connector = request.getConnector();
if (!connector.getProtocolHandler().getAdapter().prepare(request.getCoyoteRequest(), response.getCoyoteResponse())) {
return;
}
Pipeline pipeline = connector.getService().getContainer().getPipeline();
request.setAsyncSupported(pipeline.isAsyncSupported());
pipeline.getFirst().invoke(request, response);
} catch (Exception e) {
// This doesn't actually happen in the Catalina adapter implementation
}
}
} else {
getNext().invoke(request, response);
}
} finally {
invoked.set(null);
}
}
use of org.apache.tomcat.util.buf.MessageBytes in project tomcat by apache.
the class MimeHeaderField method nextElement.
@Override
public String nextElement() {
MessageBytes current = next;
findNext();
return current.toString();
}
use of org.apache.tomcat.util.buf.MessageBytes in project tomcat by apache.
the class MimeHeaderField method findNext.
private void findNext() {
next = null;
for (; pos < size; pos++) {
MessageBytes n1 = headers.getName(pos);
if (n1.equalsIgnoreCase(name)) {
next = headers.getValue(pos);
break;
}
}
pos++;
}
Aggregations