send method
Implementation
@override
Future<http.StreamedResponse> send(http.BaseRequest request) async {
if (Client.cookieStore == null) {
Client.cookieStore = SuperTokensCookieStore();
}
if (!SuperTokens.isInitCalled) {
throw http.ClientException(
"SuperTokens.initialise must be called before using Client");
}
if (SuperTokensUtils.getApiDomain(request.url.toString()) !=
SuperTokens.config.apiDomain) {
return _innerClient.send(request);
}
if (SuperTokensUtils.getApiDomain(request.url.toString()) ==
SuperTokens.refreshTokenUrl) {
return _innerClient.send(request);
}
if (!Utils.shouldDoInterceptions(
request.url.toString(),
SuperTokens.config.apiDomain,
SuperTokens.config.sessionTokenBackendDomain)) {
return _innerClient.send(request);
}
try {
while (true) {
await _refreshAPILock.acquireRead();
// http package does not allow retries with the same request object, so we clone the request when making the network call
http.BaseRequest copiedRequest;
LocalSessionState preRequestLocalSessionState;
http.StreamedResponse response;
try {
copiedRequest = SuperTokensUtils.copyRequest(request);
copiedRequest =
await _removeAuthHeaderIfMatchesLocalToken(copiedRequest);
preRequestLocalSessionState =
await SuperTokensUtils.getLocalSessionState();
String? antiCSRFToken = await AntiCSRF.getToken(
preRequestLocalSessionState.lastAccessTokenUpdate);
if (antiCSRFToken != null) {
copiedRequest.headers[antiCSRFHeaderKey] = antiCSRFToken;
}
SuperTokensTokenTransferMethod tokenTransferMethod =
SuperTokens.config.tokenTransferMethod;
copiedRequest.headers["st-auth-mode"] =
tokenTransferMethod.getValue();
// Adding Authorization headers
copiedRequest =
await Utils.setAuthorizationHeaderIfRequired(copiedRequest);
// Add cookies to request headers
String? newCookiesToAdd = await Client.cookieStore
?.getCookieHeaderStringForRequest(copiedRequest.url);
String? existingCookieHeader =
copiedRequest.headers[HttpHeaders.cookieHeader];
// If the request already has a "cookie" header, combine it with persistent cookies
if (existingCookieHeader != null && existingCookieHeader != "") {
copiedRequest.headers[HttpHeaders.cookieHeader] =
_generateCookieHeader(existingCookieHeader, newCookiesToAdd);
} else {
copiedRequest.headers[HttpHeaders.cookieHeader] =
newCookiesToAdd ?? "";
}
// http package does not allow retries with the same request object, so we clone the request when making the network call
response = await _innerClient.send(copiedRequest);
await Utils.saveTokenFromHeaders(response);
String? frontTokenInHeaders = response.headers[frontTokenHeaderKey];
SuperTokensUtils.fireSessionUpdateEventsIfNecessary(
wasLoggedIn: preRequestLocalSessionState.status ==
LocalSessionStateStatus.EXISTS,
status: response.statusCode,
frontTokenFromResponse: frontTokenInHeaders,
);
// Save cookies from the response
String? setCookieFromResponse =
response.headers[HttpHeaders.setCookieHeader];
await Client.cookieStore?.saveFromSetCookieHeader(
copiedRequest.url, setCookieFromResponse);
} finally {
_refreshAPILock.release();
}
if (response.statusCode == SuperTokens.sessionExpiryStatusCode) {
request = await _removeAuthHeaderIfMatchesLocalToken(copiedRequest);
UnauthorisedResponse shouldRetry =
await onUnauthorisedResponse(preRequestLocalSessionState);
if (shouldRetry.status == UnauthorisedStatus.RETRY) {
// Here we use the original request because it wont contain any of the modifications we make
return await send(request);
} else {
if (shouldRetry.exception != null) {
throw SuperTokensException(shouldRetry.exception!.message);
} else
return response;
}
} else {
return response;
}
}
} finally {
LocalSessionState localSessionState =
await SuperTokensUtils.getLocalSessionState();
if (localSessionState.status == LocalSessionStateStatus.NOT_EXISTS) {
await AntiCSRF.removeToken();
await FrontToken.removeToken();
}
}
}