From ad916de425a7630acd5ed13e80780205c8acafa1 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 23 Jul 2021 10:27:31 +0200 Subject: [PATCH 1/5] add additional qs and header to http client; add additional queryParams to websocket --- .../stream_chat/lib/src/client/client.dart | 7 ++++++ .../lib/src/core/http/stream_http_client.dart | 7 ++++-- .../core/http/stream_http_client_options.dart | 22 +++++++++++++++---- .../stream_chat/lib/src/ws/websocket.dart | 6 +++++ packages/stream_chat/lib/version.dart | 6 +++++ 5 files changed, 42 insertions(+), 6 deletions(-) diff --git a/packages/stream_chat/lib/src/client/client.dart b/packages/stream_chat/lib/src/client/client.dart index 050d36f1..3d314063 100644 --- a/packages/stream_chat/lib/src/client/client.dart +++ b/packages/stream_chat/lib/src/client/client.dart @@ -31,6 +31,7 @@ import 'package:stream_chat/src/event_type.dart'; import 'package:stream_chat/src/location.dart'; import 'package:stream_chat/src/ws/connection_status.dart'; import 'package:stream_chat/src/ws/websocket.dart'; +import 'package:stream_chat/version.dart'; /// Handler function used for logging records. Function requires a single /// [LogRecord] as the only parameter. @@ -80,6 +81,9 @@ class StreamChatClient { location: location, connectTimeout: connectTimeout, receiveTimeout: receiveTimeout, + headers: { + 'X-Stream-Client': userAgent, + }, ); _chatApi = chatApi ?? @@ -99,6 +103,9 @@ class StreamChatClient { tokenManager: _tokenManager, handler: handleEvent, logger: detachedLogger('🔌'), + queryParams: { + 'X-Stream-Client': userAgent, + }, ); _retryPolicy = retryPolicy ?? diff --git a/packages/stream_chat/lib/src/core/http/stream_http_client.dart b/packages/stream_chat/lib/src/core/http/stream_http_client.dart index 406138c3..c5f46144 100644 --- a/packages/stream_chat/lib/src/core/http/stream_http_client.dart +++ b/packages/stream_chat/lib/src/core/http/stream_http_client.dart @@ -33,11 +33,14 @@ class StreamHttpClient { ..options.baseUrl = _options.baseUrl ..options.receiveTimeout = _options.receiveTimeout.inMilliseconds ..options.connectTimeout = _options.connectTimeout.inMilliseconds - ..options.queryParameters = {'api_key': apiKey} + ..options.queryParameters = { + 'api_key': apiKey, + ..._options.queryParams, + } ..options.headers = { 'Content-Type': 'application/json', - 'X-Stream-Client': _options.userAgent, 'Content-Encoding': 'application/gzip', + ..._options.headers, } ..interceptors.addAll([ if (tokenManager != null) AuthInterceptor(this, tokenManager), diff --git a/packages/stream_chat/lib/src/core/http/stream_http_client_options.dart b/packages/stream_chat/lib/src/core/http/stream_http_client_options.dart index faad46a1..a2fe22e8 100644 --- a/packages/stream_chat/lib/src/core/http/stream_http_client_options.dart +++ b/packages/stream_chat/lib/src/core/http/stream_http_client_options.dart @@ -10,6 +10,8 @@ class StreamHttpClientOptions { this.location, this.connectTimeout = const Duration(seconds: 6), this.receiveTimeout = const Duration(seconds: 6), + this.queryParams = const {}, + this.headers = const {}, }) : _baseUrl = baseUrl ?? _defaultBaseURL; final String _baseUrl; @@ -32,8 +34,20 @@ class StreamHttpClientOptions { /// received timeout, default to 6s final Duration receiveTimeout; - /// Get the current user agent - String get userAgent => 'stream-chat-dart-client-' - '${CurrentPlatform.name}-' - '${PACKAGE_VERSION.split('+')[0]}'; + /// Common query parameters. + /// + /// List values use the default [ListFormat.multiCompatible]. + /// + /// The value can be overridden per parameter by adding a [MultiParam] + /// object wrapping the actual List value and the desired format. + final Map queryParams; + + /// Http request headers. + /// The keys of initial headers will be converted to lowercase, + /// for example 'Content-Type' will be converted to 'content-type'. + /// + /// The key of Header Map is case-insensitive + /// eg: content-type and Content-Type are + /// regard as the same key. + final Map headers; } diff --git a/packages/stream_chat/lib/src/ws/websocket.dart b/packages/stream_chat/lib/src/ws/websocket.dart index f9d8a210..ad378b39 100644 --- a/packages/stream_chat/lib/src/ws/websocket.dart +++ b/packages/stream_chat/lib/src/ws/websocket.dart @@ -13,6 +13,7 @@ import 'package:stream_chat/src/core/models/event.dart'; import 'package:stream_chat/src/core/models/user.dart'; import 'package:stream_chat/src/event_type.dart'; import 'package:stream_chat/src/ws/timer_helper.dart'; +import 'package:stream_chat/version.dart'; import 'package:web_socket_channel/web_socket_channel.dart'; import 'package:web_socket_channel/status.dart' as status; @@ -41,11 +42,15 @@ class WebSocket with TimerHelper { this.reconnectionMonitorInterval = 10, this.healthCheckInterval = 20, this.reconnectionMonitorTimeout = 40, + this.queryParams = const {}, }) : _logger = logger; /// final String apiKey; + /// Additional query parameters to be added to the websocket url + final Map queryParams; + /// WS base url final String baseUrl; @@ -156,6 +161,7 @@ class WebSocket with TimerHelper { 'api_key': apiKey, 'authorization': token.rawValue, 'stream-auth-type': token.authType.raw, + ...queryParams, }; final scheme = baseUrl.startsWith('https') ? 'wss' : 'ws'; final host = baseUrl.replaceAll(RegExp(r'(^\w+:|^)\/\/'), ''); diff --git a/packages/stream_chat/lib/version.dart b/packages/stream_chat/lib/version.dart index d09a2ccc..d3314525 100644 --- a/packages/stream_chat/lib/version.dart +++ b/packages/stream_chat/lib/version.dart @@ -1,6 +1,12 @@ import 'package:stream_chat/src/client/client.dart'; +import 'package:stream_chat/src/core/platform_detector/platform_detector.dart'; /// Current package version /// Used in [StreamChatClient] to build the `x-stream-client` header // ignore: constant_identifier_names const PACKAGE_VERSION = '2.0.0'; + +/// Get the current user agent +String get userAgent => 'stream-chat-dart-client-' + '${CurrentPlatform.name}-' + '${PACKAGE_VERSION.split('+')[0]}'; From 7b2bf3c4347effb3eadddf87c4f6a6a68b504445 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 23 Jul 2021 10:27:47 +0200 Subject: [PATCH 2/5] add tests --- .../http/stream_http_client_options_test.dart | 10 ++++++++ .../core/http/stream_http_client_test.dart | 24 ------------------- 2 files changed, 10 insertions(+), 24 deletions(-) diff --git a/packages/stream_chat/test/src/core/http/stream_http_client_options_test.dart b/packages/stream_chat/test/src/core/http/stream_http_client_options_test.dart index a03434fa..ab70462f 100644 --- a/packages/stream_chat/test/src/core/http/stream_http_client_options_test.dart +++ b/packages/stream_chat/test/src/core/http/stream_http_client_options_test.dart @@ -9,6 +9,8 @@ void main() { expect(options.baseUrl, 'https://chat-us-east-1.stream-io-api.com'); expect(options.connectTimeout, const Duration(seconds: 6)); expect(options.receiveTimeout, const Duration(seconds: 6)); + expect(options.queryParams, const {}); + expect(options.headers, const {}); }); test('should override all the default set params', () { @@ -16,11 +18,19 @@ void main() { baseUrl: 'base-url', connectTimeout: Duration(seconds: 3), receiveTimeout: Duration(seconds: 3), + headers: { + 'test': 'test', + }, + queryParams: { + '123': '123', + }, ); expect(options.location, isNull); expect(options.baseUrl, 'base-url'); expect(options.connectTimeout, const Duration(seconds: 3)); expect(options.receiveTimeout, const Duration(seconds: 3)); + expect(options.headers, {'test': 'test'}); + expect(options.queryParams, {'123': '123'}); }); group('should create baseUrl according to provided location', () { diff --git a/packages/stream_chat/test/src/core/http/stream_http_client_test.dart b/packages/stream_chat/test/src/core/http/stream_http_client_test.dart index ab4c4984..af3cabc0 100644 --- a/packages/stream_chat/test/src/core/http/stream_http_client_test.dart +++ b/packages/stream_chat/test/src/core/http/stream_http_client_test.dart @@ -87,30 +87,6 @@ void main() { ); }); - test('loggingInterceptor should log requests', () async { - const apiKey = 'api-key'; - final logger = MockLogger(); - final client = StreamHttpClient(apiKey, logger: logger); - - try { - await client.get('path'); - } catch (_) {} - - verify(() => logger.info(any())).called(16); - }); - - test('loggingInterceptor should log error', () async { - const apiKey = 'api-key'; - final logger = MockLogger(); - final client = StreamHttpClient(apiKey, logger: logger); - - try { - await client.get('path'); - } catch (_) {} - - verify(() => logger.severe(any())).called(8); - }); - test('`.lock` should lock the dio client', () async { final client = StreamHttpClient('api-key'); expect(client.httpClient.interceptors.requestLock.locked, isFalse); From 49ebb1e0856b95cb4ae6f9fe526ffc1f7459f1ff Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Fri, 23 Jul 2021 10:33:59 +0200 Subject: [PATCH 3/5] fix analysis --- packages/stream_chat/lib/src/core/http/stream_http_client.dart | 2 -- packages/stream_chat/lib/src/ws/websocket.dart | 1 - 2 files changed, 3 deletions(-) diff --git a/packages/stream_chat/lib/src/core/http/stream_http_client.dart b/packages/stream_chat/lib/src/core/http/stream_http_client.dart index c5f46144..900b71e9 100644 --- a/packages/stream_chat/lib/src/core/http/stream_http_client.dart +++ b/packages/stream_chat/lib/src/core/http/stream_http_client.dart @@ -10,9 +10,7 @@ import 'package:stream_chat/src/core/http/interceptor/connection_id_interceptor. import 'package:stream_chat/src/core/http/interceptor/logging_interceptor.dart'; import 'package:stream_chat/src/core/http/stream_chat_dio_error.dart'; import 'package:stream_chat/src/core/http/token_manager.dart'; -import 'package:stream_chat/src/core/platform_detector/platform_detector.dart'; import 'package:stream_chat/src/location.dart'; -import 'package:stream_chat/version.dart'; part 'stream_http_client_options.dart'; diff --git a/packages/stream_chat/lib/src/ws/websocket.dart b/packages/stream_chat/lib/src/ws/websocket.dart index ad378b39..53529d55 100644 --- a/packages/stream_chat/lib/src/ws/websocket.dart +++ b/packages/stream_chat/lib/src/ws/websocket.dart @@ -13,7 +13,6 @@ import 'package:stream_chat/src/core/models/event.dart'; import 'package:stream_chat/src/core/models/user.dart'; import 'package:stream_chat/src/event_type.dart'; import 'package:stream_chat/src/ws/timer_helper.dart'; -import 'package:stream_chat/version.dart'; import 'package:web_socket_channel/web_socket_channel.dart'; import 'package:web_socket_channel/status.dart' as status; From 44b4358c3d514d2fd2f42d02841e825fe5025b59 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 23 Jul 2021 14:53:43 +0530 Subject: [PATCH 4/5] chore(llc): minor changes Signed-off-by: xsahil03x --- packages/stream_chat/lib/src/client/client.dart | 13 +++++++------ .../lib/src/core/http/stream_http_client.dart | 2 +- .../src/core/http/stream_http_client_options.dart | 4 ++-- packages/stream_chat/lib/src/ws/websocket.dart | 6 +++--- packages/stream_chat/lib/version.dart | 6 ------ .../core/http/stream_http_client_options_test.dart | 12 ++++-------- 6 files changed, 17 insertions(+), 26 deletions(-) diff --git a/packages/stream_chat/lib/src/client/client.dart b/packages/stream_chat/lib/src/client/client.dart index 3d314063..41fe2e7a 100644 --- a/packages/stream_chat/lib/src/client/client.dart +++ b/packages/stream_chat/lib/src/client/client.dart @@ -25,6 +25,7 @@ import 'package:stream_chat/src/core/models/member.dart'; import 'package:stream_chat/src/core/models/message.dart'; import 'package:stream_chat/src/core/models/own_user.dart'; import 'package:stream_chat/src/core/models/user.dart'; +import 'package:stream_chat/src/core/platform_detector/platform_detector.dart'; import 'package:stream_chat/src/core/util/utils.dart'; import 'package:stream_chat/src/db/chat_persistence_client.dart'; import 'package:stream_chat/src/event_type.dart'; @@ -43,6 +44,10 @@ final _levelEmojiMapper = { Level.SEVERE: '🚨', }; +final _userAgent = 'stream-chat-dart-client-' + '${CurrentPlatform.name}-' + '${PACKAGE_VERSION.split('+')[0]}'; + /// The official Dart client for Stream Chat, /// a service for building chat applications. /// This library can be used on any Dart project and on both mobile and web apps @@ -81,9 +86,7 @@ class StreamChatClient { location: location, connectTimeout: connectTimeout, receiveTimeout: receiveTimeout, - headers: { - 'X-Stream-Client': userAgent, - }, + headers: {'X-Stream-Client': _userAgent}, ); _chatApi = chatApi ?? @@ -103,9 +106,7 @@ class StreamChatClient { tokenManager: _tokenManager, handler: handleEvent, logger: detachedLogger('🔌'), - queryParams: { - 'X-Stream-Client': userAgent, - }, + queryParameters: {'X-Stream-Client': _userAgent}, ); _retryPolicy = retryPolicy ?? diff --git a/packages/stream_chat/lib/src/core/http/stream_http_client.dart b/packages/stream_chat/lib/src/core/http/stream_http_client.dart index 900b71e9..c19cdb8a 100644 --- a/packages/stream_chat/lib/src/core/http/stream_http_client.dart +++ b/packages/stream_chat/lib/src/core/http/stream_http_client.dart @@ -33,7 +33,7 @@ class StreamHttpClient { ..options.connectTimeout = _options.connectTimeout.inMilliseconds ..options.queryParameters = { 'api_key': apiKey, - ..._options.queryParams, + ..._options.queryParameters, } ..options.headers = { 'Content-Type': 'application/json', diff --git a/packages/stream_chat/lib/src/core/http/stream_http_client_options.dart b/packages/stream_chat/lib/src/core/http/stream_http_client_options.dart index a2fe22e8..01cdb12e 100644 --- a/packages/stream_chat/lib/src/core/http/stream_http_client_options.dart +++ b/packages/stream_chat/lib/src/core/http/stream_http_client_options.dart @@ -10,7 +10,7 @@ class StreamHttpClientOptions { this.location, this.connectTimeout = const Duration(seconds: 6), this.receiveTimeout = const Duration(seconds: 6), - this.queryParams = const {}, + this.queryParameters = const {}, this.headers = const {}, }) : _baseUrl = baseUrl ?? _defaultBaseURL; @@ -40,7 +40,7 @@ class StreamHttpClientOptions { /// /// The value can be overridden per parameter by adding a [MultiParam] /// object wrapping the actual List value and the desired format. - final Map queryParams; + final Map queryParameters; /// Http request headers. /// The keys of initial headers will be converted to lowercase, diff --git a/packages/stream_chat/lib/src/ws/websocket.dart b/packages/stream_chat/lib/src/ws/websocket.dart index 53529d55..b26d811e 100644 --- a/packages/stream_chat/lib/src/ws/websocket.dart +++ b/packages/stream_chat/lib/src/ws/websocket.dart @@ -41,14 +41,14 @@ class WebSocket with TimerHelper { this.reconnectionMonitorInterval = 10, this.healthCheckInterval = 20, this.reconnectionMonitorTimeout = 40, - this.queryParams = const {}, + this.queryParameters = const {}, }) : _logger = logger; /// final String apiKey; /// Additional query parameters to be added to the websocket url - final Map queryParams; + final Map queryParameters; /// WS base url final String baseUrl; @@ -160,7 +160,7 @@ class WebSocket with TimerHelper { 'api_key': apiKey, 'authorization': token.rawValue, 'stream-auth-type': token.authType.raw, - ...queryParams, + ...queryParameters, }; final scheme = baseUrl.startsWith('https') ? 'wss' : 'ws'; final host = baseUrl.replaceAll(RegExp(r'(^\w+:|^)\/\/'), ''); diff --git a/packages/stream_chat/lib/version.dart b/packages/stream_chat/lib/version.dart index d3314525..d09a2ccc 100644 --- a/packages/stream_chat/lib/version.dart +++ b/packages/stream_chat/lib/version.dart @@ -1,12 +1,6 @@ import 'package:stream_chat/src/client/client.dart'; -import 'package:stream_chat/src/core/platform_detector/platform_detector.dart'; /// Current package version /// Used in [StreamChatClient] to build the `x-stream-client` header // ignore: constant_identifier_names const PACKAGE_VERSION = '2.0.0'; - -/// Get the current user agent -String get userAgent => 'stream-chat-dart-client-' - '${CurrentPlatform.name}-' - '${PACKAGE_VERSION.split('+')[0]}'; diff --git a/packages/stream_chat/test/src/core/http/stream_http_client_options_test.dart b/packages/stream_chat/test/src/core/http/stream_http_client_options_test.dart index ab70462f..02cfc07a 100644 --- a/packages/stream_chat/test/src/core/http/stream_http_client_options_test.dart +++ b/packages/stream_chat/test/src/core/http/stream_http_client_options_test.dart @@ -9,7 +9,7 @@ void main() { expect(options.baseUrl, 'https://chat-us-east-1.stream-io-api.com'); expect(options.connectTimeout, const Duration(seconds: 6)); expect(options.receiveTimeout, const Duration(seconds: 6)); - expect(options.queryParams, const {}); + expect(options.queryParameters, const {}); expect(options.headers, const {}); }); @@ -18,19 +18,15 @@ void main() { baseUrl: 'base-url', connectTimeout: Duration(seconds: 3), receiveTimeout: Duration(seconds: 3), - headers: { - 'test': 'test', - }, - queryParams: { - '123': '123', - }, + headers: {'test': 'test'}, + queryParameters: {'123': '123'}, ); expect(options.location, isNull); expect(options.baseUrl, 'base-url'); expect(options.connectTimeout, const Duration(seconds: 3)); expect(options.receiveTimeout, const Duration(seconds: 3)); expect(options.headers, {'test': 'test'}); - expect(options.queryParams, {'123': '123'}); + expect(options.queryParameters, {'123': '123'}); }); group('should create baseUrl according to provided location', () { From 2acfaf7a7c0afc15f502f1b7eff92017c00e4856 Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Fri, 23 Jul 2021 15:12:52 +0530 Subject: [PATCH 5/5] test(llc): re-add removed tests Signed-off-by: xsahil03x --- .../core/http/stream_http_client_test.dart | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/packages/stream_chat/test/src/core/http/stream_http_client_test.dart b/packages/stream_chat/test/src/core/http/stream_http_client_test.dart index af3cabc0..7860a0d6 100644 --- a/packages/stream_chat/test/src/core/http/stream_http_client_test.dart +++ b/packages/stream_chat/test/src/core/http/stream_http_client_test.dart @@ -87,6 +87,30 @@ void main() { ); }); + test('loggingInterceptor should log requests', () async { + const apiKey = 'api-key'; + final logger = MockLogger(); + final client = StreamHttpClient(apiKey, logger: logger); + + try { + await client.get('path'); + } catch (_) {} + + verify(() => logger.info(any())).called(greaterThan(0)); + }); + + test('loggingInterceptor should log error', () async { + const apiKey = 'api-key'; + final logger = MockLogger(); + final client = StreamHttpClient(apiKey, logger: logger); + + try { + await client.get('path'); + } catch (_) {} + + verify(() => logger.severe(any())).called(greaterThan(0)); + }); + test('`.lock` should lock the dio client', () async { final client = StreamHttpClient('api-key'); expect(client.httpClient.interceptors.requestLock.locked, isFalse);