use of org.apache.tomcat.util.buf.MessageBytes in project tomcat70 by apache.
the class StandardContextValve method invoke.
/**
* Select the appropriate child Wrapper to process this request,
* based on the specified request URI. If no matching Wrapper can
* be found, return an appropriate HTTP error.
*
* @param request Request to be processed
* @param response Response to be produced
*
* @exception IOException if an input/output error occurred
* @exception ServletException if a servlet error occurred
*/
@Override
public final void invoke(Request request, Response response) throws IOException, ServletException {
// Disallow any direct access to resources under WEB-INF or META-INF
MessageBytes requestPathMB = request.getRequestPathMB();
if ((requestPathMB.startsWithIgnoreCase("/META-INF/", 0)) || (requestPathMB.equalsIgnoreCase("/META-INF")) || (requestPathMB.startsWithIgnoreCase("/WEB-INF/", 0)) || (requestPathMB.equalsIgnoreCase("/WEB-INF"))) {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
// Select the Wrapper to be used for this Request
Wrapper wrapper = request.getWrapper();
if (wrapper == null || wrapper.isUnavailable()) {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
// Acknowledge the request
try {
response.sendAcknowledgement();
} catch (IOException ioe) {
container.getLogger().error(sm.getString("standardContextValve.acknowledgeException"), ioe);
request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, ioe);
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
if (request.isAsyncSupported()) {
request.setAsyncSupported(wrapper.getPipeline().isAsyncSupported());
}
wrapper.getPipeline().getFirst().invoke(request, response);
}
use of org.apache.tomcat.util.buf.MessageBytes in project tomcat70 by apache.
the class ApplicationContext 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.
*
* @param path The path to the desired resource.
*/
@Override
public RequestDispatcher getRequestDispatcher(final String path) {
// Validate the path argument
if (path == null) {
return (null);
}
if (!path.startsWith("/")) {
throw new IllegalArgumentException(sm.getString("applicationContext.requestDispatcher.iae", path));
}
// Need to separate the query string and the uri. This is required for
// the ApplicationDispatcher constructor. Mapping also requires the uri
// without the query string.
String uri;
String queryString;
int pos = path.indexOf('?');
if (pos >= 0) {
uri = path.substring(0, pos);
queryString = path.substring(pos + 1);
} else {
uri = path;
queryString = null;
}
String normalizedPath = RequestUtil.normalize(uri);
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;
}
// URI needs to include the context path
uri = URLEncoder.DEFAULT.encode(getContextPath(), "UTF-8") + uri;
} else {
// uri is passed to the constructor for ApplicationDispatcher and is
// ultimately used as the value for getRequestURI() which returns
// encoded values. Therefore, since the value passed in for path
// was decoded, encode uri here.
uri = URLEncoder.DEFAULT.encode(getContextPath() + uri, "UTF-8");
}
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);
context.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(normalizedPath, semicolon, pos - semicolon);
}
} catch (Exception e) {
// Should never happen
log(sm.getString("applicationContext.mapping.error"), e);
return (null);
}
Wrapper wrapper = (Wrapper) mappingData.wrapper;
String wrapperPath = mappingData.wrapperPath.toString();
String pathInfo = mappingData.pathInfo.toString();
mappingData.recycle();
// Construct a RequestDispatcher to process this request
return new ApplicationDispatcher(wrapper, uri, wrapperPath, pathInfo, queryString, null);
}
use of org.apache.tomcat.util.buf.MessageBytes in project tomcat70 by apache.
the class BasicAuthenticator method authenticate.
@Override
public boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws IOException {
if (checkForCachedAuthentication(request, response, true)) {
return true;
}
// Validate any credentials already included with this request
String username = null;
String password = null;
MessageBytes authorization = request.getCoyoteRequest().getMimeHeaders().getValue("authorization");
if (authorization != null) {
authorization.toBytes();
ByteChunk authorizationBC = authorization.getByteChunk();
if (authorizationBC.startsWithIgnoreCase("basic ", 0)) {
authorizationBC.setOffset(authorizationBC.getOffset() + 6);
byte[] decoded = Base64.decodeBase64(authorizationBC.getBuffer(), authorizationBC.getOffset(), authorizationBC.getLength());
// Get username and password
int colon = -1;
for (int i = 0; i < decoded.length; i++) {
if (decoded[i] == ':') {
colon = i;
break;
}
}
if (colon < 0) {
username = new String(decoded, charset);
} else {
username = new String(decoded, 0, colon, charset);
password = new String(decoded, colon + 1, decoded.length - colon - 1, charset);
}
authorizationBC.setOffset(authorizationBC.getOffset() - 6);
}
Principal principal = context.getRealm().authenticate(username, password);
if (principal != null) {
register(request, response, principal, HttpServletRequest.BASIC_AUTH, username, password);
return (true);
}
}
StringBuilder value = new StringBuilder(16);
value.append("Basic realm=\"");
if (config.getRealmName() == null) {
value.append(REALM_NAME);
} else {
value.append(config.getRealmName());
}
value.append('\"');
if (charsetString != null && !charsetString.isEmpty()) {
value.append(", charset=");
value.append(charsetString);
}
response.setHeader(AUTH_HEADER_NAME, value.toString());
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return (false);
}
use of org.apache.tomcat.util.buf.MessageBytes in project tomcat70 by apache.
the class FormAuthenticator method authenticate.
// --------------------------------------------------------- Public Methods
/**
* Authenticate the user making this request, based on the specified
* login configuration. Return <code>true</code> if any specified
* constraint has been satisfied, or <code>false</code> if we have
* created a response challenge already.
*
* @param request Request we are processing
* @param response Response we are creating
* @param config Login configuration describing how authentication
* should be performed
*
* @exception IOException if an input/output error occurs
*/
@Override
public boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws IOException {
if (checkForCachedAuthentication(request, response, true)) {
return (true);
}
// References to objects we will need later
Session session = null;
Principal principal = null;
// Have we authenticated this user before but have caching disabled?
if (!cache) {
session = request.getSessionInternal(true);
if (log.isDebugEnabled()) {
log.debug("Checking for reauthenticate in session " + session);
}
String username = (String) session.getNote(Constants.SESS_USERNAME_NOTE);
String password = (String) session.getNote(Constants.SESS_PASSWORD_NOTE);
if ((username != null) && (password != null)) {
if (log.isDebugEnabled()) {
log.debug("Reauthenticating username '" + username + "'");
}
principal = context.getRealm().authenticate(username, password);
if (principal != null) {
session.setNote(Constants.FORM_PRINCIPAL_NOTE, principal);
if (!matchRequest(request)) {
register(request, response, principal, HttpServletRequest.FORM_AUTH, username, password);
return (true);
}
}
if (log.isDebugEnabled()) {
log.debug("Reauthentication failed, proceed normally");
}
}
}
// authentication? If so, forward the *original* request instead.
if (matchRequest(request)) {
session = request.getSessionInternal(true);
if (log.isDebugEnabled()) {
log.debug("Restore request from session '" + session.getIdInternal() + "'");
}
principal = (Principal) session.getNote(Constants.FORM_PRINCIPAL_NOTE);
register(request, response, principal, HttpServletRequest.FORM_AUTH, (String) session.getNote(Constants.SESS_USERNAME_NOTE), (String) session.getNote(Constants.SESS_PASSWORD_NOTE));
// and password in the session, so remove them
if (cache) {
session.removeNote(Constants.SESS_USERNAME_NOTE);
session.removeNote(Constants.SESS_PASSWORD_NOTE);
}
if (restoreRequest(request, session)) {
if (log.isDebugEnabled()) {
log.debug("Proceed to restored request");
}
return (true);
} else {
if (log.isDebugEnabled()) {
log.debug("Restore of original request failed");
}
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
return (false);
}
}
// Acquire references to objects we will need to evaluate
MessageBytes uriMB = MessageBytes.newInstance();
CharChunk uriCC = uriMB.getCharChunk();
uriCC.setLimit(-1);
String contextPath = request.getContextPath();
String requestURI = request.getDecodedRequestURI();
// Is this the action request from the login page?
boolean loginAction = requestURI.startsWith(contextPath) && requestURI.endsWith(Constants.FORM_ACTION);
// No -- Save this request and redirect to the form login page
if (!loginAction) {
// may not go to the correct web application
if (request.getServletPath().length() == 0 && request.getPathInfo() == null) {
StringBuilder location = new StringBuilder(requestURI);
location.append('/');
if (request.getQueryString() != null) {
location.append('?');
location.append(request.getQueryString());
}
response.sendRedirect(response.encodeRedirectURL(location.toString()));
return false;
}
session = request.getSessionInternal(true);
if (log.isDebugEnabled()) {
log.debug("Save request in session '" + session.getIdInternal() + "'");
}
try {
saveRequest(request, session);
} catch (IOException ioe) {
log.debug("Request body too big to save during authentication");
response.sendError(HttpServletResponse.SC_FORBIDDEN, sm.getString("authenticator.requestBodyTooBig"));
return (false);
}
forwardToLoginPage(request, response, config);
return (false);
}
// Yes -- Acknowledge the request, validate the specified credentials
// and redirect to the error page if they are not correct
request.getResponse().sendAcknowledgement();
Realm realm = context.getRealm();
if (characterEncoding != null) {
request.setCharacterEncoding(characterEncoding);
}
String username = request.getParameter(Constants.FORM_USERNAME);
String password = request.getParameter(Constants.FORM_PASSWORD);
if (log.isDebugEnabled()) {
log.debug("Authenticating username '" + username + "'");
}
principal = realm.authenticate(username, password);
if (principal == null) {
forwardToErrorPage(request, response, config);
return (false);
}
if (log.isDebugEnabled()) {
log.debug("Authentication of '" + username + "' was successful");
}
if (session == null) {
session = request.getSessionInternal(false);
}
if (session == null) {
if (containerLog.isDebugEnabled()) {
containerLog.debug("User took so long to log on the session expired");
}
if (landingPage == null) {
response.sendError(HttpServletResponse.SC_REQUEST_TIMEOUT, sm.getString("authenticator.sessionExpired"));
} else {
// Make the authenticator think the user originally requested
// the landing page
String uri = request.getContextPath() + landingPage;
SavedRequest saved = new SavedRequest();
saved.setMethod("GET");
saved.setRequestURI(uri);
saved.setDecodedRequestURI(uri);
request.getSessionInternal(true).setNote(Constants.FORM_REQUEST_NOTE, saved);
response.sendRedirect(response.encodeRedirectURL(uri));
}
return (false);
}
// Save the authenticated Principal in our session
session.setNote(Constants.FORM_PRINCIPAL_NOTE, principal);
// Save the username and password as well
session.setNote(Constants.SESS_USERNAME_NOTE, username);
session.setNote(Constants.SESS_PASSWORD_NOTE, password);
// Redirect the user to the original request URI (which will cause
// the original request to be restored)
requestURI = savedRequestURL(session);
if (log.isDebugEnabled()) {
log.debug("Redirecting to original '" + requestURI + "'");
}
if (requestURI == null) {
if (landingPage == null) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, sm.getString("authenticator.formlogin"));
} else {
// Make the authenticator think the user originally requested
// the landing page
String uri = request.getContextPath() + landingPage;
SavedRequest saved = new SavedRequest();
saved.setMethod("GET");
saved.setRequestURI(uri);
saved.setDecodedRequestURI(uri);
session.setNote(Constants.FORM_REQUEST_NOTE, saved);
response.sendRedirect(response.encodeRedirectURL(uri));
}
} else {
response.sendRedirect(response.encodeRedirectURL(requestURI));
}
return (false);
}
use of org.apache.tomcat.util.buf.MessageBytes in project tomcat70 by apache.
the class FormAuthenticator method restoreRequest.
/**
* Restore the original request from information stored in our session.
* If the original request is no longer present (because the session
* timed out), return <code>false</code>; otherwise, return
* <code>true</code>.
*
* @param request The request to be restored
* @param session The session containing the saved information
*/
protected boolean restoreRequest(Request request, Session session) throws IOException {
// Retrieve and remove the SavedRequest object from our session
SavedRequest saved = (SavedRequest) session.getNote(Constants.FORM_REQUEST_NOTE);
session.removeNote(Constants.FORM_REQUEST_NOTE);
session.removeNote(Constants.FORM_PRINCIPAL_NOTE);
if (saved == null) {
return (false);
}
// Swallow any request body since we will be replacing it
// Need to do this before headers are restored as AJP connector uses
// content length header to determine how much data needs to be read for
// request body
byte[] buffer = new byte[4096];
InputStream is = request.createInputStream();
while (is.read(buffer) >= 0) {
// Ignore request body
}
// Modify our current request to reflect the original one
request.clearCookies();
Iterator<Cookie> cookies = saved.getCookies();
while (cookies.hasNext()) {
request.addCookie(cookies.next());
}
String method = saved.getMethod();
MimeHeaders rmh = request.getCoyoteRequest().getMimeHeaders();
rmh.recycle();
boolean cacheable = "GET".equalsIgnoreCase(method) || "HEAD".equalsIgnoreCase(method);
Iterator<String> names = saved.getHeaderNames();
while (names.hasNext()) {
String name = names.next();
// BZ 43687
if (!("If-Modified-Since".equalsIgnoreCase(name) || (cacheable && "If-None-Match".equalsIgnoreCase(name)))) {
Iterator<String> values = saved.getHeaderValues(name);
while (values.hasNext()) {
rmh.addValue(name).setString(values.next());
}
}
}
request.clearLocales();
Iterator<Locale> locales = saved.getLocales();
while (locales.hasNext()) {
request.addLocale(locales.next());
}
request.getCoyoteRequest().getParameters().recycle();
request.getCoyoteRequest().getParameters().setQueryStringEncoding(request.getConnector().getURIEncoding());
ByteChunk body = saved.getBody();
if (body != null) {
request.getCoyoteRequest().action(ActionCode.REQ_SET_BODY_REPLAY, body);
// Set content type
MessageBytes contentType = MessageBytes.newInstance();
// If no content type specified, use default for POST
String savedContentType = saved.getContentType();
if (savedContentType == null && "POST".equalsIgnoreCase(method)) {
savedContentType = "application/x-www-form-urlencoded";
}
contentType.setString(savedContentType);
request.getCoyoteRequest().setContentType(contentType);
}
request.getCoyoteRequest().method().setString(method);
request.getCoyoteRequest().queryString().setString(saved.getQueryString());
request.getCoyoteRequest().requestURI().setString(saved.getRequestURI());
return (true);
}
Aggregations