[Beta] Implement own HTTP client for online mode checks, instead of asynchttpclient
This commit is contained in:
parent
c0d581d41f
commit
be29799f5a
@ -25,12 +25,6 @@
|
|||||||
<version>14.0.1</version>
|
<version>14.0.1</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>com.ning</groupId>
|
|
||||||
<artifactId>async-http-client</artifactId>
|
|
||||||
<version>1.7.17</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.md-5</groupId>
|
<groupId>net.md-5</groupId>
|
||||||
<artifactId>bungeecord-event</artifactId>
|
<artifactId>bungeecord-event</artifactId>
|
||||||
|
@ -2,7 +2,6 @@ package net.md_5.bungee.api;
|
|||||||
|
|
||||||
import net.md_5.bungee.api.plugin.PluginManager;
|
import net.md_5.bungee.api.plugin.PluginManager;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.ning.http.client.AsyncHttpClient;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -218,15 +217,6 @@ public abstract class ProxyServer
|
|||||||
*/
|
*/
|
||||||
public abstract TaskScheduler getScheduler();
|
public abstract TaskScheduler getScheduler();
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the the web client used by this proxy to facilitate making web
|
|
||||||
* requests. Care should be taken to ensure that all operations are non
|
|
||||||
* blocking where applicable.
|
|
||||||
*
|
|
||||||
* @return the server's {@link AsyncHttpClient} instance
|
|
||||||
*/
|
|
||||||
public abstract AsyncHttpClient getHttpClient();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current number of connected users. The default implementation is
|
* Get the current number of connected users. The default implementation is
|
||||||
* more efficient than {@link #getPlayers()} as it does not take a lock or
|
* more efficient than {@link #getPlayers()} as it does not take a lock or
|
||||||
|
@ -6,10 +6,6 @@ import net.md_5.bungee.reconnect.SQLReconnectHandler;
|
|||||||
import net.md_5.bungee.scheduler.BungeeScheduler;
|
import net.md_5.bungee.scheduler.BungeeScheduler;
|
||||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.ning.http.client.AsyncHttpClient;
|
|
||||||
import com.ning.http.client.AsyncHttpClientConfig;
|
|
||||||
import com.ning.http.client.providers.netty.NettyAsyncHttpProvider;
|
|
||||||
import com.ning.http.client.providers.netty.NettyAsyncHttpProviderConfig;
|
|
||||||
import io.netty.bootstrap.ServerBootstrap;
|
import io.netty.bootstrap.ServerBootstrap;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelException;
|
import io.netty.channel.ChannelException;
|
||||||
@ -123,11 +119,6 @@ public class BungeeCord extends ProxyServer
|
|||||||
@Getter
|
@Getter
|
||||||
private final TaskScheduler scheduler = new BungeeScheduler();
|
private final TaskScheduler scheduler = new BungeeScheduler();
|
||||||
@Getter
|
@Getter
|
||||||
private final AsyncHttpClient httpClient = new AsyncHttpClient(
|
|
||||||
new NettyAsyncHttpProvider(
|
|
||||||
new AsyncHttpClientConfig.Builder().setAsyncHttpClientProviderConfig(
|
|
||||||
new NettyAsyncHttpProviderConfig().addProperty( NettyAsyncHttpProviderConfig.BOSS_EXECUTOR_SERVICE, executors ) ).setExecutorService( executors ).build() ) );
|
|
||||||
@Getter
|
|
||||||
private ConsoleReader consoleReader;
|
private ConsoleReader consoleReader;
|
||||||
@Getter
|
@Getter
|
||||||
private final Logger logger;
|
private final Logger logger;
|
||||||
@ -302,7 +293,6 @@ public class BungeeCord extends ProxyServer
|
|||||||
{
|
{
|
||||||
BungeeCord.this.isRunning = false;
|
BungeeCord.this.isRunning = false;
|
||||||
|
|
||||||
httpClient.close();
|
|
||||||
executors.shutdown();
|
executors.shutdown();
|
||||||
|
|
||||||
stopListeners();
|
stopListeners();
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
package net.md_5.bungee.connection;
|
package net.md_5.bungee.connection;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.ning.http.client.AsyncCompletionHandler;
|
|
||||||
import com.ning.http.client.Response;
|
|
||||||
import io.netty.util.concurrent.ScheduledFuture;
|
import io.netty.util.concurrent.ScheduledFuture;
|
||||||
import java.io.DataInput;
|
import java.io.DataInput;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.security.GeneralSecurityException;
|
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -33,6 +30,7 @@ import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|||||||
import net.md_5.bungee.api.event.LoginEvent;
|
import net.md_5.bungee.api.event.LoginEvent;
|
||||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
import net.md_5.bungee.api.event.PostLoginEvent;
|
||||||
import net.md_5.bungee.api.event.ProxyPingEvent;
|
import net.md_5.bungee.api.event.ProxyPingEvent;
|
||||||
|
import net.md_5.bungee.http.HttpClient;
|
||||||
import net.md_5.bungee.netty.HandlerBoss;
|
import net.md_5.bungee.netty.HandlerBoss;
|
||||||
import net.md_5.bungee.netty.ChannelWrapper;
|
import net.md_5.bungee.netty.ChannelWrapper;
|
||||||
import net.md_5.bungee.netty.CipherDecoder;
|
import net.md_5.bungee.netty.CipherDecoder;
|
||||||
@ -258,35 +256,37 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
|||||||
|
|
||||||
String encodedHash = URLEncoder.encode( new BigInteger( sha.digest() ).toString( 16 ), "UTF-8" );
|
String encodedHash = URLEncoder.encode( new BigInteger( sha.digest() ).toString( 16 ), "UTF-8" );
|
||||||
String authURL = "http://session.minecraft.net/game/checkserver.jsp?user=" + encName + "&serverId=" + encodedHash;
|
String authURL = "http://session.minecraft.net/game/checkserver.jsp?user=" + encName + "&serverId=" + encodedHash;
|
||||||
bungee.getHttpClient().prepareGet( authURL ).execute( new AsyncCompletionHandler<Response>()
|
|
||||||
|
Callback<String> handler = new Callback<String>()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public Response onCompleted(Response response) throws Exception
|
public void done(String result, Throwable error)
|
||||||
{
|
{
|
||||||
if ( "YES".equals( response.getResponseBody() ) )
|
if ( error == null )
|
||||||
|
{
|
||||||
|
if ( "YES".equals( result ) )
|
||||||
{
|
{
|
||||||
finish();
|
finish();
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
disconnect( "Not authenticated with Minecraft.net" );
|
disconnect( "Not authenticated with Minecraft.net" );
|
||||||
}
|
}
|
||||||
return response;
|
} else
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onThrowable(Throwable t)
|
|
||||||
{
|
{
|
||||||
disconnect( bungee.getTranslation( "mojang_fail" ) );
|
disconnect( bungee.getTranslation( "mojang_fail" ) );
|
||||||
bungee.getLogger().log( Level.SEVERE, "Error authenticating " + getName() + " with minecraft.net", t );
|
bungee.getLogger().log( Level.SEVERE, "Error authenticating " + getName() + " with minecraft.net", error );
|
||||||
}
|
}
|
||||||
} );
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
HttpClient.get( authURL, ch.getHandle().eventLoop(), handler );
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void finish() throws GeneralSecurityException
|
private void finish()
|
||||||
{
|
{
|
||||||
// Check for multiple connections
|
// Check for multiple connections
|
||||||
ProxiedPlayer old = bungee.getPlayer( handshake.getUsername() );
|
ProxiedPlayer old = bungee.getPlayer( handshake.getUsername() );
|
||||||
|
@ -4,7 +4,8 @@ import com.google.common.base.Preconditions;
|
|||||||
import io.netty.bootstrap.Bootstrap;
|
import io.netty.bootstrap.Bootstrap;
|
||||||
import io.netty.channel.ChannelFuture;
|
import io.netty.channel.ChannelFuture;
|
||||||
import io.netty.channel.ChannelFutureListener;
|
import io.netty.channel.ChannelFutureListener;
|
||||||
import io.netty.channel.EventLoopGroup;
|
import io.netty.channel.ChannelOption;
|
||||||
|
import io.netty.channel.EventLoop;
|
||||||
import io.netty.channel.nio.NioEventLoopGroup;
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||||
import io.netty.handler.codec.http.DefaultHttpRequest;
|
import io.netty.handler.codec.http.DefaultHttpRequest;
|
||||||
@ -13,21 +14,22 @@ import io.netty.handler.codec.http.HttpMethod;
|
|||||||
import io.netty.handler.codec.http.HttpRequest;
|
import io.netty.handler.codec.http.HttpRequest;
|
||||||
import io.netty.handler.codec.http.HttpVersion;
|
import io.netty.handler.codec.http.HttpVersion;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import net.md_5.bungee.api.Callback;
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
public class HttpClient
|
public class HttpClient
|
||||||
{
|
{
|
||||||
|
|
||||||
private final EventLoopGroup eventLoop;
|
public static int TIMEOUT = 5000;
|
||||||
|
|
||||||
public static void main(String[] args)
|
public static void get(String url, EventLoop eventLoop, final Callback<String> callback)
|
||||||
{
|
{
|
||||||
new HttpClient( new NioEventLoopGroup( 1 ) ).get( "https://session.minecraft.net/" );
|
Preconditions.checkNotNull( url, "url" );
|
||||||
}
|
Preconditions.checkNotNull( eventLoop, "eventLoop" );
|
||||||
|
Preconditions.checkNotNull( callback, "callBack" );
|
||||||
|
|
||||||
public void get(String url)
|
|
||||||
{
|
|
||||||
final URI uri = URI.create( url );
|
final URI uri = URI.create( url );
|
||||||
|
|
||||||
Preconditions.checkNotNull( uri.getScheme(), "scheme" );
|
Preconditions.checkNotNull( uri.getScheme(), "scheme" );
|
||||||
@ -56,16 +58,20 @@ public class HttpClient
|
|||||||
{
|
{
|
||||||
if ( future.isSuccess() )
|
if ( future.isSuccess() )
|
||||||
{
|
{
|
||||||
HttpRequest request = new DefaultHttpRequest( HttpVersion.HTTP_1_1, HttpMethod.GET, uri.getRawPath() );
|
String path = uri.getRawPath() + ( ( uri.getRawQuery() == null ) ? "" : "?" + uri.getRawQuery() );
|
||||||
|
|
||||||
|
HttpRequest request = new DefaultHttpRequest( HttpVersion.HTTP_1_1, HttpMethod.GET, path );
|
||||||
request.headers().set( HttpHeaders.Names.HOST, uri.getHost() );
|
request.headers().set( HttpHeaders.Names.HOST, uri.getHost() );
|
||||||
|
|
||||||
future.channel().write( request );
|
future.channel().write( request );
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
|
callback.done( null, future.cause() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
new Bootstrap().channel( NioSocketChannel.class ).group( eventLoop ).handler( new HttpInitializer( ssl ) ).remoteAddress( uri.getHost(), port ).connect().addListener( future );
|
new Bootstrap().channel( NioSocketChannel.class ).group( eventLoop ).handler( new HttpInitializer( callback, ssl ) ).
|
||||||
|
option( ChannelOption.CONNECT_TIMEOUT_MILLIS, TIMEOUT ).remoteAddress( uri.getHost(), port ).connect().addListener( future );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,29 +8,54 @@ import io.netty.handler.codec.http.HttpResponse;
|
|||||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||||
import io.netty.handler.codec.http.LastHttpContent;
|
import io.netty.handler.codec.http.LastHttpContent;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import net.md_5.bungee.api.Callback;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class HttpHandler extends SimpleChannelInboundHandler<HttpObject>
|
public class HttpHandler extends SimpleChannelInboundHandler<HttpObject>
|
||||||
{
|
{
|
||||||
|
|
||||||
|
private final Callback<String> callback;
|
||||||
|
private final StringBuilder buffer = new StringBuilder();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
callback.done( null, cause );
|
||||||
|
} finally
|
||||||
|
{
|
||||||
|
ctx.channel().close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void messageReceived(ChannelHandlerContext ctx, HttpObject msg) throws Exception
|
protected void messageReceived(ChannelHandlerContext ctx, HttpObject msg) throws Exception
|
||||||
{
|
{
|
||||||
if ( msg instanceof HttpResponse )
|
if ( msg instanceof HttpResponse )
|
||||||
{
|
{
|
||||||
HttpResponse response = (HttpResponse) msg;
|
HttpResponse response = (HttpResponse) msg;
|
||||||
if ( response.getStatus() != HttpResponseStatus.OK )
|
if ( response.getStatus().code() != 200 )
|
||||||
{
|
{
|
||||||
|
throw new IllegalStateException( "Expected HTTP response 200 OK, got " + response.getStatus() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( msg instanceof HttpContent )
|
if ( msg instanceof HttpContent )
|
||||||
{
|
{
|
||||||
HttpContent content = (HttpContent) msg;
|
HttpContent content = (HttpContent) msg;
|
||||||
String s = content.content().toString( Charset.forName( "UTF-8" ) );
|
buffer.append( content.content().toString( Charset.forName( "UTF-8" ) ) );
|
||||||
|
|
||||||
if ( msg instanceof LastHttpContent )
|
if ( msg instanceof LastHttpContent )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
callback.done( buffer.toString(), null );
|
||||||
|
} finally
|
||||||
{
|
{
|
||||||
ctx.channel().close();
|
ctx.channel().close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -4,20 +4,25 @@ import io.netty.channel.Channel;
|
|||||||
import io.netty.channel.ChannelInitializer;
|
import io.netty.channel.ChannelInitializer;
|
||||||
import io.netty.handler.codec.http.HttpClientCodec;
|
import io.netty.handler.codec.http.HttpClientCodec;
|
||||||
import io.netty.handler.ssl.SslHandler;
|
import io.netty.handler.ssl.SslHandler;
|
||||||
|
import io.netty.handler.timeout.ReadTimeoutHandler;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
import javax.net.ssl.SSLEngine;
|
import javax.net.ssl.SSLEngine;
|
||||||
import javax.net.ssl.TrustManager;
|
import javax.net.ssl.TrustManager;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import net.md_5.bungee.api.Callback;
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class HttpInitializer extends ChannelInitializer<Channel>
|
public class HttpInitializer extends ChannelInitializer<Channel>
|
||||||
{
|
{
|
||||||
|
|
||||||
|
private final Callback<String> callback;
|
||||||
private final boolean ssl;
|
private final boolean ssl;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initChannel(Channel ch) throws Exception
|
protected void initChannel(Channel ch) throws Exception
|
||||||
{
|
{
|
||||||
|
ch.pipeline().addLast( "timeout", new ReadTimeoutHandler( HttpClient.TIMEOUT, TimeUnit.MILLISECONDS ) );
|
||||||
if ( ssl )
|
if ( ssl )
|
||||||
{
|
{
|
||||||
SSLContext context = SSLContext.getInstance( "TLS" );
|
SSLContext context = SSLContext.getInstance( "TLS" );
|
||||||
@ -32,6 +37,6 @@ public class HttpInitializer extends ChannelInitializer<Channel>
|
|||||||
ch.pipeline().addLast( "ssl", new SslHandler( engine ) );
|
ch.pipeline().addLast( "ssl", new SslHandler( engine ) );
|
||||||
}
|
}
|
||||||
ch.pipeline().addLast( "http", new HttpClientCodec() );
|
ch.pipeline().addLast( "http", new HttpClientCodec() );
|
||||||
ch.pipeline().addLast( "handler", new HttpHandler() );
|
ch.pipeline().addLast( "handler", new HttpHandler( callback ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ public class LogDispatcher extends Thread
|
|||||||
|
|
||||||
public LogDispatcher(BungeeLogger logger)
|
public LogDispatcher(BungeeLogger logger)
|
||||||
{
|
{
|
||||||
super( "BungeeCord Logger Thread - " + logger );
|
super( "BungeeCord Logger Thread" );
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user