You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hugegraph.apache.org by ji...@apache.org on 2026/10/07 14:38:41 UTC
(hugegraph) branch master updated: fix(common): encode REST bodies as UTF-8 (#3281)
This is an automated email from the ASF dual-hosted git repository.
imbajin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hugegraph.git
The following commit(s) were added to refs/heads/master by this push:
new e62c961e0 fix(common): encode REST bodies as UTF-8 (#3281)
e62c961e0 is described below
commit e62c961e00221569d4f955abbadf60faee45b283
Author: imbajin <ji...@apache.org>
AuthorDate: Wed Oct 7 22:38:36 2026 +0800
fix(common): encode REST bodies as UTF-8 (#3281)
OkHttp encodes text request bodies as UTF-8 by default and declares the charset. Explicit caller-provided charsets remain supported.
---
.../apache/hugegraph/rest/AbstractRestClient.java | 2 +-
.../unit/rest/AbstractRestClientTest.java | 104 +++++++++++++++++++++
2 files changed, 105 insertions(+), 1 deletion(-)
diff --git a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/AbstractRestClient.java b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/AbstractRestClient.java
index c13a686b7..91fa90bf2 100644
--- a/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/AbstractRestClient.java
+++ b/hugegraph-commons/hugegraph-common/src/main/java/org/apache/hugegraph/rest/AbstractRestClient.java
@@ -138,7 +138,7 @@ public abstract class AbstractRestClient implements RestClient {
} else {
bodyContent = String.valueOf(body);
}
- RequestBody requestBody = RequestBody.create(bodyContent.getBytes(),
+ RequestBody requestBody = RequestBody.create(bodyContent,
MediaType.parse(contentType));
if (headers != null &&
diff --git a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/rest/AbstractRestClientTest.java b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/rest/AbstractRestClientTest.java
index b2d2b1a3b..a19e44592 100644
--- a/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/rest/AbstractRestClientTest.java
+++ b/hugegraph-commons/hugegraph-common/src/test/java/org/apache/hugegraph/unit/rest/AbstractRestClientTest.java
@@ -17,12 +17,116 @@
package org.apache.hugegraph.unit.rest;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Collections;
+import java.util.concurrent.TimeUnit;
+
import org.apache.hugegraph.rest.AbstractRestClient;
+import org.apache.hugegraph.rest.RestHeaders;
+import org.apache.hugegraph.testutil.Whitebox;
import org.junit.Assert;
import org.junit.Test;
+import okhttp3.RequestBody;
+import okio.Buffer;
+import okio.GzipSource;
+
public class AbstractRestClientTest {
+ @Test
+ public void testRequestBodiesWithAsciiDefaultCharset() throws Exception {
+ String java = Paths.get(System.getProperty("java.home"), "bin", "java").toString();
+ String classpath = System.getProperty("surefire.test.class.path",
+ System.getProperty("java.class.path"));
+ Path output = Files.createTempFile("rest-client-ascii-", ".log");
+ Process process = null;
+ try {
+ process = new ProcessBuilder(java, "-Dfile.encoding=US-ASCII", "-cp", classpath,
+ AsciiRequestBodyProbe.class.getName())
+ .redirectErrorStream(true)
+ .redirectOutput(output.toFile())
+ .start();
+ boolean finished = process.waitFor(60, TimeUnit.SECONDS);
+ String diagnostic = Files.readString(output, StandardCharsets.UTF_8);
+ Assert.assertTrue("US-ASCII probe timed out: " + diagnostic, finished);
+ Assert.assertEquals(diagnostic, 0, process.exitValue());
+ } finally {
+ if (process != null && process.isAlive()) {
+ process.destroyForcibly();
+ process.waitFor(5, TimeUnit.SECONDS);
+ }
+ Files.deleteIfExists(output);
+ }
+ }
+
+ public static class AsciiRequestBodyProbe {
+
+ public static void main(String[] args) throws IOException {
+ Assert.assertEquals(StandardCharsets.US_ASCII, Charset.defaultCharset());
+ AbstractRestClientTest tests = new AbstractRestClientTest();
+ tests.testJsonRequestBodyUsesUtf8();
+ tests.testGzipRequestBodyUsesUtf8();
+ tests.testRequestBodyRespectsExplicitCharset();
+ }
+ }
+
+ @Test
+ public void testJsonRequestBodyUsesUtf8() throws IOException {
+ String json = "{\"id\":\"\u4f60\u597d\ud83d\ude80\"}";
+ assertUtf8Body(json, null, json, false);
+ assertUtf8Body(Collections.singletonMap("id", "\u4f60\u597d\ud83d\ude80"),
+ new RestHeaders(), json, false);
+ }
+
+ @Test
+ public void testGzipRequestBodyUsesUtf8() throws IOException {
+ String json = "{\"id\":\"\u4f60\u597d\ud83d\ude80\"}";
+ RestHeaders headers = new RestHeaders().add(RestHeaders.CONTENT_ENCODING, "gzip");
+ assertUtf8Body(json, headers, json, true);
+ }
+
+ @Test
+ public void testRequestBodyRespectsExplicitCharset() throws IOException {
+ RestHeaders headers = new RestHeaders().add(RestHeaders.CONTENT_TYPE,
+ "text/plain; charset=iso-8859-1");
+ RequestBody body = requestBody("caf\u00e9", headers);
+ Buffer buffer = new Buffer();
+ body.writeTo(buffer);
+ Assert.assertEquals(StandardCharsets.ISO_8859_1, body.contentType().charset());
+ Assert.assertArrayEquals("caf\u00e9".getBytes(StandardCharsets.ISO_8859_1),
+ buffer.readByteArray());
+ }
+
+ private static void assertUtf8Body(Object value, RestHeaders headers,
+ String expected, boolean gzip) throws IOException {
+ RequestBody body = requestBody(value, headers);
+ Assert.assertEquals(StandardCharsets.UTF_8, body.contentType().charset());
+ Buffer buffer = new Buffer();
+ body.writeTo(buffer);
+ if (gzip) {
+ try (GzipSource source = new GzipSource(buffer)) {
+ Buffer decoded = new Buffer();
+ decoded.writeAll(source);
+ Assert.assertArrayEquals(expected.getBytes(StandardCharsets.UTF_8),
+ decoded.readByteArray());
+ }
+ } else {
+ Assert.assertArrayEquals(expected.getBytes(StandardCharsets.UTF_8),
+ buffer.readByteArray());
+ }
+ }
+
+ private static RequestBody requestBody(Object value, RestHeaders headers) {
+ return Whitebox.invokeStatic(AbstractRestClient.class,
+ new Class<?>[]{Object.class, RestHeaders.class},
+ "buildRequestBody", value, headers);
+ }
+
@Test
public void testEncodeWithSpaces() {
String raw = "hello world";