Skip to content

Commit

Permalink
Merge pull request #1650 from EnsembleUI/cookie0x45
Browse files Browse the repository at this point in the history
added cookie property in api body
  • Loading branch information
TheNoumanDev authored Oct 9, 2024
2 parents 076048b + eeb436d commit e1cdfb1
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ abstract class Response {
Map<String, dynamic>? headers;
int? statusCode;
String? reasonPhrase;
Map<String, String> get cookies => {};
updateState({required apiState}) {
this.apiState = apiState;
}
Expand Down
55 changes: 51 additions & 4 deletions modules/ensemble/lib/framework/apiproviders/http_api_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ import 'package:http/io_client.dart';
import 'package:yaml/yaml.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/foundation.dart' as foundation;
import 'package:cookie_jar/cookie_jar.dart';

class HTTPAPIProvider extends APIProvider {
final CookieJar _cookieJar = CookieJar();
@override
Future<HttpResponse> invokeApi(BuildContext context, YamlMap api,
DataContext eContext, String apiName) async {
Expand Down Expand Up @@ -126,6 +128,8 @@ class HTTPAPIProvider extends APIProvider {
env?['ssl_pinning_enabled']?.toLowerCase() == 'true';
String? sslPinningCertificate = secrets?['ssl_pinning_certificate'];

bool manageCookies = Utils.getBool(api['manageCookies'], fallback: false);

Completer<http.Response> completer = Completer();
http.Response response;

Expand All @@ -134,6 +138,15 @@ class HTTPAPIProvider extends APIProvider {
sslPinningEnabled: sslPinningEnabled,
sslPinningCertificate: sslPinningCertificate,
);

if (!kIsWeb && manageCookies) {
List<Cookie> cookies = await _cookieJar.loadForRequest(Uri.parse(url));
String cookieString = cookies.map((cookie) => '${cookie.name}=${cookie.value}').join('; ');
if (cookieString.isNotEmpty) {
headers['Cookie'] = cookieString;
}
}

switch (method) {
case 'POST':
response =
Expand All @@ -156,16 +169,28 @@ class HTTPAPIProvider extends APIProvider {
response = await client.get(Uri.parse(url), headers: headers);
break;
}
// Store cookies for native apps
if (!kIsWeb && manageCookies) {
_cookieJar.saveFromResponse(Uri.parse(url), _extractCookies(response));
}

final isOkay = response.statusCode >= 200 && response.statusCode <= 299;
log('Response: ${response.statusCode}');
return HttpResponse(response, isOkay ? APIState.success : APIState.error,
apiName: apiName);
apiName: apiName, manageCookies: manageCookies);
} catch (e) {
return _handleError(e, apiName);
}
}

List<Cookie> _extractCookies(http.Response response) {
List<Cookie> cookies = [];
response.headers['set-cookie']?.split(',').forEach((String cookie) {
cookies.add(Cookie.fromSetCookieValue(cookie));
});
return cookies;
}

Future<http.Client> _getHttpClient({
required bool sslPinningEnabled,
String? sslPinningCertificate,
Expand Down Expand Up @@ -301,12 +326,16 @@ class HTTPAPIProvider extends APIProvider {

/// a wrapper class around the http Response
class HttpResponse extends Response {
HttpResponse.updateState({required apiState}) {
final bool _manageCookies;
late Map<String, String> _cookies;

HttpResponse.updateState({required apiState}) : _manageCookies = false {
super.updateState(apiState: apiState);
}
// APIState get apiState => _apiState;
HttpResponse.fromBody(dynamic body,
[headers, statusCode, reasonPhrase, apiState = APIState.idle]) {
[headers, statusCode, reasonPhrase, apiState = APIState.idle])
: _manageCookies = false {
super.body = body;
super.headers = headers;
super.statusCode = statusCode;
Expand All @@ -315,7 +344,8 @@ class HttpResponse extends Response {
}

HttpResponse(http.Response response, APIState apiState,
{String apiName = ''}) {
{String apiName = '', bool manageCookies = false})
: _manageCookies = manageCookies {
try {
body = json.decode(response.body);
} on FormatException catch (_, e) {
Expand All @@ -326,7 +356,24 @@ class HttpResponse extends Response {
statusCode = response.statusCode;
reasonPhrase = response.reasonPhrase;
apiName = apiName;
_cookies = _parseCookies(response);
}

Map<String, String> _parseCookies(http.Response response) {
Map<String, String> cookies = {};
if (_manageCookies) {
response.headers['set-cookie']?.split(',').forEach((String rawCookie) {
List<String> cookieParts = rawCookie.split(';')[0].split('=');
if (cookieParts.length == 2) {
cookies[cookieParts[0].trim()] = cookieParts[1].trim();
}
});
}
return cookies;
}

Map<String, String> get cookies => _cookies;

@override
bool get isOkay =>
statusCode != null && statusCode! >= 200 && statusCode! <= 299;
Expand Down
3 changes: 2 additions & 1 deletion modules/ensemble/lib/framework/data_context.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1151,7 +1151,8 @@ class APIResponse with Invokable {
'body': () => _response?.body,
'headers': () => _response?.headers,
'statusCode': () => _response?.statusCode,
'reasonPhrase': () => _response?.reasonPhrase
'reasonPhrase': () => _response?.reasonPhrase,
'cookies': () => _response?.cookies,
};
}

Expand Down
1 change: 1 addition & 0 deletions modules/ensemble/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ dependencies:
fluttertoast: 8.2.2
video_player: ^2.6.1
lottie: ^3.0.0
cookie_jar: ^4.0.8
js_widget:
git:
url: https://github.com/EnsembleUI/ensemble.git
Expand Down
6 changes: 4 additions & 2 deletions modules/ensemble_ts_interpreter/lib/api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ class API {
String name, uri;
Map<String, String>? params;
String method = 'get';
API(this.name, this.uri, this.params);
bool manageCookies = false;
API(this.name, this.uri, this.params, {this.manageCookies = false});
Future<http.Response> call(Map<String, String>? paramValues) async {
Map<String, String> m = HashMap();
if (params != null) {
Expand Down Expand Up @@ -38,7 +39,8 @@ class API {
params[k.toString()] = v.toString();
});
}
return API(name, uri, params);
bool manageCookies = map['manageCookies'] == true;
return API(name, uri, params, manageCookies: manageCookies);
}
}

Expand Down

0 comments on commit e1cdfb1

Please sign in to comment.