Fix regression in HttpPostStandardRequestDecoder to always decode + to whitespace (#10285)
Motivations ----------- HttpPostStandardRequestDecoder was changed in 4.1.50 to provide its own ByteBuf UrlDecoder. Prior to this change, it was using the decodeComponent method from QueryStringDecoder which decoded + characters to whitespaces. This behavior needs to be preserved to maintain backward compatibility. Modifications ------------- Changed HttpPostStandardRequestDecoder to detect + bytes and decode them toe whitespaces. Added a test. Results ------- Addresses issues#10284
This commit is contained in:
parent
caf51b7284
commit
d5087deec6
@ -656,7 +656,7 @@ public class HttpPostStandardRequestDecoder implements InterfaceHttpPostRequestD
|
||||
}
|
||||
|
||||
private static ByteBuf decodeAttribute(ByteBuf b, Charset charset) {
|
||||
int firstEscaped = b.forEachByte(new ByteProcessor.IndexOfProcessor((byte) '%'));
|
||||
int firstEscaped = b.forEachByte(new UrlEncodedDetector());
|
||||
if (firstEscaped == -1) {
|
||||
return null; // nothing to decode
|
||||
}
|
||||
@ -714,6 +714,13 @@ public class HttpPostStandardRequestDecoder implements InterfaceHttpPostRequestD
|
||||
factory.removeHttpDataFromClean(request, data);
|
||||
}
|
||||
|
||||
private static final class UrlEncodedDetector implements ByteProcessor {
|
||||
@Override
|
||||
public boolean process(byte value) throws Exception {
|
||||
return value != '%' && value != '+';
|
||||
}
|
||||
}
|
||||
|
||||
private static final class UrlDecoder implements ByteProcessor {
|
||||
|
||||
private final ByteBuf output;
|
||||
@ -742,6 +749,8 @@ public class HttpPostStandardRequestDecoder implements InterfaceHttpPostRequestD
|
||||
}
|
||||
} else if (value == '%') {
|
||||
nextEscapedIdx = 1;
|
||||
} else if (value == '+') {
|
||||
output.writeByte(' ');
|
||||
} else {
|
||||
output.writeByte(value);
|
||||
}
|
||||
|
@ -829,7 +829,7 @@ public class HttpPostRequestDecoderTest {
|
||||
|
||||
@Test
|
||||
public void testDecodeFullHttpRequestWithUrlEncodedBody() throws Exception {
|
||||
byte[] bodyBytes = "foo=bar&a=b&empty=&city=%3c%22new%22%20york%20city%3e".getBytes();
|
||||
byte[] bodyBytes = "foo=bar&a=b&empty=&city=%3c%22new%22%20york%20city%3e&other_city=los+angeles".getBytes();
|
||||
ByteBuf content = Unpooled.directBuffer(bodyBytes.length);
|
||||
content.writeBytes(bodyBytes);
|
||||
|
||||
@ -838,7 +838,7 @@ public class HttpPostRequestDecoderTest {
|
||||
assertFalse(decoder.getBodyHttpDatas().isEmpty());
|
||||
|
||||
assertFalse(decoder.getBodyHttpDatas().isEmpty());
|
||||
assertEquals(4, decoder.getBodyHttpDatas().size());
|
||||
assertEquals(5, decoder.getBodyHttpDatas().size());
|
||||
|
||||
Attribute attr = (Attribute) decoder.getBodyHttpData("foo");
|
||||
assertTrue(attr.getByteBuf().isDirect());
|
||||
@ -856,6 +856,10 @@ public class HttpPostRequestDecoderTest {
|
||||
assertTrue(attr.getByteBuf().isDirect());
|
||||
assertEquals("<\"new\" york city>", attr.getValue());
|
||||
|
||||
attr = (Attribute) decoder.getBodyHttpData("other_city");
|
||||
assertTrue(attr.getByteBuf().isDirect());
|
||||
assertEquals("los angeles", attr.getValue());
|
||||
|
||||
decoder.destroy();
|
||||
req.release();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user