Author: norman Date: Wed Sep 28 13:51:14 2011 New Revision: 1176883 URL: http://svn.apache.org/viewvc?rev=1176883&view=rev Log: Move the encoding logic out of the netty code and place it in AbstractProtocolTransport which should be used as starting point when you implement your own ProtocolTransport implementation. See PROTOCOLS-33
Added: james/protocols/trunk/api/src/main/java/org/apache/james/protocols/api/StreamResponse.java (with props) Removed: james/protocols/trunk/impl/src/main/java/org/apache/james/protocols/impl/ResponseEncoder.java Modified: james/protocols/trunk/api/src/main/java/org/apache/james/protocols/api/AbstractProtocolTransport.java james/protocols/trunk/impl/src/main/java/org/apache/james/protocols/impl/AbstractChannelPipelineFactory.java james/protocols/trunk/impl/src/main/java/org/apache/james/protocols/impl/NettyProtocolTransport.java james/protocols/trunk/impl/src/main/java/org/apache/james/protocols/impl/NettyServer.java james/protocols/trunk/smtp/src/main/java/org/apache/james/protocols/smtp/core/UnknownCmdHandler.java james/protocols/trunk/smtp/src/main/java/org/apache/james/protocols/smtp/hook/UnknownHook.java Modified: james/protocols/trunk/api/src/main/java/org/apache/james/protocols/api/AbstractProtocolTransport.java URL: http://svn.apache.org/viewvc/james/protocols/trunk/api/src/main/java/org/apache/james/protocols/api/AbstractProtocolTransport.java?rev=1176883&r1=1176882&r2=1176883&view=diff ============================================================================== --- james/protocols/trunk/api/src/main/java/org/apache/james/protocols/api/AbstractProtocolTransport.java (original) +++ james/protocols/trunk/api/src/main/java/org/apache/james/protocols/api/AbstractProtocolTransport.java Wed Sep 28 13:51:14 2011 @@ -19,13 +19,27 @@ package org.apache.james.protocols.api; +import java.io.InputStream; +import java.nio.charset.Charset; import java.util.LinkedList; +import java.util.List; import org.apache.james.protocols.api.FutureResponse.ResponseListener; +/** + * Abstract base class for {@link ProtocolTransport} implementation which already takes care of all the complex + * stuff when handling {@link Response}'s. + * + * + * + */ public abstract class AbstractProtocolTransport implements ProtocolTransport{ + private final static Charset CHARSET = Charset.forName("US-ASCII"); + private final static String CRLF = "\r\n"; + + // TODO: Should we limit the size ? private final LinkedList<Response> responses = new LinkedList<Response>(); /* @@ -94,7 +108,74 @@ public abstract class AbstractProtocolTr * @param response * @param session */ - protected abstract void writeResponseToClient(Response response, ProtocolSession session); + protected void writeResponseToClient(Response response, ProtocolSession session) { + if (response != null) { + writeToClient(toBytes(response), session); + if (response instanceof StreamResponse) { + writeToClient(((StreamResponse) response).getStream(), session); + } + + if (response instanceof StartTlsResponse) { + if (isStartTLSSupported()) { + startTLS(session); + session.resetState(); + + } + } + + if (response.isEndSession()) { + // close the channel if needed after the message was written out + close(); + } + } + } + + + /** + * Take the {@link Response} and encode it to a <code>byte</code> array + * + * @param response + * @return bytes + */ + protected static byte[] toBytes(Response response) { + StringBuilder builder = new StringBuilder(); + List<CharSequence> lines = response.getLines(); + for (int i = 0; i < lines.size(); i++) { + builder.append(lines.get(i)); + if (i < lines.size()) { + builder.append(CRLF); + } + } + return builder.toString().getBytes(CHARSET); + } + + /** + * Write the given <code>byte's</code> to the remote peer + * + * @param bytes + * @param session + */ + protected abstract void writeToClient(byte[] bytes, ProtocolSession session); + + /** + * Write the given {@link InputStream} to the remote peer + * + * @param in + * @param session + */ + protected abstract void writeToClient(InputStream in, ProtocolSession session); + + /** + * Start the TLS encrpytion + * + * @param session + */ + protected abstract void startTLS(ProtocolSession session); + + /** + * Close the Transport + */ + protected abstract void close(); } Added: james/protocols/trunk/api/src/main/java/org/apache/james/protocols/api/StreamResponse.java URL: http://svn.apache.org/viewvc/james/protocols/trunk/api/src/main/java/org/apache/james/protocols/api/StreamResponse.java?rev=1176883&view=auto ============================================================================== --- james/protocols/trunk/api/src/main/java/org/apache/james/protocols/api/StreamResponse.java (added) +++ james/protocols/trunk/api/src/main/java/org/apache/james/protocols/api/StreamResponse.java Wed Sep 28 13:51:14 2011 @@ -0,0 +1,38 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you 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.apache.james.protocols.api; + +import java.io.InputStream; + +/** + * Special {@link Response} sub-type which allows to write an {@link InputStream} to the remote peer + * + * + */ +public interface StreamResponse extends Response{ + + /** + * Return the stream which needs to get written to the remote peer + * + * @return stream + */ + public InputStream getStream(); + +} Propchange: james/protocols/trunk/api/src/main/java/org/apache/james/protocols/api/StreamResponse.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: james/protocols/trunk/impl/src/main/java/org/apache/james/protocols/impl/AbstractChannelPipelineFactory.java URL: http://svn.apache.org/viewvc/james/protocols/trunk/impl/src/main/java/org/apache/james/protocols/impl/AbstractChannelPipelineFactory.java?rev=1176883&r1=1176882&r2=1176883&view=diff ============================================================================== --- james/protocols/trunk/impl/src/main/java/org/apache/james/protocols/impl/AbstractChannelPipelineFactory.java (original) +++ james/protocols/trunk/impl/src/main/java/org/apache/james/protocols/impl/AbstractChannelPipelineFactory.java Wed Sep 28 13:51:14 2011 @@ -78,9 +78,6 @@ public abstract class AbstractChannelPip // Add the text line decoder which limit the max line length, don't strip the delimiter and use CRLF as delimiter pipeline.addLast("framer", new DelimiterBasedFrameDecoder(MAX_LINE_LENGTH, false, Delimiters.lineDelimiter())); - // encoder - pipeline.addLast("encoderResponse", createEncoder()); - pipeline.addLast("streamer", new ChunkedWriteHandler()); pipeline.addLast("timeoutHandler", new TimeoutHandler(timer, timeout)); @@ -104,13 +101,6 @@ public abstract class AbstractChannelPip */ protected abstract ChannelUpstreamHandler createHandler(); - /** - * Create the {@link Response} Encoder - * - * @return encoder - */ - protected abstract OneToOneEncoder createEncoder(); - } Modified: james/protocols/trunk/impl/src/main/java/org/apache/james/protocols/impl/NettyProtocolTransport.java URL: http://svn.apache.org/viewvc/james/protocols/trunk/impl/src/main/java/org/apache/james/protocols/impl/NettyProtocolTransport.java?rev=1176883&r1=1176882&r2=1176883&view=diff ============================================================================== --- james/protocols/trunk/impl/src/main/java/org/apache/james/protocols/impl/NettyProtocolTransport.java (original) +++ james/protocols/trunk/impl/src/main/java/org/apache/james/protocols/impl/NettyProtocolTransport.java Wed Sep 28 13:51:14 2011 @@ -19,19 +19,19 @@ package org.apache.james.protocols.impl; +import java.io.InputStream; import java.net.InetSocketAddress; import javax.net.ssl.SSLEngine; import org.apache.james.protocols.api.AbstractProtocolTransport; import org.apache.james.protocols.api.ProtocolSession; -import org.apache.james.protocols.api.Response; -import org.apache.james.protocols.api.StartTlsResponse; import org.apache.james.protocols.api.handler.LineHandler; +import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelFutureListener; import org.jboss.netty.handler.ssl.SslHandler; +import org.jboss.netty.handler.stream.ChunkedStream; /** * A Netty implementation of a ProtocolTransport @@ -41,7 +41,6 @@ public class NettyProtocolTransport exte private final Channel channel; private final SSLEngine engine; private int lineHandlerCount = 0; - public NettyProtocolTransport(Channel channel, SSLEngine engine) { this.channel = channel; @@ -117,25 +116,31 @@ public class NettyProtocolTransport exte return lineHandlerCount; } + + + @Override + protected void startTLS(ProtocolSession session) { + channel.setReadable(false); + SslHandler filter = new SslHandler(engine); + filter.getEngine().setUseClientMode(false); + channel.getPipeline().addFirst("sslHandler", filter); + channel.setReadable(true); + } + + @Override + protected void writeToClient(byte[] bytes, ProtocolSession session) { + channel.write(ChannelBuffers.wrappedBuffer(bytes)); + } + + @Override + protected void close() { + channel.write(ChannelBuffers.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE); + } + + @Override - protected void writeResponseToClient(Response response, ProtocolSession session) { - if (response != null && channel.isConnected()) { - ChannelFuture cf = channel.write(response); - if (response.isEndSession()) { - // close the channel if needed after the message was written out - cf.addListener(ChannelFutureListener.CLOSE); - } - if (response instanceof StartTlsResponse) { - if (isStartTLSSupported()) { - channel.setReadable(false); - SslHandler filter = new SslHandler(engine); - filter.getEngine().setUseClientMode(false); - session.resetState(); - channel.getPipeline().addFirst("sslHandler", filter); - channel.setReadable(true); - } - } - } + protected void writeToClient(InputStream in, ProtocolSession session) { + channel.write(new ChunkedStream(in)); } Modified: james/protocols/trunk/impl/src/main/java/org/apache/james/protocols/impl/NettyServer.java URL: http://svn.apache.org/viewvc/james/protocols/trunk/impl/src/main/java/org/apache/james/protocols/impl/NettyServer.java?rev=1176883&r1=1176882&r2=1176883&view=diff ============================================================================== --- james/protocols/trunk/impl/src/main/java/org/apache/james/protocols/impl/NettyServer.java (original) +++ james/protocols/trunk/impl/src/main/java/org/apache/james/protocols/impl/NettyServer.java Wed Sep 28 13:51:14 2011 @@ -25,7 +25,6 @@ import org.apache.james.protocols.api.Pr import org.jboss.netty.channel.ChannelPipelineFactory; import org.jboss.netty.channel.ChannelUpstreamHandler; import org.jboss.netty.channel.group.ChannelGroup; -import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; import org.jboss.netty.handler.execution.ExecutionHandler; import org.jboss.netty.handler.execution.OrderedMemoryAwareThreadPoolExecutor; import org.slf4j.Logger; @@ -43,8 +42,6 @@ public class NettyServer extends Abstrac protected SSLContext context; private ExecutionHandler eHandler; - - private OneToOneEncoder responseEncoder; private ChannelUpstreamHandler coreHandler; @@ -57,7 +54,6 @@ public class NettyServer extends Abstrac super(); this.protocol = protocol; this.context = context; - this.responseEncoder = new ResponseEncoder(); } protected ExecutionHandler createExecutionHandler(int size) { @@ -99,11 +95,6 @@ public class NettyServer extends Abstrac } @Override - protected OneToOneEncoder createEncoder() { - return responseEncoder; - } - - @Override protected boolean isSSLSocket() { return context != null && !protocol.isStartTLSSupported(); } Modified: james/protocols/trunk/smtp/src/main/java/org/apache/james/protocols/smtp/core/UnknownCmdHandler.java URL: http://svn.apache.org/viewvc/james/protocols/trunk/smtp/src/main/java/org/apache/james/protocols/smtp/core/UnknownCmdHandler.java?rev=1176883&r1=1176882&r2=1176883&view=diff ============================================================================== --- james/protocols/trunk/smtp/src/main/java/org/apache/james/protocols/smtp/core/UnknownCmdHandler.java (original) +++ james/protocols/trunk/smtp/src/main/java/org/apache/james/protocols/smtp/core/UnknownCmdHandler.java Wed Sep 28 13:51:14 2011 @@ -66,7 +66,7 @@ public class UnknownCmdHandler extends A @Override protected HookResult callHook(UnknownHook rawHook, SMTPSession session, String parameters) { - return rawHook.doUnkown(session, (String) session.getState().get("CURR_COMMAND")); + return rawHook.doUnknown(session, (String) session.getState().get("CURR_COMMAND")); } @Override Modified: james/protocols/trunk/smtp/src/main/java/org/apache/james/protocols/smtp/hook/UnknownHook.java URL: http://svn.apache.org/viewvc/james/protocols/trunk/smtp/src/main/java/org/apache/james/protocols/smtp/hook/UnknownHook.java?rev=1176883&r1=1176882&r2=1176883&view=diff ============================================================================== --- james/protocols/trunk/smtp/src/main/java/org/apache/james/protocols/smtp/hook/UnknownHook.java (original) +++ james/protocols/trunk/smtp/src/main/java/org/apache/james/protocols/smtp/hook/UnknownHook.java Wed Sep 28 13:51:14 2011 @@ -34,6 +34,6 @@ public interface UnknownHook extends Hoo * @param command * @return result */ - HookResult doUnkown(SMTPSession session, String command); + HookResult doUnknown(SMTPSession session, String command); } --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org