ch.mimo.netty.handler.codec.icap.IcapMessageEncoder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of netty-icap Show documentation
Show all versions of netty-icap Show documentation
ICAP Codec implementation for JBoss Netty
The newest version!
/*******************************************************************************
* Copyright (c) 2012 Michael Mimo Moratti.
*
* Michael Mimo Moratti 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 ch.mimo.netty.handler.codec.icap;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpResponse;
import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
import org.jboss.netty.logging.InternalLogger;
import org.jboss.netty.logging.InternalLoggerFactory;
/**
* Main ICAP message encoder. This encoder is based on @see {@link OneToOneEncoder}
*
* @author Michael Mimo Moratti ([email protected])
*
* @see IcapRequestEncoder
* @see IcapResponseEncoder
*/
public abstract class IcapMessageEncoder extends OneToOneEncoder {
private final InternalLogger LOG;
public IcapMessageEncoder() {
LOG = InternalLoggerFactory.getInstance(getClass());
}
@Override
protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception {
LOG.debug("Encoding [" + msg.getClass().getName() + "]");
if(msg instanceof IcapMessage) {
IcapMessage message = (IcapMessage)msg;
ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(channel.getConfig().getBufferFactory());
encodeInitialLine(buffer,message);
encodeHeaders(buffer,message);
ChannelBuffer httpRequestBuffer = encodeHttpRequestHeader(message.getHttpRequest());
ChannelBuffer httpResponseBuffer = encodeHttpResponseHeader(message.getHttpResponse());
int index = 0;
Encapsulated encapsulated = new Encapsulated();
if(httpRequestBuffer.readableBytes() > 0) {
encapsulated.addEntry(IcapMessageElementEnum.REQHDR,index);
httpRequestBuffer.writeBytes(IcapCodecUtil.CRLF);
index += httpRequestBuffer.readableBytes();
}
if(httpResponseBuffer.readableBytes() > 0) {
encapsulated.addEntry(IcapMessageElementEnum.RESHDR,index);
httpResponseBuffer.writeBytes(IcapCodecUtil.CRLF);
index += httpResponseBuffer.readableBytes();
}
if(message.getBodyType() != null) {
encapsulated.addEntry(message.getBodyType(),index);
} else {
encapsulated.addEntry(IcapMessageElementEnum.NULLBODY,index);
}
encapsulated.encode(buffer);
buffer.writeBytes(httpRequestBuffer);
buffer.writeBytes(httpResponseBuffer);
return buffer;
} else if(msg instanceof IcapChunk) {
ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(channel.getConfig().getBufferFactory());
IcapChunk chunk = (IcapChunk)msg;
if(chunk.isLast()) {
if(chunk.isEarlyTerminated()) {
buffer.writeBytes(IcapCodecUtil.NATIVE_IEOF_SEQUENCE);
buffer.writeBytes(IcapCodecUtil.CRLF);
buffer.writeBytes(IcapCodecUtil.CRLF);
} else if(msg instanceof IcapChunkTrailer) {
buffer.writeByte((byte) '0');
buffer.writeBytes(IcapCodecUtil.CRLF);
encodeTrailingHeaders(buffer,(IcapChunkTrailer)msg);
buffer.writeBytes(IcapCodecUtil.CRLF);
} else {
buffer.writeByte((byte) '0');
buffer.writeBytes(IcapCodecUtil.CRLF);
buffer.writeBytes(IcapCodecUtil.CRLF);
}
} else {
ChannelBuffer chunkBuffer = chunk.getContent();
int contentLength = chunkBuffer.readableBytes();
buffer.writeBytes(Integer.toHexString(contentLength).getBytes(IcapCodecUtil.ASCII_CHARSET));
buffer.writeBytes(IcapCodecUtil.CRLF);
buffer.writeBytes(chunkBuffer);
buffer.writeBytes(IcapCodecUtil.CRLF);
}
return buffer;
}
return null;
}
protected abstract int encodeInitialLine(ChannelBuffer buffer, IcapMessage message) throws Exception;
private ChannelBuffer encodeHttpRequestHeader(HttpRequest httpRequest) throws UnsupportedEncodingException {
ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
if(httpRequest != null) {
buffer.writeBytes(httpRequest.getMethod().toString().getBytes(IcapCodecUtil.ASCII_CHARSET));
buffer.writeByte(IcapCodecUtil.SPACE);
buffer.writeBytes(httpRequest.getUri().getBytes(IcapCodecUtil.ASCII_CHARSET));
buffer.writeByte(IcapCodecUtil.SPACE);
buffer.writeBytes(httpRequest.getProtocolVersion().toString().getBytes(IcapCodecUtil.ASCII_CHARSET));
buffer.writeBytes(IcapCodecUtil.CRLF);
for (Map.Entry h: httpRequest.getHeaders()) {
encodeHeader(buffer, h.getKey(), h.getValue());
}
}
return buffer;
}
private ChannelBuffer encodeHttpResponseHeader(HttpResponse httpResponse) throws UnsupportedEncodingException {
ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
if(httpResponse != null) {
buffer.writeBytes(httpResponse.getProtocolVersion().toString().getBytes(IcapCodecUtil.ASCII_CHARSET));
buffer.writeByte(IcapCodecUtil.SPACE);
buffer.writeBytes(httpResponse.getStatus().toString().getBytes(IcapCodecUtil.ASCII_CHARSET));
buffer.writeBytes(IcapCodecUtil.CRLF);
for (Map.Entry h: httpResponse.getHeaders()) {
encodeHeader(buffer, h.getKey(), h.getValue());
}
}
return buffer;
}
private int encodeTrailingHeaders(ChannelBuffer buffer, IcapChunkTrailer chunkTrailer) {
int index = buffer.readableBytes();
for (Map.Entry h: chunkTrailer.getHeaders()) {
encodeHeader(buffer, h.getKey(), h.getValue());
}
return buffer.readableBytes() - index;
}
private int encodeHeaders(ChannelBuffer buffer, IcapMessage message) {
int index = buffer.readableBytes();
for (Map.Entry h: message.getHeaders()) {
encodeHeader(buffer, h.getKey(), h.getValue());
}
return buffer.readableBytes() - index;
}
private void encodeHeader(ChannelBuffer buf, String header, String value) {
buf.writeBytes(header.getBytes(IcapCodecUtil.ASCII_CHARSET));
buf.writeByte(IcapCodecUtil.COLON);
buf.writeByte(IcapCodecUtil.SPACE);
buf.writeBytes(value.getBytes(IcapCodecUtil.ASCII_CHARSET));
buf.writeBytes(IcapCodecUtil.CRLF);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy