get<T> method

Future<XRPCResponse<T>> get<T>(
  1. NSID methodId, {
  2. String? service,
  3. Map<String, String>? headers,
  4. Map<String, dynamic>? parameters,
  5. ResponseDataBuilder<T>? to,
  6. ResponseDataAdaptor? adaptor,
  7. GetClient? client,
})

Implementation

Future<xrpc.XRPCResponse<T>> get<T>(
  final NSID methodId, {
  final String? service,
  final Map<String, String>? headers,
  final Map<String, dynamic>? parameters,
  final xrpc.ResponseDataBuilder<T>? to,
  final xrpc.ResponseDataAdaptor? adaptor,
  final xrpc.GetClient? client,
}) async {
  await _state.refreshIfExpiring();
  await _ensureOAuthSessionResolved();
  final resolvedService = service ?? this.service;
  final endpoint = _endpointFor(resolvedService, methodId);

  final callerHeaders = {..._headers ?? const {}, ...headers ?? const {}};
  final callerHasAuth = _hasAuthorization(callerHeaders);

  // The access token the most recent attempt actually went out with, so a
  // `401` can be matched against the session that provoked it. Local to
  // this request: concurrent requests must not overwrite each other's.
  String? usedAccessToken;

  return await _challenge.execute(
    () async {
      usedAccessToken = null;
      // When the caller already supplied an `Authorization` header (e.g. a
      // service-auth Bearer token for the video service), leave it intact:
      // do not attach the OAuth DPoP `Authorization`/proof that would
      // clobber it.
      final oauthHeaders = callerHasAuth
          ? const <String, String>{}
          : await _oauthAuthHeaders(endpoint, 'GET');
      usedAccessToken = _credentialOf(oauthHeaders);
      return await xrpc.query(
        methodId,
        protocol: _protocol,
        service: resolvedService,
        headers: {...callerHeaders, ...oauthHeaders},
        parameters: parameters,
        to: to,
        adaptor: adaptor,
        timeout: _timeout,
        // Legacy Bearer path still uses the sync header builder; OAuth
        // headers are already merged above, so only attach the builder
        // when there is no OAuth manager.
        headerBuilder: _buildAuthHeaderRecording((t) => usedAccessToken = t),
        getClient: client ?? _getClient,
      );
    },
    isProcedure: false,
    nsid: methodId.toString(),
    onUpdateDpopNonce: (h) => _onUpdateDpopNonce(endpoint, h),
    onUnauthorized: (e) => _onUnauthorized(e, usedAccessToken),
  );
}