mirror of
https://github.com/dart-lang/sdk
synced 2024-09-18 20:51:19 +00:00
[ package:vm_service ] Fix VmServerConnection always responding with a string ID
VmServerConnection was converting request IDs into Strings, even if the ID was an integer. This resulted in request responses always having string IDs which does not conform to the JSON-RPC spec and breaks package:json_rpc_2. Change-Id: Ia42d2fbf5a32b88c57b827f493a1847119e8a08c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/161441 Reviewed-by: Devon Carew <devoncarew@google.com> Commit-Queue: Ben Konyi <bkonyi@google.com>
This commit is contained in:
parent
fb0729b35d
commit
f00e45d9b8
|
@ -4,6 +4,7 @@
|
|||
- Added `isSystemIsolate` property to `IsolateRef` and `Isolate`.
|
||||
- Added `isSystemIsolateGroup` property to `IsolateGroupRef` and `IsolateGroup`.
|
||||
- Added `serviceIsolates` and `serviceIsolateGroups` properties to `VM`.
|
||||
- Fixed issue where `VmServerConnection` would always response with a string ID even if the request ID was not a string.
|
||||
|
||||
## 4.2.0
|
||||
- Update to version `3.37.0` of the spec.
|
||||
|
|
|
@ -1166,6 +1166,20 @@ abstract class VmServiceInterface {
|
|||
Future<Success> streamListen(String streamId);
|
||||
}
|
||||
|
||||
class _PendingServiceRequest {
|
||||
Future<Map<String, Object>> get future => _completer.future;
|
||||
final _completer = Completer<Map<String, Object>>();
|
||||
|
||||
final dynamic originalId;
|
||||
|
||||
_PendingServiceRequest(this.originalId);
|
||||
|
||||
void complete(Map<String, Object> response) {
|
||||
response['id'] = originalId;
|
||||
_completer.complete(response);
|
||||
}
|
||||
}
|
||||
|
||||
/// A Dart VM Service Protocol connection that delegates requests to a
|
||||
/// [VmServiceInterface] implementation.
|
||||
///
|
||||
|
@ -1189,8 +1203,7 @@ class VmServerConnection {
|
|||
final _doneCompleter = Completer<Null>();
|
||||
|
||||
/// Pending service extension requests to this client by id.
|
||||
final _pendingServiceExtensionRequests =
|
||||
<String, Completer<Map<String, Object>>>{};
|
||||
final _pendingServiceExtensionRequests = <dynamic, _PendingServiceRequest>{};
|
||||
|
||||
VmServerConnection(this._requestStream, this._responseSink,
|
||||
this._serviceExtensionRegistry, this._serviceImplementation) {
|
||||
|
@ -1212,21 +1225,19 @@ class VmServerConnection {
|
|||
// multiple clients ids.
|
||||
var newId = '${_nextServiceRequestId++}:$originalId';
|
||||
request['id'] = newId;
|
||||
var responseCompleter = Completer<Map<String, Object>>();
|
||||
_pendingServiceExtensionRequests[newId] = responseCompleter;
|
||||
var pendingRequest = _PendingServiceRequest(originalId);
|
||||
_pendingServiceExtensionRequests[newId] = pendingRequest;
|
||||
_responseSink.add(request);
|
||||
return responseCompleter.future;
|
||||
return pendingRequest.future;
|
||||
}
|
||||
|
||||
void _delegateRequest(Map<String, Object> request) async {
|
||||
try {
|
||||
var id = request['id'] as String;
|
||||
var id = request['id'];
|
||||
// Check if this is actually a response to a pending request.
|
||||
if (_pendingServiceExtensionRequests.containsKey(id)) {
|
||||
// Restore the original request ID.
|
||||
var originalId = id.substring(id.indexOf(':') + 1);
|
||||
_pendingServiceExtensionRequests[id]
|
||||
.complete(Map.of(request)..['id'] = originalId);
|
||||
final pending = _pendingServiceExtensionRequests[id];
|
||||
pending.complete(Map.of(request));
|
||||
return;
|
||||
}
|
||||
var method = request['method'] as String;
|
||||
|
|
|
@ -627,6 +627,20 @@ abstract class VmServiceInterface {
|
|||
// The server class, takes a VmServiceInterface and delegates to it
|
||||
// automatically.
|
||||
gen.write('''
|
||||
class _PendingServiceRequest {
|
||||
Future<Map<String, Object>> get future => _completer.future;
|
||||
final _completer = Completer<Map<String, Object>>();
|
||||
|
||||
final dynamic originalId;
|
||||
|
||||
_PendingServiceRequest(this.originalId);
|
||||
|
||||
void complete(Map<String, Object> response) {
|
||||
response['id'] = originalId;
|
||||
_completer.complete(response);
|
||||
}
|
||||
}
|
||||
|
||||
/// A Dart VM Service Protocol connection that delegates requests to a
|
||||
/// [VmServiceInterface] implementation.
|
||||
///
|
||||
|
@ -649,8 +663,7 @@ abstract class VmServiceInterface {
|
|||
final _doneCompleter = Completer<Null>();
|
||||
|
||||
/// Pending service extension requests to this client by id.
|
||||
final _pendingServiceExtensionRequests =
|
||||
<String, Completer<Map<String, Object>>>{};
|
||||
final _pendingServiceExtensionRequests = <dynamic, _PendingServiceRequest>{};
|
||||
|
||||
VmServerConnection(
|
||||
this._requestStream, this._responseSink, this._serviceExtensionRegistry,
|
||||
|
@ -673,21 +686,19 @@ abstract class VmServiceInterface {
|
|||
// multiple clients ids.
|
||||
var newId = '\${_nextServiceRequestId++}:\$originalId';
|
||||
request['id'] = newId;
|
||||
var responseCompleter = Completer<Map<String, Object>>();
|
||||
_pendingServiceExtensionRequests[newId] = responseCompleter;
|
||||
var pendingRequest = _PendingServiceRequest(originalId);
|
||||
_pendingServiceExtensionRequests[newId] = pendingRequest;
|
||||
_responseSink.add(request);
|
||||
return responseCompleter.future;
|
||||
return pendingRequest.future;
|
||||
}
|
||||
|
||||
void _delegateRequest(Map<String, Object> request) async {
|
||||
try {
|
||||
var id = request['id'] as String;
|
||||
var id = request['id'];
|
||||
// Check if this is actually a response to a pending request.
|
||||
if (_pendingServiceExtensionRequests.containsKey(id)) {
|
||||
// Restore the original request ID.
|
||||
var originalId = id.substring(id.indexOf(':') + 1);
|
||||
_pendingServiceExtensionRequests[id].complete(
|
||||
Map.of(request)..['id'] = originalId);
|
||||
final pending = _pendingServiceExtensionRequests[id];
|
||||
pending.complete(Map.of(request));
|
||||
return;
|
||||
}
|
||||
var method = request['method'] as String;
|
||||
|
|
Loading…
Reference in a new issue