/* * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.http.server.reactive; import java.io.IOException; import java.nio.ByteBuffer; import javax.servlet.AsyncContext; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.catalina.connector.CoyoteInputStream; import org.apache.catalina.connector.CoyoteOutputStream; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DataBufferFactory; /** * {@link ServletHttpHandlerAdapter} extension that uses Tomcat APIs for reading * from the request and writing to the response with {@link ByteBuffer}. * * @author Violeta Georgieva * @since 5.0 */ @WebServlet(asyncSupported = true) public class TomcatHttpHandlerAdapter extends ServletHttpHandlerAdapter { public TomcatHttpHandlerAdapter(HttpHandler httpHandler) { super(httpHandler); } @Override protected ServerHttpRequest createRequest(HttpServletRequest request, AsyncContext cxt) throws IOException { return new TomcatServerHttpRequest(request, cxt, getDataBufferFactory(), getBufferSize()); } @Override protected ServerHttpResponse createResponse(HttpServletResponse response, AsyncContext cxt) throws IOException { return new TomcatServerHttpResponse(response, cxt, getDataBufferFactory(), getBufferSize()); } private final class TomcatServerHttpRequest extends ServletServerHttpRequest { public TomcatServerHttpRequest(HttpServletRequest request, AsyncContext context, DataBufferFactory factory, int bufferSize) throws IOException { super(request, context, factory, bufferSize); } @Override protected DataBuffer readFromInputStream() throws IOException { DataBuffer buffer = getDataBufferFactory().allocateBuffer(getBufferSize()); ByteBuffer byteBuffer = buffer.asByteBuffer(); byteBuffer.limit(byteBuffer.capacity()); int read = ((CoyoteInputStream) getServletRequest().getInputStream()).read(byteBuffer); if (logger.isTraceEnabled()) { logger.trace("read:" + read); } if (read > 0) { return getDataBufferFactory().wrap(byteBuffer); } return null; } } private static final class TomcatServerHttpResponse extends ServletServerHttpResponse { public TomcatServerHttpResponse(HttpServletResponse response, AsyncContext context, DataBufferFactory factory, int bufferSize) throws IOException { super(response, context, factory, bufferSize); } @Override protected int writeToOutputStream(DataBuffer dataBuffer) throws IOException { ByteBuffer input = dataBuffer.asByteBuffer(); int len = input.remaining(); ((CoyoteOutputStream) getServletResponse().getOutputStream()).write(input); return len; } } }