From 070f1470e8f98d35f9e0fed03716b00aa0058e53 Mon Sep 17 00:00:00 2001 From: Brendt Lucas Date: Fri, 4 Sep 2015 18:08:03 +0100 Subject: [PATCH] [#4185] SpdyHttpEncoder fails to convert HttpResponse to SpdyFrame Motivation: When SpdyHttpEncoder attempts to create an SpdyHeadersFrame from a HttpResponse an IllegalArgumentException is thrown if the original HttpResponse contains a header that includes uppercase characters. The IllegalArgumentException is thrown due to the additional validation check introduced by #4047. Previous versions of the SPDY codec would handle this by converting the HTTP header name to lowercase before adding the header to the SpdyHeadersFrame. Modifications: Convert the header name to lowercase before adding it to SpdyHeaders Result: SpdyHttpEncoder can now convert a valid HttpResponse into a valid SpdyFrame --- .../handler/codec/spdy/SpdyHttpEncoder.java | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpEncoder.java b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpEncoder.java index b77735530f..a2c47aa1e9 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpEncoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyHttpEncoder.java @@ -27,9 +27,12 @@ import io.netty.handler.codec.http.HttpObject; import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.LastHttpContent; +import io.netty.util.AsciiString; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Map.Entry; /** * Encodes {@link HttpRequest}s, {@link HttpResponse}s, and {@link HttpContent}s @@ -171,8 +174,10 @@ public class SpdyHttpEncoder extends MessageToMessageEncoder { // Create SPDY HEADERS frame out of trailers SpdyHeadersFrame spdyHeadersFrame = new DefaultSpdyHeadersFrame(currentStreamId); spdyHeadersFrame.setLast(true); - for (Map.Entry entry: trailers) { - spdyHeadersFrame.headers().add(entry.getKey(), entry.getValue()); + Iterator> itr = trailers.iteratorCharSequence(); + while (itr.hasNext()) { + Map.Entry entry = itr.next(); + spdyHeadersFrame.headers().add(AsciiString.of(entry.getKey()).toLowerCase(), entry.getValue()); } // Write DATA frame and append HEADERS frame @@ -232,8 +237,10 @@ public class SpdyHttpEncoder extends MessageToMessageEncoder { frameHeaders.set(SpdyHeaders.HttpNames.SCHEME, scheme); // Transfer the remaining HTTP headers - for (Map.Entry entry: httpHeaders) { - frameHeaders.add(entry.getKey(), entry.getValue()); + Iterator> itr = httpHeaders.iteratorCharSequence(); + while (itr.hasNext()) { + Map.Entry entry = itr.next(); + frameHeaders.add(AsciiString.of(entry.getKey()).toLowerCase(), entry.getValue()); } currentStreamId = spdySynStreamFrame.streamId(); if (associatedToStreamId == 0) { @@ -271,8 +278,10 @@ public class SpdyHttpEncoder extends MessageToMessageEncoder { frameHeaders.set(SpdyHeaders.HttpNames.VERSION, httpResponse.protocolVersion().text()); // Transfer the remaining HTTP headers - for (Map.Entry entry: httpHeaders) { - spdyHeadersFrame.headers().add(entry.getKey(), entry.getValue()); + Iterator> itr = httpHeaders.iteratorCharSequence(); + while (itr.hasNext()) { + Map.Entry entry = itr.next(); + spdyHeadersFrame.headers().add(AsciiString.of(entry.getKey()).toLowerCase(), entry.getValue()); } currentStreamId = streamId;