diff --git a/src/main/java/ch/mimo/netty/handler/codec/icap/DefaultIcapChunk.java b/src/main/java/ch/mimo/netty/handler/codec/icap/DefaultIcapChunk.java index 5c77eb7..ca43dfc 100644 --- a/src/main/java/ch/mimo/netty/handler/codec/icap/DefaultIcapChunk.java +++ b/src/main/java/ch/mimo/netty/handler/codec/icap/DefaultIcapChunk.java @@ -51,6 +51,6 @@ public boolean isEarlyTerminated() { } public String toString() { - return "DeafultIcapChunk: [isPreviewChunk=" + preview + "] [wasEarlyTerminated=" + earlyTerminated + "] [data=" + getContent().readableBytes() + "]"; + return "DefaultIcapChunk: [isPreviewChunk=" + preview + "] [wasEarlyTerminated=" + earlyTerminated + "] [data=" + getContent().readableBytes() + "]"; } } diff --git a/src/main/java/ch/mimo/netty/handler/codec/icap/DefaultIcapChunkTrailer.java b/src/main/java/ch/mimo/netty/handler/codec/icap/DefaultIcapChunkTrailer.java index 0b0223f..8b0bf84 100644 --- a/src/main/java/ch/mimo/netty/handler/codec/icap/DefaultIcapChunkTrailer.java +++ b/src/main/java/ch/mimo/netty/handler/codec/icap/DefaultIcapChunkTrailer.java @@ -63,6 +63,6 @@ public boolean isEarlyTerminated() { } public String toString() { - return "DeafultIcapChunkTrailer: [isPreviewChunk=" + preview + "] [wasEarlyTerminated=" + earlyTerminated + "]"; + return "DefaultIcapChunkTrailer: [isPreviewChunk=" + preview + "] [wasEarlyTerminated=" + earlyTerminated + "]"; } } diff --git a/src/main/java/ch/mimo/netty/handler/codec/icap/IcapChunkAggregator.java b/src/main/java/ch/mimo/netty/handler/codec/icap/IcapChunkAggregator.java index fa64fb5..dbaed2c 100644 --- a/src/main/java/ch/mimo/netty/handler/codec/icap/IcapChunkAggregator.java +++ b/src/main/java/ch/mimo/netty/handler/codec/icap/IcapChunkAggregator.java @@ -116,6 +116,10 @@ public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Ex ctx.sendUpstream(e); } else { IcapChunkTrailer trailer = (IcapChunkTrailer)msg; + if (trailer.isEarlyTerminated()) { + LOG.debug("chunk trailer is early terminated, removing PREVIEW header"); + message.getIcapMessage().removeHeader(IcapHeaders.Names.PREVIEW); + } if(trailer.getHeaderNames().size() > 0) { for(String name : trailer.getHeaderNames()) { message.addHeader(name,trailer.getHeader(name)); diff --git a/src/main/java/ch/mimo/netty/handler/codec/icap/IcapHeaders.java b/src/main/java/ch/mimo/netty/handler/codec/icap/IcapHeaders.java index 01a145f..399521b 100644 --- a/src/main/java/ch/mimo/netty/handler/codec/icap/IcapHeaders.java +++ b/src/main/java/ch/mimo/netty/handler/codec/icap/IcapHeaders.java @@ -334,6 +334,9 @@ public void removeHeader(String name) { after.before = before; entry = after; } else { + if (head == entry) { + head = entry.before; + } entry = null; } } else { diff --git a/src/main/java/ch/mimo/netty/handler/codec/icap/ReadIcapHeaderState.java b/src/main/java/ch/mimo/netty/handler/codec/icap/ReadIcapHeaderState.java index 45d7698..7be84b1 100644 --- a/src/main/java/ch/mimo/netty/handler/codec/icap/ReadIcapHeaderState.java +++ b/src/main/java/ch/mimo/netty/handler/codec/icap/ReadIcapHeaderState.java @@ -63,7 +63,7 @@ public StateReturnValue execute(ChannelBuffer buffer, IcapMessageDecoder icapMes } if(isOptionsRequest) { return StateReturnValue.createRelevantResult(icapMessageDecoder.message); - } else if(encapsulated != null && !encapsulated.containsEntry(IcapMessageElementEnum.REQHDR) & !encapsulated.containsEntry(IcapMessageElementEnum.RESHDR)) { + } else if(encapsulated != null && !encapsulated.containsEntry(IcapMessageElementEnum.REQHDR) && !encapsulated.containsEntry(IcapMessageElementEnum.RESHDR)) { return StateReturnValue.createRelevantResult(icapMessageDecoder.message); } return StateReturnValue.createIrrelevantResult(); @@ -119,7 +119,7 @@ private void validateMandatoryMessageHeaders(IcapMessage message) { private void handleEncapsulationHeaderVolatility(IcapMessage message) { // Pseudo code // IF Encapsulated header is missing - // IF OPTIONS request OR 100 Continue response OR 204 No Content response + // IF OPTIONS request OR 100 Continue response OR 204 No Content response OR is a server error // THEN inject synthetic null-body Encapsulated header. boolean requiresSynthecticEncapsulationHeader = false; if(!message.containsHeader(IcapHeaders.Names.ENCAPSULATED)) { @@ -128,7 +128,9 @@ private void handleEncapsulationHeaderVolatility(IcapMessage message) { } else if(message instanceof IcapResponse) { IcapResponse response = (IcapResponse)message; IcapResponseStatus status = response.getStatus(); - if(status.equals(IcapResponseStatus.CONTINUE) | status.equals(IcapResponseStatus.NO_CONTENT)) { + if(status.equals(IcapResponseStatus.CONTINUE) || + status.equals(IcapResponseStatus.NO_CONTENT) || + (status.getCode() >= 500)) { requiresSynthecticEncapsulationHeader = true; } } diff --git a/src/main/java/ch/mimo/netty/handler/codec/icap/ReadIcapInitialState.java b/src/main/java/ch/mimo/netty/handler/codec/icap/ReadIcapInitialState.java index 321dca4..a164035 100644 --- a/src/main/java/ch/mimo/netty/handler/codec/icap/ReadIcapInitialState.java +++ b/src/main/java/ch/mimo/netty/handler/codec/icap/ReadIcapInitialState.java @@ -39,7 +39,14 @@ public void onEntry(ChannelBuffer buffer, IcapMessageDecoder icapMessageDecoder) @Override public StateReturnValue execute(ChannelBuffer buffer, IcapMessageDecoder icapMessageDecoder) throws DecodingException { String[] initialLine = IcapDecoderUtil.splitInitialLine(IcapDecoderUtil.readLine(buffer,icapMessageDecoder.maxInitialLineLength)); - icapMessageDecoder.message = icapMessageDecoder.createMessage(initialLine); + if (initialLine.length >= 3) { + try { + icapMessageDecoder.message = icapMessageDecoder.createMessage(initialLine); + } + catch (IllegalArgumentException e) { + icapMessageDecoder.message = null; + } + } return StateReturnValue.createIrrelevantResult(); } diff --git a/src/test/java/ch/mimo/netty/handler/codec/icap/IcapHeaderTest.java b/src/test/java/ch/mimo/netty/handler/codec/icap/IcapHeaderTest.java index 582a1c2..701c06f 100644 --- a/src/test/java/ch/mimo/netty/handler/codec/icap/IcapHeaderTest.java +++ b/src/test/java/ch/mimo/netty/handler/codec/icap/IcapHeaderTest.java @@ -330,4 +330,17 @@ public void getDateHeader() { Date returnedDate = headers.getDateHeader(IcapHeaders.Names.DATE); assertNotNull("The returned date was null",returnedDate); } + + @Test + public void removeAddHead() { + IcapHeaders headers = new IcapHeaders(); + headers.addHeader("fuz", "buz"); + headers.addHeader("foo", "bar"); + assertTrue("Header 'FOO' should exist (1)", headers.containsHeader("foo")); + assertEquals("Header 'FOO' should be 'bar'", "bar", headers.getHeader("foo")); + headers.removeHeader("foo"); + headers.addHeader("foo", "baz"); + assertTrue("Header 'FOO' should exist (2)", headers.containsHeader("foo")); + assertEquals("Header 'FOO' should be 'baz'", "baz", headers.getHeader("foo")); + } }