Skip to content

Commit 304d159

Browse files
committed
Make the JSON-RPC output more compliant with the JSON-RPC specification.
1 parent 0dd5139 commit 304d159

1 file changed

Lines changed: 27 additions & 3 deletions

File tree

framework/src/main/java/org/tron/core/services/jsonrpc/JsonRpcServlet.java

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package org.tron.core.services.jsonrpc;
22

3+
import com.fasterxml.jackson.core.JsonFactory;
34
import com.fasterxml.jackson.core.JsonProcessingException;
5+
import com.fasterxml.jackson.core.StreamReadConstraints;
46
import com.fasterxml.jackson.databind.JsonNode;
57
import com.fasterxml.jackson.databind.ObjectMapper;
68
import com.fasterxml.jackson.databind.node.ArrayNode;
@@ -30,7 +32,19 @@
3032
@Slf4j(topic = "API")
3133
public class JsonRpcServlet extends RateLimiterServlet {
3234

33-
private static final ObjectMapper MAPPER = new ObjectMapper();
35+
// Snapshot of node.http.maxNestingDepth / maxTokenCount at class-load time (after Args.setParam).
36+
private static final ObjectMapper MAPPER = buildMapper();
37+
38+
private static ObjectMapper buildMapper() {
39+
CommonParameter p = CommonParameter.getInstance();
40+
JsonFactory factory = JsonFactory.builder()
41+
.streamReadConstraints(StreamReadConstraints.builder()
42+
.maxNestingDepth(p.getMaxNestingDepth())
43+
.maxTokenCount(p.getMaxTokenCount())
44+
.build())
45+
.build();
46+
return new ObjectMapper(factory);
47+
}
3448

3549
private enum JsonRpcError {
3650
PARSE_ERROR(-32700),
@@ -105,6 +119,11 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I
105119
return;
106120
}
107121

122+
if (!rootNode.isObject() && !rootNode.isArray()) {
123+
writeJsonRpcError(resp, JsonRpcError.INVALID_REQUEST, "Invalid Request", null, false);
124+
return;
125+
}
126+
108127
boolean isBatch = rootNode.isArray();
109128
if (isBatch && rootNode.isEmpty()) {
110129
writeJsonRpcError(resp, JsonRpcError.INVALID_REQUEST, "Invalid Request", null, false);
@@ -158,6 +177,11 @@ private void handleBatch(HttpServletResponse resp, JsonNode rootNode, int maxRes
158177
for (int i = 0; i < rootNode.size(); i++) {
159178
JsonNode subRequest = rootNode.get(i);
160179

180+
if (!subRequest.isObject()) {
181+
batchResult.add(buildErrorNode(JsonRpcError.INVALID_REQUEST, "Invalid Request", null));
182+
continue;
183+
}
184+
161185
if (overflow) {
162186
// Notifications (no "id") do not get a response even on overflow.
163187
if (subRequest.has("id")) {
@@ -219,7 +243,7 @@ private void handleBatch(HttpServletResponse resp, JsonNode rootNode, int maxRes
219243
}
220244

221245
byte[] finalBytes = MAPPER.writeValueAsBytes(batchResult);
222-
resp.setContentType("application/json-rpc; charset=utf-8");
246+
resp.setContentType("application/json-rpc");
223247
resp.setStatus(HttpServletResponse.SC_OK);
224248
resp.setContentLength(finalBytes.length);
225249
resp.getOutputStream().write(finalBytes);
@@ -261,7 +285,7 @@ private void writeJsonRpcError(HttpServletResponse resp, JsonRpcError error, Str
261285
} else {
262286
bytes = MAPPER.writeValueAsBytes(errorObj);
263287
}
264-
resp.setContentType("application/json-rpc; charset=utf-8");
288+
resp.setContentType("application/json-rpc");
265289
resp.setStatus(HttpServletResponse.SC_OK);
266290
resp.setContentLength(bytes.length);
267291
resp.getOutputStream().write(bytes);

0 commit comments

Comments
 (0)