Programmatically close a jetty client - java

I'm setting-up a jetty client that will be used to handle Google's oauth2 authorization flow
com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver receiver =
new LocalServerReceiver.Builder().setHost(redirect_host).setPort(redirect_port).build();
This will fail if a previous authorization flow failed and left the jetty client open.
INFO [log:131] jetty-6.1.26
WARN [log:265] failed SocketConnector#180.200.105.100:8085: java.net.BindException: Address already in use
WARN [log:265] failed Server#32c65328: java.net.BindException: Address already in use
Please, note that I'm using a fixed url and port.
Is there some way I can check programmatically whether or not the jetty client is already open, and handle this case, e.g by closing the previous jetty connection?

I faced a similar situation using the google api to connect on youtube service, the connection is based upon the jetty client too.
I solved by putting my localServerReceiver object in a static class (to be honest, is a singleton Spring Bean) with default value "null", in the first try to connect, It create a new instance and store it in the static class attribute.
After this, before any new try to connect I call the method localServerReceiver.stop() to cancel any previous connection.
Soomething like this:
public class LocaServerReceiverRetriever{
private static LocalServerReceiver localServerReceiver = null;
public static LocalServerReceiver getLocalServerReceiver(){
if(localServerReceiver == null){
localServerReceiver = new LocalServerReceiver.Builder().setPort(9001).build();
}else{
localServerReceiver.stop();
localServerReceiver = new LocalServerReceiver.Builder().setPort(9001).build();
}
return localServerReceiver ;
}
}
And then call "LocaServerReceiverRetriever.getLocalServerReceiver();" where is needed.
It works for me.
Good Luck

Related

Why does Apache Commons VFS consider Http Proxy and Socks5 Proxy but simply ignore Socks4 Proxy?

