[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