All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.chimerapps.niddler.core.NiddlerServer Maven / Gradle / Ivy
package com.chimerapps.niddler.core;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.chimerapps.niddler.core.debug.NiddlerDebugger;
import com.chimerapps.niddler.util.LogUtil;
import com.chimerapps.niddler.util.StringUtil;
import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.nio.channels.NotYetConnectedException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
/**
* @author Maarten Van Giel
* @author Nicola Verbeeck
*/
class NiddlerServer extends WebSocketServer {
private static final String LOG_TAG = NiddlerServer.class.getSimpleName();
private final String mPackageName;
private final WebSocketListener mListener;
private final List mConnections;
private final String mPassword;
private final NiddlerDebuggerImpl mNiddlerDebugger;
private final NiddlerServerAnnouncementManager mServerAnnouncementManager;
private final NiddlerImpl.StaticBlacklistDispatchListener mStaticBlacklistListener;
private final String mTag;
private NiddlerServer(final String password, final InetSocketAddress address, final String packageName, @Nullable final String icon,
final WebSocketListener listener, final NiddlerImpl.StaticBlacklistDispatchListener blacklistListener) {
super(address);
mPackageName = packageName;
mListener = listener;
mPassword = password;
mConnections = new LinkedList<>();
mNiddlerDebugger = new NiddlerDebuggerImpl();
mServerAnnouncementManager = new NiddlerServerAnnouncementManager(packageName, this);
mStaticBlacklistListener = blacklistListener;
mTag = UUID.randomUUID().toString().substring(0, 6);
if (icon != null) {
mServerAnnouncementManager.addExtension(new NiddlerServerAnnouncementManager.IconAnnouncementExtension(icon));
}
mServerAnnouncementManager.addExtension(new NiddlerServerAnnouncementManager.TagAnnouncementExtension(mTag));
}
NiddlerServer(final String password, final int port, final String packageName, @Nullable final String icon,
final WebSocketListener listener, final NiddlerImpl.StaticBlacklistDispatchListener blacklistListener) throws UnknownHostException {
this(password, new InetSocketAddress(port), packageName, icon, listener, blacklistListener);
}
@Override
public void start() {
mServerAnnouncementManager.stop();
super.start();
}
@Override
public void stop() throws IOException, InterruptedException {
mServerAnnouncementManager.stop();
super.stop();
}
@Override
public final void onOpen(final WebSocket conn, final ClientHandshake handshake) {
LogUtil.niddlerLogDebug(LOG_TAG, "New socket connection: " + handshake.getResourceDescriptor());
final ServerConnection connection = new ServerConnection(conn);
synchronized (mConnections) {
mConnections.add(connection);
}
if (StringUtil.isEmpty(mPassword)) {
connection.noAuth();
authSuccess(conn);
} else {
connection.sendAuthRequest(mPackageName);
}
}
@Override
public final void onClose(final WebSocket conn, final int code, final String reason, final boolean remote) {
LogUtil.niddlerLogDebug(LOG_TAG, "Connection closed: " + conn);
synchronized (mConnections) {
final Iterator iterator = mConnections.iterator();
while (iterator.hasNext()) {
final ServerConnection connection = iterator.next();
mNiddlerDebugger.onConnectionClosed(connection);
connection.closed();
if (connection.isFor(conn)) {
iterator.remove();
}
}
}
}
@Override
public void onStart() {
mServerAnnouncementManager.stop();
mServerAnnouncementManager.start();
LogUtil.niddlerLogStartup("Niddler Server running on " + getPort() + " [" + mTag + "][waitingForDebugger=" + mNiddlerDebugger.isWaitingForConnection() + "]");
}
private static final String MESSAGE_AUTH = "authReply";
private static final String MESSAGE_START_DEBUG = "startDebug";
private static final String MESSAGE_END_DEBUG = "endDebug";
private static final String MESSAGE_DEBUG_CONTROL = "controlDebug";
private static final String MESSAGE_STATIC_BLACKLIST_UPDATE = "controlStaticBlacklist";
@Override
public final void onMessage(final WebSocket conn, final String message) {
final ServerConnection connection = getConnection(conn);
if (connection == null) {
conn.close();
return;
}
try {
final JSONObject object = new JSONObject(message);
final String type = object.optString("type", null);
switch (type) {
case MESSAGE_AUTH:
if (!connection.checkAuthReply(MessageParser.parseAuthReply(object), mPassword)) {
LogUtil.niddlerLogWarning(LOG_TAG, "Client sent wrong authentication code!");
return;
}
authSuccess(conn);
break;
case MESSAGE_START_DEBUG:
if (connection.canReceiveData()) {
mNiddlerDebugger.onDebuggerAttached(connection);
}
break;
case MESSAGE_END_DEBUG:
mNiddlerDebugger.onDebuggerConnectionClosed();
break;
case MESSAGE_DEBUG_CONTROL:
mNiddlerDebugger.onControlMessage(object, connection);
break;
case MESSAGE_STATIC_BLACKLIST_UPDATE:
mStaticBlacklistListener.setBlacklistItemEnabled(object.getString("id"), object.getString("pattern"), object.getBoolean("enabled"));
break;
default:
LogUtil.niddlerLogWarning(LOG_TAG, "Received unsolicited message from client: " + message);
}
} catch (final JSONException e) {
LogUtil.niddlerLogWarning(LOG_TAG, "Received non-json message from server: " + message, e);
}
}
private ServerConnection getConnection(final WebSocket conn) {
synchronized (mConnections) {
for (final ServerConnection connection : mConnections) {
if (connection.isFor(conn)) {
return connection;
}
}
}
return null;
}
private void authSuccess(final WebSocket conn) {
if (mListener != null) {
mListener.onConnectionOpened(conn);
}
}
@Override
public final void onError(final WebSocket conn, final Exception ex) {
LogUtil.niddlerLogError(LOG_TAG, "WebSocket error", ex);
final ServerConnection connection = getConnection(conn);
if (connection != null) {
mNiddlerDebugger.onConnectionClosed(connection);
connection.closed();
}
}
/**
* Sends a String message to all sockets
*
* @param message the message to be sent
*/
final synchronized void sendToAll(final String message) {
synchronized (mConnections) {
for (final ServerConnection connection : mConnections) {
try {
if (connection.canReceiveData()) {
connection.send(message);
}
} catch (final NotYetConnectedException ignored) {
//Nothing to do, wait for the connection to complete
} catch (final IllegalArgumentException ignored) {
LogUtil.niddlerLogError(LOG_TAG, "WebSocket error", ignored);
}
}
}
}
@NonNull
NiddlerDebugger debugger() {
return mNiddlerDebugger;
}
interface WebSocketListener {
void onConnectionOpened(final WebSocket conn);
}
}