1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.mimo.netty.handler.codec.icap;
15
16 import org.jboss.netty.buffer.ChannelBuffer;
17 import org.jboss.netty.channel.ChannelDownstreamHandler;
18 import org.jboss.netty.channel.ChannelEvent;
19 import org.jboss.netty.channel.ChannelHandlerContext;
20 import org.jboss.netty.channel.DownstreamMessageEvent;
21 import org.jboss.netty.channel.MessageEvent;
22 import org.jboss.netty.logging.InternalLogger;
23 import org.jboss.netty.logging.InternalLoggerFactory;
24
25
26
27
28
29
30
31
32
33
34
35
36
37 public class IcapChunkSeparator implements ChannelDownstreamHandler {
38
39 private static final InternalLogger LOG = InternalLoggerFactory.getInstance(IcapChunkSeparator.class);
40
41 private int chunkSize;
42
43
44
45
46 public IcapChunkSeparator(int chunkSize) {
47 this.chunkSize = chunkSize;
48 }
49
50 @Override
51 public void handleDownstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception {
52 if (e instanceof MessageEvent) {
53 MessageEvent msgEvent = (MessageEvent)e;
54 Object msg = msgEvent.getMessage();
55 if(msg instanceof IcapMessage) {
56 LOG.debug("Separation of message [" + msg.getClass().getName() + "] ");
57 IcapMessage message = (IcapMessage)msg;
58 ChannelBuffer content = extractContentFromMessage(message);
59 fireDownstreamEvent(ctx,message,msgEvent);
60 if(content != null) {
61 boolean isPreview = message.isPreviewMessage();
62 boolean isEarlyTerminated = false;
63 if(isPreview) {
64 isEarlyTerminated = content.readableBytes() < message.getPreviewAmount();
65 }
66 while(content.readableBytes() > 0) {
67 IcapChunk chunk = null;
68 if(content.readableBytes() > chunkSize) {
69 chunk = new DefaultIcapChunk(content.readBytes(chunkSize));
70 } else {
71 chunk = new DefaultIcapChunk(content.readBytes(content.readableBytes()));
72 }
73 chunk.setPreviewChunk(isPreview);
74 chunk.setEarlyTermination(isEarlyTerminated);
75 fireDownstreamEvent(ctx,chunk,msgEvent);
76 if(chunk.isLast() | content.readableBytes() <= 0) {
77 IcapChunkTrailer trailer = new DefaultIcapChunkTrailer();
78 trailer.setPreviewChunk(isPreview);
79 trailer.setEarlyTermination(isEarlyTerminated);
80 fireDownstreamEvent(ctx,trailer,msgEvent);
81 }
82 }
83 }
84 } else {
85 ctx.sendDownstream(e);
86 }
87 } else {
88 ctx.sendDownstream(e);
89 }
90 }
91
92 private ChannelBuffer extractContentFromMessage(IcapMessage message) {
93 ChannelBuffer content = null;
94 if(message instanceof IcapResponse && ((IcapResponse)message).getContent() != null) {
95 IcapResponse response = (IcapResponse)message;
96 content = response.getContent();
97 if(content != null) {
98 message.setBody(IcapMessageElementEnum.OPTBODY);
99 }
100 } else if(message.getHttpRequest() != null && message.getHttpRequest().getContent() != null && message.getHttpRequest().getContent().readableBytes() > 0) {
101 content = message.getHttpRequest().getContent();
102 message.setBody(IcapMessageElementEnum.REQBODY);
103 } else if(message.getHttpResponse() != null && message.getHttpResponse().getContent() != null && message.getHttpResponse().getContent().readableBytes() > 0) {
104 content = message.getHttpResponse().getContent();
105 message.setBody(IcapMessageElementEnum.RESBODY);
106 }
107 return content;
108 }
109
110 private void fireDownstreamEvent(ChannelHandlerContext ctx, Object message, MessageEvent messageEvent) {
111 DownstreamMessageEvent downstreamMessageEvent =
112 new DownstreamMessageEvent(ctx.getChannel(),messageEvent.getFuture(),message,messageEvent.getRemoteAddress());
113 ctx.sendDownstream(downstreamMessageEvent);
114 }
115 }