Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion packages/dart/lib/src/network/options.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
part of '../../parse_server_sdk.dart';

class ParseNetworkOptions {
ParseNetworkOptions({this.headers});
ParseNetworkOptions({this.headers, this.sendInstallationId});

final Map<String, String>? headers;

/// When `false`, the client suppresses the `X-Parse-Installation-Id`
/// header for this request. `null` (the default) lets the client attach
/// the header — matching iOS PFURLSessionCommandRunner behaviour.
final bool? sendInstallationId;
// final ParseNetworkResponseType responseType;
}

Expand Down
27 changes: 27 additions & 0 deletions packages/dart/lib/src/network/parse_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,33 @@ abstract class ParseClient {

@Deprecated("Use ParseCoreData() instead.")
ParseCoreData get data => ParseCoreData();

/// Returns `options.headers` with `X-Parse-Installation-Id` attached unless
/// the caller opted out via `ParseNetworkOptions.sendInstallationId = false`
/// or the header is already set. Installation lookup failures fall through
/// silently — a network call should not fail because the install ID could
/// not be read.
@protected
Future<Map<String, String>?> buildHeaders(
ParseNetworkOptions? options,
) async {
if (options?.sendInstallationId == false) return options?.headers;
if (options?.headers?[keyHeaderInstallationId] != null) {
return options?.headers;
}
String? installationId;
try {
installationId =
(await ParseInstallation.currentInstallation()).installationId;
} catch (_) {
return options?.headers;
}
if (installationId == null) return options?.headers;
return <String, String>{
...?options?.headers,
keyHeaderInstallationId: installationId,
};
}
}

