handle method

Implementation

Future<CockpitRemoteSessionEndpointResponse> handle(
  CockpitRemoteSessionEndpointRequest request,
) async {
  try {
    final routePath = _routePathFor(request.uri.path);
    switch ((request.method, routePath)) {
      case ('GET', '/ping'):
        return CockpitRemoteSessionEndpointResponse.json(_pingPayload());
      case ('GET', '/ready'):
        return CockpitRemoteSessionEndpointResponse.json(
          await _readyPayload(),
        );
      case ('GET', '/health'):
        return CockpitRemoteSessionEndpointResponse.json(
          (await _statusProvider()).toJson(),
        );
      case ('GET', '/snapshot'):
        final snapshotOptions = _snapshotOptionsFromQuery(
          request.uri.queryParameters,
        );
        final snapshot = await _snapshotProvider(options: snapshotOptions);
        final snapshotResponse = await _snapshotResponseFor(
          snapshot,
          options: snapshotOptions,
        );
        return CockpitRemoteSessionEndpointResponse.json(
          snapshotResponse.artifactDownloads.isEmpty
              ? snapshotResponse.snapshot.toJson()
              : snapshotResponse.toJson(),
        );
      case ('GET', '/artifacts/download'):
        return _artifactResponseFor(request);
      case ('POST', '/commands/execute'):
        final command = _decodePayload(
          () => CockpitCommand.fromJson(request.jsonBody),
        );
        await _drainRuntimeSteps(clear: true);
        final execution = await _executeCommandWithinBudget(command);
        final runtimeSteps = await _drainRuntimeSteps(clear: true);
        final artifactRegistration = await _registerCommandArtifacts(
          execution,
        );
        final responsePayload = CockpitRemoteCommandResponse.fromExecution(
          CockpitCommandExecution(
            result: execution.result,
            artifactPayloads: artifactRegistration.inlinePayloads,
            runtimeSteps: <CockpitStepRecord>[
              ...execution.runtimeSteps,
              ...runtimeSteps,
            ],
          ),
        ).toJson();
        if (artifactRegistration.downloads.isNotEmpty) {
          responsePayload['artifactDownloads'] = artifactRegistration
              .downloads
              .map((download) => download.toJson())
              .toList(growable: false);
        }
        return CockpitRemoteSessionEndpointResponse.json(responsePayload);
      case ('POST', '/recording/start'):
        final recordingRequest = _decodePayload(
          () => CockpitRecordingRequest.fromJson(request.jsonBody),
        );
        final recording = await _handleStartRecording(recordingRequest);
        return CockpitRemoteSessionEndpointResponse.json(recording.toJson());
      case ('POST', '/recording/stop'):
        final result = await _handleStopRecording();
        final response = await _recordingResponseFor(result);
        return CockpitRemoteSessionEndpointResponse.json(response.toJson());
      default:
        return const CockpitRemoteSessionEndpointResponse.json(
          <String, Object?>{
            'error': 'notFound',
            'message': 'Unsupported remote session endpoint.',
          },
          statusCode: HttpStatus.notFound,
        );
    }
  } on FormatException catch (error) {
    return CockpitRemoteSessionEndpointResponse.json(<String, Object?>{
      'error': 'invalidPayload',
      'message': error.message,
    }, statusCode: HttpStatus.badRequest);
  } catch (error) {
    return CockpitRemoteSessionEndpointResponse.json(<String, Object?>{
      'error': 'serverError',
      'message': error.toString(),
    }, statusCode: HttpStatus.internalServerError);
  }
}