I am working on a application that connects to an SFTP server and downloads files using Apache Commons VFS, it works just fine, with the exception that the system needs to allow the user to specify a proxy, as needed.
Now, I know Apache Commons VFS is built on top of Jsch and I know Jsch contains the classes: com.jcraft.jsch.ProxyHTTP, com.jcraft.jsch.ProxySOCKS4 and com.jcraft.jsch.ProxySOCKS5.
The code below is an extract of VFS class org.apache.commons.vfs2.provider.sftp.SftpClientFactory:
public static Session createConnection(
...
final SftpFileSystemConfigBuilder.ProxyType proxyType = builder.getProxyType(fileSystemOptions);
...
final String proxyUser = builder.getProxyUser(fileSystemOptions);
final String proxyPassword = builder.getProxyPassword(fileSystemOptions);
Proxy proxy = null;
if (SftpFileSystemConfigBuilder.PROXY_HTTP.equals(proxyType)) {
proxy = createProxyHTTP(proxyHost, proxyPort);
((ProxyHTTP)proxy).setUserPasswd(proxyUser, proxyPassword);
} else if (SftpFileSystemConfigBuilder.PROXY_SOCKS5.equals(proxyType)) {
proxy = createProxySOCKS5(proxyHost, proxyPort);
((ProxySOCKS5)proxy).setUserPasswd(proxyUser, proxyPassword);
} else if (SftpFileSystemConfigBuilder.PROXY_STREAM.equals(proxyType)) {
proxy = createStreamProxy(proxyHost, proxyPort, fileSystemOptions, builder);
}
...
As you can you see, there's no "if" statement to instantiate ProxySOCKS4!
I have duplicated the SftpClientFactory class, set my version to load before the original class on the classpath and changed the code as follow:
public static Session createConnection(
...
final SftpFileSystemConfigBuilder.ProxyType proxyType = builder.getProxyType(fileSystemOptions);
...
final String proxyUser = builder.getProxyUser(fileSystemOptions);
final String proxyPassword = builder.getProxyPassword(fileSystemOptions);
Proxy proxy = null;
if (SftpFileSystemConfigBuilder.PROXY_HTTP.equals(proxyType)) {
proxy = createProxyHTTP(proxyHost, proxyPort);
((ProxyHTTP)proxy).setUserPasswd(proxyUser, proxyPassword);
/// change start (I also created the PROXY_SOCKS4 constant)
} else if (SftpFileSystemConfigBuilder.PROXY_SOCKS4.equals(proxyType)) {
proxy = createProxySOCKS4(proxyHost, proxyPort);
((ProxySOCKS4)proxy).setUserPasswd(proxyUser, proxyPassword);
/// change end
} else if (SftpFileSystemConfigBuilder.PROXY_SOCKS5.equals(proxyType)) {
proxy = createProxySOCKS5(proxyHost, proxyPort);
((ProxySOCKS5)proxy).setUserPasswd(proxyUser, proxyPassword);
} else if (SftpFileSystemConfigBuilder.PROXY_STREAM.equals(proxyType)) {
proxy = createStreamProxy(proxyHost, proxyPort, fileSystemOptions, builder);
}
...
.. and guess what, when I set my application to use a Socks 4 Proxy it works alright with the change above. It is important to say that setting the application to work with Socks 5 does not work if the proxy server is a Socks 4 type, and that's true not only for my application with VFS, but also any other client I tested, like Fillezila or WinSCP.
So, the main question is:
Why does VFS predicts the usage of ProxyHTTP, ProxySOCKS5 but completely ignores the JSch ProxySOCKS4 class? Am I missing some SFTP or Proxy concept here or should I consider VFS bugged? That's the first time I work with VFS.
Please consider the question in bold as the main question not to make it too broad.
I wasn't able to get or find a better answer in time, so what I did to solve my problem was exactly what I described in the question.
I duplicated the classes SftpClientFactory e SftpFileSystemConfigBuilder, made the necessary adjustments and used them instead of the original classes, it's ugly and now I am stuck with a specific VFS version, I know, but the problem was solved.
Lesson for next time: use Jsch instead of VFS.
I'll leave the question open though, in case someone else have a proper solution or answer.

How to use java with Braid framework example: pigtail?

I try to define Braid server in java like this repo. And the following is my BootstrapBraidService class:
#CordaService
public class BootstrapBraidService extends SingletonSerializeAsToken{
private AppServiceHub appServiceHub;
private BraidConfig braidConfig;
public BootstrapBraidService(AppServiceHub appServiceHub){
this.appServiceHub = appServiceHub;
this.braidConfig = new BraidConfig();
// Include a flow on the Braid server.
braidConfig.withFlow(ExtendedStatusFlow.IssueFlow.class);
// Include a service on the Braid server.
braidConfig.withService("myService", new BraidService(appServiceHub));
// The port the Braid server listens on.
braidConfig.withPort(3001);
// Using http instead of https.
braidConfig.withHttpServerOptions(new HttpServerOptions().setSsl(false));
// Start the Braid server.
braidConfig.bootstrapBraid(this.appServiceHub,Object::notify);
}
}
However node startup without my setting, like port use default(8080) instead of my setting(3001).
And NodeJS server fails to get services descriptor:
{ Error: failed to get services descriptor from
http://localhost:8080/api/
at createHangUpError (_http_client.js:331:15)
at Socket.socketOnEnd (_http_client.js:423:23)
at emitNone (events.js:111:20)
at Socket.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9) code: 'ECONNRESET', url: 'http://localhost:8080/api/' }
Can somebody tell me how to fix this problem? Thanks.
Update:
the node shell screenshot
The reason why this isn't working is because BraidConfig is an immutable class with a fluent API, but your code is using it as a classic mutable POJO which means none of your changes are being applied to the BraidConfig.
The following should work fine:
#CordaService
public class BootstrapBraidService extends SingletonSerializeAsToken{
private AppServiceHub appServiceHub;
private BraidConfig braidConfig;
public BootstrapBraidService(AppServiceHub appServiceHub){
this.appServiceHub = appServiceHub;
this.braidConfig = new BraidConfig()
// Include a flow on the Braid server.
.withFlow(ExtendedStatusFlow.IssueFlow.class)
// Include a service on the Braid server.
braidConfig.withService(new BraidService(appServiceHub))
// The port the Braid server listens on.
braidConfig.withPort(3001)
// Using http instead of https.
braidConfig.withHttpServerOptions(new HttpServerOptions().setSsl(false));
// Start the Braid server.
braidConfig.bootstrapBraid(this.appServiceHub,null);
}
}
regards,
Fuzz

Vertx HttpClient getNow not working

I have problem with vertx HttpClient.
Here's code which shows that tests GET using vertx and plain java.
Vertx vertx = Vertx.vertx();
HttpClientOptions options = new HttpClientOptions()
.setTrustAll(true)
.setSsl(false)
.setDefaultPort(80)
.setProtocolVersion(HttpVersion.HTTP_1_1)
.setLogActivity(true);
HttpClient client = vertx.createHttpClient(options);
client.getNow("google.com", "/", response -> {
System.out.println("Received response with status code " + response.statusCode());
});
System.out.println(getHTML("http://google.com"));
Where getHTML() is from here: How do I do a HTTP GET in Java?
This is my output:
<!doctype html><html... etc <- correct output from plain java
Feb 08, 2017 11:31:21 AM io.vertx.core.http.impl.HttpClientRequestImpl
SEVERE: java.net.UnknownHostException: failed to resolve 'google.com'. Exceeded max queries per resolve 3
But vertx can't connect. What's wrong here? I'm not using any proxy.
For reference: a solution, as described in this question and in tsegismont's comment here, is to set the flag vertx.disableDnsResolver to true:
-Dvertx.disableDnsResolver=true
in order to fall back to the JVM DNS resolver as explained here:
sometimes it can be desirable to use the JVM built-in resolver, the JVM system property -Dvertx.disableDnsResolver=true activates this behavior
I observed this DNS resolution issue with a redis client in a kubernetes environment.
I had this issue, what caused it for me was stale DNS servers being picked up by the Java runtime, i.e. servers registered for a network the machine was no longer connected to. The issue is first in the Sun JNDI implementation, it also exists in Netty which uses JNDI to bootstrap its list of name servers on most platforms, then finally shows up in VertX.
I think a good place to fix this would be in the Netty layer where the set of default DNS servers is bootstrapped. I have raised a ticket with the Netty project so we'll see if they agree with me! Here is the Netty ticket
In the mean time a fairly basic workaround is to filter the default DNS servers detected by Netty, based on whether they are reachable or not. Here is a code Sample in Kotlin to apply before constructing the main VertX instance.
// The default set of name servers provided by JNDI can contain stale entries
// This default set is picked up by Netty and in turn by VertX
// To work around this, we filter for only reachable name servers on startup
val nameServers = DefaultDnsServerAddressStreamProvider.defaultAddressList()
val reachableNameServers = nameServers.stream()
.filter {ns -> ns.address.isReachable(NS_REACHABLE_TIMEOUT)}
.map {ns -> ns.address.hostAddress}
.collect(Collectors.toList())
if (reachableNameServers.size == 0)
throw StartupException("There are no reachable name servers available")
val opts = VertxOptions()
opts.addressResolverOptions.servers = reachableNameServers
// The primary Vertx instance
val vertx = Vertx.vertx(opts)
A little more detail in case it is helpful. I have a company machine, which at some point was connected to the company network by a physical cable. Details of the company's internal name servers were set up by DHCP on the physical interface. Using the wireless interface at home, DNS for the wireless interface gets set to my home DNS while the config for the physical interface is not updated. This is fine since that device is not active, ipconfig /all does not show the internal company DNS servers. However, looking in the registry they are still there:
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces
They get picked up by the JNDI mechanism, which feeds Netty and in turn VertX. Since they are not reachable from my home location, DNS resolution fails. I can imagine this home/office situation is not unique to me! I don't know whether something similar could occur with multiple virtual interfaces on containers or VMs, it could be worth looking at if you are having problems.
Here is the sample code which works for me.
public class TemplVerticle extends HttpVerticle {
public static void main(String[] args) {
Vertx vertx = Vertx.vertx();
// Create the web client and enable SSL/TLS with a trust store
WebClient client = WebClient.create(vertx,
new WebClientOptions()
.setSsl(true)
.setTrustAll(true)
.setDefaultPort(443)
.setKeepAlive(true)
.setDefaultHost("www.w3schools.com")
);
client.get("www.w3schools.com")
.as(BodyCodec.string())
.send(ar -> {
if (ar.succeeded()) {
HttpResponse<String> response = ar.result();
System.out.println("Got HTTP response body");
System.out.println(response.body().toString());
} else {
ar.cause().printStackTrace();
}
});
}
}
Try using web client instead of httpclient, here you have an example (with rx):
private val client: WebClient = WebClient.create(vertx, WebClientOptions()
.setSsl(true)
.setTrustAll(true)
.setDefaultPort(443)
.setKeepAlive(true)
)
open fun <T> get(uri: String, marshaller: Class<T>): Single<T> {
return client.getAbs(host + uri).rxSend()
.map { extractJson(it, uri, marshaller) }
}
Another option is to use getAbs.

How to get client's Proxy IP address in CometD?

Using fiddler as a HTTP proxy, i connect to a local CometD server.
I inherit the class DefaultSecurityPolicy, and got the client's IP address with server.getContext().getRemoteAddress().getAddress().getHostAddress() in canHandshake Method.
However, it returns the client's real IP (original IP), but what i want is the one directly communicates with the server. Any help?
If the client using WebSocket to communicate with CometD server, The HTTP proxy doesn't take effect at all, So what i got is the original addr, am i right?
public function getlocationFromIp()
{
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
// Check if using Shared Internet Environment
$ipAddress = $_SERVER['HTTP_CLIENT_IP'];
}elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){
// Check if using Proxy User
$ipAddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
}else{
$ipAddress = $_SERVER['REMOTE_ADDR'];
}
$ip_geo_url = 'http://freegeoip.net/json/'.$ipAddress;
$ip_json = file_get_contents($ip_geo_url);
$ip_json = json_decode($ip_json);
return $ip_json;
}
it will get the location whit ip if it help you ...
it will be get the proxy location too

