getHeaders method

Future<Map<String, String>> getHeaders(
  1. HttpOptions? options, {
  2. bool isFile = false,
})

Implementation

Future<Map<String, String>> getHeaders(
  HttpOptions? options, {
  bool isFile = false,
}) async {
  // The caller's headers go down first, minus the ones the transport owns, and
  // the SDK's own go on top. Spreading the caller's map over the SDK's let it
  // replace `x-api-key`, the refresh-token `Cookie` or the transport marker,
  // and the request then came back as an opaque 400. `Authorization` survived
  // only because it happened to be assigned further down.
  //
  // Dropping the reserved names rather than relying on assignment order,
  // because the order alone does not cover a header the SDK sets only
  // sometimes: `x-auth-transport` is written on the auth endpoints, so on
  // every other request a caller's value would have gone out unopposed.
  final headers = <String, String>{};

  // Copied out rather than filtered in place: an HttpOptions may be held and
  // reused by the application, and stripping its map would be a side effect of
  // sending one request that changed the next.
  options?.headers?.forEach((name, value) {
    if (!_isReservedHeader(name)) headers[name] = value;
  });

  headers['x-api-key'] = config.getApiKey();

  if (options?.useAuthBodyTransport == true) {
    headers[authTransportHeader] = 'body';
  }

  // One copy of the credential per request, not two. Setting both
  // `refreshToken` and `useAuthBodyTransport` used to put the token in this
  // Cookie *and* in the JSON body - and `_refreshTokens`, the only caller that
  // passes a refresh token, sets both. Two copies is two chances for a proxy
  // log, a WAF rule or a crash dump to capture it, for no gain: the
  // `x-auth-transport: body` header above exists precisely to tell the API
  // which one to read.
  if (options?.refreshToken != null &&
      options?.useAuthBodyTransport != true) {
    headers['Cookie'] = '$refreshTokenCookieName=${options!.refreshToken}';
  }

  if (options?.refreshToken == null &&
      options?.skipAuthHeader != true &&
      _tokenProvider != null) {
    final token = await _tokenProvider();
    if (token != null) {
      headers['Authorization'] = 'Bearer $token';
    }
  }

  if (isFile != true) {
    headers['Content-Type'] = 'application/json';
  }

  return headers;
}