[#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
This commit is contained in:
Brendt Lucas 2015-09-04 18:08:03 +01:00 committed by Scott Mitchell
parent 983920f25f
commit 070f1470e8

View File

@ -27,9 +27,12 @@ import io.netty.handler.codec.http.HttpObject;
import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.HttpResponse;
import io.netty.handler.codec.http.LastHttpContent; import io.netty.handler.codec.http.LastHttpContent;
import io.netty.util.AsciiString;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
/** /**
* Encodes {@link HttpRequest}s, {@link HttpResponse}s, and {@link HttpContent}s * Encodes {@link HttpRequest}s, {@link HttpResponse}s, and {@link HttpContent}s
@ -171,8 +174,10 @@ public class SpdyHttpEncoder extends MessageToMessageEncoder<HttpObject> {
// Create SPDY HEADERS frame out of trailers // Create SPDY HEADERS frame out of trailers
SpdyHeadersFrame spdyHeadersFrame = new DefaultSpdyHeadersFrame(currentStreamId); SpdyHeadersFrame spdyHeadersFrame = new DefaultSpdyHeadersFrame(currentStreamId);
spdyHeadersFrame.setLast(true); spdyHeadersFrame.setLast(true);
for (Map.Entry<String, String> entry: trailers) { Iterator<Entry<CharSequence, CharSequence>> itr = trailers.iteratorCharSequence();
spdyHeadersFrame.headers().add(entry.getKey(), entry.getValue()); while (itr.hasNext()) {
Map.Entry<CharSequence, CharSequence> entry = itr.next();
spdyHeadersFrame.headers().add(AsciiString.of(entry.getKey()).toLowerCase(), entry.getValue());
} }
// Write DATA frame and append HEADERS frame // Write DATA frame and append HEADERS frame
@ -232,8 +237,10 @@ public class SpdyHttpEncoder extends MessageToMessageEncoder<HttpObject> {
frameHeaders.set(SpdyHeaders.HttpNames.SCHEME, scheme); frameHeaders.set(SpdyHeaders.HttpNames.SCHEME, scheme);
// Transfer the remaining HTTP headers // Transfer the remaining HTTP headers
for (Map.Entry<String, String> entry: httpHeaders) { Iterator<Entry<CharSequence, CharSequence>> itr = httpHeaders.iteratorCharSequence();
frameHeaders.add(entry.getKey(), entry.getValue()); while (itr.hasNext()) {
Map.Entry<CharSequence, CharSequence> entry = itr.next();
frameHeaders.add(AsciiString.of(entry.getKey()).toLowerCase(), entry.getValue());
} }
currentStreamId = spdySynStreamFrame.streamId(); currentStreamId = spdySynStreamFrame.streamId();
if (associatedToStreamId == 0) { if (associatedToStreamId == 0) {
@ -271,8 +278,10 @@ public class SpdyHttpEncoder extends MessageToMessageEncoder<HttpObject> {
frameHeaders.set(SpdyHeaders.HttpNames.VERSION, httpResponse.protocolVersion().text()); frameHeaders.set(SpdyHeaders.HttpNames.VERSION, httpResponse.protocolVersion().text());
// Transfer the remaining HTTP headers // Transfer the remaining HTTP headers
for (Map.Entry<String, String> entry: httpHeaders) { Iterator<Entry<CharSequence, CharSequence>> itr = httpHeaders.iteratorCharSequence();
spdyHeadersFrame.headers().add(entry.getKey(), entry.getValue()); while (itr.hasNext()) {
Map.Entry<CharSequence, CharSequence> entry = itr.next();
spdyHeadersFrame.headers().add(AsciiString.of(entry.getKey()).toLowerCase(), entry.getValue());
} }
currentStreamId = streamId; currentStreamId = streamId;