Destroy HttpPostMultipartRequestDecoder if contructor throws (#11207)
Motivation: We need to call destroy() if the constructor of HttpPostMultipartRequestDecoder throws as otherwise we may leak memory. Modifications: - Call destroy() if we throw - Add unit test Result: No more leaks when constructor throws Co-authored-by: Frederic Bregier <frederic.bregier@waarp.fr>
This commit is contained in:
parent
3657805711
commit
def8a3f17d
@ -31,6 +31,7 @@ import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder.MultiPartSta
|
|||||||
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder.NotEnoughDataDecoderException;
|
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder.NotEnoughDataDecoderException;
|
||||||
import io.netty.util.CharsetUtil;
|
import io.netty.util.CharsetUtil;
|
||||||
import io.netty.util.internal.InternalThreadLocalMap;
|
import io.netty.util.internal.InternalThreadLocalMap;
|
||||||
|
import io.netty.util.internal.PlatformDependent;
|
||||||
import io.netty.util.internal.StringUtil;
|
import io.netty.util.internal.StringUtil;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -199,6 +200,7 @@ public class HttpPostMultipartRequestDecoder implements InterfaceHttpPostRequest
|
|||||||
}
|
}
|
||||||
currentStatus = MultiPartStatus.HEADERDELIMITER;
|
currentStatus = MultiPartStatus.HEADERDELIMITER;
|
||||||
|
|
||||||
|
try {
|
||||||
if (request instanceof HttpContent) {
|
if (request instanceof HttpContent) {
|
||||||
// Offer automatically if the given request is als type of HttpContent
|
// Offer automatically if the given request is als type of HttpContent
|
||||||
// See #1089
|
// See #1089
|
||||||
@ -206,6 +208,10 @@ public class HttpPostMultipartRequestDecoder implements InterfaceHttpPostRequest
|
|||||||
} else {
|
} else {
|
||||||
parseBody();
|
parseBody();
|
||||||
}
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
destroy();
|
||||||
|
PlatformDependent.throwException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkDestroyed() {
|
private void checkDestroyed() {
|
||||||
|
@ -15,11 +15,13 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.http.multipart;
|
package io.netty.handler.codec.http.multipart;
|
||||||
|
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.handler.codec.http.DefaultFullHttpRequest;
|
import io.netty.handler.codec.http.DefaultFullHttpRequest;
|
||||||
import io.netty.handler.codec.http.FullHttpRequest;
|
import io.netty.handler.codec.http.FullHttpRequest;
|
||||||
import io.netty.handler.codec.http.HttpHeaderNames;
|
import io.netty.handler.codec.http.HttpHeaderNames;
|
||||||
import io.netty.handler.codec.http.HttpMethod;
|
import io.netty.handler.codec.http.HttpMethod;
|
||||||
import io.netty.handler.codec.http.HttpVersion;
|
import io.netty.handler.codec.http.HttpVersion;
|
||||||
|
import io.netty.util.CharsetUtil;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
@ -55,4 +57,28 @@ public class HttpPostMultiPartRequestDecoderTest {
|
|||||||
assertTrue(req.release());
|
assertTrue(req.release());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDecodeFullHttpRequestWithInvalidPayloadReleaseBuffer() {
|
||||||
|
String content = "\n--861fbeab-cd20-470c-9609-d40a0f704466\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"image1\"; filename*=\"'some.jpeg\"\n" +
|
||||||
|
"Content-Type: image/jpeg\n" +
|
||||||
|
"Content-Length: 1\n" +
|
||||||
|
"x\n" +
|
||||||
|
"--861fbeab-cd20-470c-9609-d40a0f704466--\n";
|
||||||
|
|
||||||
|
FullHttpRequest req = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/upload",
|
||||||
|
Unpooled.copiedBuffer(content, CharsetUtil.US_ASCII));
|
||||||
|
req.headers().set("content-type", "multipart/form-data; boundary=861fbeab-cd20-470c-9609-d40a0f704466");
|
||||||
|
req.headers().set("content-length", content.length());
|
||||||
|
|
||||||
|
try {
|
||||||
|
new HttpPostMultipartRequestDecoder(req);
|
||||||
|
fail("Was expecting an ErrorDataDecoderException");
|
||||||
|
} catch (HttpPostRequestDecoder.ErrorDataDecoderException expected) {
|
||||||
|
// expected
|
||||||
|
} finally {
|
||||||
|
assertTrue(req.release());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user