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 <leosiepel@gmail.com>
Signed-off-by: Leo Siepel <leosiepel@gmail.com>
This commit is contained in:
lsiepel
2023-10-19 22:30:41 +02:00
committed by GitHub
parent c7568cb206
commit 7313415ae0
32 changed files with 135 additions and 48 deletions

View File

@@ -218,7 +218,7 @@ public class BondHttpApi {
final Request request = httpClient.newRequest(url).method(HttpMethod.GET).header("BOND-Token", final Request request = httpClient.newRequest(url).method(HttpMethod.GET).header("BOND-Token",
bridgeHandler.getBridgeToken()); bridgeHandler.getBridgeToken());
ContentResponse response; ContentResponse response;
response = request.send(); response = request.timeout(BOND_API_TIMEOUT_MS, TimeUnit.MILLISECONDS).send();
String encoding = response.getEncoding() != null ? response.getEncoding().replace("\"", "").trim() String encoding = response.getEncoding() != null ? response.getEncoding().replace("\"", "").trim()
: StandardCharsets.UTF_8.name(); : StandardCharsets.UTF_8.name();
try { try {

View File

@@ -12,10 +12,13 @@
*/ */
package org.openhab.binding.chatgpt.internal; package org.openhab.binding.chatgpt.internal;
import static org.openhab.binding.chatgpt.internal.ChatGPTBindingConstants.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
@@ -55,6 +58,7 @@ import com.google.gson.JsonObject;
@NonNullByDefault @NonNullByDefault
public class ChatGPTHandler extends BaseThingHandler { public class ChatGPTHandler extends BaseThingHandler {
private static final int REQUEST_TIMEOUT_MS = 10_000;
private final Logger logger = LoggerFactory.getLogger(ChatGPTHandler.class); private final Logger logger = LoggerFactory.getLogger(ChatGPTHandler.class);
private HttpClient httpClient; private HttpClient httpClient;
@@ -125,8 +129,8 @@ public class ChatGPTHandler extends BaseThingHandler {
String queryJson = gson.toJson(root); String queryJson = gson.toJson(root);
Request request = httpClient.newRequest(apiUrl).method(HttpMethod.POST) Request request = httpClient.newRequest(apiUrl).method(HttpMethod.POST)
.header("Content-Type", "application/json").header("Authorization", "Bearer " + apiKey) .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS).header("Content-Type", "application/json")
.content(new StringContentProvider(queryJson)); .header("Authorization", "Bearer " + apiKey).content(new StringContentProvider(queryJson));
logger.trace("Query '{}'", queryJson); logger.trace("Query '{}'", queryJson);
try { try {
ContentResponse response = request.send(); ContentResponse response = request.send();
@@ -166,8 +170,8 @@ public class ChatGPTHandler extends BaseThingHandler {
scheduler.execute(() -> { scheduler.execute(() -> {
try { try {
Request request = httpClient.newRequest(modelUrl).method(HttpMethod.GET).header("Authorization", Request request = httpClient.newRequest(modelUrl).timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS)
"Bearer " + apiKey); .method(HttpMethod.GET).header("Authorization", "Bearer " + apiKey);
ContentResponse response = request.send(); ContentResponse response = request.send();
if (response.getStatus() == 200) { if (response.getStatus() == 200) {
updateStatus(ThingStatus.ONLINE); updateStatus(ThingStatus.ONLINE);

View File

@@ -15,6 +15,7 @@ package org.openhab.binding.electroluxair.internal.api;
import java.time.Instant; import java.time.Instant;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.eclipse.jdt.annotation.NonNullByDefault; 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 String JSON_CONTENT_TYPE = "application/json";
private static final int MAX_RETRIES = 3; 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 Logger logger = LoggerFactory.getLogger(ElectroluxDeltaAPI.class);
private final Gson gson; private final Gson gson;
@@ -176,7 +178,7 @@ public class ElectroluxDeltaAPI {
private Request createRequest(String uri, HttpMethod httpMethod) { private Request createRequest(String uri, HttpMethod httpMethod) {
Request request = httpClient.newRequest(uri).method(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.ACCEPT, JSON_CONTENT_TYPE);
request.header(HttpHeader.CONTENT_TYPE, JSON_CONTENT_TYPE); request.header(HttpHeader.CONTENT_TYPE, JSON_CONTENT_TYPE);

View File

@@ -25,6 +25,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors; 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_REMAINING_CALLS = "RemainingCalls";
private static final String HEADER_TOTAL_CALLS = "TotalCalls"; 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 Logger logger = LoggerFactory.getLogger(ApiController.class);
private final Gson gson = new GsonBuilder() // private final Gson gson = new GsonBuilder() //
@@ -110,6 +112,7 @@ public class ApiController {
} }
Request request = httpClient.newRequest(ENDPOINT + DATASET_PATH + DATASET_NAME_SPOT_PRICES) Request request = httpClient.newRequest(ENDPOINT + DATASET_PATH + DATASET_NAME_SPOT_PRICES)
.timeout(REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS) //
.param("start", start.toString()) // .param("start", start.toString()) //
.param("filter", "{\"" + FILTER_KEY_PRICE_AREA + "\":\"" + priceArea + "\"}") // .param("filter", "{\"" + FILTER_KEY_PRICE_AREA + "\":\"" + priceArea + "\"}") //
.param("columns", "HourUTC,SpotPrice" + currency) // .param("columns", "HourUTC,SpotPrice" + currency) //
@@ -198,6 +201,7 @@ public class ApiController {
} }
Request request = httpClient.newRequest(ENDPOINT + DATASET_PATH + DATASET_NAME_DATAHUB_PRICELIST) Request request = httpClient.newRequest(ENDPOINT + DATASET_PATH + DATASET_NAME_DATAHUB_PRICELIST)
.timeout(REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS) //
.param("filter", mapToFilter(filterMap)) // .param("filter", mapToFilter(filterMap)) //
.param("columns", columns) // .param("columns", columns) //
.agent(userAgent) // .agent(userAgent) //

View File

@@ -18,6 +18,7 @@ import java.net.URI;
import java.util.Locale; import java.util.Locale;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriBuilder;
@@ -51,6 +52,7 @@ import org.slf4j.LoggerFactory;
public class FreeboxOsIconProvider extends AbstractResourceIconProvider { public class FreeboxOsIconProvider extends AbstractResourceIconProvider {
private final Logger logger = LoggerFactory.getLogger(FreeboxOsIconProvider.class); private final Logger logger = LoggerFactory.getLogger(FreeboxOsIconProvider.class);
private static final int REQUEST_TIMEOUT_MS = 8000;
private final HttpClient httpClient; private final HttpClient httpClient;
private final UriBuilder uriBuilder; private final UriBuilder uriBuilder;
@@ -77,7 +79,8 @@ public class FreeboxOsIconProvider extends AbstractResourceIconProvider {
@Override @Override
protected @Nullable InputStream getResource(String iconSetId, String resourceName) { protected @Nullable InputStream getResource(String iconSetId, String resourceName) {
URI uri = uriBuilder.clone().path(resourceName).build(); 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 { try {
ContentResponse response = request.send(); ContentResponse response = request.send();

View File

@@ -73,6 +73,7 @@ import com.google.gson.JsonSyntaxException;
@NonNullByDefault @NonNullByDefault
public class GardenaSmartImpl implements GardenaSmart, GardenaSmartWebSocketListener { public class GardenaSmartImpl implements GardenaSmart, GardenaSmartWebSocketListener {
private final Logger logger = LoggerFactory.getLogger(GardenaSmartImpl.class); 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(); 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) 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"); .header(HttpHeader.ACCEPT, "application/vnd.api+json").header(HttpHeader.ACCEPT_ENCODING, "gzip");
if (!URL_API_TOKEN.equals(url)) { if (!URL_API_TOKEN.equals(url)) {

View File

@@ -69,6 +69,7 @@ import com.google.gson.JsonSyntaxException;
@NonNullByDefault @NonNullByDefault
public class GeneracMobileLinkAccountHandler extends BaseBridgeHandler { public class GeneracMobileLinkAccountHandler extends BaseBridgeHandler {
private final Logger logger = LoggerFactory.getLogger(GeneracMobileLinkAccountHandler.class); 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 API_BASE = "https://app.mobilelinkgen.com/api";
private static final String LOGIN_BASE = "https://generacconnectivity.b2clogin.com/generacconnectivity.onmicrosoft.com/B2C_1A_MobileLink_SignIn"; 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); fields.put("password", config.password);
Request selfAssertedRequest = httpClient.POST(LOGIN_BASE + "/SelfAsserted") Request selfAssertedRequest = httpClient.POST(LOGIN_BASE + "/SelfAsserted")
.header("X-Csrf-Token", signInConfig.csrf).param("tx", "StateProperties=" + signInConfig.transId) .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS).header("X-Csrf-Token", signInConfig.csrf)
.param("p", "B2C_1A_SignUpOrSigninOnline").content(new FormContentProvider(fields)); .param("tx", "StateProperties=" + signInConfig.transId).param("p", "B2C_1A_SignUpOrSigninOnline")
.content(new FormContentProvider(fields));
ContentResponse selfAssertedResponse = selfAssertedRequest.send(); ContentResponse selfAssertedResponse = selfAssertedRequest.send();
@@ -309,8 +311,8 @@ public class GeneracMobileLinkAccountHandler extends BaseBridgeHandler {
} }
Request confirmedRequest = httpClient.newRequest(LOGIN_BASE + "/api/CombinedSigninAndSignup/confirmed") Request confirmedRequest = httpClient.newRequest(LOGIN_BASE + "/api/CombinedSigninAndSignup/confirmed")
.param("csrf_token", signInConfig.csrf).param("tx", "StateProperties=" + signInConfig.transId) .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS).param("csrf_token", signInConfig.csrf)
.param("p", "B2C_1A_SignUpOrSigninOnline"); .param("tx", "StateProperties=" + signInConfig.transId).param("p", "B2C_1A_SignUpOrSigninOnline");
ContentResponse confirmedResponse = confirmedRequest.send(); ContentResponse confirmedResponse = confirmedRequest.send();
@@ -362,7 +364,8 @@ public class GeneracMobileLinkAccountHandler extends BaseBridgeHandler {
fields.put("state", loginState.attr("value")); fields.put("state", loginState.attr("value"));
fields.put("code", loginCode.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(); ContentResponse loginResponse = loginRequest.send();
if (logger.isTraceEnabled()) { if (logger.isTraceEnabled()) {

View File

@@ -66,6 +66,7 @@ public class GatewayWebTargets implements Closeable, HostnameVerifier {
private static final String IDS = "ids"; private static final String IDS = "ids";
private static final int SLEEP_SECONDS = 360; private static final int SLEEP_SECONDS = 360;
private static final Set<Integer> HTTP_OK_CODES = Set.of(HttpStatus.OK_200, HttpStatus.NO_CONTENT_204); private static final Set<Integer> 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 Logger logger = LoggerFactory.getLogger(GatewayWebTargets.class);
private final Gson jsonParser = new Gson(); private final Gson jsonParser = new Gson();
@@ -248,7 +249,8 @@ public class GatewayWebTargets implements Closeable, HostnameVerifier {
logger.trace("invoke() request JSON:{}", jsonCommand); 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) { if (query != null) {
request.param(query.getKey(), query.getValue()); request.param(query.getKey(), query.getValue());
} }

View File

@@ -16,6 +16,7 @@ import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
@@ -75,6 +76,7 @@ import com.google.gson.JsonParser;
*/ */
@NonNullByDefault @NonNullByDefault
public class HDPowerViewWebTargets { public class HDPowerViewWebTargets {
private static final int REQUEST_TIMEOUT_MS = 30_000;
private final Logger logger = LoggerFactory.getLogger(HDPowerViewWebTargets.class); private final Logger logger = LoggerFactory.getLogger(HDPowerViewWebTargets.class);
@@ -581,7 +583,8 @@ public class HDPowerViewWebTargets {
logger.trace("JSON command = {}", jsonCommand); 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) { if (query != null) {
request.param(query.getKey(), query.getValue()); request.param(query.getKey(), query.getValue());
} }

View File

@@ -89,7 +89,8 @@ class PullJob implements Runnable {
@Override @Override
public void run() { 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; final Authentication.Result currentAuthentication = authentication;
if (currentAuthentication != null) { if (currentAuthentication != null) {
currentAuthentication.apply(request); currentAuthentication.apply(request);

View File

@@ -18,6 +18,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.eclipse.jdt.annotation.NonNullByDefault; 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_HOST = "https://jbv1-api.emotorwerks.com/";
private static final String API_ACCOUNT = API_HOST + "box_pin"; private static final String API_ACCOUNT = API_HOST + "box_pin";
private static final String API_DEVICE = API_HOST + "box_api_secure"; private static final String API_DEVICE = API_HOST + "box_api_secure";
private static final int REQUEST_TIMEOUT_MS = 10_000;
private String apiToken = ""; private String apiToken = "";
private HttpClient httpClient; private HttpClient httpClient;
@@ -180,6 +182,7 @@ public class JuiceNetApi {
public JsonObject postApiCommand(ApiCommand cmd, @Nullable String token, Map<String, Object> params) public JsonObject postApiCommand(ApiCommand cmd, @Nullable String token, Map<String, Object> params)
throws InterruptedException, JuiceNetApiException { throws InterruptedException, JuiceNetApiException {
Request request = httpClient.POST(cmd.uri); Request request = httpClient.POST(cmd.uri);
request.timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
request.header(HttpHeader.CONTENT_TYPE, "application/json"); request.header(HttpHeader.CONTENT_TYPE, "application/json");
// Add required params // Add required params

View File

@@ -17,6 +17,7 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.Base64; import java.util.Base64;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
@@ -42,6 +43,8 @@ import com.google.gson.JsonParser;
@NonNullByDefault @NonNullByDefault
public class SecondGenerationConfigurationHandler { public class SecondGenerationConfigurationHandler {
private static final int REQUEST_TIMEOUT_MS = 5000;
public static void executeConfigurationChanges(HttpClient httpClient, String url, String username, String password, public static void executeConfigurationChanges(HttpClient httpClient, String url, String username, String password,
String dxsId, String value) String dxsId, String value)
throws InterruptedException, ExecutionException, TimeoutException, NoSuchAlgorithmException { throws InterruptedException, ExecutionException, TimeoutException, NoSuchAlgorithmException {
@@ -75,7 +78,8 @@ public class SecondGenerationConfigurationHandler {
String loginPostJsonData = "{\"mode\":1,\"userId\":\"" + username + "\",\"pwh\":\"" + saltedmDigestedPwd 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.header(HttpHeader.CONTENT_TYPE, "application/json");
loginPostJsonResponse.content(new StringContentProvider(loginPostJsonData)); loginPostJsonResponse.content(new StringContentProvider(loginPostJsonData));
ContentResponse loginPostJsonDataContentResponse = loginPostJsonResponse.send(); ContentResponse loginPostJsonDataContentResponse = loginPostJsonResponse.send();
@@ -91,7 +95,8 @@ public class SecondGenerationConfigurationHandler {
// Part for sending data to Inverter // Part for sending data to Inverter
String postJsonData = "{\"dxsEntries\":[{\"dxsId\":" + dxsId + ",\"value\":" + value + "}]}"; 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.header(HttpHeader.CONTENT_TYPE, "application/json");
postJsonDataRequest.content(new StringContentProvider(postJsonData)); postJsonDataRequest.content(new StringContentProvider(postJsonData));
postJsonDataRequest.send(); postJsonDataRequest.send();

View File

@@ -25,6 +25,7 @@ import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
@@ -58,6 +59,7 @@ import com.google.gson.JsonSyntaxException;
public class LiquidCheckDiscoveryService extends AbstractDiscoveryService { public class LiquidCheckDiscoveryService extends AbstractDiscoveryService {
private static final int DISCOVER_TIMEOUT_SECONDS = 300; 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 Logger logger = LoggerFactory.getLogger(this.getClass());
private final HttpClient httpClient; private final HttpClient httpClient;
@@ -97,7 +99,8 @@ public class LiquidCheckDiscoveryService extends AbstractDiscoveryService {
List<InetAddress> hosts = findActiveHosts(addresses); List<InetAddress> hosts = findActiveHosts(addresses);
for (InetAddress host : hosts) { for (InetAddress host : hosts) {
Request request = httpClient.newRequest("http://" + host.getHostAddress() + "/infos.json") 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 { try {
ContentResponse response = request.send(); ContentResponse response = request.send();
if (response.getStatus() == 200) { if (response.getStatus() == 200) {

View File

@@ -34,7 +34,6 @@ import org.slf4j.LoggerFactory;
*/ */
@NonNullByDefault @NonNullByDefault
public class LiquidCheckHttpClient { public class LiquidCheckHttpClient {
private final Logger logger = LoggerFactory.getLogger(LiquidCheckHttpClient.class); private final Logger logger = LoggerFactory.getLogger(LiquidCheckHttpClient.class);
private final HttpClient client; private final HttpClient client;
private final LiquidCheckConfiguration config; private final LiquidCheckConfiguration config;
@@ -78,7 +77,7 @@ public class LiquidCheckHttpClient {
*/ */
public String measureCommand() throws InterruptedException, TimeoutException, ExecutionException { public String measureCommand() throws InterruptedException, TimeoutException, ExecutionException {
String uri = "http://" + config.hostname + "/command"; 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.method(HttpMethod.POST);
request.header(HttpHeader.CONTENT_TYPE, "applicaton/json"); request.header(HttpHeader.CONTENT_TYPE, "applicaton/json");
request.content(new StringContentProvider( request.content(new StringContentProvider(

View File

@@ -47,6 +47,7 @@ import com.google.gson.JsonObject;
@NonNullByDefault @NonNullByDefault
public class McdBridgeHandler extends BaseBridgeHandler { public class McdBridgeHandler extends BaseBridgeHandler {
private static final int REQUEST_TIMEOUT_MS = 10_000;
private final Logger logger = LoggerFactory.getLogger(McdBridgeHandler.class); private final Logger logger = LoggerFactory.getLogger(McdBridgeHandler.class);
private @Nullable McdBridgeConfiguration config; private @Nullable McdBridgeConfiguration config;
@@ -107,7 +108,9 @@ public class McdBridgeHandler extends BaseBridgeHandler {
Request request = httpClient.newRequest("https://cunds-syncapi.azurewebsites.net/token") Request request = httpClient.newRequest("https://cunds-syncapi.azurewebsites.net/token")
.method(HttpMethod.POST).header(HttpHeader.CONTENT_TYPE, "application/x-www-form-urlencoded") .method(HttpMethod.POST).header(HttpHeader.CONTENT_TYPE, "application/x-www-form-urlencoded")
.header(HttpHeader.HOST, "cunds-syncapi.azurewebsites.net") .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=" String content = "grant_type=password&username=" + localConfig.getUserEmail() + "&password="
+ localConfig.getUserPassword(); + localConfig.getUserPassword();
request.content(new StringContentProvider(content), "application/x-www-form-urlencoded"); request.content(new StringContentProvider(content), "application/x-www-form-urlencoded");

View File

@@ -17,6 +17,7 @@ import static org.openhab.binding.mcd.internal.McdBindingConstants.*;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.concurrent.TimeUnit;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
@@ -53,7 +54,9 @@ import com.google.gson.JsonObject;
@NonNullByDefault @NonNullByDefault
public class SensorThingHandler extends BaseThingHandler { public class SensorThingHandler extends BaseThingHandler {
private static final int REQUEST_TIMEOUT_MS = 10_000;
private final Logger logger = LoggerFactory.getLogger(SensorThingHandler.class); private final Logger logger = LoggerFactory.getLogger(SensorThingHandler.class);
private final HttpClient httpClient; private final HttpClient httpClient;
private final @Nullable Gson gson; private final @Nullable Gson gson;
private @Nullable McdBridgeHandler mcdBridgeHandler; private @Nullable McdBridgeHandler mcdBridgeHandler;
@@ -237,7 +240,9 @@ public class SensorThingHandler extends BaseThingHandler {
Request request = httpClient.newRequest(urlString).method(HttpMethod.GET) Request request = httpClient.newRequest(urlString).method(HttpMethod.GET)
.header(HttpHeader.HOST, "cunds-syncapi.azurewebsites.net") .header(HttpHeader.HOST, "cunds-syncapi.azurewebsites.net")
.header(HttpHeader.ACCEPT, "application/json") .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() { request.send(new BufferingResponseListener() {
@NonNullByDefault({}) @NonNullByDefault({})
@Override @Override
@@ -265,7 +270,8 @@ public class SensorThingHandler extends BaseThingHandler {
String accessToken = localMcdBridgeHandler.getAccessToken(); String accessToken = localMcdBridgeHandler.getAccessToken();
Request request = httpClient Request request = httpClient
.newRequest("https://cunds-syncapi.azurewebsites.net/api/Device?serialNumber=" + serialNumber) .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.ACCEPT, "application/json")
.header(HttpHeader.AUTHORIZATION, "Bearer " + accessToken); .header(HttpHeader.AUTHORIZATION, "Bearer " + accessToken);
request.send(new BufferingResponseListener() { request.send(new BufferingResponseListener() {
@@ -297,7 +303,8 @@ public class SensorThingHandler extends BaseThingHandler {
if (localMcdBridgeHandler != null) { if (localMcdBridgeHandler != null) {
String accessToken = localMcdBridgeHandler.getAccessToken(); String accessToken = localMcdBridgeHandler.getAccessToken();
Request request = httpClient.newRequest("https://cunds-syncapi.azurewebsites.net/api/ApiSensor/GetEventDef") 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.ACCEPT, "application/json")
.header(HttpHeader.AUTHORIZATION, "Bearer " + accessToken); .header(HttpHeader.AUTHORIZATION, "Bearer " + accessToken);
request.send(new BufferingResponseListener() { request.send(new BufferingResponseListener() {
@@ -401,7 +408,8 @@ public class SensorThingHandler extends BaseThingHandler {
Date date = new Date(); Date date = new Date();
String dateString = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").format(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") 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.ACCEPT, "application/json")
.header(HttpHeader.AUTHORIZATION, "Bearer " + accessToken); .header(HttpHeader.AUTHORIZATION, "Bearer " + accessToken);
JsonObject jsonObject = new JsonObject(); JsonObject jsonObject = new JsonObject();

View File

@@ -15,6 +15,7 @@ package org.openhab.binding.meater.internal.api;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
@@ -56,6 +57,7 @@ public class MeaterRestAPI {
private static final String LOGIN = "login"; private static final String LOGIN = "login";
private static final String DEVICES = "devices"; private static final String DEVICES = "devices";
private static final int MAX_RETRIES = 3; 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 Logger logger = LoggerFactory.getLogger(MeaterRestAPI.class);
private final Gson gson; private final Gson gson;
@@ -99,7 +101,8 @@ public class MeaterRestAPI {
// Login // Login
String json = "{ \"email\": \"" + configuration.email + "\", \"password\": \"" + configuration.password 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.ACCEPT, JSON_CONTENT_TYPE);
request.header(HttpHeader.CONTENT_TYPE, JSON_CONTENT_TYPE); request.header(HttpHeader.CONTENT_TYPE, JSON_CONTENT_TYPE);
request.content(new StringContentProvider(json), JSON_CONTENT_TYPE); request.content(new StringContentProvider(json), JSON_CONTENT_TYPE);
@@ -132,7 +135,8 @@ public class MeaterRestAPI {
try { try {
for (int i = 0; i < MAX_RETRIES; i++) { for (int i = 0; i < MAX_RETRIES; i++) {
try { 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.AUTHORIZATION, "Bearer " + authToken);
request.header(HttpHeader.ACCEPT, JSON_CONTENT_TYPE); request.header(HttpHeader.ACCEPT, JSON_CONTENT_TYPE);
request.header(HttpHeader.CONTENT_TYPE, JSON_CONTENT_TYPE); request.header(HttpHeader.CONTENT_TYPE, JSON_CONTENT_TYPE);

View File

@@ -83,6 +83,7 @@ import org.slf4j.LoggerFactory;
*/ */
@NonNullByDefault @NonNullByDefault
public class VehicleHandler extends BaseThingHandler { 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 EXT_IMG_RES = "ExtImageResources_";
private static final String INITIALIZE_COMMAND = "Initialze"; 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 params = UrlEncoded.encode(parameterMap, StandardCharsets.UTF_8, false);
String url = String.format(IMAGE_EXTERIOR_RESOURCE_URL, config.get().vin) + "?" + params; String url = String.format(IMAGE_EXTERIOR_RESOURCE_URL, config.get().vin) + "?" + params;
logger.debug("Get Image resources {} {} ", accountHandler.get().getImageApiKey(), url); 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("x-api-key", accountHandler.get().getImageApiKey());
req.header(HttpHeader.ACCEPT, "application/json"); req.header(HttpHeader.ACCEPT, "application/json");
try { try {
@@ -378,7 +379,7 @@ public class VehicleHandler extends BaseThingHandler {
} }
String url = IMAGE_BASE_URL + "/images/" + imageId; 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("x-api-key", accountHandler.get().getImageApiKey());
req.header(HttpHeader.ACCEPT, "*/*"); req.header(HttpHeader.ACCEPT, "*/*");
ContentResponse cr; ContentResponse cr;
@@ -400,7 +401,7 @@ public class VehicleHandler extends BaseThingHandler {
// debug prefix contains Thing label and call endpoint for propper debugging // debug prefix contains Thing label and call endpoint for propper debugging
String debugPrefix = this.getThing().getLabel() + Constants.COLON + finalEndpoint; 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()); req.header(HttpHeader.AUTHORIZATION, "Bearer " + accountHandler.get().getToken());
try { try {
ContentResponse cr = req.send(); ContentResponse cr = req.send();

View File

@@ -17,6 +17,7 @@ import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.Random; import java.util.Random;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
@@ -44,6 +45,7 @@ import com.google.gson.JsonParser;
*/ */
@NonNullByDefault @NonNullByDefault
public class MieleGatewayCommunicationController { public class MieleGatewayCommunicationController {
private static final int REQUEST_TIMEOUT_MS = 10_000;
private final URI uri; private final URI uri;
private final Random rand = new Random(); private final Random rand = new Random();
@@ -83,6 +85,7 @@ public class MieleGatewayCommunicationController {
String requestBody = requestBodyAsJson.toString(); String requestBody = requestBodyAsJson.toString();
Request request = httpClient.newRequest(uri).method(HttpMethod.POST) Request request = httpClient.newRequest(uri).method(HttpMethod.POST)
.timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS)
.content(new StringContentProvider(requestBody), "application/json"); .content(new StringContentProvider(requestBody), "application/json");
String responseData = null; String responseData = null;

View File

@@ -305,7 +305,8 @@ public class MyBMWProxy {
*/ */
String authValuesUrl = "https://" + BimmerConstants.EADRAX_SERVER_MAP.get(configuration.region) String authValuesUrl = "https://" + BimmerConstants.EADRAX_SERVER_MAP.get(configuration.region)
+ BimmerConstants.API_OAUTH_CONFIG; + 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(ACP_SUBSCRIPTION_KEY, BimmerConstants.OCP_APIM_KEYS.get(configuration.region));
authValuesRequest.header(X_USER_AGENT, authValuesRequest.header(X_USER_AGENT,
String.format(BimmerConstants.X_USER_AGENT, BimmerConstants.BRAND_BMW, configuration.region)); 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 * Step 3) Authorization with username and password
*/ */
String loginUrl = aqr.gcdmBaseUrl + BimmerConstants.OAUTH_ENDPOINT; 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); loginRequest.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_URL_ENCODED);
MultiMap<String> loginParams = new MultiMap<String>(baseParams); MultiMap<String> loginParams = new MultiMap<String>(baseParams);
@@ -364,7 +365,8 @@ public class MyBMWProxy {
/** /**
* Step 4) Authorize with code * 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<String> authParams = new MultiMap<String>(baseParams); MultiMap<String> authParams = new MultiMap<String>(baseParams);
authParams.put(AUTHORIZATION, authCode); authParams.put(AUTHORIZATION, authCode);
authRequest.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_URL_ENCODED); authRequest.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_URL_ENCODED);
@@ -380,7 +382,7 @@ public class MyBMWProxy {
/** /**
* Step 5) Request token * 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 " String basicAuth = "Basic "
+ Base64.getUrlEncoder().encodeToString((aqr.clientId + ":" + aqr.clientSecret).getBytes()); + Base64.getUrlEncoder().encodeToString((aqr.clientId + ":" + aqr.clientSecret).getBytes());
codeRequest.header(HttpHeader.CONTENT_TYPE, CONTENT_TYPE_URL_ENCODED); 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) String publicKeyUrl = "https://" + BimmerConstants.EADRAX_SERVER_MAP.get(BimmerConstants.REGION_CHINA)
+ BimmerConstants.CHINA_PUBLIC_KEY; + 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(HttpHeader.USER_AGENT, BimmerConstants.USER_AGENT);
oauthQueryRequest.header(X_USER_AGENT, oauthQueryRequest.header(X_USER_AGENT,
String.format(BimmerConstants.X_USER_AGENT, BimmerConstants.BRAND_BMW, configuration.region)); 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) String tokenUrl = "https://" + BimmerConstants.EADRAX_SERVER_MAP.get(BimmerConstants.REGION_CHINA)
+ BimmerConstants.CHINA_LOGIN; + BimmerConstants.CHINA_LOGIN;
Request loginRequest = httpClient.POST(tokenUrl); Request loginRequest = httpClient.POST(tokenUrl).timeout(HTTP_TIMEOUT_SEC, TimeUnit.SECONDS);
loginRequest.header(X_USER_AGENT, loginRequest.header(X_USER_AGENT,
String.format(BimmerConstants.X_USER_AGENT, BimmerConstants.BRAND_BMW, configuration.region)); String.format(BimmerConstants.X_USER_AGENT, BimmerConstants.BRAND_BMW, configuration.region));
String jsonContent = "{ \"mobile\":\"" + configuration.userName + "\", \"password\":\"" + encodedPassword String jsonContent = "{ \"mobile\":\"" + configuration.userName + "\", \"password\":\"" + encodedPassword

View File

@@ -92,6 +92,8 @@ import com.google.gson.JsonSyntaxException;
*/ */
@NonNullByDefault @NonNullByDefault
public class MyQAccountHandler extends BaseBridgeHandler implements AccessTokenRefreshListener { public class MyQAccountHandler extends BaseBridgeHandler implements AccessTokenRefreshListener {
private static final int REQUEST_TIMEOUT_MS = 10_000;
/* /*
* MyQ oAuth relate fields * MyQ oAuth relate fields
*/ */
@@ -416,7 +418,8 @@ public class MyQAccountHandler extends BaseBridgeHandler implements AccessTokenR
needsLogin = false; 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)); .header("Authorization", authTokenHeader(tokenResponse));
if (content != null & contentType != null) { if (content != null & contentType != null) {
request = request.content(content, contentType); request = request.content(content, contentType);
@@ -484,6 +487,7 @@ public class MyQAccountHandler extends BaseBridgeHandler implements AccessTokenR
throws InterruptedException, ExecutionException, TimeoutException { throws InterruptedException, ExecutionException, TimeoutException {
try { try {
Request request = httpClient.newRequest(LOGIN_AUTHORIZE_URL) // Request request = httpClient.newRequest(LOGIN_AUTHORIZE_URL) //
.timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS) //
.param("client_id", CLIENT_ID) // .param("client_id", CLIENT_ID) //
.param("code_challenge", generateCodeChallange(codeVerifier)) // .param("code_challenge", generateCodeChallange(codeVerifier)) //
.param("code_challenge_method", "S256") // .param("code_challenge_method", "S256") //
@@ -531,6 +535,7 @@ public class MyQAccountHandler extends BaseBridgeHandler implements AccessTokenR
fields.add("ReturnUrl", returnURL); fields.add("ReturnUrl", returnURL);
Request request = httpClient.newRequest(url).method(HttpMethod.POST) // Request request = httpClient.newRequest(url).method(HttpMethod.POST) //
.timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS) //
.content(new FormContentProvider(fields)) // .content(new FormContentProvider(fields)) //
.agent(userAgent) // .agent(userAgent) //
.followRedirects(false); .followRedirects(false);
@@ -557,7 +562,8 @@ public class MyQAccountHandler extends BaseBridgeHandler implements AccessTokenR
location = loc; location = loc;
break; 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); setCookies(request);
response = request.send(); response = request.send();
} }
@@ -589,11 +595,11 @@ public class MyQAccountHandler extends BaseBridgeHandler implements AccessTokenR
fields.add("scope", params.get("scope")); fields.add("scope", params.get("scope"));
Request request = httpClient.newRequest(LOGIN_TOKEN_URL) // Request request = httpClient.newRequest(LOGIN_TOKEN_URL) //
.timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS) //
.content(new FormContentProvider(fields)) // .content(new FormContentProvider(fields)) //
.method(HttpMethod.POST) // .method(HttpMethod.POST) //
.agent(userAgent).followRedirects(true); .agent(userAgent).followRedirects(true);
setCookies(request); setCookies(request);
ContentResponse response = request.send(); ContentResponse response = request.send();
if (logger.isTraceEnabled()) { if (logger.isTraceEnabled()) {
logger.trace("Login Code {} Response {}", response.getStatus(), response.getContentAsString()); logger.trace("Login Code {} Response {}", response.getStatus(), response.getContentAsString());

View File

@@ -14,6 +14,7 @@ package org.openhab.binding.ojelectronics.internal.services;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
@@ -43,7 +44,7 @@ import com.google.gson.Gson;
*/ */
@NonNullByDefault @NonNullByDefault
public final class UpdateService { public final class UpdateService {
private static final int REQUEST_TIMEOUT_MS = 10_000;
private final Gson gson = OJGSonBuilder.getGSon(); private final Gson gson = OJGSonBuilder.getGSon();
private final Logger logger = LoggerFactory.getLogger(UpdateService.class); 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)); String jsonPayload = gson.toJson(new UpdateThermostatRequestModel(thermostat).withApiKey(configuration.apiKey));
Request request = httpClient.POST(configuration.getRestApiUrl() + "/Thermostat/UpdateThermostat") Request request = httpClient.POST(configuration.getRestApiUrl() + "/Thermostat/UpdateThermostat")
.param("sessionid", sessionId).header(HttpHeader.CONTENT_TYPE, "application/json") .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS).param("sessionid", sessionId)
.content(new StringContentProvider(jsonPayload)); .header(HttpHeader.CONTENT_TYPE, "application/json").content(new StringContentProvider(jsonPayload));
logger.trace("updateThermostat payload for themostat with serial {} is {}", thermostat.serialNumber, logger.trace("updateThermostat payload for themostat with serial {} is {}", thermostat.serialNumber,
jsonPayload); jsonPayload);

View File

@@ -228,7 +228,8 @@ public class PlexApiConnector {
response = HttpUtil.executeUrl(method, url, headers, null, null, REQUEST_TIMEOUT_MS); response = HttpUtil.executeUrl(method, url, headers, null, null, REQUEST_TIMEOUT_MS);
} else { } else {
// Requests sent to the local server need to bypass certificate checking via the custom httpClient // 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()) { for (String httpHeaderKey : headers.stringPropertyNames()) {
if (httpHeaderKey.equalsIgnoreCase(HttpHeader.USER_AGENT.toString())) { if (httpHeaderKey.equalsIgnoreCase(HttpHeader.USER_AGENT.toString())) {
request.agent(headers.getProperty(httpHeaderKey)); request.agent(headers.getProperty(httpHeaderKey));

View File

@@ -44,6 +44,7 @@ import org.slf4j.LoggerFactory;
public class RadioThermostatConnector { public class RadioThermostatConnector {
private final Logger logger = LoggerFactory.getLogger(RadioThermostatConnector.class); 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 static final String URL = "http://%s/%s";
private final HttpClient httpClient; private final HttpClient httpClient;
@@ -124,7 +125,8 @@ public class RadioThermostatConnector {
String postJson = cmdJson != null ? cmdJson : "{\"" + cmdKey + "\":" + cmdVal + "}"; String postJson = cmdJson != null ? cmdJson : "{\"" + cmdKey + "\":" + cmdVal + "}";
try { 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.ACCEPT, "text/plain");
request.header(HttpHeader.CONTENT_TYPE, "text/plain"); request.header(HttpHeader.CONTENT_TYPE, "text/plain");
request.content(new StringContentProvider(postJson), "application/json"); request.content(new StringContentProvider(postJson), "application/json");

View File

@@ -13,6 +13,7 @@
package org.openhab.binding.renault.internal.api; package org.openhab.binding.renault.internal.api;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.eclipse.jdt.annotation.NonNullByDefault; 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_SCHEDULE = "schedule_mode";
private static final String CHARGING_MODE_ALWAYS = "always_charging"; private static final String CHARGING_MODE_ALWAYS = "always_charging";
private static final int REQUEST_TIMEOUT_MS = 10_000;
private RenaultConfiguration config; private RenaultConfiguration config;
private HttpClient httpClient; private HttpClient httpClient;
@@ -287,7 +289,8 @@ public class MyRenaultHttpSession {
private void postKamereonRequest(final String path, final String content) throws RenaultForbiddenException, private void postKamereonRequest(final String path, final String content) throws RenaultForbiddenException,
RenaultNotImplementedException, RenaultActionException, RenaultAPIGatewayException { RenaultNotImplementedException, RenaultActionException, RenaultAPIGatewayException {
Request request = httpClient.newRequest(this.constants.getKamereonRootUrl() + path).method(HttpMethod.POST) 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) .header("x-kamereon-authorization", "Bearer " + kamereonToken).header("x-gigya-id_token", jwt)
.content(new StringContentProvider(content, "utf-8")); .content(new StringContentProvider(content, "utf-8"));
try { try {
@@ -305,7 +308,8 @@ public class MyRenaultHttpSession {
private @Nullable JsonObject getKamereonResponse(String path) throws RenaultForbiddenException, private @Nullable JsonObject getKamereonResponse(String path) throws RenaultForbiddenException,
RenaultNotImplementedException, RenaultUpdateException, RenaultAPIGatewayException { RenaultNotImplementedException, RenaultUpdateException, RenaultAPIGatewayException {
Request request = httpClient.newRequest(this.constants.getKamereonRootUrl() + path).method(HttpMethod.GET) 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); .header("x-kamereon-authorization", "Bearer " + kamereonToken).header("x-gigya-id_token", jwt);
try { try {
ContentResponse response = request.send(); ContentResponse response = request.send();

View File

@@ -16,6 +16,7 @@ import java.nio.charset.StandardCharsets;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import javax.ws.rs.core.MediaType; 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"; private static final String LIST_URL = BASE_URL + "api/PowerStationMonitor/QueryPowerStationMonitorForApp";
// the token holds the credential information for the portal // the token holds the credential information for the portal
private static final String HTTP_HEADER_TOKEN = "Token"; 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 // used to parse json from / to the SEMS portal API
private final Gson gson; private final Gson gson;
@@ -147,7 +149,8 @@ public class PortalHandler extends BaseBridgeHandler {
private @Nullable String sendPost(String url, String payload) { private @Nullable String sendPost(String url, String payload) {
try { 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)) .header(HTTP_HEADER_TOKEN, gson.toJson(sessionToken))
.content(new StringContentProvider(payload, StandardCharsets.UTF_8.name()), .content(new StringContentProvider(payload, StandardCharsets.UTF_8.name()),
MediaType.APPLICATION_JSON); MediaType.APPLICATION_JSON);

View File

@@ -82,6 +82,7 @@ import com.google.gson.stream.JsonWriter;
public class SensiboAccountHandler extends BaseBridgeHandler { public class SensiboAccountHandler extends BaseBridgeHandler {
private static final int MIN_TIME_BETWEEEN_MODEL_UPDATES_MS = 30_000; private static final int MIN_TIME_BETWEEEN_MODEL_UPDATES_MS = 30_000;
private static final int SECONDS_IN_MINUTE = 60; 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"; public static String API_ENDPOINT = "https://home.sensibo.com/api";
private final Logger logger = LoggerFactory.getLogger(SensiboAccountHandler.class); private final Logger logger = LoggerFactory.getLogger(SensiboAccountHandler.class);
private final HttpClient httpClient; private final HttpClient httpClient;
@@ -275,6 +276,7 @@ public class SensiboAccountHandler extends BaseBridgeHandler {
private Request buildRequest(final AbstractRequest req) { private Request buildRequest(final AbstractRequest req) {
Request request = httpClient.newRequest(API_ENDPOINT + req.getRequestUrl()).param("apiKey", config.apiKey) Request request = httpClient.newRequest(API_ENDPOINT + req.getRequestUrl()).param("apiKey", config.apiKey)
.method(req.getMethod()); .method(req.getMethod());
request.timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
if (!req.getMethod().contentEquals(HttpMethod.GET.asString())) { // POST, PATCH if (!req.getMethod().contentEquals(HttpMethod.GET.asString())) { // POST, PATCH
final String reqJson = gson.toJson(req); final String reqJson = gson.toJson(req);

View File

@@ -16,6 +16,7 @@ import static org.openhab.binding.tapocontrol.internal.constants.TapoBindingSett
import static org.openhab.binding.tapocontrol.internal.constants.TapoErrorCode.*; import static org.openhab.binding.tapocontrol.internal.constants.TapoErrorCode.*;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
@@ -213,6 +214,7 @@ public class TapoCloudConnector {
@Nullable @Nullable
protected ContentResponse sendCloudRequest(String url, String payload) { protected ContentResponse sendCloudRequest(String url, String payload) {
Request httpRequest = httpClient.newRequest(url).method(HttpMethod.POST.toString()); Request httpRequest = httpClient.newRequest(url).method(HttpMethod.POST.toString());
httpRequest.timeout(TAPO_HTTP_CLOUD_TIMEOUT_MS, TimeUnit.MILLISECONDS);
/* set header */ /* set header */
httpRequest.header("content-type", CONTENT_TYPE_JSON); httpRequest.header("content-type", CONTENT_TYPE_JSON);

View File

@@ -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_CONNECTIONS = 10; // setMaxConnectionsPerDestination for HTTP-Client
public static final Integer HTTP_MAX_QUEUED_REQUESTS = 10; // setMaxRequestsQueuedPerDestination 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_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_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_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 public static final Integer TAPO_SEND_MIN_GAP_MS = 1000; // min gap between sending command request

View File

@@ -15,6 +15,7 @@ package org.openhab.binding.tellstick.internal.local;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.eclipse.jetty.client.HttpClient; 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_API_DEVICE_TURNOFF = HTTP_LOCAL_API + "device/turnOff?id=%d";
static final String HTTP_LOCAL_DEVICE_TURNON = HTTP_LOCAL_API + "device/turnOn?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 MAX_RETRIES = 3;
private static final int REQUEST_TIMEOUT_MS = 10_000;
public TelldusLocalDeviceController(TelldusLocalConfiguration configuration, HttpClient httpClient) { public TelldusLocalDeviceController(TelldusLocalConfiguration configuration, HttpClient httpClient) {
this.httpClient = httpClient; this.httpClient = httpClient;
@@ -270,7 +272,8 @@ public class TelldusLocalDeviceController implements DeviceChangeListener, Senso
throws ExecutionException, InterruptedException, TimeoutException, JsonSyntaxException { throws ExecutionException, InterruptedException, TimeoutException, JsonSyntaxException {
logger.trace("HTTP GET: {}", uri); 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); request.header("Authorization", authorizationHeader);
ContentResponse response = request.send(); ContentResponse response = request.send();

View File

@@ -30,6 +30,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
@@ -88,6 +89,7 @@ public class VerisureSession {
"https://m-api02.verisure.com"); "https://m-api02.verisure.com");
private int apiServerInUseIndex = 0; private int apiServerInUseIndex = 0;
private int numberOfEvents = 15; private int numberOfEvents = 15;
private static final int REQUEST_TIMEOUT_MS = 10_000;
private static final String USER_NAME = "username"; private static final String USER_NAME = "username";
private static final String VID = "vid"; private static final String VID = "vid";
private static final String VS_STEPUP = "vs-stepup"; private static final String VS_STEPUP = "vs-stepup";
@@ -333,6 +335,7 @@ public class VerisureSession {
logger.debug("postVerisureAPI URL: {} Data:{}", url, data); logger.debug("postVerisureAPI URL: {} Data:{}", url, data);
Request request = httpClient.newRequest(url).method(HttpMethod.POST); Request request = httpClient.newRequest(url).method(HttpMethod.POST);
request.timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
if (isJSON) { if (isJSON) {
request.header("content-type", "application/json"); request.header("content-type", "application/json");
} else { } else {

View File

@@ -13,6 +13,7 @@
package org.openhab.binding.vizio.internal.communication; package org.openhab.binding.vizio.internal.communication;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
@@ -51,6 +52,7 @@ public class VizioCommunicator {
private static final String AUTH_HEADER = "AUTH"; private static final String AUTH_HEADER = "AUTH";
private static final String JSON_CONTENT_TYPE = "application/json"; private static final String JSON_CONTENT_TYPE = "application/json";
private static final String JSON_VALUE = "{\"VALUE\": %s}"; private static final String JSON_VALUE = "{\"VALUE\": %s}";
private static final int REQUEST_TIMEOUT_MS = 10_000;
private final HttpClient httpClient; private final HttpClient httpClient;
private final Gson gson = new GsonBuilder().serializeNulls().create(); private final Gson gson = new GsonBuilder().serializeNulls().create();
@@ -230,6 +232,7 @@ public class VizioCommunicator {
private String getCommand(String url) throws VizioException { private String getCommand(String url) throws VizioException {
try { try {
final Request request = httpClient.newRequest(url).method(HttpMethod.GET); final Request request = httpClient.newRequest(url).method(HttpMethod.GET);
request.timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
request.header(AUTH_HEADER, authToken); request.header(AUTH_HEADER, authToken);
request.header(HttpHeader.CONTENT_TYPE, JSON_CONTENT_TYPE); request.header(HttpHeader.CONTENT_TYPE, JSON_CONTENT_TYPE);
@@ -254,6 +257,7 @@ public class VizioCommunicator {
private String putCommand(String url, String commandJSON) throws VizioException { private String putCommand(String url, String commandJSON) throws VizioException {
try { try {
final Request request = httpClient.newRequest(url).method(HttpMethod.PUT); final Request request = httpClient.newRequest(url).method(HttpMethod.PUT);
request.timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
if (!url.contains("pairing")) { if (!url.contains("pairing")) {
request.header(AUTH_HEADER, authToken); request.header(AUTH_HEADER, authToken);
} }