[SCB-2333] HttpServerOptions.maxFormAttributeSize can be configurable (#2579)
* [SCB-2333] HttpServerOptions.maxFormAttributeSize can be configurable
* fix problem of highest-basedir
diff --git a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/FormRequestClient.java b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/FormRequestClient.java
new file mode 100644
index 0000000..b9ac606
--- /dev/null
+++ b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/FormRequestClient.java
@@ -0,0 +1,79 @@
+/*
+ * 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.servicecomb.demo.jaxrs.client;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.servicecomb.demo.TestMgr;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestTemplate;
+
+import com.google.common.base.Strings;
+
+
+@Component
+public class FormRequestClient {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(FormRequestClient.class);
+
+ private static final String CSE_URL = "cse://jaxrs/form/formRequest";
+
+ public static void testFormRequest(RestTemplate restTemplate) throws Exception {
+ testFormRequestFail(restTemplate);
+ //testFormRequestFail maybe close connection,sleep two seconds in case testFormRequestSuccess fail
+ Thread.sleep(2000);
+ testFormRequestSuccess(restTemplate);
+ }
+
+
+ // formSize is less than default maxFormAttributeSize , success
+ private static void testFormRequestSuccess(RestTemplate restTemplate) {
+ try {
+ ResponseEntity<String> responseEntity = restTemplate
+ .postForEntity(FormRequestClient.CSE_URL, createFormHttpEntity(512), String.class);
+ TestMgr.check(responseEntity.getBody(), "formRequest success : 512");
+ } catch (Throwable e) {
+ LOGGER.error("formRequest success error : ", e);
+ TestMgr.failed("", e);
+ }
+ }
+
+ // formSize is greater than default maxFormAttributeSize , throw exception
+ private static void testFormRequestFail(RestTemplate restTemplate) {
+ try {
+ restTemplate.postForEntity(FormRequestClient.CSE_URL, createFormHttpEntity(2048), String.class);
+ TestMgr.failed("", new Exception("formRequest fail"));
+ } catch (Throwable e) {
+ TestMgr.check(e.getMessage().contains("Size exceed allowed maximum capacity"), true);
+ }
+ }
+
+ private static HttpEntity<MultiValueMap<String, String>> createFormHttpEntity(int size) {
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+ MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
+ formData.add("formData", Strings.repeat("a", size));
+ return new HttpEntity<>(formData, headers);
+ }
+}
diff --git a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java
index cd4f783..8e456dc 100644
--- a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java
+++ b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java
@@ -78,6 +78,8 @@
testSpringMvcDefaultValuesJavaPrimitive(templateNew);
MultiErrorCodeServiceClient.runTest();
+ FormRequestClient.testFormRequest(templateNew);
+
BeanParamPojoClient beanParamPojoClient = new BeanParamPojoClient();
beanParamPojoClient.testAll();
BeanParamRestTemplateClient beanParamRestTemplateClient = new BeanParamRestTemplateClient();
diff --git a/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/FormRequest.java b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/FormRequest.java
new file mode 100644
index 0000000..7932da0
--- /dev/null
+++ b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/FormRequest.java
@@ -0,0 +1,40 @@
+/*
+ * 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.servicecomb.demo.jaxrs.server;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+
+@RestSchema(schemaId = "FormRequestSchema")
+@Path("/form")
+@Produces(MediaType.APPLICATION_JSON)
+public class FormRequest {
+
+ @Path("/formRequest")
+ @POST
+ @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+ public String formRequestSuccess(@FormParam("formData") String formData) throws Exception {
+ return "formRequest success : " + formData.length();
+ }
+}
diff --git a/demo/demo-jaxrs/jaxrs-server/src/main/resources/microservice.yaml b/demo/demo-jaxrs/jaxrs-server/src/main/resources/microservice.yaml
index 89f324c..065dcec 100644
--- a/demo/demo-jaxrs/jaxrs-server/src/main/resources/microservice.yaml
+++ b/demo/demo-jaxrs/jaxrs-server/src/main/resources/microservice.yaml
@@ -25,6 +25,8 @@
address: http://127.0.0.1:30100
rest:
address: 0.0.0.0:8080
+ server:
+ maxFormAttributeSize: 1024
highway:
address: 0.0.0.0:7070
handler:
diff --git a/demo/docker-build-config/pom.xml b/demo/docker-build-config/pom.xml
index cbe21ca..e1e6486 100644
--- a/demo/docker-build-config/pom.xml
+++ b/demo/docker-build-config/pom.xml
@@ -49,7 +49,7 @@
</ports>
<assembly>
<mode>tar</mode>
- <descriptor>${root.basedir}/demo/assembly/assembly.xml</descriptor>
+ <descriptor>${root.basedir}/assembly/assembly.xml</descriptor>
</assembly>
<entryPoint>
<shell>java $JAVA_OPTS -jar $JAR_PATH</shell>
@@ -75,11 +75,15 @@
<execution>
<id>directories</id>
<goals>
- <goal>highest-basedir</goal>
+ <goal>directory-of</goal>
</goals>
<phase>initialize</phase>
<configuration>
<property>root.basedir</property>
+ <project>
+ <groupId>org.apache.servicecomb.demo</groupId>
+ <artifactId>demo-parent</artifactId>
+ </project>
</configuration>
</execution>
</executions>
diff --git a/demo/pom.xml b/demo/pom.xml
index 4069072..ff0f7d9 100644
--- a/demo/pom.xml
+++ b/demo/pom.xml
@@ -142,7 +142,7 @@
<plugin>
<groupId>org.commonjava.maven.plugins</groupId>
<artifactId>directory-maven-plugin</artifactId>
- <version>0.1</version>
+ <version>0.3.1</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestServerVerticle.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestServerVerticle.java
index 6ac5235..afc43d1 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestServerVerticle.java
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestServerVerticle.java
@@ -241,10 +241,22 @@
serverOptions.setIdleTimeout(TransportConfig.getConnectionIdleTimeoutInSeconds());
serverOptions.setCompressionSupported(TransportConfig.getCompressed());
serverOptions.setMaxHeaderSize(TransportConfig.getMaxHeaderSize());
+ serverOptions.setMaxFormAttributeSize(TransportConfig.getMaxFormAttributeSize());
+ serverOptions.setCompressionLevel(TransportConfig.getCompressionLevel());
+ serverOptions.setMaxChunkSize(TransportConfig.getMaxChunkSize());
+ serverOptions.setDecompressionSupported(TransportConfig.getDecompressionSupported());
+ serverOptions.setDecoderInitialBufferSize(TransportConfig.getDecoderInitialBufferSize());
+ serverOptions.setHttp2ConnectionWindowSize(TransportConfig.getHttp2ConnectionWindowSize());
serverOptions.setMaxInitialLineLength(TransportConfig.getMaxInitialLineLength());
if (endpointObject.isHttp2Enabled()) {
serverOptions.setUseAlpn(TransportConfig.getUseAlpn())
- .setInitialSettings(new Http2Settings().setMaxConcurrentStreams(TransportConfig.getMaxConcurrentStreams()));
+ .setInitialSettings(new Http2Settings().setPushEnabled(TransportConfig.getPushEnabled())
+ .setMaxConcurrentStreams(TransportConfig.getMaxConcurrentStreams())
+ .setHeaderTableSize(TransportConfig.getHttp2HeaderTableSize())
+ .setInitialWindowSize(TransportConfig.getInitialWindowSize())
+ .setMaxFrameSize(TransportConfig.getMaxFrameSize())
+ .setMaxHeaderListSize(TransportConfig.getMaxHeaderListSize())
+ );
}
if (endpointObject.isSslEnabled()) {
SSLOptionFactory factory =
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/TransportConfig.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/TransportConfig.java
index 2ef3c1f..c692bd0 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/TransportConfig.java
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/TransportConfig.java
@@ -28,6 +28,7 @@
import com.netflix.config.DynamicStringProperty;
import io.vertx.core.Verticle;
+import io.vertx.core.http.Http2Settings;
import io.vertx.core.http.HttpServerOptions;
public final class TransportConfig {
@@ -59,6 +60,36 @@
return address.get();
}
+ public static int getMaxFormAttributeSize() {
+ return DynamicPropertyFactory.getInstance()
+ .getIntProperty("servicecomb.rest.server.maxFormAttributeSize",
+ HttpServerOptions.DEFAULT_MAX_FORM_ATTRIBUTE_SIZE).get();
+ }
+
+ public static int getCompressionLevel() {
+ return DynamicPropertyFactory.getInstance()
+ .getIntProperty("servicecomb.rest.server.compressionLevel",
+ HttpServerOptions.DEFAULT_COMPRESSION_LEVEL).get();
+ }
+
+ public static int getMaxChunkSize() {
+ return DynamicPropertyFactory.getInstance()
+ .getIntProperty("servicecomb.rest.server.maxChunkSize",
+ HttpServerOptions.DEFAULT_MAX_CHUNK_SIZE).get();
+ }
+
+ public static int getDecoderInitialBufferSize() {
+ return DynamicPropertyFactory.getInstance()
+ .getIntProperty("servicecomb.rest.server.decoderInitialBufferSize",
+ HttpServerOptions.DEFAULT_DECODER_INITIAL_BUFFER_SIZE).get();
+ }
+
+ public static int getHttp2ConnectionWindowSize() {
+ return DynamicPropertyFactory.getInstance()
+ .getIntProperty("servicecomb.rest.server.http2ConnectionWindowSize",
+ HttpServerOptions.DEFAULT_HTTP2_CONNECTION_WINDOW_SIZE).get();
+ }
+
public static int getThreadCount() {
return TransportConfigUtils.readVerticleCount(
"servicecomb.rest.server.verticle-count",
@@ -78,6 +109,12 @@
.get();
}
+ public static boolean getDecompressionSupported() {
+ return DynamicPropertyFactory.getInstance()
+ .getBooleanProperty("servicecomb.rest.server.decompressionSupported",
+ HttpServerOptions.DEFAULT_DECOMPRESSION_SUPPORTED).get();
+ }
+
public static long getMaxConcurrentStreams() {
return DynamicPropertyFactory.getInstance()
.getLongProperty("servicecomb.rest.server.http2.concurrentStreams",
@@ -85,6 +122,36 @@
.get();
}
+ public static long getHttp2HeaderTableSize() {
+ return DynamicPropertyFactory.getInstance()
+ .getLongProperty("servicecomb.rest.server.http2.HeaderTableSize",
+ Http2Settings.DEFAULT_HEADER_TABLE_SIZE).get();
+ }
+
+ public static boolean getPushEnabled() {
+ return DynamicPropertyFactory.getInstance()
+ .getBooleanProperty("servicecomb.rest.server.http2.pushEnabled",
+ Http2Settings.DEFAULT_ENABLE_PUSH).get();
+ }
+
+ public static int getInitialWindowSize() {
+ return DynamicPropertyFactory.getInstance()
+ .getIntProperty("servicecomb.rest.server.http2.initialWindowSize",
+ Http2Settings.DEFAULT_INITIAL_WINDOW_SIZE).get();
+ }
+
+ public static int getMaxFrameSize() {
+ return DynamicPropertyFactory.getInstance()
+ .getIntProperty("servicecomb.rest.server.http2.maxFrameSize",
+ Http2Settings.DEFAULT_MAX_FRAME_SIZE).get();
+ }
+
+ public static int getMaxHeaderListSize() {
+ return DynamicPropertyFactory.getInstance()
+ .getIntProperty("servicecomb.rest.server.http2.maxHeaderListSize",
+ Http2Settings.DEFAULT_MAX_HEADER_LIST_SIZE).get();
+ }
+
public static boolean getUseAlpn() {
return DynamicPropertyFactory.getInstance()
.getBooleanProperty("servicecomb.rest.server.http2.useAlpnEnabled", true)
diff --git a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/TestTransportConfig.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/TestTransportConfig.java
index c944c1a..3e2ff21 100644
--- a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/TestTransportConfig.java
+++ b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/TestTransportConfig.java
@@ -76,6 +76,48 @@
}
@Test
+ public void testGetDecompressed() {
+ Assert.assertEquals(false, TransportConfig.getDecompressionSupported());
+ ArchaiusUtils.setProperty("servicecomb.rest.server.decompressionSupported", true);
+ Assert.assertEquals(true, TransportConfig.getDecompressionSupported());
+ }
+
+ @Test
+ public void testGetDecoderInitialBufferSize() {
+ Assert.assertEquals(128, TransportConfig.getDecoderInitialBufferSize());
+ ArchaiusUtils.setProperty("servicecomb.rest.server.decoderInitialBufferSize", 256);
+ Assert.assertEquals(256, TransportConfig.getDecoderInitialBufferSize());
+ }
+
+ @Test
+ public void testGetHttp2ConnectionWindowSize() {
+ Assert.assertEquals(-1, TransportConfig.getHttp2ConnectionWindowSize());
+ ArchaiusUtils.setProperty("servicecomb.rest.server.http2ConnectionWindowSize", 1);
+ Assert.assertEquals(1, TransportConfig.getHttp2ConnectionWindowSize());
+ }
+
+ @Test
+ public void testGetMaxFormAttributeSize() {
+ Assert.assertEquals(2048, TransportConfig.getMaxFormAttributeSize());
+ ArchaiusUtils.setProperty("servicecomb.rest.server.maxFormAttributeSize", 3072);
+ Assert.assertEquals(3072, TransportConfig.getMaxFormAttributeSize());
+ }
+
+ @Test
+ public void testGeCompressionLevel() {
+ Assert.assertEquals(6, TransportConfig.getCompressionLevel());
+ ArchaiusUtils.setProperty("servicecomb.rest.server.compressionLevel", 8);
+ Assert.assertEquals(8, TransportConfig.getCompressionLevel());
+ }
+
+ @Test
+ public void testGetMaxChunkSize() {
+ Assert.assertEquals(8192, TransportConfig.getMaxChunkSize());
+ ArchaiusUtils.setProperty("servicecomb.rest.server.maxChunkSize", 65536);
+ Assert.assertEquals(65536, TransportConfig.getMaxChunkSize());
+ }
+
+ @Test
public void testIsCorsEnabled() {
Assert.assertFalse(TransportConfig.isCorsEnabled());
ArchaiusUtils.setProperty("servicecomb.cors.enabled", true);
@@ -151,10 +193,30 @@
}
@Test
- public void testMaxConcurrentStreams() {
+ public void testHttp2Setting() {
Assert.assertEquals(100L, TransportConfig.getMaxConcurrentStreams());
ArchaiusUtils.setProperty("servicecomb.rest.server.http2.concurrentStreams", 200L);
Assert.assertEquals(200L, TransportConfig.getMaxConcurrentStreams());
+
+ Assert.assertEquals(4096L, TransportConfig.getHttp2HeaderTableSize());
+ ArchaiusUtils.setProperty("servicecomb.rest.server.http2.HeaderTableSize", 8192L);
+ Assert.assertEquals(8192L, TransportConfig.getHttp2HeaderTableSize());
+
+ Assert.assertTrue(TransportConfig.getPushEnabled());
+ ArchaiusUtils.setProperty("servicecomb.rest.server.http2.pushEnabled", false);
+ Assert.assertFalse(TransportConfig.getPushEnabled());
+
+ Assert.assertEquals(65535, TransportConfig.getInitialWindowSize());
+ ArchaiusUtils.setProperty("servicecomb.rest.server.http2.initialWindowSize", 2 * 65535);
+ Assert.assertEquals(2 * 65535, TransportConfig.getInitialWindowSize());
+
+ Assert.assertEquals(16384, TransportConfig.getMaxFrameSize());
+ ArchaiusUtils.setProperty("servicecomb.rest.server.http2.maxFrameSize", 65535);
+ Assert.assertEquals(65535, TransportConfig.getMaxFrameSize());
+
+ Assert.assertEquals(Integer.MAX_VALUE, TransportConfig.getMaxHeaderListSize());
+ ArchaiusUtils.setProperty("servicecomb.rest.server.http2.maxHeaderListSize", 65535);
+ Assert.assertEquals(65535, TransportConfig.getMaxHeaderListSize());
}
@Test