From 248aea9e853d432d341776613ede8d0084a67589 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A8=E3=81=8B=E3=81=84?= <25.r55u2n444tag@gmail.com> Date: Thu, 5 Nov 2020 15:22:56 +0900 Subject: [PATCH] Fix request.getContentLength() to return 0 if it is less than 0 (#8448) ### Motivation - "Negative initial size: -1" error occurs when submitting an HTTP request which has "Content-Type: application/json" and no request body . ### Modifications - Pass 0 to argument of ByteArrayOutputStream if request.getContentLength() returns a negative number. - Add unit test. --- .../proxy/server/AdminProxyHandler.java | 2 +- .../proxy/server/AdminProxyHandlerTest.java | 56 +++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/AdminProxyHandlerTest.java diff --git a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/AdminProxyHandler.java b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/AdminProxyHandler.java index 697ddf96178304..28a314019ecca9 100644 --- a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/AdminProxyHandler.java +++ b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/AdminProxyHandler.java @@ -169,7 +169,7 @@ protected class ReplayableProxyContentProvider extends ProxyInputStreamContentPr private final ByteArrayOutputStream bodyBuffer; protected ReplayableProxyContentProvider(HttpServletRequest request, HttpServletResponse response, Request proxyRequest, InputStream input) { super(request, response, proxyRequest, input); - bodyBuffer = new ByteArrayOutputStream(request.getContentLength()); + bodyBuffer = new ByteArrayOutputStream(Math.max(request.getContentLength(), 0)); } @Override diff --git a/pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/AdminProxyHandlerTest.java b/pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/AdminProxyHandlerTest.java new file mode 100644 index 00000000000000..ad7f0e5e24615b --- /dev/null +++ b/pulsar-proxy/src/test/java/org/apache/pulsar/proxy/server/AdminProxyHandlerTest.java @@ -0,0 +1,56 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.pulsar.proxy.server; + +import static org.mockito.Mockito.*; + +import org.eclipse.jetty.client.api.Request; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.io.InputStream; +import java.io.ByteArrayOutputStream; +import java.lang.reflect.Field; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class AdminProxyHandlerTest { + + @Test + public void replayableProxyContentProviderTest() throws Exception { + + AdminProxyHandler adminProxyHandler = new AdminProxyHandler(mock(ProxyConfiguration.class), + mock(BrokerDiscoveryProvider.class)); + + HttpServletRequest request = mock(HttpServletRequest.class); + doReturn(-1).when(request).getContentLength(); + + try { + AdminProxyHandler.ReplayableProxyContentProvider replayableProxyContentProvider = adminProxyHandler.new ReplayableProxyContentProvider( + request, mock(HttpServletResponse.class), mock(Request.class), mock(InputStream.class)); + Field field = replayableProxyContentProvider.getClass().getDeclaredField("bodyBuffer"); + field.setAccessible(true); + Assert.assertEquals(((ByteArrayOutputStream) field.get(replayableProxyContentProvider)).size(), 0); + } catch (IllegalArgumentException e) { + Assert.fail("IllegalArgumentException should not be thrown"); + } + + } +}