diff --git a/example/complex_example.dart b/example/complex_example.dart index 9e9c2a5c..6b33d29b 100644 --- a/example/complex_example.dart +++ b/example/complex_example.dart @@ -76,18 +76,15 @@ const thingDescriptionJson = { }; final Map basicCredentials = { - "urn:test": const BasicCredentials("username", "password"), + "httpbin.org": const BasicCredentials("username", "password"), }; Future basicCredentialsCallback( Uri uri, - AugmentedForm? form, [ + AugmentedForm? form, BasicCredentials? invalidCredentials, -]) async { - final id = form?.tdIdentifier; - - return basicCredentials[id]; -} +) async => + basicCredentials[uri.authority]; Future main() async { final coapClientFactory = CoapClientFactory( diff --git a/example/http_basic_authentication.dart b/example/http_basic_authentication.dart index 6e722659..5c8f1936 100644 --- a/example/http_basic_authentication.dart +++ b/example/http_basic_authentication.dart @@ -38,22 +38,15 @@ const thingDescriptionJson = { const basicCredentials = BasicCredentials("username", "password"); final Map basicCredentialsMap = { - "urn:test": basicCredentials, + "httpbin.org": basicCredentials, }; Future basicCredentialsCallback( Uri uri, AugmentedForm? form, BasicCredentials? invalidCredentials, -) async { - if (form == null) { - return basicCredentials; - } - - final id = form.tdIdentifier; - - return basicCredentialsMap[id]; -} +) async => + basicCredentialsMap[uri.authority]; /// Illustrates the usage of both the basic and the automatic security scheme, /// with a server supporting basic authentication. diff --git a/example/mqtt_example.dart b/example/mqtt_example.dart index 2c72c272..e363b11a 100644 --- a/example/mqtt_example.dart +++ b/example/mqtt_example.dart @@ -46,18 +46,18 @@ const thingDescriptionJson = { }; final Map basicCredentials = { - "urn:test": const BasicCredentials("rw", "readwrite"), + "test.mosquitto.org:1884": const BasicCredentials( + "rw", + "readwrite", + ), }; Future basicCredentialsCallback( Uri uri, AugmentedForm? form, [ BasicCredentials? invalidCredentials, -]) async { - final id = form?.tdIdentifier; - - return basicCredentials[id]; -} +]) async => + basicCredentials[uri.authority]; Future main(List args) async { final servient = Servient.create( diff --git a/lib/src/binding_coap/coap_client.dart b/lib/src/binding_coap/coap_client.dart index e2e22f6c..4579560d 100644 --- a/lib/src/binding_coap/coap_client.dart +++ b/lib/src/binding_coap/coap_client.dart @@ -132,7 +132,7 @@ final class CoapClient extends ProtocolClient final code = requestMethod.code; return _sendRequest( - form.resolvedHref, + form.href, code, content: content, format: form.contentFormat, @@ -232,7 +232,7 @@ final class CoapClient extends ProtocolClient ) async { final requestMethod = (form.method ?? CoapRequestMethod.get).code; - final creationHintUri = form.resolvedHref.replace(scheme: "coap"); + final creationHintUri = form.href.replace(scheme: "coap"); final request = await _createRequest( requestMethod, @@ -419,13 +419,13 @@ final class CoapClient extends ProtocolClient final request = await _createRequest( (form.method ?? CoapRequestMethod.get).code, - form.resolvedHref, + form.href, format: form.contentFormat, accept: form.accept, ); final coapClient = coap.CoapClient( - form.resolvedHref, + form.href, config: _InternalCoapConfig(_coapConfig ?? const CoapConfig()), ); diff --git a/lib/src/binding_http/http_client.dart b/lib/src/binding_http/http_client.dart index 2508297c..83478802 100644 --- a/lib/src/binding_http/http_client.dart +++ b/lib/src/binding_http/http_client.dart @@ -104,8 +104,7 @@ final class HttpClient extends ProtocolClient return false; } - final basicCredentials = - await _getBasicCredentials(form.resolvedHref, form); + final basicCredentials = await _getBasicCredentials(form.href, form); if (basicCredentials == null) { return false; @@ -127,8 +126,7 @@ final class HttpClient extends ProtocolClient return false; } - final bearerCredentials = - await _getBearerCredentials(form.resolvedHref, form); + final bearerCredentials = await _getBearerCredentials(form.href, form); if (bearerCredentials == null) { return false; @@ -222,7 +220,7 @@ final class HttpClient extends ProtocolClient ) async { final requestMethod = HttpRequestMethod.getRequestMethod(form, operationType); - final Uri uri = form.resolvedHref; + final Uri uri = form.href; final request = Request(requestMethod.methodName, uri) ..headers.addAll(_getHeadersFromForm(form)) diff --git a/lib/src/binding_http/http_subscription.dart b/lib/src/binding_http/http_subscription.dart index db52243b..57cd12f1 100644 --- a/lib/src/binding_http/http_subscription.dart +++ b/lib/src/binding_http/http_subscription.dart @@ -20,7 +20,7 @@ final class HttpSseSubscription extends ProtocolSubscription { void Function(Exception error)? onError, void Function()? complete, }) : _active = true, - _sseChannel = SseChannel.connect(form.resolvedHref) { + _sseChannel = SseChannel.connect(form.href) { _sseChannel.stream.listen( (data) { if (data is! String) { diff --git a/lib/src/binding_mqtt/mqtt_client.dart b/lib/src/binding_mqtt/mqtt_client.dart index 8463e82b..612eb68f 100644 --- a/lib/src/binding_mqtt/mqtt_client.dart +++ b/lib/src/binding_mqtt/mqtt_client.dart @@ -68,7 +68,7 @@ final class MqttClient extends ProtocolClient with MqttDiscoverer { } Future _connectWithForm(AugmentedForm form) async => - _connect(form.resolvedHref, form); + _connect(form.href, form); Future _connect(Uri brokerUri, AugmentedForm? form) async { final client = brokerUri.createClient(_mqttConfig.keepAlivePeriod); diff --git a/lib/src/binding_mqtt/mqtt_extensions.dart b/lib/src/binding_mqtt/mqtt_extensions.dart index 6607cc0f..c3f66e6d 100644 --- a/lib/src/binding_mqtt/mqtt_extensions.dart +++ b/lib/src/binding_mqtt/mqtt_extensions.dart @@ -140,8 +140,7 @@ extension MqttFormExtension on AugmentedForm { if (qosValue != null) { throw FormatException( "Encountered unknown QoS value $qosValue. " - "in form with href $href of Thing Description with Identifier " - "$tdIdentifier.", + "in form with resolved href $href.", ); } diff --git a/lib/src/core/implementation/augmented_form.dart b/lib/src/core/implementation/augmented_form.dart index eec2f8ad..851412fb 100644 --- a/lib/src/core/implementation/augmented_form.dart +++ b/lib/src/core/implementation/augmented_form.dart @@ -31,9 +31,6 @@ final class AugmentedForm implements Form { final Map? _userProvidedUriVariables; - /// The identifier of the [_thingDescription] associated with this form. - String get tdIdentifier => _thingDescription.identifier; - @override Map get additionalFields => _form.additionalFields; @@ -47,8 +44,9 @@ final class AugmentedForm implements Form { @override String get contentType => _form.contentType; - @override - Uri get href { + /// Resolves all [_userProvidedUriVariables] in this [Form] and returns the + /// resulting [Uri]. + Uri get _resolvedHref { final baseUri = _thingDescription.base; if (baseUri != null) { @@ -58,6 +56,39 @@ final class AugmentedForm implements Form { return _form.href; } + @override + Uri get href { + final href = _resolvedHref; + final hrefUriVariables = _filterUriVariables(href); + + if (hrefUriVariables.isEmpty) { + return href; + } + + final Map affordanceUriVariables = { + ..._thingDescription.uriVariables ?? {}, + ..._interactionAffordance.uriVariables ?? {}, + }; + + final userProvidedUriVariables = _userProvidedUriVariables; + + if (userProvidedUriVariables != null) { + _validateUriVariables( + hrefUriVariables, + affordanceUriVariables, + userProvidedUriVariables, + ); + } + + // As "{" and "}" are "percent encoded" due to Uri.parse(), we need to + // revert the encoding first before we can insert the values. + final decodedHref = Uri.decodeFull(href.toString()); + + final expandedHref = + UriTemplate(decodedHref).expand(userProvidedUriVariables ?? {}); + return Uri.parse(expandedHref); + } + @override List get op => _form.op ?? OperationType.defaultOpValues(_interactionAffordance); @@ -98,38 +129,6 @@ final class AugmentedForm implements Form { .toList(growable: false); } - /// Resolves all [_userProvidedUriVariables] in this [Form] and returns the - /// resulting [Uri]. - Uri get resolvedHref { - final hrefUriVariables = _filterUriVariables(href); - - if (hrefUriVariables.isEmpty) { - return href; - } - - final Map affordanceUriVariables = { - ..._thingDescription.uriVariables ?? {}, - ..._interactionAffordance.uriVariables ?? {}, - }; - - final userProvidedUriVariables = _userProvidedUriVariables; - if (userProvidedUriVariables != null) { - _validateUriVariables( - hrefUriVariables, - affordanceUriVariables, - userProvidedUriVariables, - ); - } - - // As "{" and "}" are "percent encoded" due to Uri.parse(), we need to - // revert the encoding first before we can insert the values. - final decodedHref = Uri.decodeFull(href.toString()); - - final expandedHref = - UriTemplate(decodedHref).expand(userProvidedUriVariables ?? {}); - return Uri.parse(expandedHref); - } - void _validateUriVariables( List uriVariablesInHref, Map affordanceUriVariables, diff --git a/lib/src/core/implementation/consumed_thing.dart b/lib/src/core/implementation/consumed_thing.dart index 4e72fa81..e432796d 100644 --- a/lib/src/core/implementation/consumed_thing.dart +++ b/lib/src/core/implementation/consumed_thing.dart @@ -78,7 +78,7 @@ class ConsumedThing implements scripting_api.ConsumedThing { } return servient.supportsOperation( - form.resolvedHref.scheme, + form.href.scheme, operationType, form.subprotocol, ); diff --git a/test/core/augmented_form_test.dart b/test/core/augmented_form_test.dart index caaae7bb..e22724d1 100644 --- a/test/core/augmented_form_test.dart +++ b/test/core/augmented_form_test.dart @@ -63,7 +63,6 @@ void main() { expect(augmentedForm.href, Uri.parse(href)); expect(augmentedForm.security, ["nosec_sc"]); expect(augmentedForm.securityDefinitions.first, isA()); - expect(augmentedForm.tdIdentifier, id); expect( augmentedForm.additionalResponses?.first.contentType, "application/json", @@ -145,15 +144,10 @@ void main() { ); expect( - augmentedForm1.resolvedHref, + augmentedForm1.href, Uri.parse("http://example.org/weather/?lat=5&long=10"), ); - expect( - augmentedForm1.resolvedHref != augmentedForm1.href, - isTrue, - ); - final augmentedForm2 = AugmentedForm( affordance.forms.first, affordance, @@ -164,7 +158,7 @@ void main() { ); expect( - augmentedForm2.resolvedHref, + augmentedForm2.href, Uri.parse("http://example.org/weather/?lat=5"), ); @@ -178,7 +172,7 @@ void main() { ); expect( - augmentedForm3.resolvedHref, + augmentedForm3.href, Uri.parse("http://example.org/weather/?long=10"), ); @@ -193,7 +187,7 @@ void main() { ); expect( - () => augmentedForm4.resolvedHref, + () => augmentedForm4.href, throwsA(isA()), ); @@ -208,21 +202,9 @@ void main() { ); expect( - () => augmentedForm5.resolvedHref, + () => augmentedForm5.href, throwsA(isA()), ); - - final augmentedForm6 = AugmentedForm( - affordance.forms[2], - affordance, - thingDescription, - const {}, - ); - - expect( - augmentedForm6.href, - augmentedForm6.resolvedHref, - ); }); }); } diff --git a/test/core/discovery_test.dart b/test/core/discovery_test.dart index 6ec6e2b5..c208b0dc 100644 --- a/test/core/discovery_test.dart +++ b/test/core/discovery_test.dart @@ -147,7 +147,7 @@ final class _MockedProtocolClient extends ProtocolClient with DirectDiscoverer { @override Future readResource(AugmentedForm form) async { - final href = form.resolvedHref; + final href = form.href; if (href == directoryTestThingsUri1) { return "[$validTestThingDescription]".toContent("application/td+json");