Merge branch 'master' into 08-scratch

This commit is contained in:
ghubstan 2020-12-14 15:02:21 -03:00
commit a0f1c22d19
No known key found for this signature in database
GPG Key ID: E35592D6800A861E
20 changed files with 267 additions and 137 deletions

View File

@ -17,9 +17,8 @@
package bisq.core.account.witness;
import bisq.network.p2p.storage.P2PDataStorage;
import bisq.network.p2p.storage.payload.PersistableNetworkPayload;
import bisq.network.p2p.storage.persistence.MapStoreService;
import bisq.network.p2p.storage.persistence.HistoricalDataStoreService;
import bisq.common.config.Config;
import bisq.common.persistence.PersistenceManager;
@ -29,12 +28,10 @@ import javax.inject.Named;
import java.io.File;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class AccountAgeWitnessStorageService extends MapStoreService<AccountAgeWitnessStore, PersistableNetworkPayload> {
public class AccountAgeWitnessStorageService extends HistoricalDataStoreService<AccountAgeWitnessStore> {
private static final String FILE_NAME = "AccountAgeWitnessStore";
@ -48,23 +45,19 @@ public class AccountAgeWitnessStorageService extends MapStoreService<AccountAgeW
super(storageDir, persistenceManager);
}
///////////////////////////////////////////////////////////////////////////////////////////
// API
///////////////////////////////////////////////////////////////////////////////////////////
@Override
protected void initializePersistenceManager() {
persistenceManager.initialize(store, PersistenceManager.Source.NETWORK);
}
@Override
public String getFileName() {
return FILE_NAME;
}
@Override
public Map<P2PDataStorage.ByteArray, PersistableNetworkPayload> getMap() {
return store.getMap();
protected void initializePersistenceManager() {
persistenceManager.initialize(store, PersistenceManager.Source.NETWORK);
}
@Override

View File

@ -26,7 +26,6 @@ import bisq.core.btc.wallet.BsqWalletService;
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 @@ public class BitcoinModule extends AppModule {
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);

View File

@ -256,6 +256,11 @@ public class MobileNotificationService {
boolean useSound,
Consumer<String> resultHandler,
Consumer<Throwable> 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 @@ public class MobileNotificationService {
String threadName = "sendMobileNotification-" + msgAsHex.substring(0, 5) + "...";
ListenableFuture<String> 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);

View File

@ -17,7 +17,6 @@
package bisq.core.payment;
import bisq.core.locale.CurrencyUtil;
import bisq.core.payment.payload.PaymentAccountPayload;
import bisq.core.payment.payload.PaymentMethod;
import bisq.core.payment.payload.TransferwiseAccountPayload;
@ -28,8 +27,6 @@ import lombok.EqualsAndHashCode;
public final class TransferwiseAccount extends PaymentAccount {
public TransferwiseAccount() {
super(PaymentMethod.TRANSFERWISE);
tradeCurrencies.addAll(CurrencyUtil.getAllTransferwiseCurrencies());
}
@Override

View File

@ -21,12 +21,14 @@ import bisq.network.Socks5ProxyProvider;
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);
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}

View File

@ -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 @@ import lombok.extern.slf4j.Slf4j;
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<String, Long>, Map<String, Long>> 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<String, Long> tsMap = new HashMap<>();
@ -64,4 +66,8 @@ public class FeeProvider extends HttpClientProvider {
}
return new Tuple2<>(tsMap, map);
}
public HttpClient getHttpClient() {
return httpClient;
}
}

View File

