diff --git a/core/src/main/java/bisq/core/btc/BitcoinModule.java b/core/src/main/java/bisq/core/btc/BitcoinModule.java index 053f61c32d7..3f733fb570a 100644 --- a/core/src/main/java/bisq/core/btc/BitcoinModule.java +++ b/core/src/main/java/bisq/core/btc/BitcoinModule.java @@ -26,7 +26,6 @@ import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.NonBsqCoinSelector; import bisq.core.btc.wallet.TradeWalletService; -import bisq.core.provider.PriceNodeHttpClient; import bisq.core.provider.ProvidersRepository; import bisq.core.provider.fee.FeeProvider; import bisq.core.provider.fee.FeeService; @@ -95,8 +94,6 @@ protected void configure() { bind(BtcNodes.class).in(Singleton.class); bind(Balances.class).in(Singleton.class); - bind(PriceNodeHttpClient.class).in(Singleton.class); - bind(ProvidersRepository.class).in(Singleton.class); bind(FeeProvider.class).in(Singleton.class); bind(PriceFeedService.class).in(Singleton.class); diff --git a/core/src/main/java/bisq/core/notifications/MobileNotificationService.java b/core/src/main/java/bisq/core/notifications/MobileNotificationService.java index 1d924316c0e..76ba9313df7 100644 --- a/core/src/main/java/bisq/core/notifications/MobileNotificationService.java +++ b/core/src/main/java/bisq/core/notifications/MobileNotificationService.java @@ -256,6 +256,11 @@ private void doSendMessage(String iv, boolean useSound, Consumer resultHandler, Consumer errorHandler) throws Exception { + if (httpClient.hasPendingRequest()) { + log.warn("We have a pending request open. We ignore that request. httpClient {}", httpClient); + return; + } + String msg; if (mobileModel.getOs() == null) throw new RuntimeException("No mobileModel OS set"); @@ -297,7 +302,7 @@ private void doSendMessage(String iv, String threadName = "sendMobileNotification-" + msgAsHex.substring(0, 5) + "..."; ListenableFuture future = executorService.submit(() -> { Thread.currentThread().setName(threadName); - String result = httpClient.requestWithGET(param, "User-Agent", + String result = httpClient.get(param, "User-Agent", "bisq/" + Version.VERSION + ", uid:" + httpClient.getUid()); log.info("sendMobileNotification result: " + result); checkArgument(result.equals(SUCCESS), "Result was not 'success'. result=" + result); diff --git a/core/src/main/java/bisq/core/provider/PriceNodeHttpClient.java b/core/src/main/java/bisq/core/provider/FeeHttpClient.java similarity index 84% rename from core/src/main/java/bisq/core/provider/PriceNodeHttpClient.java rename to core/src/main/java/bisq/core/provider/FeeHttpClient.java index fbe396f1d8a..2579c6ffb2a 100644 --- a/core/src/main/java/bisq/core/provider/PriceNodeHttpClient.java +++ b/core/src/main/java/bisq/core/provider/FeeHttpClient.java @@ -21,12 +21,14 @@ import bisq.network.http.HttpClientImpl; import javax.inject.Inject; +import javax.inject.Singleton; import javax.annotation.Nullable; -public class PriceNodeHttpClient extends HttpClientImpl { +@Singleton +public class FeeHttpClient extends HttpClientImpl { @Inject - public PriceNodeHttpClient(@Nullable Socks5ProxyProvider socks5ProxyProvider) { + public FeeHttpClient(@Nullable Socks5ProxyProvider socks5ProxyProvider) { super(socks5ProxyProvider); } } diff --git a/core/src/main/java/bisq/core/provider/PriceHttpClient.java b/core/src/main/java/bisq/core/provider/PriceHttpClient.java new file mode 100644 index 00000000000..1f0b47d8e8f --- /dev/null +++ b/core/src/main/java/bisq/core/provider/PriceHttpClient.java @@ -0,0 +1,34 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.core.provider; + +import bisq.network.Socks5ProxyProvider; +import bisq.network.http.HttpClientImpl; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import javax.annotation.Nullable; + +@Singleton +public class PriceHttpClient extends HttpClientImpl { + @Inject + public PriceHttpClient(@Nullable Socks5ProxyProvider socks5ProxyProvider) { + super(socks5ProxyProvider); + } +} diff --git a/core/src/main/java/bisq/core/provider/fee/FeeProvider.java b/core/src/main/java/bisq/core/provider/fee/FeeProvider.java index 3fe55c7f74e..3a1e4f4f807 100644 --- a/core/src/main/java/bisq/core/provider/fee/FeeProvider.java +++ b/core/src/main/java/bisq/core/provider/fee/FeeProvider.java @@ -17,10 +17,12 @@ package bisq.core.provider.fee; +import bisq.core.provider.FeeHttpClient; import bisq.core.provider.HttpClientProvider; -import bisq.core.provider.PriceNodeHttpClient; import bisq.core.provider.ProvidersRepository; +import bisq.network.http.HttpClient; + import bisq.common.app.Version; import bisq.common.util.Tuple2; @@ -40,12 +42,12 @@ public class FeeProvider extends HttpClientProvider { @Inject - public FeeProvider(PriceNodeHttpClient httpClient, ProvidersRepository providersRepository) { + public FeeProvider(FeeHttpClient httpClient, ProvidersRepository providersRepository) { super(httpClient, providersRepository.getBaseUrl(), false); } public Tuple2, Map> getFees() throws IOException { - String json = httpClient.requestWithGET("getFees", "User-Agent", "bisq/" + Version.VERSION); + String json = httpClient.get("getFees", "User-Agent", "bisq/" + Version.VERSION); LinkedTreeMap linkedTreeMap = new Gson().fromJson(json, LinkedTreeMap.class); Map tsMap = new HashMap<>(); @@ -64,4 +66,8 @@ public Tuple2, Map> getFees() throws IOException } return new Tuple2<>(tsMap, map); } + + public HttpClient getHttpClient() { + return httpClient; + } } diff --git a/core/src/main/java/bisq/core/provider/fee/FeeRequest.java b/core/src/main/java/bisq/core/provider/fee/FeeRequest.java index 5dcb7e2ae25..007a5d39594 100644 --- a/core/src/main/java/bisq/core/provider/fee/FeeRequest.java +++ b/core/src/main/java/bisq/core/provider/fee/FeeRequest.java @@ -45,7 +45,7 @@ public FeeRequest() { public SettableFuture, Map>> getFees(FeeProvider provider) { final SettableFuture, Map>> resultFuture = SettableFuture.create(); ListenableFuture, Map>> future = executorService.submit(() -> { - Thread.currentThread().setName("FeeRequest-" + provider.toString()); + Thread.currentThread().setName("FeeRequest @ " + provider.getHttpClient().getBaseUrl()); return provider.getFees(); }); diff --git a/core/src/main/java/bisq/core/provider/fee/FeeService.java b/core/src/main/java/bisq/core/provider/fee/FeeService.java index 66723b904c3..46ba82e4f62 100644 --- a/core/src/main/java/bisq/core/provider/fee/FeeService.java +++ b/core/src/main/java/bisq/core/provider/fee/FeeService.java @@ -137,6 +137,11 @@ public void requestFees(Runnable resultHandler) { } public void requestFees(@Nullable Runnable resultHandler, @Nullable FaultHandler faultHandler) { + if (feeProvider.getHttpClient().hasPendingRequest()) { + log.warn("We have a pending request open. We ignore that request. httpClient {}", feeProvider.getHttpClient()); + return; + } + long now = Instant.now().getEpochSecond(); // We all requests only each 2 minutes if (now - lastRequest > MIN_PAUSE_BETWEEN_REQUESTS_IN_MIN * 60) { diff --git a/core/src/main/java/bisq/core/provider/price/PriceFeedService.java b/core/src/main/java/bisq/core/provider/price/PriceFeedService.java index 24a50430f92..57e9a5197dc 100644 --- a/core/src/main/java/bisq/core/provider/price/PriceFeedService.java +++ b/core/src/main/java/bisq/core/provider/price/PriceFeedService.java @@ -21,7 +21,7 @@ import bisq.core.locale.TradeCurrency; import bisq.core.monetary.Altcoin; import bisq.core.monetary.Price; -import bisq.core.provider.PriceNodeHttpClient; +import bisq.core.provider.PriceHttpClient; import bisq.core.provider.ProvidersRepository; import bisq.core.trade.statistics.TradeStatistics3; import bisq.core.user.Preferences; @@ -101,7 +101,7 @@ public class PriceFeedService { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - public PriceFeedService(@SuppressWarnings("SameParameterValue") PriceNodeHttpClient httpClient, + public PriceFeedService(PriceHttpClient httpClient, @SuppressWarnings("SameParameterValue") ProvidersRepository providersRepository, @SuppressWarnings("SameParameterValue") Preferences preferences) { this.httpClient = httpClient; @@ -194,9 +194,9 @@ private void request(boolean repeatRequests) { if (throwable instanceof PriceRequestException) { String baseUrlOfFaultyRequest = ((PriceRequestException) throwable).priceProviderBaseUrl; String baseUrlOfCurrentRequest = priceProvider.getBaseUrl(); - if (baseUrlOfFaultyRequest != null && baseUrlOfCurrentRequest.equals(baseUrlOfFaultyRequest)) { - log.warn("We received an error: baseUrlOfCurrentRequest={}, baseUrlOfFaultyRequest={}", - baseUrlOfCurrentRequest, baseUrlOfFaultyRequest); + if (baseUrlOfCurrentRequest.equals(baseUrlOfFaultyRequest)) { + log.warn("We received an error: baseUrlOfCurrentRequest={}, baseUrlOfFaultyRequest={}, error={}", + baseUrlOfCurrentRequest, baseUrlOfFaultyRequest, throwable.toString()); retryWithNewProvider(); } else { log.debug("We received an error from an earlier request. We have started a new request already so we ignore that error. " + @@ -204,7 +204,7 @@ private void request(boolean repeatRequests) { baseUrlOfCurrentRequest, baseUrlOfFaultyRequest); } } else { - log.warn("We received an error with throwable={}", throwable); + log.warn("We received an error with throwable={}", throwable.toString()); retryWithNewProvider(); } @@ -393,6 +393,11 @@ private boolean applyPriceToConsumer() { } private void requestAllPrices(PriceProvider provider, Runnable resultHandler, FaultHandler faultHandler) { + if (httpClient.hasPendingRequest()) { + log.warn("We have a pending request open. We ignore that request. httpClient {}", httpClient); + return; + } + priceRequest = new PriceRequest(); SettableFuture, Map>> future = priceRequest.requestAllPrices(provider); Futures.addCallback(future, new FutureCallback<>() { diff --git a/core/src/main/java/bisq/core/provider/price/PriceProvider.java b/core/src/main/java/bisq/core/provider/price/PriceProvider.java index 3d733fa145e..3a69bb0f61b 100644 --- a/core/src/main/java/bisq/core/provider/price/PriceProvider.java +++ b/core/src/main/java/bisq/core/provider/price/PriceProvider.java @@ -58,7 +58,7 @@ public Tuple2, Map> getAll() throws IOExc if (P2PService.getMyNodeAddress() != null) hsVersion = P2PService.getMyNodeAddress().getHostName().length() > 22 ? ", HSv3" : ", HSv2"; - String json = httpClient.requestWithGET("getAllMarketPrices", "User-Agent", "bisq/" + String json = httpClient.get("getAllMarketPrices", "User-Agent", "bisq/" + Version.VERSION + hsVersion); diff --git a/core/src/main/java/bisq/core/provider/price/PriceRequest.java b/core/src/main/java/bisq/core/provider/price/PriceRequest.java index 80f276e796c..8d5025d3c7c 100644 --- a/core/src/main/java/bisq/core/provider/price/PriceRequest.java +++ b/core/src/main/java/bisq/core/provider/price/PriceRequest.java @@ -50,7 +50,7 @@ public SettableFuture, Map>> reque String baseUrl = provider.getBaseUrl(); SettableFuture, Map>> resultFuture = SettableFuture.create(); ListenableFuture, Map>> future = executorService.submit(() -> { - Thread.currentThread().setName("PriceRequest-" + baseUrl); + Thread.currentThread().setName("PriceRequest @ " + baseUrl); return provider.getAll(); }); diff --git a/core/src/main/java/bisq/core/trade/txproof/xmr/XmrTxProofRequest.java b/core/src/main/java/bisq/core/trade/txproof/xmr/XmrTxProofRequest.java index 438d19121b3..5e4e21dd472 100644 --- a/core/src/main/java/bisq/core/trade/txproof/xmr/XmrTxProofRequest.java +++ b/core/src/main/java/bisq/core/trade/txproof/xmr/XmrTxProofRequest.java @@ -197,6 +197,11 @@ public void requestFromService(Consumer resultHandler, FaultHandler faul return; } + if (httpClient.hasPendingRequest()) { + log.warn("We have a pending request open. We ignore that request. httpClient {}", httpClient); + return; + } + // Timeout handing is delegated to the connection timeout handling in httpClient. ListenableFuture future = executorService.submit(() -> { @@ -206,7 +211,7 @@ public void requestFromService(Consumer resultHandler, FaultHandler faul "&viewkey=" + model.getTxKey() + "&txprove=1"; log.info("Param {} for {}", param, this); - String json = httpClient.requestWithGET(param, "User-Agent", "bisq/" + Version.VERSION); + String json = httpClient.get(param, "User-Agent", "bisq/" + Version.VERSION); try { String prettyJson = new GsonBuilder().setPrettyPrinting().create().toJson(new JsonParser().parse(json)); log.info("Response json from {}\n{}", this, prettyJson); diff --git a/p2p/src/main/java/bisq/network/http/HttpClient.java b/p2p/src/main/java/bisq/network/http/HttpClient.java index fff78049b6d..bb507c0e677 100644 --- a/p2p/src/main/java/bisq/network/http/HttpClient.java +++ b/p2p/src/main/java/bisq/network/http/HttpClient.java @@ -26,17 +26,19 @@ public interface HttpClient { void setIgnoreSocks5Proxy(boolean ignoreSocks5Proxy); - String requestWithGET(String param, - @Nullable String headerKey, - @Nullable String headerValue) throws IOException; + String get(String param, + @Nullable String headerKey, + @Nullable String headerValue) throws IOException; - String requestWithGETNoProxy(String param, - @Nullable String headerKey, - @Nullable String headerValue) throws IOException; + String post(String param, + @Nullable String headerKey, + @Nullable String headerValue) throws IOException; String getUid(); String getBaseUrl(); + boolean hasPendingRequest(); + void shutDown(); } diff --git a/p2p/src/main/java/bisq/network/http/HttpClientImpl.java b/p2p/src/main/java/bisq/network/http/HttpClientImpl.java index 57b2ac86eae..3f5a6ee4299 100644 --- a/p2p/src/main/java/bisq/network/http/HttpClientImpl.java +++ b/p2p/src/main/java/bisq/network/http/HttpClientImpl.java @@ -20,9 +20,12 @@ import bisq.network.Socks5ProxyProvider; import bisq.common.app.Version; +import bisq.common.util.Utilities; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; @@ -49,10 +52,12 @@ import java.util.concurrent.TimeUnit; import lombok.Getter; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import javax.annotation.Nullable; +import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; // TODO close connection if failing @@ -60,14 +65,19 @@ public class HttpClientImpl implements HttpClient { @Nullable private Socks5ProxyProvider socks5ProxyProvider; + @Nullable + private HttpURLConnection connection; + @Nullable + private CloseableHttpClient closeableHttpClient; + @Getter + @Setter private String baseUrl; + @Setter private boolean ignoreSocks5Proxy; + @Getter private final String uid; - @Nullable - private HttpURLConnection connection; - @Nullable - private CloseableHttpClient httpclient; + private boolean hasPendingRequest; @Inject public HttpClientImpl(@Nullable Socks5ProxyProvider socks5ProxyProvider) { @@ -82,103 +92,111 @@ public HttpClientImpl(String baseUrl) { @Override public void shutDown() { - if (connection != null) { - connection.disconnect(); - } - if (httpclient != null) { - try { - httpclient.close(); - } catch (IOException ignore) { + try { + if (connection != null) { + connection.getInputStream().close(); + connection.disconnect(); + } + if (closeableHttpClient != null) { + closeableHttpClient.close(); } + } catch (IOException ignore) { } } @Override - public void setBaseUrl(String baseUrl) { - this.baseUrl = baseUrl; + public boolean hasPendingRequest() { + return hasPendingRequest; } @Override - public void setIgnoreSocks5Proxy(boolean ignoreSocks5Proxy) { - this.ignoreSocks5Proxy = ignoreSocks5Proxy; + public String get(String param, + @Nullable String headerKey, + @Nullable String headerValue) throws IOException { + return doRequest(param, HttpMethod.GET, headerKey, headerValue); } @Override - public String requestWithGET(String param, - @Nullable String headerKey, - @Nullable String headerValue) throws IOException { - checkNotNull(baseUrl, "baseUrl must be set before calling requestWithGET"); - - Socks5Proxy socks5Proxy = null; - if (socks5ProxyProvider != null) { - // We use the custom socks5ProxyHttp. If not set we request socks5ProxyProvider.getSocks5ProxyBtc() - // which delivers the btc proxy if set, otherwise the internal proxy. - socks5Proxy = socks5ProxyProvider.getSocks5ProxyHttp(); - if (socks5Proxy == null) - socks5Proxy = socks5ProxyProvider.getSocks5Proxy(); - } + public String post(String param, + @Nullable String headerKey, + @Nullable String headerValue) throws IOException { + return doRequest(param, HttpMethod.POST, headerKey, headerValue); + } + + private String doRequest(String param, + HttpMethod httpMethod, + @Nullable String headerKey, + @Nullable String headerValue) throws IOException { + checkNotNull(baseUrl, "baseUrl must be set before calling doRequest"); + checkArgument(!hasPendingRequest, "We got called on the same HttpClient again while a request is still open."); + + hasPendingRequest = true; + Socks5Proxy socks5Proxy = getSocks5Proxy(socks5ProxyProvider); if (ignoreSocks5Proxy || socks5Proxy == null || baseUrl.contains("localhost")) { - log.debug("Use clear net for HttpClient. socks5Proxy={}, ignoreSocks5Proxy={}, baseUrl={}", - socks5Proxy, ignoreSocks5Proxy, baseUrl); - return requestWithGETNoProxy(param, headerKey, headerValue); + return requestWithoutProxy(baseUrl, param, httpMethod, headerKey, headerValue); } else { - log.debug("Use socks5Proxy for HttpClient: " + socks5Proxy); - return doRequestWithGETProxy(param, socks5Proxy, headerKey, headerValue); + return doRequestWithProxy(baseUrl, param, httpMethod, socks5Proxy, headerKey, headerValue); } } - /** - * Make an HTTP Get request directly (not routed over socks5 proxy). - */ - @Override - public String requestWithGETNoProxy(String param, - @Nullable String headerKey, - @Nullable String headerValue) throws IOException { - log.debug("Executing HTTP request " + baseUrl + param + " proxy: none."); - URL url = new URL(baseUrl + param); + private String requestWithoutProxy(String baseUrl, + String param, + HttpMethod httpMethod, + @Nullable String headerKey, + @Nullable String headerValue) throws IOException { + long ts = System.currentTimeMillis(); + String spec = baseUrl + param; + log.info("requestWithoutProxy: URL={}, httpMethod={}", spec, httpMethod); try { + URL url = new URL(spec); connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("GET"); + connection.setRequestMethod(httpMethod.name()); connection.setConnectTimeout((int) TimeUnit.SECONDS.toMillis(120)); connection.setReadTimeout((int) TimeUnit.SECONDS.toMillis(120)); connection.setRequestProperty("User-Agent", "bisq/" + Version.VERSION); - if (headerKey != null && headerValue != null) + if (headerKey != null && headerValue != null) { connection.setRequestProperty(headerKey, headerValue); + } if (connection.getResponseCode() == 200) { - return convertInputStreamToString(connection.getInputStream()); + String response = convertInputStreamToString(connection.getInputStream()); + log.info("Response for {} took {} ms. Data size:{}, response: {}", + spec, + System.currentTimeMillis() - ts, + Utilities.readableFileSize(response.getBytes().length), + Utilities.toTruncatedString(response)); + return response; } else { String error = convertInputStreamToString(connection.getErrorStream()); connection.getErrorStream().close(); throw new HttpException(error); } } catch (Throwable t) { - final String message = "Error at requestWithGETNoProxy with URL: " + (baseUrl + param) + ". Throwable=" + t.getMessage(); + String message = "Error at requestWithoutProxy with URL: " + spec + ". Throwable=" + t.getMessage(); log.error(message); throw new IOException(message); } finally { try { - if (connection != null) + if (connection != null) { connection.getInputStream().close(); + connection.disconnect(); + connection = null; + } } catch (Throwable ignore) { } + hasPendingRequest = false; } } - @Override - public String getUid() { - return uid; - } - - - /** - * Make an HTTP Get request routed over socks5 proxy. - */ - private String doRequestWithGETProxy(String param, - Socks5Proxy socks5Proxy, - @Nullable String headerKey, - @Nullable String headerValue) throws IOException { - log.debug("requestWithGETProxy param=" + param); + private String doRequestWithProxy(String baseUrl, + String param, + HttpMethod httpMethod, + Socks5Proxy socks5Proxy, + @Nullable String headerKey, + @Nullable String headerValue) throws IOException { + long ts = System.currentTimeMillis(); + String uri = baseUrl + param; + log.info("requestWithoutProxy: uri={}, httpMethod={}", uri, httpMethod); // This code is adapted from: // http://stackoverflow.com/a/25203021/5616248 @@ -194,7 +212,7 @@ private String doRequestWithGETProxy(String param, new PoolingHttpClientConnectionManager(reg) : new PoolingHttpClientConnectionManager(reg, new FakeDnsResolver()); try { - httpclient = HttpClients.custom().setConnectionManager(cm).build(); + closeableHttpClient = HttpClients.custom().setConnectionManager(cm).build(); InetSocketAddress socksAddress = new InetSocketAddress(socks5Proxy.getInetAddress(), socks5Proxy.getPort()); // remove me: Use this to test with system-wide Tor proxy, or change port for another proxy. @@ -203,23 +221,60 @@ private String doRequestWithGETProxy(String param, HttpClientContext context = HttpClientContext.create(); context.setAttribute("socks.address", socksAddress); - HttpGet request = new HttpGet(baseUrl + param); + HttpUriRequest request = getHttpUriRequest(httpMethod, uri); if (headerKey != null && headerValue != null) request.setHeader(headerKey, headerValue); - log.debug("Executing request " + request + " proxy: " + socksAddress); - try (CloseableHttpResponse response = checkNotNull(httpclient).execute(request, context)) { - return convertInputStreamToString(response.getEntity().getContent()); + try (CloseableHttpResponse httpResponse = checkNotNull(closeableHttpClient).execute(request, context)) { + String response = convertInputStreamToString(httpResponse.getEntity().getContent()); + log.info("Response for {} took {} ms. Data size:{}, response: {}", + uri, + System.currentTimeMillis() - ts, + Utilities.readableFileSize(response.getBytes().length), + Utilities.toTruncatedString(response)); + return response; } } catch (Throwable t) { - throw new IOException("Error at requestWithGETProxy with URL: " + (baseUrl + param) + ". Throwable=" + t.getMessage()); + String message = "Error at doRequestWithProxy with URL: " + uri + ". Throwable=" + t.getMessage(); + log.error(message); + throw new IOException(message); } finally { - if (httpclient != null) { - httpclient.close(); + if (closeableHttpClient != null) { + closeableHttpClient.close(); + closeableHttpClient = null; } + hasPendingRequest = false; + } + } + + private HttpUriRequest getHttpUriRequest(HttpMethod httpMethod, String uri) { + switch (httpMethod) { + case GET: + return new HttpGet(uri); + case POST: + return new HttpPost(uri); + default: + throw new IllegalArgumentException("HttpMethod not supported: " + httpMethod); } } + @Nullable + private Socks5Proxy getSocks5Proxy(Socks5ProxyProvider socks5ProxyProvider) { + if (socks5ProxyProvider == null) { + return null; + } + + // We use the custom socks5ProxyHttp. + Socks5Proxy socks5Proxy = socks5ProxyProvider.getSocks5ProxyHttp(); + if (socks5Proxy != null) { + return socks5Proxy; + } + + // If not set we request socks5ProxyProvider.getSocks5Proxy() + // which delivers the btc proxy if set, otherwise the internal proxy. + return socks5ProxyProvider.getSocks5Proxy(); + } + private String convertInputStreamToString(InputStream inputStream) throws IOException { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); StringBuilder stringBuilder = new StringBuilder(); @@ -232,10 +287,13 @@ private String convertInputStreamToString(InputStream inputStream) throws IOExce @Override public String toString() { - return "HttpClient{" + - "socks5ProxyProvider=" + socks5ProxyProvider + - ", baseUrl='" + baseUrl + '\'' + - ", ignoreSocks5Proxy=" + ignoreSocks5Proxy + - '}'; + return "HttpClientImpl{" + + "\n socks5ProxyProvider=" + socks5ProxyProvider + + ",\n baseUrl='" + baseUrl + '\'' + + ",\n ignoreSocks5Proxy=" + ignoreSocks5Proxy + + ",\n uid='" + uid + '\'' + + ",\n connection=" + connection + + ",\n httpclient=" + closeableHttpClient + + "\n}"; } } diff --git a/p2p/src/main/java/bisq/network/http/HttpMethod.java b/p2p/src/main/java/bisq/network/http/HttpMethod.java new file mode 100644 index 00000000000..b68ea538458 --- /dev/null +++ b/p2p/src/main/java/bisq/network/http/HttpMethod.java @@ -0,0 +1,23 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.network.http; + +public enum HttpMethod { + GET, + POST +}