This is an automated email from the ASF dual-hosted git repository.
liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git
The following commit(s) were added to refs/heads/master by this push:
new fff8c3e [SCB-2333] HttpServerOptions.maxFormAttributeSize can be
configurable (#2566)
fff8c3e is described below
commit fff8c3e97fcbcf1572f27ae1cd8443a7cebeb19c
Author: david6969xin <[email protected]>
AuthorDate: Wed Sep 15 19:53:43 2021 +0800
[SCB-2333] HttpServerOptions.maxFormAttributeSize can be configurable
(#2566)
---
.../demo/jaxrs/client/TestFormRequestSchema.java | 89 ++++++++++++++++++++++
.../demo/jaxrs/server/FormRequestSchema.java | 41 ++++++++++
.../src/main/resources/microservice.yaml | 2 +
.../src/main/resources/application.yml | 2 +-
.../src/main/resources/application.yml | 2 +-
.../rest/client/http/DefaultHttpClientFilter.java | 4 +-
.../transport/rest/vertx/RestServerVerticle.java | 14 +++-
.../transport/rest/vertx/TransportConfig.java | 70 ++++++++++++++++-
.../transport/rest/vertx/TestTransportConfig.java | 65 +++++++++++++++-
9 files changed, 281 insertions(+), 8 deletions(-)
diff --git
a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/TestFormRequestSchema.java
b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/TestFormRequestSchema.java
new file mode 100644
index 0000000..c243c9d
--- /dev/null
+++
b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/TestFormRequestSchema.java
@@ -0,0 +1,89 @@
+/*
+ * 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.apache.servicecomb.demo.CategorizedTestCase;
+import org.apache.servicecomb.demo.TestMgr;
+import org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+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;
+
+
+@Component
+public class TestFormRequestSchema implements CategorizedTestCase {
+
+ private static final Logger LOGGER =
LoggerFactory.getLogger(TestFormRequestSchema.class);
+
+ private RestTemplate restTemplate = RestTemplateBuilder.create();
+
+ @Override
+ public void testRestTransport() throws Exception {
+ testFormRequestFail();
+ // testFormRequestFail会关闭连接,防止下个测试用例失败,睡眠2s
+ Thread.sleep(2000);
+ testFormRequestSuccess();
+ }
+
+ // formSize is less than default maxFormAttributeSize , success
+ private void testFormRequestSuccess() throws Exception {
+ try {
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+ MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
+ StringBuffer stringBuffer = new StringBuffer();
+ for (int i = 0; i < 512; i++) {
+ stringBuffer.append("a");
+ }
+ formData.add("formData", stringBuffer.toString());
+ HttpEntity<MultiValueMap<String, String>> requestEntity = new
HttpEntity<>(formData, headers);
+ ResponseEntity<String> responseEntity = restTemplate
+ .postForEntity("cse://jaxrs/form/formRequest", requestEntity,
String.class);
+ TestMgr.check(responseEntity.getBody(), "formRequest success : 512");
+ } catch (Throwable e) {
+ LOGGER.error("testFormRequestSuccess-->", e);
+ TestMgr.failed("", e);
+ }
+ }
+
+ // formSize is greater than default maxFormAttributeSize , throw exception
+ private void testFormRequestFail() throws Exception {
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+ MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
+ StringBuffer stringBuffer = new StringBuffer();
+ for (int i = 0; i < 1688; i++) {
+ stringBuffer.append("a");
+ }
+ formData.add("formData", String.valueOf(stringBuffer));
+ HttpEntity<MultiValueMap<String, String>> requestEntity = new
HttpEntity<>(formData, headers);
+ try {
+ restTemplate.postForEntity("cse://jaxrs/form/formRequest",
requestEntity, String.class);
+ TestMgr.fail("Size exceed allowed maximum capacity");
+ } catch (Throwable e) {
+ TestMgr.check(e.getMessage().contains("Size exceed allowed maximum
capacity"), true);
+ }
+ }
+}
diff --git
a/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/FormRequestSchema.java
b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/FormRequestSchema.java
new file mode 100644
index 0000000..7ceaf74
--- /dev/null
+++
b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/FormRequestSchema.java
@@ -0,0 +1,41 @@
+/*
+ * 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 FormRequestSchema {
+
+ @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 a6cb992..f4f585e 100644
--- a/demo/demo-jaxrs/jaxrs-server/src/main/resources/microservice.yaml
+++ b/demo/demo-jaxrs/jaxrs-server/src/main/resources/microservice.yaml
@@ -24,6 +24,8 @@ servicecomb:
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/demo-spring-boot-provider/demo-spring-boot-jaxrs-client/src/main/resources/application.yml
b/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-client/src/main/resources/application.yml
index 541ceeb..f0dc3cd 100644
---
a/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-client/src/main/resources/application.yml
+++
b/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-client/src/main/resources/application.yml
@@ -32,4 +32,4 @@ servicecomb:
handler:
chain:
Consumer:
- default: bizkeeper-consumer,loadbalance
\ No newline at end of file
+ default: bizkeeper-consumer,loadbalance
diff --git
a/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/resources/application.yml
b/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/resources/application.yml
index 6a4380f..6f97575 100644
---
a/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/resources/application.yml
+++
b/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/resources/application.yml
@@ -35,4 +35,4 @@ servicecomb:
handler:
chain:
Provider:
- default: bizkeeper-provider
+ default: bizkeeper-provider
\ No newline at end of file
diff --git
a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/http/DefaultHttpClientFilter.java
b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/http/DefaultHttpClientFilter.java
index 94e15a8..d41b156 100644
---
a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/http/DefaultHttpClientFilter.java
+++
b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/http/DefaultHttpClientFilter.java
@@ -104,8 +104,8 @@ public class DefaultHttpClientFilter implements
HttpClientFilter {
result = produceProcessor.decodeResponse(responseEx.getBodyBuffer(),
responseType);
Response response = Response.create(responseEx.getStatusType(), result);
if (response.isFailed()) {
- LOGGER.warn("invoke operation [{}] failed, status={}",
invocation.getMicroserviceQualifiedName(),
- responseEx.getStatusType().getStatusCode());
+ LOGGER.warn("invoke operation [{}] failed, status={}, msg={}",
invocation.getMicroserviceQualifiedName(),
+ responseEx.getStatusType().getStatusCode(), result == null ? "" :
result.toString());
}
return response;
} catch (Exception e) {
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 3bebea7..addb843 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
@@ -253,10 +253,22 @@ public class RestServerVerticle extends AbstractVerticle {
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..36118ad 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.DynamicPropertyFactory;
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 @@ public final class TransportConfig {
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,11 +109,46 @@ public final class TransportConfig {
.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",
- HttpServerOptions.DEFAULT_INITIAL_SETTINGS_MAX_CONCURRENT_STREAMS)
- .get();
+
HttpServerOptions.DEFAULT_INITIAL_SETTINGS_MAX_CONCURRENT_STREAMS).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() {
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..4cacf9e 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 @@ public class TestTransportConfig {
}
@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,12 +193,33 @@ public class TestTransportConfig {
}
@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
public void testUseAlpn() {
Assert.assertTrue(TransportConfig.getUseAlpn());