From 7313415ae0657a363440b735dc51b1ffff657581 Mon Sep 17 00:00:00 2001 From: lsiepel Date: Thu, 19 Oct 2023 22:30:41 +0200 Subject: [PATCH] Set explicit timeout for http request (#15505) * Bondhome * chatgpt * electroluxair * energidataservice * freeboxos * gardena * generacmobilelink * hdpowerview * icalendar * juicenet * kostalinverter * liquidcheck * mcd * meater * miele * mercedesme * mybmw * myq * ojelectronics * plex * radiothermostat * renault * semsportal * sensibo * tapocontrol * tellstick * verisure * vizio --------- Signed-off-by: lsiepel Signed-off-by: Leo Siepel --- .../bondhome/internal/api/BondHttpApi.java | 2 +- .../binding/chatgpt/internal/ChatGPTHandler.java | 12 ++++++++---- .../internal/api/ElectroluxDeltaAPI.java | 4 +++- .../internal/ApiController.java | 4 ++++ .../internal/api/FreeboxOsIconProvider.java | 5 ++++- .../gardena/internal/GardenaSmartImpl.java | 2 ++ .../handler/GeneracMobileLinkAccountHandler.java | 13 ++++++++----- .../hdpowerview/internal/GatewayWebTargets.java | 4 +++- .../internal/HDPowerViewWebTargets.java | 5 ++++- .../icalendar/internal/handler/PullJob.java | 3 ++- .../juicenet/internal/api/JuiceNetApi.java | 3 +++ .../SecondGenerationConfigurationHandler.java | 9 +++++++-- .../discovery/LiquidCheckDiscoveryService.java | 5 ++++- .../httpclient/LiquidCheckHttpClient.java | 3 +-- .../mcd/internal/handler/McdBridgeHandler.java | 5 ++++- .../mcd/internal/handler/SensorThingHandler.java | 16 ++++++++++++---- .../meater/internal/api/MeaterRestAPI.java | 8 ++++++-- .../internal/handler/VehicleHandler.java | 7 ++++--- .../MieleGatewayCommunicationController.java | 3 +++ .../mybmw/internal/handler/MyBMWProxy.java | 14 ++++++++------ .../myq/internal/handler/MyQAccountHandler.java | 12 +++++++++--- .../internal/services/UpdateService.java | 7 ++++--- .../plex/internal/handler/PlexApiConnector.java | 3 ++- .../communication/RadioThermostatConnector.java | 4 +++- .../internal/api/MyRenaultHttpSession.java | 8 ++++++-- .../semsportal/internal/PortalHandler.java | 5 ++++- .../internal/handler/SensiboAccountHandler.java | 2 ++ .../internal/api/TapoCloudConnector.java | 2 ++ .../internal/constants/TapoBindingSettings.java | 1 + .../local/TelldusLocalDeviceController.java | 5 ++++- .../verisure/internal/VerisureSession.java | 3 +++ .../communication/VizioCommunicator.java | 4 ++++ 32 files changed, 135 insertions(+), 48 deletions(-) diff --git a/bundles/org.openhab.binding.bondhome/src/main/java/org/openhab/binding/bondhome/internal/api/BondHttpApi.java b/bundles/org.openhab.binding.bondhome/src/main/java/org/openhab/binding/bondhome/internal/api/BondHttpApi.java index a9c0b9fc1..8dedf69df 100644 --- a/bundles/org.openhab.binding.bondhome/src/main/java/org/openhab/binding/bondhome/internal/api/BondHttpApi.java +++ b/bundles/org.openhab.binding.bondhome/src/main/java/org/openhab/binding/bondhome/internal/api/BondHttpApi.java @@ -218,7 +218,7 @@ public class BondHttpApi { final Request request = httpClient.newRequest(url).method(HttpMethod.GET).header("BOND-Token", bridgeHandler.getBridgeToken()); ContentResponse response; - response = request.send(); + response = request.timeout(BOND_API_TIMEOUT_MS, TimeUnit.MILLISECONDS).send(); String encoding = response.getEncoding() != null ? response.getEncoding().replace("\"", "").trim() : StandardCharsets.UTF_8.name(); try { diff --git a/bundles/org.openhab.binding.chatgpt/src/main/java/org/openhab/binding/chatgpt/internal/ChatGPTHandler.java b/bundles/org.openhab.binding.chatgpt/src/main/java/org/openhab/binding/chatgpt/internal/ChatGPTHandler.java index e04ee01d0..f5bae70ee 100644 --- a/bundles/org.openhab.binding.chatgpt/src/main/java/org/openhab/binding/chatgpt/internal/ChatGPTHandler.java +++ b/bundles/org.openhab.binding.chatgpt/src/main/java/org/openhab/binding/chatgpt/internal/ChatGPTHandler.java @@ -12,10 +12,13 @@ */ package org.openhab.binding.chatgpt.internal; +import static org.openhab.binding.chatgpt.internal.ChatGPTBindingConstants.*; + import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -55,6 +58,7 @@ import com.google.gson.JsonObject; @NonNullByDefault public class ChatGPTHandler extends BaseThingHandler { + private static final int REQUEST_TIMEOUT_MS = 10_000; private final Logger logger = LoggerFactory.getLogger(ChatGPTHandler.class); private HttpClient httpClient; @@ -125,8 +129,8 @@ public class ChatGPTHandler extends BaseThingHandler { String queryJson = gson.toJson(root); Request request = httpClient.newRequest(apiUrl).method(HttpMethod.POST) - .header("Content-Type", "application/json").header("Authorization", "Bearer " + apiKey) - .content(new StringContentProvider(queryJson)); + .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS).header("Content-Type", "application/json") + .header("Authorization", "Bearer " + apiKey).content(new StringContentProvider(queryJson)); logger.trace("Query '{}'", queryJson); try { ContentResponse response = request.send(); @@ -166,8 +170,8 @@ public class ChatGPTHandler extends BaseThingHandler { scheduler.execute(() -> { try { - Request request = httpClient.newRequest(modelUrl).method(HttpMethod.GET).header("Authorization", - "Bearer " + apiKey); + Request request = httpClient.newRequest(modelUrl).timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS) + .method(HttpMethod.GET).header("Authorization", "Bearer " + apiKey); ContentResponse response = request.send(); if (response.getStatus() == 200) { updateStatus(ThingStatus.ONLINE); diff --git a/bundles/org.openhab.binding.electroluxair/src/main/java/org/openhab/binding/electroluxair/internal/api/ElectroluxDeltaAPI.java b/bundles/org.openhab.binding.electroluxair/src/main/java/org/openhab/binding/electroluxair/internal/api/ElectroluxDeltaAPI.java index 07c5d7d91..4fc93ad9c 100644 --- a/bundles/org.openhab.binding.electroluxair/src/main/java/org/openhab/binding/electroluxair/internal/api/ElectroluxDeltaAPI.java +++ b/bundles/org.openhab.binding.electroluxair/src/main/java/org/openhab/binding/electroluxair/internal/api/ElectroluxDeltaAPI.java @@ -15,6 +15,7 @@ package org.openhab.binding.electroluxair.internal.api; import java.time.Instant; import java.util.Map; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -55,6 +56,7 @@ public class ElectroluxDeltaAPI { private static final String JSON_CONTENT_TYPE = "application/json"; private static final int MAX_RETRIES = 3; + private static final int REQUEST_TIMEOUT_MS = 10_000; private final Logger logger = LoggerFactory.getLogger(ElectroluxDeltaAPI.class); private final Gson gson; @@ -176,7 +178,7 @@ public class ElectroluxDeltaAPI { private Request createRequest(String uri, HttpMethod httpMethod) { Request request = httpClient.newRequest(uri).method(httpMethod); - + request.timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS); request.header(HttpHeader.ACCEPT, JSON_CONTENT_TYPE); request.header(HttpHeader.CONTENT_TYPE, JSON_CONTENT_TYPE); diff --git a/bundles/org.openhab.binding.energidataservice/src/main/java/org/openhab/binding/energidataservice/internal/ApiController.java b/bundles/org.openhab.binding.energidataservice/src/main/java/org/openhab/binding/energidataservice/internal/ApiController.java index 484986ff8..c0bed681d 100644 --- a/bundles/org.openhab.binding.energidataservice/src/main/java/org/openhab/binding/energidataservice/internal/ApiController.java +++ b/bundles/org.openhab.binding.energidataservice/src/main/java/org/openhab/binding/energidataservice/internal/ApiController.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.stream.Collectors; @@ -76,6 +77,7 @@ public class ApiController { private static final String HEADER_REMAINING_CALLS = "RemainingCalls"; private static final String HEADER_TOTAL_CALLS = "TotalCalls"; + private static final int REQUEST_TIMEOUT_SECONDS = 30; private final Logger logger = LoggerFactory.getLogger(ApiController.class); private final Gson gson = new GsonBuilder() // @@ -110,6 +112,7 @@ public class ApiController { } Request request = httpClient.newRequest(ENDPOINT + DATASET_PATH + DATASET_NAME_SPOT_PRICES) + .timeout(REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS) // .param("start", start.toString()) // .param("filter", "{\"" + FILTER_KEY_PRICE_AREA + "\":\"" + priceArea + "\"}") // .param("columns", "HourUTC,SpotPrice" + currency) // @@ -198,6 +201,7 @@ public class ApiController { } Request request = httpClient.newRequest(ENDPOINT + DATASET_PATH + DATASET_NAME_DATAHUB_PRICELIST) + .timeout(REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS) // .param("filter", mapToFilter(filterMap)) // .param("columns", columns) // .agent(userAgent) // diff --git a/bundles/org.openhab.binding.freeboxos/src/main/java/org/openhab/binding/freeboxos/internal/api/FreeboxOsIconProvider.java b/bundles/org.openhab.binding.freeboxos/src/main/java/org/openhab/binding/freeboxos/internal/api/FreeboxOsIconProvider.java index 8c5067226..363856d3d 100644 --- a/bundles/org.openhab.binding.freeboxos/src/main/java/org/openhab/binding/freeboxos/internal/api/FreeboxOsIconProvider.java +++ b/bundles/org.openhab.binding.freeboxos/src/main/java/org/openhab/binding/freeboxos/internal/api/FreeboxOsIconProvider.java @@ -18,6 +18,7 @@ import java.net.URI; import java.util.Locale; import java.util.Set; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import javax.ws.rs.core.UriBuilder; @@ -51,6 +52,7 @@ import org.slf4j.LoggerFactory; public class FreeboxOsIconProvider extends AbstractResourceIconProvider { private final Logger logger = LoggerFactory.getLogger(FreeboxOsIconProvider.class); + private static final int REQUEST_TIMEOUT_MS = 8000; private final HttpClient httpClient; private final UriBuilder uriBuilder; @@ -77,7 +79,8 @@ public class FreeboxOsIconProvider extends AbstractResourceIconProvider { @Override protected @Nullable InputStream getResource(String iconSetId, String resourceName) { URI uri = uriBuilder.clone().path(resourceName).build(); - Request request = httpClient.newRequest(uri).method(HttpMethod.GET); + Request request = httpClient.newRequest(uri).method(HttpMethod.GET).timeout(REQUEST_TIMEOUT_MS, + TimeUnit.MILLISECONDS); try { ContentResponse response = request.send(); diff --git a/bundles/org.openhab.binding.gardena/src/main/java/org/openhab/binding/gardena/internal/GardenaSmartImpl.java b/bundles/org.openhab.binding.gardena/src/main/java/org/openhab/binding/gardena/internal/GardenaSmartImpl.java index bb596f42a..da529d4f0 100644 --- a/bundles/org.openhab.binding.gardena/src/main/java/org/openhab/binding/gardena/internal/GardenaSmartImpl.java +++ b/bundles/org.openhab.binding.gardena/src/main/java/org/openhab/binding/gardena/internal/GardenaSmartImpl.java @@ -73,6 +73,7 @@ import com.google.gson.JsonSyntaxException; @NonNullByDefault public class GardenaSmartImpl implements GardenaSmart, GardenaSmartWebSocketListener { private final Logger logger = LoggerFactory.getLogger(GardenaSmartImpl.class); + private static final int REQUEST_TIMEOUT_MS = 10_000; private Gson gson = new GsonBuilder().registerTypeAdapter(DataItem.class, new DataItemDeserializer()).create(); @@ -212,6 +213,7 @@ public class GardenaSmartImpl implements GardenaSmart, GardenaSmartWebSocketList } Request request = httpClient.newRequest(url).method(method).header(HttpHeader.CONTENT_TYPE, contentType) + .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS) .header(HttpHeader.ACCEPT, "application/vnd.api+json").header(HttpHeader.ACCEPT_ENCODING, "gzip"); if (!URL_API_TOKEN.equals(url)) { diff --git a/bundles/org.openhab.binding.generacmobilelink/src/main/java/org/openhab/binding/generacmobilelink/internal/handler/GeneracMobileLinkAccountHandler.java b/bundles/org.openhab.binding.generacmobilelink/src/main/java/org/openhab/binding/generacmobilelink/internal/handler/GeneracMobileLinkAccountHandler.java index 09ca46d44..55749aa3a 100644 --- a/bundles/org.openhab.binding.generacmobilelink/src/main/java/org/openhab/binding/generacmobilelink/internal/handler/GeneracMobileLinkAccountHandler.java +++ b/bundles/org.openhab.binding.generacmobilelink/src/main/java/org/openhab/binding/generacmobilelink/internal/handler/GeneracMobileLinkAccountHandler.java @@ -69,6 +69,7 @@ import com.google.gson.JsonSyntaxException; @NonNullByDefault public class GeneracMobileLinkAccountHandler extends BaseBridgeHandler { private final Logger logger = LoggerFactory.getLogger(GeneracMobileLinkAccountHandler.class); + private static final int REQUEST_TIMEOUT_MS = 10_000; private static final String API_BASE = "https://app.mobilelinkgen.com/api"; private static final String LOGIN_BASE = "https://generacconnectivity.b2clogin.com/generacconnectivity.onmicrosoft.com/B2C_1A_MobileLink_SignIn"; @@ -286,8 +287,9 @@ public class GeneracMobileLinkAccountHandler extends BaseBridgeHandler { fields.put("password", config.password); Request selfAssertedRequest = httpClient.POST(LOGIN_BASE + "/SelfAsserted") - .header("X-Csrf-Token", signInConfig.csrf).param("tx", "StateProperties=" + signInConfig.transId) - .param("p", "B2C_1A_SignUpOrSigninOnline").content(new FormContentProvider(fields)); + .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS).header("X-Csrf-Token", signInConfig.csrf) + .param("tx", "StateProperties=" + signInConfig.transId).param("p", "B2C_1A_SignUpOrSigninOnline") + .content(new FormContentProvider(fields)); ContentResponse selfAssertedResponse = selfAssertedRequest.send(); @@ -309,8 +311,8 @@ public class GeneracMobileLinkAccountHandler extends BaseBridgeHandler { } Request confirmedRequest = httpClient.newRequest(LOGIN_BASE + "/api/CombinedSigninAndSignup/confirmed") - .param("csrf_token", signInConfig.csrf).param("tx", "StateProperties=" + signInConfig.transId) - .param("p", "B2C_1A_SignUpOrSigninOnline"); + .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS).param("csrf_token", signInConfig.csrf) + .param("tx", "StateProperties=" + signInConfig.transId).param("p", "B2C_1A_SignUpOrSigninOnline"); ContentResponse confirmedResponse = confirmedRequest.send(); @@ -362,7 +364,8 @@ public class GeneracMobileLinkAccountHandler extends BaseBridgeHandler { fields.put("state", loginState.attr("value")); fields.put("code", loginCode.attr("value")); - Request loginRequest = httpClient.POST(action).content(new FormContentProvider(fields)); + Request loginRequest = httpClient.POST(action).timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS) + .content(new FormContentProvider(fields)); ContentResponse loginResponse = loginRequest.send(); if (logger.isTraceEnabled()) { diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/GatewayWebTargets.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/GatewayWebTargets.java index afc5cae81..1aebd8590 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/GatewayWebTargets.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/GatewayWebTargets.java @@ -66,6 +66,7 @@ public class GatewayWebTargets implements Closeable, HostnameVerifier { private static final String IDS = "ids"; private static final int SLEEP_SECONDS = 360; private static final Set HTTP_OK_CODES = Set.of(HttpStatus.OK_200, HttpStatus.NO_CONTENT_204); + private static final int REQUEST_TIMEOUT_MS = 10_000; private final Logger logger = LoggerFactory.getLogger(GatewayWebTargets.class); private final Gson jsonParser = new Gson(); @@ -248,7 +249,8 @@ public class GatewayWebTargets implements Closeable, HostnameVerifier { logger.trace("invoke() request JSON:{}", jsonCommand); } } - Request request = httpClient.newRequest(url).method(method).header("Connection", "close").accept("*/*"); + Request request = httpClient.newRequest(url).method(method).header("Connection", "close").accept("*/*") + .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS); if (query != null) { request.param(query.getKey(), query.getValue()); } diff --git a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewWebTargets.java b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewWebTargets.java index 1b0a78d5d..1b2af7870 100644 --- a/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewWebTargets.java +++ b/bundles/org.openhab.binding.hdpowerview/src/main/java/org/openhab/binding/hdpowerview/internal/HDPowerViewWebTargets.java @@ -16,6 +16,7 @@ import java.time.Duration; import java.time.Instant; import java.util.List; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -75,6 +76,7 @@ import com.google.gson.JsonParser; */ @NonNullByDefault public class HDPowerViewWebTargets { + private static final int REQUEST_TIMEOUT_MS = 30_000; private final Logger logger = LoggerFactory.getLogger(HDPowerViewWebTargets.class); @@ -581,7 +583,8 @@ public class HDPowerViewWebTargets { logger.trace("JSON command = {}", jsonCommand); } } - Request request = httpClient.newRequest(url).method(method).header("Connection", "close").accept("*/*"); + Request request = httpClient.newRequest(url).method(method).header("Connection", "close").accept("*/*") + .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS); if (query != null) { request.param(query.getKey(), query.getValue()); } diff --git a/bundles/org.openhab.binding.icalendar/src/main/java/org/openhab/binding/icalendar/internal/handler/PullJob.java b/bundles/org.openhab.binding.icalendar/src/main/java/org/openhab/binding/icalendar/internal/handler/PullJob.java index 84275f821..e55efaf86 100644 --- a/bundles/org.openhab.binding.icalendar/src/main/java/org/openhab/binding/icalendar/internal/handler/PullJob.java +++ b/bundles/org.openhab.binding.icalendar/src/main/java/org/openhab/binding/icalendar/internal/handler/PullJob.java @@ -89,7 +89,8 @@ class PullJob implements Runnable { @Override public void run() { - final Request request = httpClient.newRequest(sourceURI).followRedirects(true).method(HttpMethod.GET); + final Request request = httpClient.newRequest(sourceURI).followRedirects(true).method(HttpMethod.GET) + .timeout(HTTP_TIMEOUT_SECS, TimeUnit.SECONDS); final Authentication.Result currentAuthentication = authentication; if (currentAuthentication != null) { currentAuthentication.apply(request); diff --git a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/JuiceNetApi.java b/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/JuiceNetApi.java index 29785ddcc..ec9b5f1a7 100644 --- a/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/JuiceNetApi.java +++ b/bundles/org.openhab.binding.juicenet/src/main/java/org/openhab/binding/juicenet/internal/api/JuiceNetApi.java @@ -18,6 +18,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -54,6 +55,7 @@ public class JuiceNetApi { private static final String API_HOST = "https://jbv1-api.emotorwerks.com/"; private static final String API_ACCOUNT = API_HOST + "box_pin"; private static final String API_DEVICE = API_HOST + "box_api_secure"; + private static final int REQUEST_TIMEOUT_MS = 10_000; private String apiToken = ""; private HttpClient httpClient; @@ -180,6 +182,7 @@ public class JuiceNetApi { public JsonObject postApiCommand(ApiCommand cmd, @Nullable String token, Map params) throws InterruptedException, JuiceNetApiException { Request request = httpClient.POST(cmd.uri); + request.timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS); request.header(HttpHeader.CONTENT_TYPE, "application/json"); // Add required params diff --git a/bundles/org.openhab.binding.kostalinverter/src/main/java/org/openhab/binding/kostalinverter/internal/secondgeneration/SecondGenerationConfigurationHandler.java b/bundles/org.openhab.binding.kostalinverter/src/main/java/org/openhab/binding/kostalinverter/internal/secondgeneration/SecondGenerationConfigurationHandler.java index df282ea0e..aedf192a2 100644 --- a/bundles/org.openhab.binding.kostalinverter/src/main/java/org/openhab/binding/kostalinverter/internal/secondgeneration/SecondGenerationConfigurationHandler.java +++ b/bundles/org.openhab.binding.kostalinverter/src/main/java/org/openhab/binding/kostalinverter/internal/secondgeneration/SecondGenerationConfigurationHandler.java @@ -17,6 +17,7 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Base64; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -42,6 +43,8 @@ import com.google.gson.JsonParser; @NonNullByDefault public class SecondGenerationConfigurationHandler { + private static final int REQUEST_TIMEOUT_MS = 5000; + public static void executeConfigurationChanges(HttpClient httpClient, String url, String username, String password, String dxsId, String value) throws InterruptedException, ExecutionException, TimeoutException, NoSuchAlgorithmException { @@ -75,7 +78,8 @@ public class SecondGenerationConfigurationHandler { String loginPostJsonData = "{\"mode\":1,\"userId\":\"" + username + "\",\"pwh\":\"" + saltedmDigestedPwd + "\"}"; - Request loginPostJsonResponse = httpClient.POST(urlLogin + "?sessionId=" + sessionId); + Request loginPostJsonResponse = httpClient.POST(urlLogin + "?sessionId=" + sessionId) + .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS); loginPostJsonResponse.header(HttpHeader.CONTENT_TYPE, "application/json"); loginPostJsonResponse.content(new StringContentProvider(loginPostJsonData)); ContentResponse loginPostJsonDataContentResponse = loginPostJsonResponse.send(); @@ -91,7 +95,8 @@ public class SecondGenerationConfigurationHandler { // Part for sending data to Inverter String postJsonData = "{\"dxsEntries\":[{\"dxsId\":" + dxsId + ",\"value\":" + value + "}]}"; - Request postJsonDataRequest = httpClient.POST(url + "/api/dxs.json?sessionId=" + sessionId); + Request postJsonDataRequest = httpClient.POST(url + "/api/dxs.json?sessionId=" + sessionId) + .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS); postJsonDataRequest.header(HttpHeader.CONTENT_TYPE, "application/json"); postJsonDataRequest.content(new StringContentProvider(postJsonData)); postJsonDataRequest.send(); diff --git a/bundles/org.openhab.binding.liquidcheck/src/main/java/org/openhab/binding/liquidcheck/internal/discovery/LiquidCheckDiscoveryService.java b/bundles/org.openhab.binding.liquidcheck/src/main/java/org/openhab/binding/liquidcheck/internal/discovery/LiquidCheckDiscoveryService.java index 13091d770..678f60e36 100644 --- a/bundles/org.openhab.binding.liquidcheck/src/main/java/org/openhab/binding/liquidcheck/internal/discovery/LiquidCheckDiscoveryService.java +++ b/bundles/org.openhab.binding.liquidcheck/src/main/java/org/openhab/binding/liquidcheck/internal/discovery/LiquidCheckDiscoveryService.java @@ -25,6 +25,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -58,6 +59,7 @@ import com.google.gson.JsonSyntaxException; public class LiquidCheckDiscoveryService extends AbstractDiscoveryService { private static final int DISCOVER_TIMEOUT_SECONDS = 300; + private static final int REQUEST_TIMEOUT_MS = 10_000; private final Logger logger = LoggerFactory.getLogger(this.getClass()); private final HttpClient httpClient; @@ -97,7 +99,8 @@ public class LiquidCheckDiscoveryService extends AbstractDiscoveryService { List hosts = findActiveHosts(addresses); for (InetAddress host : hosts) { Request request = httpClient.newRequest("http://" + host.getHostAddress() + "/infos.json") - .method(HttpMethod.GET).followRedirects(false); + .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS).method(HttpMethod.GET) + .followRedirects(false); try { ContentResponse response = request.send(); if (response.getStatus() == 200) { diff --git a/bundles/org.openhab.binding.liquidcheck/src/main/java/org/openhab/binding/liquidcheck/internal/httpclient/LiquidCheckHttpClient.java b/bundles/org.openhab.binding.liquidcheck/src/main/java/org/openhab/binding/liquidcheck/internal/httpclient/LiquidCheckHttpClient.java index 2ffa6e2b2..8f9274346 100644 --- a/bundles/org.openhab.binding.liquidcheck/src/main/java/org/openhab/binding/liquidcheck/internal/httpclient/LiquidCheckHttpClient.java +++ b/bundles/org.openhab.binding.liquidcheck/src/main/java/org/openhab/binding/liquidcheck/internal/httpclient/LiquidCheckHttpClient.java @@ -34,7 +34,6 @@ import org.slf4j.LoggerFactory; */ @NonNullByDefault public class LiquidCheckHttpClient { - private final Logger logger = LoggerFactory.getLogger(LiquidCheckHttpClient.class); private final HttpClient client; private final LiquidCheckConfiguration config; @@ -78,7 +77,7 @@ public class LiquidCheckHttpClient { */ public String measureCommand() throws InterruptedException, TimeoutException, ExecutionException { String uri = "http://" + config.hostname + "/command"; - Request request = client.newRequest(uri); + Request request = client.newRequest(uri).timeout(config.connectionTimeout, TimeUnit.SECONDS); request.method(HttpMethod.POST); request.header(HttpHeader.CONTENT_TYPE, "applicaton/json"); request.content(new StringContentProvider( diff --git a/bundles/org.openhab.binding.mcd/src/main/java/org/openhab/binding/mcd/internal/handler/McdBridgeHandler.java b/bundles/org.openhab.binding.mcd/src/main/java/org/openhab/binding/mcd/internal/handler/McdBridgeHandler.java index 882a51be7..71b68276f 100644 --- a/bundles/org.openhab.binding.mcd/src/main/java/org/openhab/binding/mcd/internal/handler/McdBridgeHandler.java +++ b/bundles/org.openhab.binding.mcd/src/main/java/org/openhab/binding/mcd/internal/handler/McdBridgeHandler.java @@ -47,6 +47,7 @@ import com.google.gson.JsonObject; @NonNullByDefault public class McdBridgeHandler extends BaseBridgeHandler { + private static final int REQUEST_TIMEOUT_MS = 10_000; private final Logger logger = LoggerFactory.getLogger(McdBridgeHandler.class); private @Nullable McdBridgeConfiguration config; @@ -107,7 +108,9 @@ public class McdBridgeHandler extends BaseBridgeHandler { Request request = httpClient.newRequest("https://cunds-syncapi.azurewebsites.net/token") .method(HttpMethod.POST).header(HttpHeader.CONTENT_TYPE, "application/x-www-form-urlencoded") .header(HttpHeader.HOST, "cunds-syncapi.azurewebsites.net") - .header(HttpHeader.ACCEPT, "application/json"); + .header(HttpHeader.ACCEPT, "application/json") + .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS); + String content = "grant_type=password&username=" + localConfig.getUserEmail() + "&password=" + localConfig.getUserPassword(); request.content(new StringContentProvider(content), "application/x-www-form-urlencoded"); diff --git a/bundles/org.openhab.binding.mcd/src/main/java/org/openhab/binding/mcd/internal/handler/SensorThingHandler.java b/bundles/org.openhab.binding.mcd/src/main/java/org/openhab/binding/mcd/internal/handler/SensorThingHandler.java index d4d058066..16881b570 100644 --- a/bundles/org.openhab.binding.mcd/src/main/java/org/openhab/binding/mcd/internal/handler/SensorThingHandler.java +++ b/bundles/org.openhab.binding.mcd/src/main/java/org/openhab/binding/mcd/internal/handler/SensorThingHandler.java @@ -17,6 +17,7 @@ import static org.openhab.binding.mcd.internal.McdBindingConstants.*; import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.concurrent.TimeUnit; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; @@ -53,7 +54,9 @@ import com.google.gson.JsonObject; @NonNullByDefault public class SensorThingHandler extends BaseThingHandler { + private static final int REQUEST_TIMEOUT_MS = 10_000; private final Logger logger = LoggerFactory.getLogger(SensorThingHandler.class); + private final HttpClient httpClient; private final @Nullable Gson gson; private @Nullable McdBridgeHandler mcdBridgeHandler; @@ -237,7 +240,9 @@ public class SensorThingHandler extends BaseThingHandler { Request request = httpClient.newRequest(urlString).method(HttpMethod.GET) .header(HttpHeader.HOST, "cunds-syncapi.azurewebsites.net") .header(HttpHeader.ACCEPT, "application/json") - .header(HttpHeader.AUTHORIZATION, "Bearer " + accessToken); + .header(HttpHeader.AUTHORIZATION, "Bearer " + accessToken) + .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS); + request.send(new BufferingResponseListener() { @NonNullByDefault({}) @Override @@ -265,7 +270,8 @@ public class SensorThingHandler extends BaseThingHandler { String accessToken = localMcdBridgeHandler.getAccessToken(); Request request = httpClient .newRequest("https://cunds-syncapi.azurewebsites.net/api/Device?serialNumber=" + serialNumber) - .method(HttpMethod.GET).header(HttpHeader.HOST, "cunds-syncapi.azurewebsites.net") + .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS).method(HttpMethod.GET) + .header(HttpHeader.HOST, "cunds-syncapi.azurewebsites.net") .header(HttpHeader.ACCEPT, "application/json") .header(HttpHeader.AUTHORIZATION, "Bearer " + accessToken); request.send(new BufferingResponseListener() { @@ -297,7 +303,8 @@ public class SensorThingHandler extends BaseThingHandler { if (localMcdBridgeHandler != null) { String accessToken = localMcdBridgeHandler.getAccessToken(); Request request = httpClient.newRequest("https://cunds-syncapi.azurewebsites.net/api/ApiSensor/GetEventDef") - .method(HttpMethod.GET).header(HttpHeader.HOST, "cunds-syncapi.azurewebsites.net") + .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS).method(HttpMethod.GET) + .header(HttpHeader.HOST, "cunds-syncapi.azurewebsites.net") .header(HttpHeader.ACCEPT, "application/json") .header(HttpHeader.AUTHORIZATION, "Bearer " + accessToken); request.send(new BufferingResponseListener() { @@ -401,7 +408,8 @@ public class SensorThingHandler extends BaseThingHandler { Date date = new Date(); String dateString = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").format(date); Request request = httpClient.newRequest("https://cunds-syncapi.azurewebsites.net/api/ApiSensor") - .method(HttpMethod.POST).header(HttpHeader.CONTENT_TYPE, "application/json") + .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS).method(HttpMethod.POST) + .header(HttpHeader.CONTENT_TYPE, "application/json") .header(HttpHeader.ACCEPT, "application/json") .header(HttpHeader.AUTHORIZATION, "Bearer " + accessToken); JsonObject jsonObject = new JsonObject(); diff --git a/bundles/org.openhab.binding.meater/src/main/java/org/openhab/binding/meater/internal/api/MeaterRestAPI.java b/bundles/org.openhab.binding.meater/src/main/java/org/openhab/binding/meater/internal/api/MeaterRestAPI.java index 0832b4943..8a7ae3efd 100644 --- a/bundles/org.openhab.binding.meater/src/main/java/org/openhab/binding/meater/internal/api/MeaterRestAPI.java +++ b/bundles/org.openhab.binding.meater/src/main/java/org/openhab/binding/meater/internal/api/MeaterRestAPI.java @@ -15,6 +15,7 @@ package org.openhab.binding.meater.internal.api; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -56,6 +57,7 @@ public class MeaterRestAPI { private static final String LOGIN = "login"; private static final String DEVICES = "devices"; private static final int MAX_RETRIES = 3; + private static final int REQUEST_TIMEOUT_MS = 10_000; private final Logger logger = LoggerFactory.getLogger(MeaterRestAPI.class); private final Gson gson; @@ -99,7 +101,8 @@ public class MeaterRestAPI { // Login String json = "{ \"email\": \"" + configuration.email + "\", \"password\": \"" + configuration.password + "\" }"; - Request request = httpClient.newRequest(API_ENDPOINT + LOGIN).method(HttpMethod.POST); + Request request = httpClient.newRequest(API_ENDPOINT + LOGIN).method(HttpMethod.POST) + .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS); request.header(HttpHeader.ACCEPT, JSON_CONTENT_TYPE); request.header(HttpHeader.CONTENT_TYPE, JSON_CONTENT_TYPE); request.content(new StringContentProvider(json), JSON_CONTENT_TYPE); @@ -132,7 +135,8 @@ public class MeaterRestAPI { try { for (int i = 0; i < MAX_RETRIES; i++) { try { - Request request = httpClient.newRequest(API_ENDPOINT + uri).method(HttpMethod.GET); + Request request = httpClient.newRequest(API_ENDPOINT + uri).method(HttpMethod.GET) + .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS); request.header(HttpHeader.AUTHORIZATION, "Bearer " + authToken); request.header(HttpHeader.ACCEPT, JSON_CONTENT_TYPE); request.header(HttpHeader.CONTENT_TYPE, JSON_CONTENT_TYPE); diff --git a/bundles/org.openhab.binding.mercedesme/src/main/java/org/openhab/binding/mercedesme/internal/handler/VehicleHandler.java b/bundles/org.openhab.binding.mercedesme/src/main/java/org/openhab/binding/mercedesme/internal/handler/VehicleHandler.java index e377159d8..fc048da75 100644 --- a/bundles/org.openhab.binding.mercedesme/src/main/java/org/openhab/binding/mercedesme/internal/handler/VehicleHandler.java +++ b/bundles/org.openhab.binding.mercedesme/src/main/java/org/openhab/binding/mercedesme/internal/handler/VehicleHandler.java @@ -83,6 +83,7 @@ import org.slf4j.LoggerFactory; */ @NonNullByDefault public class VehicleHandler extends BaseThingHandler { + private static final int REQUEST_TIMEOUT_MS = 10_000; private static final String EXT_IMG_RES = "ExtImageResources_"; private static final String INITIALIZE_COMMAND = "Initialze"; @@ -317,7 +318,7 @@ public class VehicleHandler extends BaseThingHandler { String params = UrlEncoded.encode(parameterMap, StandardCharsets.UTF_8, false); String url = String.format(IMAGE_EXTERIOR_RESOURCE_URL, config.get().vin) + "?" + params; logger.debug("Get Image resources {} {} ", accountHandler.get().getImageApiKey(), url); - Request req = httpClient.newRequest(url); + Request req = httpClient.newRequest(url).timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS); req.header("x-api-key", accountHandler.get().getImageApiKey()); req.header(HttpHeader.ACCEPT, "application/json"); try { @@ -378,7 +379,7 @@ public class VehicleHandler extends BaseThingHandler { } String url = IMAGE_BASE_URL + "/images/" + imageId; - Request req = httpClient.newRequest(url); + Request req = httpClient.newRequest(url).timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS); req.header("x-api-key", accountHandler.get().getImageApiKey()); req.header(HttpHeader.ACCEPT, "*/*"); ContentResponse cr; @@ -400,7 +401,7 @@ public class VehicleHandler extends BaseThingHandler { // debug prefix contains Thing label and call endpoint for propper debugging String debugPrefix = this.getThing().getLabel() + Constants.COLON + finalEndpoint; - Request req = httpClient.newRequest(requestUrl); + Request req = httpClient.newRequest(requestUrl).timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS); req.header(HttpHeader.AUTHORIZATION, "Bearer " + accountHandler.get().getToken()); try { ContentResponse cr = req.send(); diff --git a/bundles/org.openhab.binding.miele/src/main/java/org/openhab/binding/miele/internal/MieleGatewayCommunicationController.java b/bundles/org.openhab.binding.miele/src/main/java/org/openhab/binding/miele/internal/MieleGatewayCommunicationController.java index 049f0cae4..dd9cd6f6c 100644 --- a/bundles/org.openhab.binding.miele/src/main/java/org/openhab/binding/miele/internal/MieleGatewayCommunicationController.java +++ b/bundles/org.openhab.binding.miele/src/main/java/org/openhab/binding/miele/internal/MieleGatewayCommunicationController.java @@ -17,6 +17,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.Random; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -44,6 +45,7 @@ import com.google.gson.JsonParser; */ @NonNullByDefault public class MieleGatewayCommunicationController { + private static final int REQUEST_TIMEOUT_MS = 10_000; private final URI uri; private final Random rand = new Random(); @@ -83,6 +85,7 @@ public class MieleGatewayCommunicationController { String requestBody = requestBodyAsJson.toString(); Request request = httpClient.newRequest(uri).method(HttpMethod.POST) + .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS) .content(new StringContentProvider(requestBody), "application/json"); String responseData = null; diff --git a/bundles/org.openhab.binding.mybmw/src/main/java/org/openhab/binding/mybmw/internal/handler/MyBMWProxy.java b/bundles/org.openhab.binding.mybmw/src/main/java/org/openhab/binding/mybmw/internal/handler/MyBMWProxy.java index 8a82eb18c..82014a400 100644 --- a/bundles/org.openhab.binding.mybmw/src/main/java/org/openhab/binding/mybmw/internal/handler/MyBMWProxy.java +++ b/bundles/org.openhab.binding.mybmw/src/main/java/org/openhab/binding/mybmw/internal/handler/MyBMWProxy.java @@ -305,7 +305,8 @@ public class MyBMWProxy { */ String authValuesUrl = "https://" + BimmerConstants.EADRAX_SERVER_MAP.get(configuration.region) + BimmerConstants.API_OAUTH_CONFIG; - Request authValuesRequest = httpClient.newRequest(authValuesUrl); + Request authValuesRequest = httpClient.newRequest(authValuesUrl).timeout(HTTP_TIMEOUT_SEC, + TimeUnit.SECONDS); authValuesRequest.header(ACP_SUBSCRIPTION_KEY, BimmerConstants.OCP_APIM_KEYS.get(configuration.region)); authValuesRequest.header(X_USER_AGENT, String.format(BimmerConstants.X_USER_AGENT, BimmerConstants.BRAND_BMW, configuration.region)); @@ -344,7 +345,7 @@ public class MyBMWProxy { * Step 3) Authorization with username and password */ String loginUrl = aqr.gcdmBaseUrl + BimmerConstants.OAUTH_ENDPOINT; - Request loginRequest = httpClient.POST(loginUrl); + Request loginRequest = httpClient.POST(loginUrl).timeout(HTTP_TIMEOUT_SEC, TimeUnit.SECONDS); loginRequest.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_URL_ENCODED); MultiMap loginParams = new MultiMap(baseParams); @@ -364,7 +365,8 @@ public class MyBMWProxy { /** * Step 4) Authorize with code */ - Request authRequest = httpClient.POST(loginUrl).followRedirects(false); + Request authRequest = httpClient.POST(loginUrl).followRedirects(false).timeout(HTTP_TIMEOUT_SEC, + TimeUnit.SECONDS); MultiMap authParams = new MultiMap(baseParams); authParams.put(AUTHORIZATION, authCode); authRequest.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_URL_ENCODED); @@ -380,7 +382,7 @@ public class MyBMWProxy { /** * Step 5) Request token */ - Request codeRequest = httpClient.POST(aqr.tokenEndpoint); + Request codeRequest = httpClient.POST(aqr.tokenEndpoint).timeout(HTTP_TIMEOUT_SEC, TimeUnit.SECONDS); String basicAuth = "Basic " + Base64.getUrlEncoder().encodeToString((aqr.clientId + ":" + aqr.clientSecret).getBytes()); codeRequest.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_URL_ENCODED); @@ -444,7 +446,7 @@ public class MyBMWProxy { */ String publicKeyUrl = "https://" + BimmerConstants.EADRAX_SERVER_MAP.get(BimmerConstants.REGION_CHINA) + BimmerConstants.CHINA_PUBLIC_KEY; - Request oauthQueryRequest = httpClient.newRequest(publicKeyUrl); + Request oauthQueryRequest = httpClient.newRequest(publicKeyUrl).timeout(HTTP_TIMEOUT_SEC, TimeUnit.SECONDS); oauthQueryRequest.header(HttpHeader.USER_AGENT, BimmerConstants.USER_AGENT); oauthQueryRequest.header(X_USER_AGENT, String.format(BimmerConstants.X_USER_AGENT, BimmerConstants.BRAND_BMW, configuration.region)); @@ -480,7 +482,7 @@ public class MyBMWProxy { */ String tokenUrl = "https://" + BimmerConstants.EADRAX_SERVER_MAP.get(BimmerConstants.REGION_CHINA) + BimmerConstants.CHINA_LOGIN; - Request loginRequest = httpClient.POST(tokenUrl); + Request loginRequest = httpClient.POST(tokenUrl).timeout(HTTP_TIMEOUT_SEC, TimeUnit.SECONDS); loginRequest.header(X_USER_AGENT, String.format(BimmerConstants.X_USER_AGENT, BimmerConstants.BRAND_BMW, configuration.region)); String jsonContent = "{ \"mobile\":\"" + configuration.userName + "\", \"password\":\"" + encodedPassword diff --git a/bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/handler/MyQAccountHandler.java b/bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/handler/MyQAccountHandler.java index bd3b095b9..0e8cccf0b 100644 --- a/bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/handler/MyQAccountHandler.java +++ b/bundles/org.openhab.binding.myq/src/main/java/org/openhab/binding/myq/internal/handler/MyQAccountHandler.java @@ -92,6 +92,8 @@ import com.google.gson.JsonSyntaxException; */ @NonNullByDefault public class MyQAccountHandler extends BaseBridgeHandler implements AccessTokenRefreshListener { + private static final int REQUEST_TIMEOUT_MS = 10_000; + /* * MyQ oAuth relate fields */ @@ -416,7 +418,8 @@ public class MyQAccountHandler extends BaseBridgeHandler implements AccessTokenR needsLogin = false; } - Request request = httpClient.newRequest(url).method(method).agent(userAgent).timeout(10, TimeUnit.SECONDS) + Request request = httpClient.newRequest(url).method(method).agent(userAgent) + .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS) .header("Authorization", authTokenHeader(tokenResponse)); if (content != null & contentType != null) { request = request.content(content, contentType); @@ -484,6 +487,7 @@ public class MyQAccountHandler extends BaseBridgeHandler implements AccessTokenR throws InterruptedException, ExecutionException, TimeoutException { try { Request request = httpClient.newRequest(LOGIN_AUTHORIZE_URL) // + .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS) // .param("client_id", CLIENT_ID) // .param("code_challenge", generateCodeChallange(codeVerifier)) // .param("code_challenge_method", "S256") // @@ -531,6 +535,7 @@ public class MyQAccountHandler extends BaseBridgeHandler implements AccessTokenR fields.add("ReturnUrl", returnURL); Request request = httpClient.newRequest(url).method(HttpMethod.POST) // + .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS) // .content(new FormContentProvider(fields)) // .agent(userAgent) // .followRedirects(false); @@ -557,7 +562,8 @@ public class MyQAccountHandler extends BaseBridgeHandler implements AccessTokenR location = loc; break; } - request = httpClient.newRequest(LOGIN_BASE_URL + loc).agent(userAgent).followRedirects(false); + request = httpClient.newRequest(LOGIN_BASE_URL + loc).timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS) + .agent(userAgent).followRedirects(false); setCookies(request); response = request.send(); } @@ -589,11 +595,11 @@ public class MyQAccountHandler extends BaseBridgeHandler implements AccessTokenR fields.add("scope", params.get("scope")); Request request = httpClient.newRequest(LOGIN_TOKEN_URL) // + .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS) // .content(new FormContentProvider(fields)) // .method(HttpMethod.POST) // .agent(userAgent).followRedirects(true); setCookies(request); - ContentResponse response = request.send(); if (logger.isTraceEnabled()) { logger.trace("Login Code {} Response {}", response.getStatus(), response.getContentAsString()); diff --git a/bundles/org.openhab.binding.ojelectronics/src/main/java/org/openhab/binding/ojelectronics/internal/services/UpdateService.java b/bundles/org.openhab.binding.ojelectronics/src/main/java/org/openhab/binding/ojelectronics/internal/services/UpdateService.java index 22ac84d6c..960496e9e 100644 --- a/bundles/org.openhab.binding.ojelectronics/src/main/java/org/openhab/binding/ojelectronics/internal/services/UpdateService.java +++ b/bundles/org.openhab.binding.ojelectronics/src/main/java/org/openhab/binding/ojelectronics/internal/services/UpdateService.java @@ -14,6 +14,7 @@ package org.openhab.binding.ojelectronics.internal.services; import java.util.List; import java.util.Objects; +import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -43,7 +44,7 @@ import com.google.gson.Gson; */ @NonNullByDefault public final class UpdateService { - + private static final int REQUEST_TIMEOUT_MS = 10_000; private final Gson gson = OJGSonBuilder.getGSon(); private final Logger logger = LoggerFactory.getLogger(UpdateService.class); @@ -83,8 +84,8 @@ public final class UpdateService { } String jsonPayload = gson.toJson(new UpdateThermostatRequestModel(thermostat).withApiKey(configuration.apiKey)); Request request = httpClient.POST(configuration.getRestApiUrl() + "/Thermostat/UpdateThermostat") - .param("sessionid", sessionId).header(HttpHeader.CONTENT_TYPE, "application/json") - .content(new StringContentProvider(jsonPayload)); + .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS).param("sessionid", sessionId) + .header(HttpHeader.CONTENT_TYPE, "application/json").content(new StringContentProvider(jsonPayload)); logger.trace("updateThermostat payload for themostat with serial {} is {}", thermostat.serialNumber, jsonPayload); diff --git a/bundles/org.openhab.binding.plex/src/main/java/org/openhab/binding/plex/internal/handler/PlexApiConnector.java b/bundles/org.openhab.binding.plex/src/main/java/org/openhab/binding/plex/internal/handler/PlexApiConnector.java index 9d6adb82b..23d79a205 100644 --- a/bundles/org.openhab.binding.plex/src/main/java/org/openhab/binding/plex/internal/handler/PlexApiConnector.java +++ b/bundles/org.openhab.binding.plex/src/main/java/org/openhab/binding/plex/internal/handler/PlexApiConnector.java @@ -228,7 +228,8 @@ public class PlexApiConnector { response = HttpUtil.executeUrl(method, url, headers, null, null, REQUEST_TIMEOUT_MS); } else { // Requests sent to the local server need to bypass certificate checking via the custom httpClient - final Request request = httpClient.newRequest(url).method(HttpUtil.createHttpMethod(method)); + final Request request = httpClient.newRequest(url).method(HttpUtil.createHttpMethod(method)) + .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS); for (String httpHeaderKey : headers.stringPropertyNames()) { if (httpHeaderKey.equalsIgnoreCase(HttpHeader.USER_AGENT.toString())) { request.agent(headers.getProperty(httpHeaderKey)); diff --git a/bundles/org.openhab.binding.radiothermostat/src/main/java/org/openhab/binding/radiothermostat/internal/communication/RadioThermostatConnector.java b/bundles/org.openhab.binding.radiothermostat/src/main/java/org/openhab/binding/radiothermostat/internal/communication/RadioThermostatConnector.java index 191645e79..50b174c90 100644 --- a/bundles/org.openhab.binding.radiothermostat/src/main/java/org/openhab/binding/radiothermostat/internal/communication/RadioThermostatConnector.java +++ b/bundles/org.openhab.binding.radiothermostat/src/main/java/org/openhab/binding/radiothermostat/internal/communication/RadioThermostatConnector.java @@ -44,6 +44,7 @@ import org.slf4j.LoggerFactory; public class RadioThermostatConnector { private final Logger logger = LoggerFactory.getLogger(RadioThermostatConnector.class); + private static final int REQUEST_TIMEOUT_MS = 10_000; private static final String URL = "http://%s/%s"; private final HttpClient httpClient; @@ -124,7 +125,8 @@ public class RadioThermostatConnector { String postJson = cmdJson != null ? cmdJson : "{\"" + cmdKey + "\":" + cmdVal + "}"; try { - Request request = httpClient.POST(buildRequestURL(resource)); + Request request = httpClient.POST(buildRequestURL(resource)).timeout(REQUEST_TIMEOUT_MS, + TimeUnit.MILLISECONDS); request.header(HttpHeader.ACCEPT, "text/plain"); request.header(HttpHeader.CONTENT_TYPE, "text/plain"); request.content(new StringContentProvider(postJson), "application/json"); diff --git a/bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/api/MyRenaultHttpSession.java b/bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/api/MyRenaultHttpSession.java index 55bf3c0fc..675cb9331 100644 --- a/bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/api/MyRenaultHttpSession.java +++ b/bundles/org.openhab.binding.renault/src/main/java/org/openhab/binding/renault/internal/api/MyRenaultHttpSession.java @@ -13,6 +13,7 @@ package org.openhab.binding.renault.internal.api; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -52,6 +53,7 @@ public class MyRenaultHttpSession { private static final String CHARGING_MODE_SCHEDULE = "schedule_mode"; private static final String CHARGING_MODE_ALWAYS = "always_charging"; + private static final int REQUEST_TIMEOUT_MS = 10_000; private RenaultConfiguration config; private HttpClient httpClient; @@ -287,7 +289,8 @@ public class MyRenaultHttpSession { private void postKamereonRequest(final String path, final String content) throws RenaultForbiddenException, RenaultNotImplementedException, RenaultActionException, RenaultAPIGatewayException { Request request = httpClient.newRequest(this.constants.getKamereonRootUrl() + path).method(HttpMethod.POST) - .header("Content-type", "application/vnd.api+json").header("apikey", this.config.kamereonApiKey) + .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS).header("Content-type", "application/vnd.api+json") + .header("apikey", this.config.kamereonApiKey) .header("x-kamereon-authorization", "Bearer " + kamereonToken).header("x-gigya-id_token", jwt) .content(new StringContentProvider(content, "utf-8")); try { @@ -305,7 +308,8 @@ public class MyRenaultHttpSession { private @Nullable JsonObject getKamereonResponse(String path) throws RenaultForbiddenException, RenaultNotImplementedException, RenaultUpdateException, RenaultAPIGatewayException { Request request = httpClient.newRequest(this.constants.getKamereonRootUrl() + path).method(HttpMethod.GET) - .header("Content-type", "application/vnd.api+json").header("apikey", this.config.kamereonApiKey) + .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS).header("Content-type", "application/vnd.api+json") + .header("apikey", this.config.kamereonApiKey) .header("x-kamereon-authorization", "Bearer " + kamereonToken).header("x-gigya-id_token", jwt); try { ContentResponse response = request.send(); diff --git a/bundles/org.openhab.binding.semsportal/src/main/java/org/openhab/binding/semsportal/internal/PortalHandler.java b/bundles/org.openhab.binding.semsportal/src/main/java/org/openhab/binding/semsportal/internal/PortalHandler.java index 853fd94f6..7c204dd19 100644 --- a/bundles/org.openhab.binding.semsportal/src/main/java/org/openhab/binding/semsportal/internal/PortalHandler.java +++ b/bundles/org.openhab.binding.semsportal/src/main/java/org/openhab/binding/semsportal/internal/PortalHandler.java @@ -16,6 +16,7 @@ import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.List; import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; import javax.ws.rs.core.MediaType; @@ -69,6 +70,7 @@ public class PortalHandler extends BaseBridgeHandler { private static final String LIST_URL = BASE_URL + "api/PowerStationMonitor/QueryPowerStationMonitorForApp"; // the token holds the credential information for the portal private static final String HTTP_HEADER_TOKEN = "Token"; + private static final int REQUEST_TIMEOUT_MS = 10_000; // used to parse json from / to the SEMS portal API private final Gson gson; @@ -147,7 +149,8 @@ public class PortalHandler extends BaseBridgeHandler { private @Nullable String sendPost(String url, String payload) { try { - Request request = httpClient.POST(url).header(HttpHeader.CONTENT_TYPE, MediaType.APPLICATION_JSON) + Request request = httpClient.POST(url).timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS) + .header(HttpHeader.CONTENT_TYPE, MediaType.APPLICATION_JSON) .header(HTTP_HEADER_TOKEN, gson.toJson(sessionToken)) .content(new StringContentProvider(payload, StandardCharsets.UTF_8.name()), MediaType.APPLICATION_JSON); diff --git a/bundles/org.openhab.binding.sensibo/src/main/java/org/openhab/binding/sensibo/internal/handler/SensiboAccountHandler.java b/bundles/org.openhab.binding.sensibo/src/main/java/org/openhab/binding/sensibo/internal/handler/SensiboAccountHandler.java index 334f9d24d..15c633a59 100644 --- a/bundles/org.openhab.binding.sensibo/src/main/java/org/openhab/binding/sensibo/internal/handler/SensiboAccountHandler.java +++ b/bundles/org.openhab.binding.sensibo/src/main/java/org/openhab/binding/sensibo/internal/handler/SensiboAccountHandler.java @@ -82,6 +82,7 @@ import com.google.gson.stream.JsonWriter; public class SensiboAccountHandler extends BaseBridgeHandler { private static final int MIN_TIME_BETWEEEN_MODEL_UPDATES_MS = 30_000; private static final int SECONDS_IN_MINUTE = 60; + private static final int REQUEST_TIMEOUT_MS = 10_000; public static String API_ENDPOINT = "https://home.sensibo.com/api"; private final Logger logger = LoggerFactory.getLogger(SensiboAccountHandler.class); private final HttpClient httpClient; @@ -275,6 +276,7 @@ public class SensiboAccountHandler extends BaseBridgeHandler { private Request buildRequest(final AbstractRequest req) { Request request = httpClient.newRequest(API_ENDPOINT + req.getRequestUrl()).param("apiKey", config.apiKey) .method(req.getMethod()); + request.timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS); if (!req.getMethod().contentEquals(HttpMethod.GET.asString())) { // POST, PATCH final String reqJson = gson.toJson(req); diff --git a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/api/TapoCloudConnector.java b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/api/TapoCloudConnector.java index 468948e07..a0e4fa950 100644 --- a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/api/TapoCloudConnector.java +++ b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/api/TapoCloudConnector.java @@ -16,6 +16,7 @@ import static org.openhab.binding.tapocontrol.internal.constants.TapoBindingSett import static org.openhab.binding.tapocontrol.internal.constants.TapoErrorCode.*; import java.util.UUID; +import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -213,6 +214,7 @@ public class TapoCloudConnector { @Nullable protected ContentResponse sendCloudRequest(String url, String payload) { Request httpRequest = httpClient.newRequest(url).method(HttpMethod.POST.toString()); + httpRequest.timeout(TAPO_HTTP_CLOUD_TIMEOUT_MS, TimeUnit.MILLISECONDS); /* set header */ httpRequest.header("content-type", CONTENT_TYPE_JSON); diff --git a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/constants/TapoBindingSettings.java b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/constants/TapoBindingSettings.java index e9024b64d..e53a85d05 100644 --- a/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/constants/TapoBindingSettings.java +++ b/bundles/org.openhab.binding.tapocontrol/src/main/java/org/openhab/binding/tapocontrol/internal/constants/TapoBindingSettings.java @@ -36,6 +36,7 @@ public class TapoBindingSettings { public static final Integer HTTP_MAX_CONNECTIONS = 10; // setMaxConnectionsPerDestination for HTTP-Client public static final Integer HTTP_MAX_QUEUED_REQUESTS = 10; // setMaxRequestsQueuedPerDestination for HTTP-Client public static final Integer TAPO_HTTP_TIMEOUT_MS = 5000; // http request timeout + public static final Integer TAPO_HTTP_CLOUD_TIMEOUT_MS = 10000; // http request cloud timeout public static final Integer TAPO_PING_TIMEOUT_MS = 2000; // ping timeout public static final Integer TAPO_REFRESH_MIN_GAP_MS = 5000; // min gap between sending refresh request public static final Integer TAPO_SEND_MIN_GAP_MS = 1000; // min gap between sending command request diff --git a/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/TelldusLocalDeviceController.java b/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/TelldusLocalDeviceController.java index 2da7a0146..076f11542 100644 --- a/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/TelldusLocalDeviceController.java +++ b/bundles/org.openhab.binding.tellstick/src/main/java/org/openhab/binding/tellstick/internal/local/TelldusLocalDeviceController.java @@ -15,6 +15,7 @@ package org.openhab.binding.tellstick.internal.local; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.eclipse.jetty.client.HttpClient; @@ -69,6 +70,7 @@ public class TelldusLocalDeviceController implements DeviceChangeListener, Senso static final String HTTP_LOCAL_API_DEVICE_TURNOFF = HTTP_LOCAL_API + "device/turnOff?id=%d"; static final String HTTP_LOCAL_DEVICE_TURNON = HTTP_LOCAL_API + "device/turnOn?id=%d"; private static final int MAX_RETRIES = 3; + private static final int REQUEST_TIMEOUT_MS = 10_000; public TelldusLocalDeviceController(TelldusLocalConfiguration configuration, HttpClient httpClient) { this.httpClient = httpClient; @@ -270,7 +272,8 @@ public class TelldusLocalDeviceController implements DeviceChangeListener, Senso throws ExecutionException, InterruptedException, TimeoutException, JsonSyntaxException { logger.trace("HTTP GET: {}", uri); - Request request = httpClient.newRequest(uri).method(HttpMethod.GET); + Request request = httpClient.newRequest(uri).method(HttpMethod.GET).timeout(REQUEST_TIMEOUT_MS, + TimeUnit.MILLISECONDS); request.header("Authorization", authorizationHeader); ContentResponse response = request.send(); diff --git a/bundles/org.openhab.binding.verisure/src/main/java/org/openhab/binding/verisure/internal/VerisureSession.java b/bundles/org.openhab.binding.verisure/src/main/java/org/openhab/binding/verisure/internal/VerisureSession.java index 3b892cc3a..1390bbd5c 100644 --- a/bundles/org.openhab.binding.verisure/src/main/java/org/openhab/binding/verisure/internal/VerisureSession.java +++ b/bundles/org.openhab.binding.verisure/src/main/java/org/openhab/binding/verisure/internal/VerisureSession.java @@ -30,6 +30,7 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -88,6 +89,7 @@ public class VerisureSession { "https://m-api02.verisure.com"); private int apiServerInUseIndex = 0; private int numberOfEvents = 15; + private static final int REQUEST_TIMEOUT_MS = 10_000; private static final String USER_NAME = "username"; private static final String VID = "vid"; private static final String VS_STEPUP = "vs-stepup"; @@ -333,6 +335,7 @@ public class VerisureSession { logger.debug("postVerisureAPI URL: {} Data:{}", url, data); Request request = httpClient.newRequest(url).method(HttpMethod.POST); + request.timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS); if (isJSON) { request.header("content-type", "application/json"); } else { diff --git a/bundles/org.openhab.binding.vizio/src/main/java/org/openhab/binding/vizio/internal/communication/VizioCommunicator.java b/bundles/org.openhab.binding.vizio/src/main/java/org/openhab/binding/vizio/internal/communication/VizioCommunicator.java index 2a9bac3ee..cca3aabba 100644 --- a/bundles/org.openhab.binding.vizio/src/main/java/org/openhab/binding/vizio/internal/communication/VizioCommunicator.java +++ b/bundles/org.openhab.binding.vizio/src/main/java/org/openhab/binding/vizio/internal/communication/VizioCommunicator.java @@ -13,6 +13,7 @@ package org.openhab.binding.vizio.internal.communication; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -51,6 +52,7 @@ public class VizioCommunicator { private static final String AUTH_HEADER = "AUTH"; private static final String JSON_CONTENT_TYPE = "application/json"; private static final String JSON_VALUE = "{\"VALUE\": %s}"; + private static final int REQUEST_TIMEOUT_MS = 10_000; private final HttpClient httpClient; private final Gson gson = new GsonBuilder().serializeNulls().create(); @@ -230,6 +232,7 @@ public class VizioCommunicator { private String getCommand(String url) throws VizioException { try { final Request request = httpClient.newRequest(url).method(HttpMethod.GET); + request.timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS); request.header(AUTH_HEADER, authToken); request.header(HttpHeader.CONTENT_TYPE, JSON_CONTENT_TYPE); @@ -254,6 +257,7 @@ public class VizioCommunicator { private String putCommand(String url, String commandJSON) throws VizioException { try { final Request request = httpClient.newRequest(url).method(HttpMethod.PUT); + request.timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS); if (!url.contains("pairing")) { request.header(AUTH_HEADER, authToken); }