@ -45,7 +45,7 @@ public class FeeRequest {
public SettableFuture<Tuple2<Map<String, Long>, Map<String, Long>>> getFees(FeeProvider provider) {
final SettableFuture<Tuple2<Map<String, Long>, Map<String, Long>>> resultFuture = SettableFuture.create();
ListenableFuture<Tuple2<Map<String, Long>, Map<String, Long>>> future = executorService.submit(() -> {
Thread.currentThread().setName("FeeRequest-" + provider.toString());
Thread.currentThread().setName("FeeRequest @ " + provider.getHttpClient().getBaseUrl());
return provider.getFees();
});

View File

@ -137,6 +137,11 @@ public class FeeService {
}
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) {

View File

@ -21,7 +21,7 @@ import bisq.core.locale.CurrencyUtil;
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 @@ public class PriceFeedService {
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 @@ public class PriceFeedService {
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 @@ public class PriceFeedService {
}
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<Tuple2<Map<String, Long>, Map<String, MarketPrice>>> future = priceRequest.requestAllPrices(provider);
Futures.addCallback(future, new FutureCallback<>() {

View File

@ -58,7 +58,7 @@ public class PriceProvider extends HttpClientProvider {
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);

View File

@ -50,7 +50,7 @@ public class PriceRequest {
String baseUrl = provider.getBaseUrl();
SettableFuture<Tuple2<Map<String, Long>, Map<String, MarketPrice>>> resultFuture = SettableFuture.create();
ListenableFuture<Tuple2<Map<String, Long>, Map<String, MarketPrice>>> future = executorService.submit(() -> {
Thread.currentThread().setName("PriceRequest-" + baseUrl);
Thread.currentThread().setName("PriceRequest @ " + baseUrl);
return provider.getAll();
});

View File

@ -197,6 +197,11 @@ class XmrTxProofRequest implements AssetTxProofRequest<XmrTxProofRequest.Result>
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<Result> future = executorService.submit(() -> {
@ -206,7 +211,7 @@ class XmrTxProofRequest implements AssetTxProofRequest<XmrTxProofRequest.Result>
"&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);

View File

@ -3152,6 +3152,7 @@ payment.venmo.venmoUserName=Venmo username
payment.popmoney.accountId=Email or phone no.
payment.promptPay.promptPayId=Citizen ID/Tax ID or phone no.
payment.supportedCurrencies=Supported currencies
payment.supportedCurrenciesForReceiver=Currencies for receiving funds
payment.limitations=Limitations
payment.salt=Salt for account age verification
payment.error.noHexSalt=The salt needs to be in HEX format.\n\

View File

@ -12,6 +12,6 @@ resDir=p2p/src/main/resources
# Only commit new TradeStatistics3Store if you plan to add it to
# https://github.com/bisq-network/bisq/blob/0345c795e2c227d827a1f239a323dda1250f4e69/common/src/main/java/bisq/common/app/Version.java#L40 as well.
cp "$dbDir/TradeStatistics3Store" "$resDir/TradeStatistics3Store_${version}_BTC_MAINNET"
cp "$dbDir/AccountAgeWitnessStore" "$resDir/AccountAgeWitnessStore_BTC_MAINNET"
cp "$dbDir/AccountAgeWitnessStore" "$resDir/AccountAgeWitnessStore_${version}_BTC_MAINNET"
cp "$dbDir/DaoStateStore" "$resDir/DaoStateStore_BTC_MAINNET"
cp "$dbDir/SignedWitnessStore" "$resDir/SignedWitnessStore_BTC_MAINNET"

View File

@ -78,7 +78,7 @@ public class TransferwiseForm extends PaymentMethodForm {
private void addCurrenciesGrid(boolean isEditable) {
FlowPane flowPane = FormBuilder.addTopLabelFlowPane(gridPane, ++gridRow,
Res.get("payment.supportedCurrencies"), 20, 20).second;
Res.get("payment.supportedCurrenciesForReceiver"), 20, 20).second;
if (isEditable) {
flowPane.setId("flow-pane-checkboxes-bg");

View File

@ -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();
}

View File

@ -20,9 +20,12 @@ package bisq.network.http;
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.UUID;
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 @@ import static com.google.common.base.Preconditions.checkNotNull;
public class HttpClientImpl implements HttpClient {
@Nullable
private Socks5ProxyProvider socks5ProxyProvider;
@Getter
private String baseUrl;
private boolean ignoreSocks5Proxy;
private final String uid;
@Nullable
private HttpURLConnection connection;
@Nullable
private CloseableHttpClient httpclient;
private CloseableHttpClient closeableHttpClient;
@Getter
@Setter
private String baseUrl;
@Setter
private boolean ignoreSocks5Proxy;
@Getter
private final String uid;
private boolean hasPendingRequest;
@Inject
public HttpClientImpl(@Nullable Socks5ProxyProvider socks5ProxyProvider) {
@ -82,103 +92,111 @@ public class HttpClientImpl implements HttpClient {
@Override
public void shutDown() {
if (connection != null) {
connection.disconnect();
}
if (httpclient != null) {
try {
httpclient.close();
} catch (IOException ignore) {
}
}
}
@Override
public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
}
@Override
public void setIgnoreSocks5Proxy(boolean ignoreSocks5Proxy) {
this.ignoreSocks5Proxy = ignoreSocks5Proxy;
}
@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();
}
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);
} else {
log.debug("Use socks5Proxy for HttpClient: " + socks5Proxy);
return doRequestWithGETProxy(param, 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);
try {
if (connection != null) {
connection.getInputStream().close();
connection.disconnect();
}
if (closeableHttpClient != null) {
closeableHttpClient.close();
}
} catch (IOException ignore) {
}
}
@Override
public boolean hasPendingRequest() {
return hasPendingRequest;
}
@Override
public String get(String param,
@Nullable String headerKey,
@Nullable String headerValue) throws IOException {
return doRequest(param, HttpMethod.GET, headerKey, headerValue);
}
@Override
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")) {
return requestWithoutProxy(baseUrl, param, httpMethod, headerKey, headerValue);
} else {
return doRequestWithProxy(baseUrl, param, httpMethod, socks5Proxy, headerKey, headerValue);
}
}
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 @@ public class HttpClientImpl implements HttpClient {
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 @@ public class HttpClientImpl implements HttpClient {
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 @@ public class HttpClientImpl implements HttpClient {
@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}";
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
package bisq.network.http;
public enum HttpMethod {
GET,
POST
}

View File

@ -192,10 +192,7 @@ public abstract class HistoricalDataStoreService<T extends PersistableNetworkPay
pruneStore(persisted, version);
completeHandler.run();
},
() -> {
log.warn("Resource file with file name {} does not exits.", fileName);
completeHandler.run();
});
completeHandler::run);
}
private void pruneStore(PersistableNetworkPayloadStore<? extends PersistableNetworkPayload> historicalStore,