From 1a96b48026488696ec35055532efb5f658615689 Mon Sep 17 00:00:00 2001 From: Andy Taylor Date: Mon, 16 Feb 2009 10:21:44 +0000 Subject: [PATCH] added ClientSocketChannelFactory to ServletClientSocketChannelFactory constructor --- .../servlet/ServletClientSocketChannel.java | 299 ++++++++---------- .../ServletClientSocketChannelFactory.java | 6 +- .../example/servlet/ServletClientExample.java | 3 +- .../codec/http/DefaultHttpMessage.java | 17 + .../handler/codec/http/HttpCodecUtil.java | 5 + .../netty/handler/codec/http/HttpCookie.java | 45 +++ .../netty/handler/codec/http/HttpMessage.java | 10 + .../codec/http/HttpMessageDecoder.java | 1 + .../codec/http/HttpMessageEncoder.java | 22 ++ .../codec/http/HttpRequestDecoder.java | 5 + .../codec/http/HttpRequestEncoder.java | 5 +- .../codec/http/HttpResponseDecoder.java | 5 + .../codec/http/HttpResponseEncoder.java | 6 + .../servlet/NettyServletContextListener.java | 2 + .../netty/servlet/NettySessionListener.java | 2 +- 15 files changed, 265 insertions(+), 168 deletions(-) create mode 100644 src/main/java/org/jboss/netty/handler/codec/http/HttpCookie.java diff --git a/src/main/java/org/jboss/netty/channel/socket/servlet/ServletClientSocketChannel.java b/src/main/java/org/jboss/netty/channel/socket/servlet/ServletClientSocketChannel.java index 031ab17d8e..4cc68cc2cf 100644 --- a/src/main/java/org/jboss/netty/channel/socket/servlet/ServletClientSocketChannel.java +++ b/src/main/java/org/jboss/netty/channel/socket/servlet/ServletClientSocketChannel.java @@ -22,29 +22,36 @@ */ package org.jboss.netty.channel.socket.servlet; -import static org.jboss.netty.channel.Channels.*; -import static org.jboss.netty.channel.socket.servlet.ServletClientSocketPipelineSink.*; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.PushbackInputStream; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.net.SocketAddress; -import java.net.SocketException; -import java.net.URL; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.AbstractChannel; import org.jboss.netty.channel.ChannelFactory; import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelSink; +import static org.jboss.netty.channel.Channels.fireChannelOpen; +import static org.jboss.netty.channel.Channels.pipeline; +import org.jboss.netty.channel.DefaultChannelPipeline; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.channel.SimpleChannelHandler; +import org.jboss.netty.channel.ExceptionEvent; +import org.jboss.netty.channel.ChannelStateEvent; +import org.jboss.netty.channel.ChannelPipelineCoverage; +import org.jboss.netty.channel.socket.ClientSocketChannelFactory; +import org.jboss.netty.channel.socket.SocketChannel; import org.jboss.netty.channel.socket.SocketChannelConfig; +import static org.jboss.netty.channel.socket.servlet.ServletClientSocketPipelineSink.LINE_TERMINATOR; +import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder; +import org.jboss.netty.handler.codec.frame.Delimiters; +import org.jboss.netty.util.LinkedTransferQueue; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.net.URL; +import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.locks.Lock; /** * @author The Netty Project (netty-dev@lists.jboss.org) @@ -52,58 +59,67 @@ import org.jboss.netty.channel.socket.SocketChannelConfig; * @version $Rev$, $Date$ */ class ServletClientSocketChannel extends AbstractChannel - implements org.jboss.netty.channel.socket.SocketChannel { + implements org.jboss.netty.channel.socket.SocketChannel { - private final Lock lock = new ReentrantLock(); + private final Lock reconnectLock = new ReentrantLock(); + + private volatile boolean awaitingInitialResponse = true; private final Object writeLock = new Object(); - private Socket socket; - - private ServletSocketChannelConfig config; - volatile Thread workerThread; - private volatile PushbackInputStream in; - - private volatile OutputStream out; - private String sessionId; private boolean closed = false; + LinkedTransferQueue messages = new LinkedTransferQueue(); + private final URL url; + private ClientSocketChannelFactory clientSocketChannelFactory; + + private SocketChannel channel; + + private DelimiterBasedFrameDecoder handler = new DelimiterBasedFrameDecoder(8092, ChannelBuffers.wrappedBuffer(new byte[] { '\r', '\n' })); + + private ServletClientSocketChannel.ServletChannelHandler servletHandler = new ServletChannelHandler(); + ServletClientSocketChannel( - ChannelFactory factory, - ChannelPipeline pipeline, - ChannelSink sink, URL url) { + ChannelFactory factory, + ChannelPipeline pipeline, + ChannelSink sink, URL url, ClientSocketChannelFactory clientSocketChannelFactory) { super(null, factory, pipeline, sink); this.url = url; - socket = new Socket(); - config = new ServletSocketChannelConfig(socket); + this.clientSocketChannelFactory = clientSocketChannelFactory; + + DefaultChannelPipeline channelPipeline = new DefaultChannelPipeline(); + channelPipeline.addLast("DelimiterBasedFrameDecoder", handler); + channelPipeline.addLast("servletHandler", servletHandler); + channel = clientSocketChannelFactory.newChannel(channelPipeline); + fireChannelOpen(this); } public SocketChannelConfig getConfig() { - return config; + return channel.getConfig(); } public InetSocketAddress getLocalAddress() { - return (InetSocketAddress) socket.getLocalSocketAddress(); + return channel.getLocalAddress(); } public InetSocketAddress getRemoteAddress() { - return (InetSocketAddress) socket.getRemoteSocketAddress(); + return channel.getRemoteAddress(); } public boolean isBound() { - return isOpen() && socket.isBound(); + return channel.isOpen(); } public boolean isConnected() { - return isOpen() && socket.isConnected(); + return channel.isConnected(); } @Override @@ -126,172 +142,129 @@ class ServletClientSocketChannel extends AbstractChannel } } - PushbackInputStream getInputStream() { - return in; - } - - - OutputStream getOutputStream() { - return out; - } - void connectAndSendHeaders(boolean reconnect, SocketAddress remoteAddress) throws IOException { if (reconnect) { - System.out.println("reconnecting"); - socket.close(); - socket = new Socket(); - config = config.copyConfig(socket); + DefaultChannelPipeline channelPipeline = new DefaultChannelPipeline(); + channelPipeline.addLast("DelimiterBasedFrameDecoder", handler); + channelPipeline.addLast("servletHandler", servletHandler); + channel = clientSocketChannelFactory.newChannel(channelPipeline); } - socket.connect( - remoteAddress, getConfig().getConnectTimeoutMillis()); - - // Obtain I/O stream. - in = new PushbackInputStream(socket.getInputStream(), 1); - out = socket.getOutputStream(); - //write and read headers + channel.connect(remoteAddress); StringBuilder builder = new StringBuilder(); builder.append("POST ").append(url.toExternalForm()).append(" HTTP/1.1").append(LINE_TERMINATOR). - append("HOST: ").append(url.getHost()).append(":").append(url.getPort()).append(LINE_TERMINATOR). - append("Content-Type: application/octet-stream").append(LINE_TERMINATOR).append("Transfer-Encoding: chunked"). - append(LINE_TERMINATOR).append("Content-Transfer-Encoding: Binary").append(LINE_TERMINATOR).append("Connection: Keep-Alive"). - append(LINE_TERMINATOR); + append("HOST: ").append(url.getHost()).append(":").append(url.getPort()).append(LINE_TERMINATOR). + append("Content-Type: application/octet-stream").append(LINE_TERMINATOR).append("Transfer-Encoding: chunked"). + append(LINE_TERMINATOR).append("Content-Transfer-Encoding: Binary").append(LINE_TERMINATOR).append("Connection: Keep-Alive"). + append(LINE_TERMINATOR); if (reconnect) { builder.append("Cookie: JSESSIONID=").append(sessionId).append(LINE_TERMINATOR); } builder.append(LINE_TERMINATOR); String msg = builder.toString(); - socket.getOutputStream().write(msg.getBytes("ASCII7")); - BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); - String line; - while ((line = br.readLine()) != null) { - - if (!reconnect) { - if (line.contains("Set-Cookie")) { - int start = line.indexOf("JSESSIONID=") + 11; - int end = line.indexOf(";", start); - sessionId = line.substring(start, end); - } - } - if (line.equals(LINE_TERMINATOR) || line.equals("")) { - break; - } - } + channel.write(ChannelBuffers.wrappedBuffer(msg.getBytes("ASCII7"))); } public void sendChunk(ChannelBuffer a) throws IOException { int size = a.readableBytes(); String hex = Integer.toHexString(size) + LINE_TERMINATOR; - try { - synchronized (writeLock) { - out.write(hex.getBytes()); - a.getBytes(a.readerIndex(), out, a.readableBytes()); - out.write(LINE_TERMINATOR.getBytes()); - } - } - catch (SocketException e) { - if (closed) { - throw e; - } - if (lock.tryLock()) { - try { - connectAndSendHeaders(true, getRemoteAddress()); - } - finally { - lock.unlock(); - } - } - else { - try { - lock.lock(); - } - finally { - lock.unlock(); - } - } + // try { + synchronized (writeLock) { + a.writeBytes(LINE_TERMINATOR.getBytes()); + channel.write(ChannelBuffers.wrappedBuffer(hex.getBytes())); + channel.write(a).awaitUninterruptibly(); + //channel.write(ChannelBuffers.wrappedBuffer(LINE_TERMINATOR.getBytes())); } } public byte[] receiveChunk() throws IOException { - byte[] buf; - + byte[] buf = null; try { - buf = read(); + buf = messages.take(); } - catch (SocketException e) { - if (closed) { - throw e; + catch (InterruptedException e) { + e.printStackTrace(); + } + return buf; + } + + private void reConnect() throws Exception{ + if (closed) { + throw new IllegalStateException("channel closed"); } - if (lock.tryLock()) { + if (reconnectLock.tryLock()) { try { - connectAndSendHeaders(true, socket.getRemoteSocketAddress()); + awaitingInitialResponse = true; + + connectAndSendHeaders(true, channel.getRemoteAddress()); } finally { - lock.unlock(); + reconnectLock.unlock(); } } else { try { - lock.lock(); + reconnectLock.lock(); } finally { - lock.unlock(); + reconnectLock.unlock(); } } - buf = read(); - } - return buf; - } - - private byte[] read() throws IOException { - // - byte[] buf; - StringBuffer hex = new StringBuffer(); - int b; - while ((b = in.read()) != -1) { - if (b == 13) { - int end = in.read(); - if (end != 10) { - in.unread(end); - } - break; - } - hex.append((char) b); - } - int bytesToRead = Integer.parseInt(hex.toString(), 16); - - buf = new byte[bytesToRead]; - - if (in.available() >= bytesToRead) { - in.read(buf, 0, bytesToRead); - } - else { - int readBytes = 0; - do { - readBytes += in.read(buf, readBytes, bytesToRead - readBytes); - } - while (bytesToRead != readBytes); - } - int end = in.read(); - if (end != 13) { - in.unread(end); - } - else { - end = in.read(); - if (end != 10) { - in.unread(end); - } - } - return buf; } public void closeSocket() throws IOException { - setClosed(); - closed = true; - socket.close(); + setClosed(); + closed = true; + channel.close(); } public void bindSocket(SocketAddress localAddress) throws IOException { - socket.bind(localAddress); + channel.bind(localAddress); + } + + @ChannelPipelineCoverage("one") + class ServletChannelHandler extends SimpleChannelHandler { + int nextChunkSize = -1; + + + public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { + ChannelBuffer buf = (ChannelBuffer) e.getMessage(); + byte[] bytes = new byte[buf.readableBytes()]; + buf.getBytes(0, bytes); + if (awaitingInitialResponse) { + String line = new String(bytes); + if (line.contains("Set-Cookie")) { + int start = line.indexOf("JSESSIONID=") + 11; + int end = line.indexOf(";", start); + sessionId = line.substring(start, end); + } + else if (line.equals("")) { + awaitingInitialResponse = false; + } + } + else { + if(nextChunkSize == -1) { + String hex = new String(bytes); + nextChunkSize = Integer.parseInt(hex, 16); + if(nextChunkSize == 0) { + if(!closed) { + nextChunkSize = -1; + awaitingInitialResponse = true; + reConnect(); + } + } + } + else { + messages.put(bytes); + nextChunkSize = -1; + } + } + + } + + public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception { + channel.close(); + } + } } \ No newline at end of file diff --git a/src/main/java/org/jboss/netty/channel/socket/servlet/ServletClientSocketChannelFactory.java b/src/main/java/org/jboss/netty/channel/socket/servlet/ServletClientSocketChannelFactory.java index 24a51ed0b1..cedcfb708f 100644 --- a/src/main/java/org/jboss/netty/channel/socket/servlet/ServletClientSocketChannelFactory.java +++ b/src/main/java/org/jboss/netty/channel/socket/servlet/ServletClientSocketChannelFactory.java @@ -41,13 +41,15 @@ public class ServletClientSocketChannelFactory implements ClientSocketChannelFac private final Executor workerExecutor; private final ChannelSink sink; private final URL url; + ClientSocketChannelFactory clientSocketChannelFactory; /** * * @param workerExecutor */ - public ServletClientSocketChannelFactory(Executor workerExecutor, URL url) { + public ServletClientSocketChannelFactory(ClientSocketChannelFactory clientSocketChannelFactory, Executor workerExecutor, URL url) { this(url, workerExecutor, Runtime.getRuntime().availableProcessors()); + this.clientSocketChannelFactory = clientSocketChannelFactory; } /** @@ -80,7 +82,7 @@ public class ServletClientSocketChannelFactory implements ClientSocketChannelFac } public SocketChannel newChannel(ChannelPipeline pipeline) { - return new ServletClientSocketChannel(this, pipeline, sink, url); + return new ServletClientSocketChannel(this, pipeline, sink, url, clientSocketChannelFactory); } public void releaseExternalResources() { diff --git a/src/main/java/org/jboss/netty/example/servlet/ServletClientExample.java b/src/main/java/org/jboss/netty/example/servlet/ServletClientExample.java index 0a17a3698f..68b6a1e574 100644 --- a/src/main/java/org/jboss/netty/example/servlet/ServletClientExample.java +++ b/src/main/java/org/jboss/netty/example/servlet/ServletClientExample.java @@ -33,6 +33,7 @@ import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelPipelineCoverage; import org.jboss.netty.channel.socket.servlet.ServletClientSocketChannelFactory; +import org.jboss.netty.channel.socket.oio.OioClientSocketChannelFactory; import org.jboss.netty.handler.codec.oneone.OneToOneDecoder; import org.jboss.netty.handler.codec.string.StringDecoder; import org.jboss.netty.handler.codec.string.StringEncoder; @@ -86,7 +87,7 @@ import org.jboss.netty.handler.codec.string.StringEncoder; public class ServletClientExample { public static void main(String[] args) throws Exception { URL url = new URL("http", "localhost", 8080, "/netty/nettyServlet"); - ServletClientSocketChannelFactory factory = new ServletClientSocketChannelFactory(Executors.newCachedThreadPool(), url); + ServletClientSocketChannelFactory factory = new ServletClientSocketChannelFactory(new OioClientSocketChannelFactory(Executors.newCachedThreadPool()), Executors.newCachedThreadPool(), url); ClientBootstrap bootstrap = new ClientBootstrap(factory); bootstrap.getPipeline().addLast("decoder", new StringDecoder()); bootstrap.getPipeline().addLast("encoder", new StringEncoder()); diff --git a/src/main/java/org/jboss/netty/handler/codec/http/DefaultHttpMessage.java b/src/main/java/org/jboss/netty/handler/codec/http/DefaultHttpMessage.java index 6cd35e1f5d..b4508ba5e6 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/DefaultHttpMessage.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/DefaultHttpMessage.java @@ -28,6 +28,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; +import java.util.Collection; import org.jboss.netty.buffer.ChannelBuffer; @@ -44,6 +45,7 @@ public class DefaultHttpMessage implements HttpMessage { private final HttpVersion version; private final Map> headers = new TreeMap>(caseIgnoringComparator); + private final Map cookies = new TreeMap(caseIgnoringComparator); private ChannelBuffer content; protected DefaultHttpMessage(final HttpVersion version) { @@ -140,6 +142,21 @@ public class DefaultHttpMessage implements HttpMessage { return content; } + public void addCookie(HttpCookie cookie) { + cookies.put(cookie.getName(), cookie); + } + + public HttpCookie getCookie(String name) { + return cookies.get(name); + } + + public Collection getCookies() { + return cookies.values(); + } + public Collection getCookieNames() { + return cookies.keySet(); + } + private static final class CaseIgnoringComparator implements Comparator, Serializable { diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpCodecUtil.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpCodecUtil.java index 42d81fa818..18c79019c4 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpCodecUtil.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpCodecUtil.java @@ -58,6 +58,11 @@ class HttpCodecUtil { */ static final byte COLON = 58; + /** + * Semicolon ';' + */ + static final byte SEMICOLON = 59; + private HttpCodecUtil() { super(); } diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpCookie.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpCookie.java new file mode 100644 index 0000000000..30e44cdc97 --- /dev/null +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpCookie.java @@ -0,0 +1,45 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.netty.handler.codec.http; + +/** + * @author Andy Taylor + */ +public class HttpCookie { + + private final String name; + + private final String value; + + public HttpCookie(String name, String value) { + this.name = name; + this.value = value; + } + + public String getName() { + return name; + } + + public String getValue() { + return value; + } +} \ No newline at end of file diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpMessage.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpMessage.java index ac46a309c5..e77b8a8d33 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpMessage.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpMessage.java @@ -23,6 +23,7 @@ package org.jboss.netty.handler.codec.http; import java.util.List; import java.util.Set; +import java.util.Collection; import org.jboss.netty.buffer.ChannelBuffer; @@ -64,4 +65,13 @@ public interface HttpMessage { boolean isChunked(); void clearHeaders(); + + void addCookie(HttpCookie cookie); + + HttpCookie getCookie(String name); + + Collection getCookies(); + + Collection getCookieNames(); + } diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageDecoder.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageDecoder.java index ef36611dce..d31fa4a9af 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageDecoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageDecoder.java @@ -258,6 +258,7 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder cookieNames = message.getCookieNames(); + if(cookieNames.isEmpty()) { + return; + } + buf.writeBytes(getCookieHeaderName()); + buf.writeByte(COLON); + buf.writeByte(SP); + for (String cookieName : cookieNames) { + buf.writeBytes(cookieName.getBytes()); + buf.writeByte(EQUALS); + buf.writeBytes(message.getCookie(cookieName).getValue().getBytes()); + buf.writeByte(SEMICOLON); + } + buf.writeBytes(CRLF); + } + + public abstract byte[] getCookieHeaderName(); + protected abstract void encodeInitialLine(ChannelBuffer buf, HttpMessage message) throws Exception; } diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpRequestDecoder.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpRequestDecoder.java index 08c94359e8..0b492b96b3 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpRequestDecoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpRequestDecoder.java @@ -54,4 +54,9 @@ public class HttpRequestDecoder extends HttpMessageDecoder { protected boolean isDecodingRequest() { return true; } + + @Override + protected String getCookieHeaderName() { + return "Cookie"; + } } diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpRequestEncoder.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpRequestEncoder.java index 0250c875c2..c2d5111cf8 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpRequestEncoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpRequestEncoder.java @@ -34,7 +34,7 @@ import org.jboss.netty.buffer.ChannelBuffer; * @version $Rev$, $Date$ */ public class HttpRequestEncoder extends HttpMessageEncoder { - + private static final byte[] COOKIE_HEADER = "Cookie".getBytes(); /** * writes the initial line i.e. 'GET /path/to/file/index.html HTTP/1.0' */ @@ -49,4 +49,7 @@ public class HttpRequestEncoder extends HttpMessageEncoder { buf.writeBytes(CRLF); } + public byte[] getCookieHeaderName() { + return COOKIE_HEADER; + } } diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseDecoder.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseDecoder.java index d5b55bb85d..8f97f9476a 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseDecoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseDecoder.java @@ -53,4 +53,9 @@ public class HttpResponseDecoder extends HttpMessageDecoder { protected boolean isDecodingRequest() { return false; } + + @Override + protected String getCookieHeaderName() { + return "Set-Cookie"; + } } diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseEncoder.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseEncoder.java index 9167c5c0f2..d453b11433 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseEncoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseEncoder.java @@ -34,6 +34,8 @@ import org.jboss.netty.buffer.ChannelBuffer; * @version $Rev$, $Date$ */ public class HttpResponseEncoder extends HttpMessageEncoder { + private static final byte[] COOKIE_HEADER = "Set Cookie: ".getBytes(); + @Override protected void encodeInitialLine(ChannelBuffer buf, HttpMessage message) { HttpResponse response = (HttpResponse) message; @@ -44,4 +46,8 @@ public class HttpResponseEncoder extends HttpMessageEncoder { buf.writeBytes(String.valueOf(response.getStatus().getReasonPhrase()).getBytes()); buf.writeBytes(CRLF); } + + public byte[] getCookieHeaderName() { + return COOKIE_HEADER; + } } diff --git a/src/main/java/org/jboss/netty/servlet/NettyServletContextListener.java b/src/main/java/org/jboss/netty/servlet/NettyServletContextListener.java index 237c05778b..bfeebe4a76 100644 --- a/src/main/java/org/jboss/netty/servlet/NettyServletContextListener.java +++ b/src/main/java/org/jboss/netty/servlet/NettyServletContextListener.java @@ -58,6 +58,8 @@ public class NettyServletContextListener implements ServletContextListener { context.getServletContext().setAttribute(RECONNECT_PROP, timeoutParam == null?DEFAULT_RECONNECT_TIMEOUT:Long.decode(timeoutParam.trim())); String streaming = context.getServletContext().getInitParameter(STREAMING_PROP); context.getServletContext().setAttribute(STREAMING_PROP, streaming == null?DEFAULT_IS_STREAMING: Boolean.valueOf(streaming.trim())); + String serverChannel = context.getServletContext().getInitParameter(SERVER_CHANNEL_PROP); + context.getServletContext().setAttribute(SERVER_CHANNEL_PROP, serverChannel); } public void contextDestroyed(ServletContextEvent context) { diff --git a/src/main/java/org/jboss/netty/servlet/NettySessionListener.java b/src/main/java/org/jboss/netty/servlet/NettySessionListener.java index dc90906c8b..c8952c2a53 100644 --- a/src/main/java/org/jboss/netty/servlet/NettySessionListener.java +++ b/src/main/java/org/jboss/netty/servlet/NettySessionListener.java @@ -62,7 +62,7 @@ public class NettySessionListener implements HttpSessionListener, ChannelHandler return pipeline; } }); - ChannelFuture future = bootstrap.connect(new LocalAddress("netty")); + ChannelFuture future = bootstrap.connect(new LocalAddress((String) session.getServletContext().getAttribute(SERVER_CHANNEL_PROP))); future.awaitUninterruptibly(); final Channel ch = future.getChannel(); session.setAttribute(CHANNEL_PROP, ch);