| 1988 | } |
| 1989 | |
| 1990 | private void initHttpClient() { |
| 1991 | var builder = HttpClient.newBuilder(); |
| 1992 | // Java's HttpClient defaults to Redirect.NEVER, but TS/Node fetch and |
| 1993 | // browsers transparently follow 3xx. Without this, requests against |
| 1994 | // endpoints that redirect (e.g. gemini's exchange.gemini.com → 303 to |
| 1995 | // a signed-in URL) come back with an empty body, leaving downstream |
| 1996 | // parsers (fetchCurrenciesFromWeb populating options['tradingPairs']) |
| 1997 | // empty-handed and silently degrading market metadata. |
| 1998 | builder.followRedirects(HttpClient.Redirect.NORMAL); |
| 1999 | |
| 2000 | boolean httpsProxySet = this.httpsProxy != null && !this.httpsProxy.toString().isEmpty(); |
| 2001 | boolean httpProxySet = this.httpProxy != null && !this.httpProxy.toString().isEmpty(); |
| 2002 | boolean socksProxySet = this.socksProxy != null && !this.socksProxy.toString().isEmpty(); |
| 2003 | |
| 2004 | if (!httpsProxySet && !httpProxySet && !socksProxySet) { |
| 2005 | this.httpClient = builder.build(); |
| 2006 | return; |
| 2007 | } |
| 2008 | |
| 2009 | if (socksProxySet) { |
| 2010 | // SOCKS proxy requires a custom ProxySelector with Proxy.Type.SOCKS |
| 2011 | String proxyString = this.socksProxy.toString(); |
| 2012 | java.net.URI proxyUri = java.net.URI.create(proxyString); |
| 2013 | String host = proxyUri.getHost(); |
| 2014 | int port = (proxyUri.getPort() != -1) ? proxyUri.getPort() : 1080; |
| 2015 | java.net.InetSocketAddress socksAddr = new java.net.InetSocketAddress(host, port); |
| 2016 | builder.proxy(new java.net.ProxySelector() { |
| 2017 | @Override |
| 2018 | public java.util.List<java.net.Proxy> select(java.net.URI uri) { |
| 2019 | return java.util.List.of(new java.net.Proxy(java.net.Proxy.Type.SOCKS, socksAddr)); |
| 2020 | } |
| 2021 | @Override |
| 2022 | public void connectFailed(java.net.URI uri, java.net.SocketAddress sa, java.io.IOException ioe) {} |
| 2023 | }); |
| 2024 | } else { |
| 2025 | // HTTP/HTTPS proxy |
| 2026 | Object proxyUrl = httpsProxySet ? this.httpsProxy : this.httpProxy; |
| 2027 | String proxyString = proxyUrl.toString(); |
| 2028 | java.net.URI proxyUri = java.net.URI.create(proxyString); |
| 2029 | String host = proxyUri.getHost(); |
| 2030 | int port = (proxyUri.getPort() != -1) ? proxyUri.getPort() : 80; |
| 2031 | builder.proxy(java.net.ProxySelector.of(new java.net.InetSocketAddress(host, port))); |
| 2032 | } |
| 2033 | |
| 2034 | this.httpClient = builder.build(); |
| 2035 | } |
| 2036 | |
| 2037 | public CompletableFuture<Object> fetch(Object url2, Object method2, Object headers2, Object body2) { |
| 2038 | if (this.fetchResponse != null) { |