//======================================================================== // Parts Copyright 2006 Mort Bay Consulting Pty. Ltd. //------------------------------------------------------------------------ // 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.mortbay.jetty.grizzly; import com.sun.grizzly.Context; import com.sun.grizzly.Controller; import com.sun.grizzly.ProtocolFilter; import com.sun.grizzly.SelectorHandler; import com.sun.grizzly.util.WorkerThread; import java.io.EOFException; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.SocketChannel; import java.util.logging.Level; import org.mortbay.io.nio.NIOBuffer; import org.mortbay.jetty.Handler; import org.mortbay.jetty.HttpConnection; import org.mortbay.jetty.HttpParser; /** * Delegate the processing of the request to a GrizzlyEndPoint * * @author Jeanfrancois Arcand */ public class HttpProtocolFilter implements ProtocolFilter { private Handler handler; private boolean keepAlive=true; private GrizzlyEndPoint endPoint; private GrizzlySocketChannel _channel = new GrizzlySocketChannel(); private HttpParser parser; boolean isError = false; public HttpProtocolFilter() { } /** * Read available bytes and delegate the processing of them to the next * ProtocolFilter in the ProtocolChain. * @return true if the next ProtocolFilter on the ProtocolChain * need to bve invoked. */ public boolean execute(Context ctx) throws IOException { ctx.getSelectionKey().attach(null); isError = false; _channel.setSelectionKey(ctx.getSelectionKey()); _channel.setSocketChannel((SocketChannel)ctx.getSelectionKey().channel()); endPoint.setChannel(_channel); ByteBuffer bb = ((WorkerThread)Thread.currentThread()).getByteBuffer(); try { int nRead = 1; while (nRead > 0) { endPoint.handle(); if (endPoint.isComplete()) { break; } else { nRead = endPoint.fill(parser.getHeaderBuffer()); } } } catch(Throwable t) { isError = true; Controller.logger().log(Level.FINE,"endPoint.handler",t); return false; } finally { if (isError) { endPoint.getHttpConnection().reset(true); } parser.reset(true); _channel.setSelectionKey(null); endPoint.setChannel(null); } bb.clear(); if (parser.getBodyBuffer() != null) { ByteBuffer bodyBuffer = ((NIOBuffer)parser.getBodyBuffer()).getByteBuffer(); if (bodyBuffer != null){ bodyBuffer.clear(); Thread.currentThread().dumpStack(); } } ctx.getSelectionKey().attach(null); return true; } /** * If no bytes were available, close the connection by cancelling the * SelectionKey. If bytes were available, register the SelectionKey * for new bytes. * * @return true if the previous ProtocolFilter postExecute method * needs to be invoked. */ public boolean postExecute(Context ctx) throws IOException { final SelectorHandler selectorHandler = ctx.getSelectorHandler(); final SelectionKey key = ctx.getSelectionKey(); if (!isError && endPoint.keepAlive()) { ctx.setKeyRegistrationState(Context.KeyRegistrationState.REGISTER); } else { ctx.setKeyRegistrationState(Context.KeyRegistrationState.CANCEL); } return true; } public GrizzlyEndPoint getEndPoint() { return endPoint; } public void setEndPoint(GrizzlyEndPoint endPoint) { this.endPoint = endPoint; } public HttpParser getParser() { return parser; } public void setParser(HttpParser parser) { this.parser = parser; } }