]> git.basschouten.com Git - openhab-addons.git/commitdiff
[remoteopenhab] Avoid registering conflicting filters for SSE connection (#10870)
authorlolodomo <lg.hc@free.fr>
Sun, 20 Jun 2021 17:36:34 +0000 (19:36 +0200)
committerGitHub <noreply@github.com>
Sun, 20 Jun 2021 17:36:34 +0000 (19:36 +0200)
* [remoteopenhab] Avoid registering conflicting filters for SSE connection

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
* Remove default constructor

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
* Review comment: declare the hostname verifier in a variable

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
bundles/org.openhab.binding.remoteopenhab/src/main/java/org/openhab/binding/remoteopenhab/internal/rest/RemoteopenhabRestClient.java
bundles/org.openhab.binding.remoteopenhab/src/main/java/org/openhab/binding/remoteopenhab/internal/rest/RemoteopenhabStreamingRequestFilter.java

index b6ebe5d1a330717bdc62657fd396f22e3acfb644..f43becaf11c1dac559c8af7aeec9e44ea2cb8233 100644 (file)
@@ -273,21 +273,44 @@ public class RemoteopenhabRestClient {
 
     private SseEventSource createEventSource(String restSseUrl) {
         String credentialToken = restSseUrl.startsWith("https:") || authenticateAnyway ? this.credentialToken : "";
+
+        RemoteopenhabStreamingRequestFilter filter;
+        boolean filterRegistered = clientBuilder.getConfiguration()
+                .isRegistered(RemoteopenhabStreamingRequestFilter.class);
+        if (filterRegistered) {
+            filter = clientBuilder.getConfiguration().getInstances().stream()
+                    .filter(instance -> instance instanceof RemoteopenhabStreamingRequestFilter)
+                    .map(instance -> (RemoteopenhabStreamingRequestFilter) instance).findAny().orElseThrow();
+        } else {
+            filter = new RemoteopenhabStreamingRequestFilter();
+        }
+        filter.setCredentialToken(restSseUrl, credentialToken);
+
         Client client;
         // Avoid a timeout exception after 1 minute by setting the read timeout to 0 (infinite)
         if (trustedCertificate) {
-            client = clientBuilder.sslContext(httpClient.getSslContextFactory().getSslContext())
-                    .hostnameVerifier(new HostnameVerifier() {
-                        @Override
-                        public boolean verify(@Nullable String hostname, @Nullable SSLSession session) {
-                            return true;
-                        }
-                    }).readTimeout(0, TimeUnit.SECONDS)
-                    .register(new RemoteopenhabStreamingRequestFilter(credentialToken)).build();
+            HostnameVerifier alwaysValidHostname = new HostnameVerifier() {
+                @Override
+                public boolean verify(@Nullable String hostname, @Nullable SSLSession session) {
+                    return true;
+                }
+            };
+            if (filterRegistered) {
+                client = clientBuilder.sslContext(httpClient.getSslContextFactory().getSslContext())
+                        .hostnameVerifier(alwaysValidHostname).readTimeout(0, TimeUnit.SECONDS).build();
+            } else {
+                client = clientBuilder.sslContext(httpClient.getSslContextFactory().getSslContext())
+                        .hostnameVerifier(alwaysValidHostname).readTimeout(0, TimeUnit.SECONDS).register(filter)
+                        .build();
+            }
         } else {
-            client = clientBuilder.readTimeout(0, TimeUnit.SECONDS)
-                    .register(new RemoteopenhabStreamingRequestFilter(credentialToken)).build();
+            if (filterRegistered) {
+                client = clientBuilder.readTimeout(0, TimeUnit.SECONDS).build();
+            } else {
+                client = clientBuilder.readTimeout(0, TimeUnit.SECONDS).register(filter).build();
+            }
         }
+
         SseEventSource eventSource = eventSourceFactory.newSource(client.target(restSseUrl));
         eventSource.register(this::onEvent, this::onError, this::onComplete);
         return eventSource;
index 8e9b03eef5ace5bef0394bdc236daebf7132d7c7..37d58b03951c5d2e7d2149faeb01903495519f32 100644 (file)
@@ -13,6 +13,7 @@
 package org.openhab.binding.remoteopenhab.internal.rest;
 
 import java.io.IOException;
+import java.util.concurrent.ConcurrentHashMap;
 
 import javax.ws.rs.client.ClientRequestContext;
 import javax.ws.rs.client.ClientRequestFilter;
@@ -21,6 +22,8 @@ import javax.ws.rs.core.MultivaluedMap;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Inserts Authorization and Cache-Control headers for requests on the streaming REST API.
@@ -30,20 +33,28 @@ import org.eclipse.jdt.annotation.Nullable;
 @NonNullByDefault
 public class RemoteopenhabStreamingRequestFilter implements ClientRequestFilter {
 
-    private final String credentialToken;
+    private final Logger logger = LoggerFactory.getLogger(RemoteopenhabStreamingRequestFilter.class);
 
-    public RemoteopenhabStreamingRequestFilter(String credentialToken) {
-        this.credentialToken = credentialToken;
-    }
+    private final ConcurrentHashMap<String, String> credentialTokens = new ConcurrentHashMap<>();
 
     @Override
     public void filter(@Nullable ClientRequestContext requestContext) throws IOException {
         if (requestContext != null) {
             MultivaluedMap<String, Object> headers = requestContext.getHeaders();
-            if (!credentialToken.isEmpty()) {
-                headers.putSingle(HttpHeaders.AUTHORIZATION, "Basic " + credentialToken);
+            String credentialToken = credentialTokens.get(requestContext.getUri().toString());
+            if (credentialToken != null) {
+                if (!credentialToken.isEmpty()) {
+                    headers.putSingle(HttpHeaders.AUTHORIZATION, "Basic " + credentialToken);
+                }
+            } else {
+                logger.warn("No credential token set! uri={}", requestContext.getUri());
             }
             headers.putSingle(HttpHeaders.CACHE_CONTROL, "no-cache");
         }
     }
+
+    public void setCredentialToken(String target, String token) {
+        logger.debug("Set credential token. target={}, token={}", target, token);
+        credentialTokens.put(target, token);
+    }
 }