Jetty HTTP Client with SSL

I am following the Jetty HttpClient Example, but I am unable to get an SSL connection working. When I connect using a proxy, it throws a "Not Implemented" exception. When I don't use a proxy, it doesn't return anything.
HttpClient client = new HttpClient();
client.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
client.setProxy(new Address("www.example.com", 80));
client.start();
// create the exchange object, which lets you define where you want to go
// and what you want to do once you get a response
ContentExchange exchange = new ContentExchange()
{
// define the callback method to process the response when you get it
// back
protected void onResponseComplete() throws IOException
{
super.onResponseComplete();
String responseContent = this.getResponseContent();
// do something with the response content
System.out.println(responseContent);
}
};
exchange.setMethod("GET");
exchange.setURL("https://www.example.com");
exchange.setScheme(HttpSchemes.HTTPS_BUFFER);
// start the exchange
client.send(exchange);
exchange.waitForDone();
System.err.println("Response status: " + exchange.getResponseStatus());
Jetty v7.4.1:
if (dest.isSecure()) {
if (dest.isProxied()) {
SSLEngine engine=newSslEngine(channel); ep = new ProxySelectChannelEndPoint(channel, selectSet, key, _sslBuffers, engine, (int)_httpClient.getIdleTimeout());
} else { ...
Yeah weird, the source code for the Jetty-Client's SelectConnector looks like the following:
if (dest.isProxied()) {
String connect = HttpMethods.CONNECT+" "+dest.getAddress()+HttpVersions.HTTP_1_0+"\r\n\r\n";
// TODO need to send this over channel unencrypted and setup endpoint to ignore the 200 OK response.
throw new IllegalStateException("Not Implemented");
}
so the functionality doesn't exist at present - at least in the version I'm using (6.1.16) for using a proxy in this kind of way. It's also the same in the milestone Jetty 7 version (I found after downloading the source code).
I suggest your try a different client - check out Apache HttpClient:
http://hc.apache.org/httpclient-3.x/
The Jetty developers should really have marked this clearly in the Javadocs. another alternative is to implementinghave a go at implementing the feature for them and submitting it back as a patch.
try ProxyHandler (jetty 7) which handle connect-command for tunneling https-connection (via proxy)

Categories

Resources