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.Channel;
18 import org.jboss.netty.channel.ChannelHandlerContext;
19 import org.jboss.netty.handler.codec.replay.ReplayingDecoder;
20 import org.jboss.netty.logging.InternalLogger;
21 import org.jboss.netty.logging.InternalLoggerFactory;
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 public abstract class IcapMessageDecoder extends ReplayingDecoder<StateEnum> {
38
39 private final InternalLogger LOG;
40
41 protected final int maxInitialLineLength;
42 protected final int maxIcapHeaderSize;
43 protected final int maxHttpHeaderSize;
44 protected final int maxChunkSize;
45
46 protected IcapMessage message;
47
48 protected int currentChunkSize;
49
50
51
52
53
54
55
56
57 protected IcapMessageDecoder() {
58 this(4096,8192,8192,8192);
59 }
60
61
62
63
64
65
66
67
68 protected IcapMessageDecoder(int maxInitialLineLength, int maxIcapHeaderSize, int maxHttpHeaderSize, int maxChunkSize) {
69 super(StateEnum.SKIP_CONTROL_CHARS,true);
70 LOG = InternalLoggerFactory.getInstance(getClass());
71 if (maxInitialLineLength <= 0) {
72 throw new IllegalArgumentException("maxInitialLineLength must be a positive integer: " + maxInitialLineLength);
73 }
74 if (maxIcapHeaderSize <= 0) {
75 throw new IllegalArgumentException("maxIcapHeaderSize must be a positive integer: " + maxIcapHeaderSize);
76 }
77 if(maxHttpHeaderSize <= 0) {
78 throw new IllegalArgumentException("maxHttpHeaderSize must be a positive integer: " + maxIcapHeaderSize);
79 }
80 if (maxChunkSize <= 0) {
81 throw new IllegalArgumentException("maxChunkSize must be a positive integer: " + maxChunkSize);
82 }
83 this.maxInitialLineLength = maxInitialLineLength;
84 this.maxIcapHeaderSize = maxIcapHeaderSize;
85 this.maxHttpHeaderSize = maxHttpHeaderSize;
86 this.maxChunkSize = maxChunkSize;
87 }
88
89 @SuppressWarnings({ "rawtypes", "unchecked" })
90 @Override
91 protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, StateEnum stateEnumValue) throws Exception {
92 if(stateEnumValue != null) {
93 try {
94 State state = stateEnumValue.getState();
95 LOG.debug("Executing state [" + state + ']');
96 state.onEntry(buffer,this);
97 StateReturnValue returnValue = state.execute(buffer,this);
98 LOG.debug("Return value from state [" + state + "] = [" + returnValue + "]");
99 StateEnum nextState = state.onExit(buffer,this,returnValue.getDecisionInformation());
100 LOG.debug("Next State [" + nextState + "]");
101 if(nextState != null) {
102 checkpoint(nextState);
103 } else {
104 reset();
105 }
106 if(returnValue.isRelevant()) {
107 return returnValue.getValue();
108 }
109 } catch(DecodingException e) {
110 reset();
111 throw e;
112 }
113 }
114 return null;
115 }
116
117
118
119
120 private void reset() {
121 this.message = null;
122 checkpoint(StateEnum.SKIP_CONTROL_CHARS);
123 }
124
125 public abstract boolean isDecodingResponse();
126
127 protected abstract IcapMessage createMessage(String[] initialLine);
128 }