use of org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError.INVALID_REQUEST in project besu by hyperledger.
the class JsonRpcHttpService method handleJsonBatchRequest.
@SuppressWarnings("rawtypes")
private void handleJsonBatchRequest(final RoutingContext routingContext, final JsonArray jsonArray, final Optional<User> user) {
// Interpret json as rpc request
final List<Future> responses = jsonArray.stream().map(obj -> {
if (!(obj instanceof JsonObject)) {
return Future.succeededFuture(errorResponse(null, INVALID_REQUEST));
}
final JsonObject req = (JsonObject) obj;
return vertx.executeBlocking(future -> future.complete(process(routingContext, req, user)));
}).collect(toList());
CompositeFuture.all(responses).onComplete((res) -> {
final HttpServerResponse response = routingContext.response();
if (response.closed() || response.headWritten()) {
return;
}
if (res.failed()) {
response.setStatusCode(HttpResponseStatus.BAD_REQUEST.code()).end();
return;
}
final JsonRpcResponse[] completed = res.result().list().stream().map(JsonRpcResponse.class::cast).filter(this::isNonEmptyResponses).toArray(JsonRpcResponse[]::new);
try {
// underlying output stream lifecycle is managed by the json object writer
JSON_OBJECT_WRITER.writeValue(new JsonResponseStreamer(response, routingContext.request().remoteAddress()), completed);
} catch (IOException ex) {
LOG.error("Error streaming JSON-RPC response", ex);
}
});
}
use of org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError.INVALID_REQUEST in project besu by hyperledger.
the class WebSocketMessageHandler method handle.
public void handle(final ServerWebSocket websocket, final Buffer buffer, final Optional<User> user) {
if (buffer.length() == 0) {
replyToClient(websocket, errorResponse(null, JsonRpcError.INVALID_REQUEST));
} else {
try {
final JsonObject jsonRpcRequest = buffer.toJsonObject();
vertx.<JsonRpcResponse>executeBlocking(promise -> {
try {
final JsonRpcResponse jsonRpcResponse = jsonRpcExecutor.execute(user, null, null, new IsAliveHandler(ethScheduler, timeoutSec), jsonRpcRequest, req -> {
final WebSocketRpcRequest websocketRequest = req.mapTo(WebSocketRpcRequest.class);
websocketRequest.setConnectionId(websocket.textHandlerID());
return websocketRequest;
});
promise.complete(jsonRpcResponse);
} catch (RuntimeException e) {
promise.fail(e);
}
}).onSuccess(jsonRpcResponse -> replyToClient(websocket, jsonRpcResponse)).onFailure(throwable -> {
try {
final Integer id = jsonRpcRequest.getInteger("id", null);
replyToClient(websocket, errorResponse(id, JsonRpcError.INTERNAL_ERROR));
} catch (ClassCastException idNotIntegerException) {
replyToClient(websocket, errorResponse(null, JsonRpcError.INTERNAL_ERROR));
}
});
} catch (DecodeException jsonObjectDecodeException) {
try {
final JsonArray batchJsonRpcRequest = buffer.toJsonArray();
vertx.<List<JsonRpcResponse>>executeBlocking(promise -> {
List<JsonRpcResponse> responses = new ArrayList<>();
for (int i = 0; i < batchJsonRpcRequest.size(); i++) {
final JsonObject jsonRequest;
try {
jsonRequest = batchJsonRpcRequest.getJsonObject(i);
} catch (ClassCastException e) {
responses.add(new JsonRpcErrorResponse(null, INVALID_REQUEST));
continue;
}
responses.add(jsonRpcExecutor.execute(user, null, null, new IsAliveHandler(ethScheduler, timeoutSec), jsonRequest, req -> {
final WebSocketRpcRequest websocketRequest = req.mapTo(WebSocketRpcRequest.class);
websocketRequest.setConnectionId(websocket.textHandlerID());
return websocketRequest;
}));
}
promise.complete(responses);
}).onSuccess(jsonRpcBatchResponse -> {
final JsonRpcResponse[] completed = jsonRpcBatchResponse.stream().filter(jsonRpcResponse -> jsonRpcResponse.getType() != JsonRpcResponseType.NONE).toArray(JsonRpcResponse[]::new);
replyToClient(websocket, completed);
}).onFailure(throwable -> replyToClient(websocket, errorResponse(null, JsonRpcError.INTERNAL_ERROR)));
} catch (RuntimeException jsonArrayDecodeException) {
replyToClient(websocket, errorResponse(null, JsonRpcError.INTERNAL_ERROR));
}
}
}
}
use of org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError.INVALID_REQUEST in project besu by hyperledger.
the class JsonRpcIpcService method start.
public Future<NetServer> start() {
netServer = vertx.createNetServer(buildNetServerOptions());
netServer.connectHandler(socket -> {
AtomicBoolean closedSocket = new AtomicBoolean(false);
socket.closeHandler(unused -> closedSocket.set(true)).handler(buffer -> {
if (buffer.length() == 0) {
errorReturn(socket, null, JsonRpcError.INVALID_REQUEST);
} else {
try {
final JsonObject jsonRpcRequest = buffer.toJsonObject();
vertx.<JsonRpcResponse>executeBlocking(promise -> {
final JsonRpcResponse jsonRpcResponse = jsonRpcExecutor.execute(Optional.empty(), null, null, closedSocket::get, jsonRpcRequest, req -> req.mapTo(JsonRpcRequest.class));
promise.complete(jsonRpcResponse);
}).onSuccess(jsonRpcResponse -> {
try {
socket.write(JSON_OBJECT_WRITER.writeValueAsString(jsonRpcResponse) + '\n');
} catch (JsonProcessingException e) {
LOG.error("Error streaming JSON-RPC response", e);
}
}).onFailure(throwable -> {
try {
final Integer id = jsonRpcRequest.getInteger("id", null);
errorReturn(socket, id, JsonRpcError.INTERNAL_ERROR);
} catch (ClassCastException idNotIntegerException) {
errorReturn(socket, null, JsonRpcError.INTERNAL_ERROR);
}
});
} catch (DecodeException jsonObjectDecodeException) {
try {
final JsonArray batchJsonRpcRequest = buffer.toJsonArray();
if (batchJsonRpcRequest.isEmpty()) {
errorReturn(socket, null, JsonRpcError.INVALID_REQUEST);
} else {
vertx.<List<JsonRpcResponse>>executeBlocking(promise -> {
List<JsonRpcResponse> responses = new ArrayList<>();
for (int i = 0; i < batchJsonRpcRequest.size(); i++) {
final JsonObject jsonRequest;
try {
jsonRequest = batchJsonRpcRequest.getJsonObject(i);
} catch (ClassCastException e) {
responses.add(new JsonRpcErrorResponse(null, INVALID_REQUEST));
continue;
}
responses.add(jsonRpcExecutor.execute(Optional.empty(), null, null, closedSocket::get, jsonRequest, req -> req.mapTo(JsonRpcRequest.class)));
}
promise.complete(responses);
}).onSuccess(jsonRpcBatchResponse -> {
try {
final JsonRpcResponse[] completed = jsonRpcBatchResponse.stream().filter(jsonRpcResponse -> jsonRpcResponse.getType() != JsonRpcResponseType.NONE).toArray(JsonRpcResponse[]::new);
socket.write(JSON_OBJECT_WRITER.writeValueAsString(completed) + '\n');
} catch (JsonProcessingException e) {
LOG.error("Error streaming JSON-RPC response", e);
}
}).onFailure(throwable -> errorReturn(socket, null, JsonRpcError.INTERNAL_ERROR));
}
} catch (DecodeException jsonArrayDecodeException) {
errorReturn(socket, null, JsonRpcError.PARSE_ERROR);
}
}
}
});
});
return netServer.listen(SocketAddress.domainSocketAddress(path.toString())).onSuccess(successServer -> LOG.info("IPC endpoint opened: {}", path)).onFailure(throwable -> LOG.error("Unable to open IPC endpoint", throwable));
}
use of org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError.INVALID_REQUEST in project besu by hyperledger.
the class JsonRpcExecutorHandler method handler.
public static Handler<RoutingContext> handler(final JsonRpcExecutor jsonRpcExecutor, final Tracer tracer) {
return ctx -> {
HttpServerResponse response = ctx.response();
try {
Optional<User> user = ContextKey.AUTHENTICATED_USER.extractFrom(ctx, Optional::empty);
Context spanContext = ctx.get(SPAN_CONTEXT);
response = response.putHeader("Content-Type", APPLICATION_JSON);
if (ctx.data().containsKey(ContextKey.REQUEST_BODY_AS_JSON_OBJECT.name())) {
JsonObject jsonRequest = ctx.get(ContextKey.REQUEST_BODY_AS_JSON_OBJECT.name());
JsonRpcResponse jsonRpcResponse = jsonRpcExecutor.execute(user, tracer, spanContext, () -> !ctx.response().closed(), jsonRequest, req -> req.mapTo(JsonRpcRequest.class));
response.setStatusCode(status(jsonRpcResponse).code());
if (jsonRpcResponse.getType() == JsonRpcResponseType.NONE) {
response.end();
} else {
try (final JsonResponseStreamer streamer = new JsonResponseStreamer(response, ctx.request().remoteAddress())) {
// underlying output stream lifecycle is managed by the json object writer
JSON_OBJECT_WRITER.writeValue(streamer, jsonRpcResponse);
}
}
} else if (ctx.data().containsKey(ContextKey.REQUEST_BODY_AS_JSON_ARRAY.name())) {
JsonArray batchJsonRequest = ctx.get(ContextKey.REQUEST_BODY_AS_JSON_ARRAY.name());
List<JsonRpcResponse> jsonRpcBatchResponse;
try {
List<JsonRpcResponse> responses = new ArrayList<>();
for (int i = 0; i < batchJsonRequest.size(); i++) {
final JsonObject jsonRequest;
try {
jsonRequest = batchJsonRequest.getJsonObject(i);
} catch (ClassCastException e) {
responses.add(new JsonRpcErrorResponse(null, INVALID_REQUEST));
continue;
}
responses.add(jsonRpcExecutor.execute(user, tracer, spanContext, () -> !ctx.response().closed(), jsonRequest, req -> req.mapTo(JsonRpcRequest.class)));
}
jsonRpcBatchResponse = responses;
} catch (RuntimeException e) {
response.setStatusCode(HttpResponseStatus.BAD_REQUEST.code()).end();
return;
}
final JsonRpcResponse[] completed = jsonRpcBatchResponse.stream().filter(jsonRpcResponse -> jsonRpcResponse.getType() != JsonRpcResponseType.NONE).toArray(JsonRpcResponse[]::new);
try (final JsonResponseStreamer streamer = new JsonResponseStreamer(response, ctx.request().remoteAddress())) {
// underlying output stream lifecycle is managed by the json object writer
JSON_OBJECT_WRITER.writeValue(streamer, completed);
}
} else {
handleJsonRpcError(ctx, null, JsonRpcError.PARSE_ERROR);
}
} catch (IOException ex) {
LOG.error("Error streaming JSON-RPC response", ex);
} catch (RuntimeException e) {
handleJsonRpcError(ctx, null, JsonRpcError.INTERNAL_ERROR);
}
};
}
use of org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcError.INVALID_REQUEST in project besu by hyperledger.
the class WebSocketRequestHandler method executeHandler.
private Handler<Promise<Object>> executeHandler(final Optional<AuthenticationService> authenticationService, final ServerWebSocket websocket, final String payload, final Optional<User> user, final Collection<String> noAuthApiMethods) {
return future -> {
final String json = payload.trim();
if (!json.isEmpty() && json.charAt(0) == '{') {
try {
handleSingleRequest(authenticationService, websocket, user, future, getRequest(payload), noAuthApiMethods);
} catch (final IllegalArgumentException | DecodeException e) {
LOG.debug("Error mapping json to WebSocketRpcRequest", e);
future.complete(new JsonRpcErrorResponse(null, JsonRpcError.INVALID_REQUEST));
return;
}
} else if (json.length() == 0) {
future.complete(errorResponse(null, INVALID_REQUEST));
return;
} else {
final JsonArray jsonArray = new JsonArray(json);
if (jsonArray.size() < 1) {
future.complete(errorResponse(null, INVALID_REQUEST));
return;
}
// handle batch request
LOG.debug("batch request size {}", jsonArray.size());
handleJsonBatchRequest(authenticationService, websocket, jsonArray, user, noAuthApiMethods);
}
};
}
Aggregations