/// Callback to listen the progress for sending/receiving data.
Expand Down
18 changes: 12 additions & 6 deletions packages/dart/lib/src/network/parse_dio_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,13 @@ class ParseDioClient extends ParseClient {
ParseNetworkOptions? options,
ProgressCallback? onReceiveProgress,
}) async {
final Map<String, String>? headers = await buildHeaders(options);
return executeWithRetry(
operation: () async {
try {
final dio.Response<String> dioResponse = await _client.get<String>(
path,
options: _Options(headers: options?.headers),
options: _Options(headers: headers),
);

return ParseNetworkResponse(
Expand All @@ -76,6 +77,7 @@ class ParseDioClient extends ParseClient {
ProgressCallback? onReceiveProgress,
dynamic cancelToken,
}) async {
final Map<String, String>? headers = await buildHeaders(options);
return executeWithRetry(
operation: () async {
try {
Expand All @@ -85,7 +87,7 @@ class ParseDioClient extends ParseClient {
cancelToken: cancelToken,
onReceiveProgress: onReceiveProgress,
options: _Options(
headers: options?.headers,
headers: headers,
responseType: dio.ResponseType.bytes,
),
);
Expand Down Expand Up @@ -116,14 +118,15 @@ class ParseDioClient extends ParseClient {
String? data,
ParseNetworkOptions? options,
}) async {
final Map<String, String>? headers = await buildHeaders(options);
return executeWithRetry(
isWriteOperation: true,
operation: () async {
try {
final dio.Response<String> dioResponse = await _client.put<String>(
path,
data: data,
options: _Options(headers: options?.headers),
options: _Options(headers: headers),
);

return ParseNetworkResponse(
Expand All @@ -146,14 +149,15 @@ class ParseDioClient extends ParseClient {
String? data,
ParseNetworkOptions? options,
}) async {
final Map<String, String>? headers = await buildHeaders(options);
return executeWithRetry(
isWriteOperation: true,
operation: () async {
try {
final dio.Response<String> dioResponse = await _client.post<String>(
path,
data: data,
options: _Options(headers: options?.headers),
options: _Options(headers: headers),
);

return ParseNetworkResponse(
Expand All @@ -178,6 +182,7 @@ class ParseDioClient extends ParseClient {
ProgressCallback? onSendProgress,
dynamic cancelToken,
}) async {
final Map<String, String>? headers = await buildHeaders(options);
return executeWithRetry(
isWriteOperation: true,
operation: () async {
Expand All @@ -186,7 +191,7 @@ class ParseDioClient extends ParseClient {
path,
data: data,
cancelToken: cancelToken,
options: _Options(headers: options?.headers),
options: _Options(headers: headers),
onSendProgress: onSendProgress,
);

Expand Down Expand Up @@ -235,12 +240,13 @@ class ParseDioClient extends ParseClient {
String path, {
ParseNetworkOptions? options,
}) async {
final Map<String, String>? headers = await buildHeaders(options);
return executeWithRetry(
operation: () async {
try {
final dio.Response<String> dioResponse = await _client.delete<String>(
path,
options: _Options(headers: options?.headers),
options: _Options(headers: headers),
);

return ParseNetworkResponse(
Expand Down
18 changes: 12 additions & 6 deletions packages/dart/lib/src/network/parse_http_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,13 @@ class ParseHTTPClient extends ParseClient {
ParseNetworkOptions? options,
ProgressCallback? onReceiveProgress,
}) async {
final Map<String, String>? headers = await buildHeaders(options);
return executeWithRetry(
operation: () async {
try {
final http.Response response = await _client.get(
Uri.parse(path),
headers: options?.headers,
headers: headers,
);
return ParseNetworkResponse(
data: response.body,
Expand All @@ -75,12 +76,13 @@ class ParseHTTPClient extends ParseClient {
ProgressCallback? onReceiveProgress,
dynamic cancelToken,
}) async {
final Map<String, String>? headers = await buildHeaders(options);
return executeWithRetry(
operation: () async {
try {
final http.Response response = await _client.get(
Uri.parse(path),
headers: options?.headers,
headers: headers,
);
return ParseNetworkByteResponse(
bytes: response.bodyBytes,
Expand All @@ -102,14 +104,15 @@ class ParseHTTPClient extends ParseClient {
String? data,
ParseNetworkOptions? options,
}) async {
final Map<String, String>? headers = await buildHeaders(options);
return executeWithRetry(
isWriteOperation: true,
operation: () async {
try {
final http.Response response = await _client.put(
Uri.parse(path),
body: data,
headers: options?.headers,
headers: headers,
);
return ParseNetworkResponse(
data: response.body,
Expand All @@ -131,14 +134,15 @@ class ParseHTTPClient extends ParseClient {
String? data,
ParseNetworkOptions? options,
}) async {
final Map<String, String>? headers = await buildHeaders(options);
return executeWithRetry(
isWriteOperation: true,
operation: () async {
try {
final http.Response response = await _client.post(
Uri.parse(path),
body: data,
headers: options?.headers,
headers: headers,
);
return ParseNetworkResponse(
data: response.body,
Expand All @@ -162,6 +166,7 @@ class ParseHTTPClient extends ParseClient {
ProgressCallback? onSendProgress,
dynamic cancelToken,
}) async {
final Map<String, String>? headers = await buildHeaders(options);
return executeWithRetry(
isWriteOperation: true,
operation: () async {
Expand All @@ -174,7 +179,7 @@ class ParseHTTPClient extends ParseClient {
(List<int> previous, List<int> element) =>
previous..addAll(element),
),
headers: options?.headers,
headers: headers,
);
return ParseNetworkResponse(
data: response.body,
Expand All @@ -195,12 +200,13 @@ class ParseHTTPClient extends ParseClient {
String path, {
ParseNetworkOptions? options,
}) async {
final Map<String, String>? headers = await buildHeaders(options);
return executeWithRetry(
operation: () async {
try {
final http.Response response = await _client.delete(
Uri.parse(path),
headers: options?.headers,
headers: headers,
);
return ParseNetworkResponse(
data: response.body,
Expand Down
38 changes: 8 additions & 30 deletions packages/dart/lib/src/objects/parse_user.dart
Original file line number Diff line number Diff line change
Expand Up @@ -216,15 +216,11 @@ class ParseUser extends ParseObject implements ParseCloneable {
final Uri url = getSanitisedUri(_client, path);
final String body = json.encode(toJson(forApiRQ: true));
_saveChanges();
final String? installationId = await _getInstallationId();
final ParseNetworkResponse response = await _client.post(
url.toString(),
options: ParseNetworkOptions(
headers: <String, String>{
keyHeaderRevocableSession: '1',
if (installationId != null && !doNotSendInstallationID)
keyHeaderInstallationId: installationId,
},
headers: <String, String>{keyHeaderRevocableSession: '1'},
sendInstallationId: !doNotSendInstallationID,
),
data: body,
);
Expand Down Expand Up @@ -255,18 +251,14 @@ class ParseUser extends ParseObject implements ParseCloneable {
keyVarUsername: username!,
keyVarPassword: password!,
};
final String? installationId = await _getInstallationId();
final Uri url = getSanitisedUri(_client, keyEndPointLogin);
_saveChanges();
final ParseNetworkResponse response = await _client.post(
url.toString(),
data: jsonEncode(queryParams),
options: ParseNetworkOptions(
headers: <String, String>{
keyHeaderRevocableSession: '1',
if (installationId != null && !doNotSendInstallationID)
keyHeaderInstallationId: installationId,
},
headers: <String, String>{keyHeaderRevocableSession: '1'},
sendInstallationId: !doNotSendInstallationID,
),
);

Expand All @@ -292,16 +284,12 @@ class ParseUser extends ParseObject implements ParseCloneable {
try {
final Uri url = getSanitisedUri(_client, keyEndPointUsers);
const Uuid uuid = Uuid();
final String? installationId = await _getInstallationId();

final ParseNetworkResponse response = await _client.post(
url.toString(),
options: ParseNetworkOptions(
headers: <String, String>{
keyHeaderRevocableSession: '1',
if (installationId != null && !doNotSendInstallationID)
keyHeaderInstallationId: installationId,
},
headers: <String, String>{keyHeaderRevocableSession: '1'},
sendInstallationId: !doNotSendInstallationID,
),
data: jsonEncode(<String, dynamic>{
'authData': <String, dynamic>{
Expand Down Expand Up @@ -356,17 +344,13 @@ class ParseUser extends ParseObject implements ParseCloneable {
}) async {
try {
final Uri url = getSanitisedUri(_client, keyEndPointUsers);
final String? installationId = await _getInstallationId();
final Map<String, dynamic> body = toJson(forApiRQ: true);
body['authData'] = <String, dynamic>{provider: authData};
final ParseNetworkResponse response = await _client.post(
url.toString(),
options: ParseNetworkOptions(
headers: <String, String>{
keyHeaderRevocableSession: '1',
if (installationId != null && !doNotSendInstallationID)
keyHeaderInstallationId: installationId,
},
headers: <String, String>{keyHeaderRevocableSession: '1'},
sendInstallationId: !doNotSendInstallationID,
),
data: jsonEncode(body),
);
Expand Down Expand Up @@ -630,10 +614,4 @@ class ParseUser extends ParseObject implements ParseCloneable {

static ParseUser _getEmptyUser() =>
ParseCoreData.instance.createParseUser(null, null, null);

static Future<String?> _getInstallationId() async {
final ParseInstallation parseInstallation =
await ParseInstallation.currentInstallation();
return parseInstallation.installationId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -209,4 +209,14 @@ class MockParseClient extends _i1.Mock implements _i2.ParseClient {
),
)
as _i3.Future<_i2.ParseNetworkByteResponse>);

@override
_i3.Future<Map<String, String>?> buildHeaders(
_i2.ParseNetworkOptions? options,
) =>
(super.noSuchMethod(
Invocation.method(#buildHeaders, [options]),
returnValue: _i3.Future<Map<String, String>?>.value(),
)
as _i3.Future<Map<String, String>?>);
}
Loading
Loading