use of org.apache.tomcat.util.buf.MessageBytes in project tomcat by apache.
the class TestCookies method test.
private void test(String header, Cookie... expected) {
MimeHeaders mimeHeaders = new MimeHeaders();
ServerCookies serverCookies = new ServerCookies(4);
CookieProcessor cookieProcessor = new Rfc6265CookieProcessor();
MessageBytes cookieHeaderValue = mimeHeaders.addValue("Cookie");
byte[] bytes = header.getBytes(StandardCharsets.UTF_8);
cookieHeaderValue.setBytes(bytes, 0, bytes.length);
cookieProcessor.parseCookieHeader(mimeHeaders, serverCookies);
Assert.assertEquals(expected.length, serverCookies.getCookieCount());
for (int i = 0; i < expected.length; i++) {
Cookie cookie = expected[i];
ServerCookie actual = serverCookies.getCookie(i);
Assert.assertEquals(cookie.getName(), actual.getName().toString());
actual.getValue().getByteChunk().setCharset(StandardCharsets.UTF_8);
Assert.assertEquals(cookie.getValue(), actual.getValue().toString());
}
}
use of org.apache.tomcat.util.buf.MessageBytes in project tomcat by apache.
the class StandardWrapperValve method invoke.
// --------------------------------------------------------- Public Methods
/**
* Invoke the servlet we are managing, respecting the rules regarding
* servlet lifecycle support.
*
* @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 {
// Initialize local variables we may need
boolean unavailable = false;
Throwable throwable = null;
// This should be a Request attribute...
long t1 = System.currentTimeMillis();
requestCount.incrementAndGet();
StandardWrapper wrapper = (StandardWrapper) getContainer();
Servlet servlet = null;
Context context = (Context) wrapper.getParent();
// Check for the application being marked unavailable
if (!context.getState().isAvailable()) {
response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, sm.getString("standardContext.isUnavailable"));
unavailable = true;
}
// Check for the servlet being marked unavailable
if (!unavailable && wrapper.isUnavailable()) {
container.getLogger().info(sm.getString("standardWrapper.isUnavailable", wrapper.getName()));
long available = wrapper.getAvailable();
if ((available > 0L) && (available < Long.MAX_VALUE)) {
response.setDateHeader("Retry-After", available);
response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, sm.getString("standardWrapper.isUnavailable", wrapper.getName()));
} else if (available == Long.MAX_VALUE) {
response.sendError(HttpServletResponse.SC_NOT_FOUND, sm.getString("standardWrapper.notFound", wrapper.getName()));
}
unavailable = true;
}
// Allocate a servlet instance to process this request
try {
if (!unavailable) {
servlet = wrapper.allocate();
}
} catch (UnavailableException e) {
container.getLogger().error(sm.getString("standardWrapper.allocateException", wrapper.getName()), e);
long available = wrapper.getAvailable();
if ((available > 0L) && (available < Long.MAX_VALUE)) {
response.setDateHeader("Retry-After", available);
response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, sm.getString("standardWrapper.isUnavailable", wrapper.getName()));
} else if (available == Long.MAX_VALUE) {
response.sendError(HttpServletResponse.SC_NOT_FOUND, sm.getString("standardWrapper.notFound", wrapper.getName()));
}
} catch (ServletException e) {
container.getLogger().error(sm.getString("standardWrapper.allocateException", wrapper.getName()), StandardWrapper.getRootCause(e));
throwable = e;
exception(request, response, e);
} catch (Throwable e) {
ExceptionUtils.handleThrowable(e);
container.getLogger().error(sm.getString("standardWrapper.allocateException", wrapper.getName()), e);
throwable = e;
exception(request, response, e);
servlet = null;
}
MessageBytes requestPathMB = request.getRequestPathMB();
DispatcherType dispatcherType = DispatcherType.REQUEST;
if (request.getDispatcherType() == DispatcherType.ASYNC) {
dispatcherType = DispatcherType.ASYNC;
}
request.setAttribute(Globals.DISPATCHER_TYPE_ATTR, dispatcherType);
request.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR, requestPathMB);
// Create the filter chain for this request
ApplicationFilterChain filterChain = ApplicationFilterFactory.createFilterChain(request, wrapper, servlet);
// Call the filter chain for this request
// NOTE: This also calls the servlet's service() method
Container container = this.container;
try {
if ((servlet != null) && (filterChain != null)) {
// Swallow output if needed
if (context.getSwallowOutput()) {
try {
SystemLogHandler.startCapture();
if (request.isAsyncDispatching()) {
request.getAsyncContextInternal().doInternalDispatch();
} else {
filterChain.doFilter(request.getRequest(), response.getResponse());
}
} finally {
String log = SystemLogHandler.stopCapture();
if (log != null && log.length() > 0) {
context.getLogger().info(log);
}
}
} else {
if (request.isAsyncDispatching()) {
request.getAsyncContextInternal().doInternalDispatch();
} else {
filterChain.doFilter(request.getRequest(), response.getResponse());
}
}
}
} catch (ClientAbortException | CloseNowException e) {
if (container.getLogger().isDebugEnabled()) {
container.getLogger().debug(sm.getString("standardWrapper.serviceException", wrapper.getName(), context.getName()), e);
}
throwable = e;
exception(request, response, e);
} catch (IOException e) {
container.getLogger().error(sm.getString("standardWrapper.serviceException", wrapper.getName(), context.getName()), e);
throwable = e;
exception(request, response, e);
} catch (UnavailableException e) {
container.getLogger().error(sm.getString("standardWrapper.serviceException", wrapper.getName(), context.getName()), e);
// throwable = e;
// exception(request, response, e);
wrapper.unavailable(e);
long available = wrapper.getAvailable();
if ((available > 0L) && (available < Long.MAX_VALUE)) {
response.setDateHeader("Retry-After", available);
response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, sm.getString("standardWrapper.isUnavailable", wrapper.getName()));
} else if (available == Long.MAX_VALUE) {
response.sendError(HttpServletResponse.SC_NOT_FOUND, sm.getString("standardWrapper.notFound", wrapper.getName()));
}
// Do not save exception in 'throwable', because we
// do not want to do exception(request, response, e) processing
} catch (ServletException e) {
Throwable rootCause = StandardWrapper.getRootCause(e);
if (!(rootCause instanceof ClientAbortException)) {
container.getLogger().error(sm.getString("standardWrapper.serviceExceptionRoot", wrapper.getName(), context.getName(), e.getMessage()), rootCause);
}
throwable = e;
exception(request, response, e);
} catch (Throwable e) {
ExceptionUtils.handleThrowable(e);
container.getLogger().error(sm.getString("standardWrapper.serviceException", wrapper.getName(), context.getName()), e);
throwable = e;
exception(request, response, e);
} finally {
// Release the filter chain (if any) for this request
if (filterChain != null) {
filterChain.release();
}
// Deallocate the allocated servlet instance
try {
if (servlet != null) {
wrapper.deallocate(servlet);
}
} catch (Throwable e) {
ExceptionUtils.handleThrowable(e);
container.getLogger().error(sm.getString("standardWrapper.deallocateException", wrapper.getName()), e);
if (throwable == null) {
throwable = e;
exception(request, response, e);
}
}
// unload it and release this instance
try {
if ((servlet != null) && (wrapper.getAvailable() == Long.MAX_VALUE)) {
wrapper.unload();
}
} catch (Throwable e) {
ExceptionUtils.handleThrowable(e);
container.getLogger().error(sm.getString("standardWrapper.unloadException", wrapper.getName()), e);
if (throwable == null) {
exception(request, response, e);
}
}
long t2 = System.currentTimeMillis();
long time = t2 - t1;
processingTime += time;
if (time > maxTime) {
maxTime = time;
}
if (time < minTime) {
minTime = time;
}
}
}
use of org.apache.tomcat.util.buf.MessageBytes in project tomcat by apache.
the class Http11Processor method prepareRequest.
/**
* After reading the request headers, we have to setup the request filters.
*/
private void prepareRequest() throws IOException {
if (protocol.isSSLEnabled()) {
request.scheme().setString("https");
}
MimeHeaders headers = request.getMimeHeaders();
// Check connection header
MessageBytes connectionValueMB = headers.getValue(Constants.CONNECTION);
if (connectionValueMB != null && !connectionValueMB.isNull()) {
Set<String> tokens = new HashSet<>();
TokenList.parseTokenList(headers.values(Constants.CONNECTION), tokens);
if (tokens.contains(Constants.CLOSE)) {
keepAlive = false;
} else if (tokens.contains(Constants.KEEP_ALIVE_HEADER_VALUE_TOKEN)) {
keepAlive = true;
}
}
if (http11) {
prepareExpectation(headers);
}
// Check user-agent header
Pattern restrictedUserAgents = protocol.getRestrictedUserAgentsPattern();
if (restrictedUserAgents != null && (http11 || keepAlive)) {
MessageBytes userAgentValueMB = headers.getValue("user-agent");
// and keepAlive flags accordingly
if (userAgentValueMB != null && !userAgentValueMB.isNull()) {
String userAgentValue = userAgentValueMB.toString();
if (restrictedUserAgents.matcher(userAgentValue).matches()) {
http11 = false;
keepAlive = false;
}
}
}
// Check host header
MessageBytes hostValueMB = null;
try {
hostValueMB = headers.getUniqueValue("host");
} catch (IllegalArgumentException iae) {
// Multiple Host headers are not permitted
badRequest("http11processor.request.multipleHosts");
}
if (http11 && hostValueMB == null) {
badRequest("http11processor.request.noHostHeader");
}
// Check for an absolute-URI less the query string which has already
// been removed during the parsing of the request line
ByteChunk uriBC = request.requestURI().getByteChunk();
byte[] uriB = uriBC.getBytes();
if (uriBC.startsWithIgnoreCase("http", 0)) {
int pos = 4;
// Check for https
if (uriBC.startsWithIgnoreCase("s", pos)) {
pos++;
}
// Next 3 characters must be "://"
if (uriBC.startsWith("://", pos)) {
pos += 3;
int uriBCStart = uriBC.getStart();
// '/' does not appear in the authority so use the first
// instance to split the authority and the path segments
int slashPos = uriBC.indexOf('/', pos);
// '@' in the authority delimits the userinfo
int atPos = uriBC.indexOf('@', pos);
if (slashPos > -1 && atPos > slashPos) {
// First '@' is in the path segments so no userinfo
atPos = -1;
}
if (slashPos == -1) {
slashPos = uriBC.getLength();
// Set URI as "/". Use 6 as it will always be a '/'.
// 01234567
// http://
// https://
request.requestURI().setBytes(uriB, uriBCStart + 6, 1);
} else {
request.requestURI().setBytes(uriB, uriBCStart + slashPos, uriBC.getLength() - slashPos);
}
// Skip any user info
if (atPos != -1) {
// Validate the userinfo
for (; pos < atPos; pos++) {
byte c = uriB[uriBCStart + pos];
if (!HttpParser.isUserInfo(c)) {
// Strictly there needs to be a check for valid %nn
// encoding here but skip it since it will never be
// decoded because the userinfo is ignored
badRequest("http11processor.request.invalidUserInfo");
break;
}
}
// Skip the '@'
pos = atPos + 1;
}
if (http11) {
// Missing host header is illegal but handled above
if (hostValueMB != null) {
// the Host header
if (!hostValueMB.getByteChunk().equals(uriB, uriBCStart + pos, slashPos - pos)) {
if (protocol.getAllowHostHeaderMismatch()) {
// The requirements of RFC 2616 are being
// applied. If the host header and the request
// line do not agree, the request line takes
// precedence
hostValueMB = headers.setValue("host");
hostValueMB.setBytes(uriB, uriBCStart + pos, slashPos - pos);
} else {
// The requirements of RFC 7230 are being
// applied. If the host header and the request
// line do not agree, trigger a 400 response.
badRequest("http11processor.request.inconsistentHosts");
}
}
}
} else {
// Tomcat internals assume it is set
try {
hostValueMB = headers.setValue("host");
hostValueMB.setBytes(uriB, uriBCStart + pos, slashPos - pos);
} catch (IllegalStateException e) {
// Edge case
// If the request has too many headers it won't be
// possible to create the host header. Ignore this as
// processing won't reach the point where the Tomcat
// internals expect there to be a host header.
}
}
} else {
badRequest("http11processor.request.invalidScheme");
}
}
// the point of decoding.
for (int i = uriBC.getStart(); i < uriBC.getEnd(); i++) {
if (!httpParser.isAbsolutePathRelaxed(uriB[i])) {
badRequest("http11processor.request.invalidUri");
break;
}
}
// Input filter setup
prepareInputFilters(headers);
// Validate host name and extract port if present
parseHost(hostValueMB);
if (!getErrorState().isIoAllowed()) {
getAdapter().log(request, response, 0);
}
}
use of org.apache.tomcat.util.buf.MessageBytes in project tomcat by apache.
the class Http11Processor method prepareExpectation.
private void prepareExpectation(MimeHeaders headers) {
MessageBytes expectMB = headers.getValue("expect");
if (expectMB != null && !expectMB.isNull()) {
if (expectMB.toString().trim().equalsIgnoreCase("100-continue")) {
inputBuffer.setSwallowInput(false);
request.setExpectation(true);
} else {
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
setErrorState(ErrorState.CLOSE_CLEAN, null);
}
}
}
use of org.apache.tomcat.util.buf.MessageBytes in project tomcat by apache.
the class Http11Processor method isConnectionToken.
private static boolean isConnectionToken(MimeHeaders headers, String token) throws IOException {
MessageBytes connection = headers.getValue(Constants.CONNECTION);
if (connection == null) {
return false;
}
Set<String> tokens = new HashSet<>();
TokenList.parseTokenList(headers.values(Constants.CONNECTION), tokens);
return tokens.contains(token);
}
Aggregations