Added builtin ClassicHandler
This commit is contained in:
@@ -19,7 +19,8 @@ public enum ProtocolVersion implements Serializable {
|
||||
/**
|
||||
* First Beta Version of OAC-Protocol
|
||||
*/
|
||||
PV_1_0_0_BETA("1.0.0", ProtocolType.BETA, ProtocolSide.ALL, List.of(Protocol.OAC), PV_1_0_0_CLASSIC),;
|
||||
PV_1_0_0_BETA("1.0.0", ProtocolType.BETA, ProtocolSide.ALL, List.of(Protocol.OAC), PV_1_0_0_CLASSIC),
|
||||
;
|
||||
|
||||
/**
|
||||
* The version string of the protocol version.
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package org.openautonomousconnection.protocol.versions.v1_0_0.beta;
|
||||
|
||||
import org.openautonomousconnection.protocol.side.ins.ProtocolINSServer;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.beta.INSRecord;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.beta.INSRecordType;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -42,7 +40,6 @@ public final class INSRecordTools {
|
||||
* @param name InfoName.
|
||||
* @param sub Optional sub-name, may be {@code null}.
|
||||
* @param type Desired record type.
|
||||
*
|
||||
* @return A list of resolved records. May be empty if nothing could be resolved.
|
||||
*/
|
||||
public static List<INSRecord> resolveWithCNAME(ProtocolINSServer server,
|
||||
@@ -87,7 +84,7 @@ public final class INSRecordTools {
|
||||
ParsedName target = parseTargetName(cname.value);
|
||||
if (target == null) continue;
|
||||
|
||||
List<INSRecord> resolved = server.resolve(target.tln, target.name,target.sub, targetType);
|
||||
List<INSRecord> resolved = server.resolve(target.tln, target.name, target.sub, targetType);
|
||||
|
||||
if (!resolved.isEmpty()) return resolved;
|
||||
|
||||
@@ -110,7 +107,6 @@ public final class INSRecordTools {
|
||||
* and the one before that is the InfoName.
|
||||
*
|
||||
* @param target FQDN string.
|
||||
*
|
||||
* @return ParsedName or {@code null} if it cannot be parsed.
|
||||
*/
|
||||
private static ParsedName parseTargetName(String target) {
|
||||
@@ -130,12 +126,6 @@ public final class INSRecordTools {
|
||||
return new ParsedName(tln, name, sub);
|
||||
}
|
||||
|
||||
private record ParsedName(String tln, String name, String sub) {}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Validation helpers
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Performs basic validation on a single {@link INSRecord}.
|
||||
* <p>
|
||||
@@ -148,7 +138,6 @@ public final class INSRecordTools {
|
||||
* </ul>
|
||||
*
|
||||
* @param record The record to validate.
|
||||
*
|
||||
* @return {@code true} if the record passes all checks, {@code false} otherwise.
|
||||
*/
|
||||
public static boolean isValidRecord(INSRecord record) {
|
||||
@@ -157,17 +146,18 @@ public final class INSRecordTools {
|
||||
if (record.value == null || record.value.isEmpty()) return false;
|
||||
|
||||
if (record.port < 0 || record.port > 65535) return false;
|
||||
if (record.ttl < 0) return false;
|
||||
|
||||
return true;
|
||||
return record.ttl >= 0;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Validation helpers
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Validates a collection of records by applying {@link #isValidRecord(INSRecord)}
|
||||
* to each element.
|
||||
*
|
||||
* @param records Records to validate.
|
||||
*
|
||||
* @return A new list containing only valid records.
|
||||
*/
|
||||
public static List<INSRecord> filterValid(List<INSRecord> records) {
|
||||
@@ -178,4 +168,7 @@ public final class INSRecordTools {
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
private record ParsedName(String tln, String name, String sub) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ public abstract class ClassicHandlerClient {
|
||||
public abstract void handleMessage(String message, Classic_ProtocolVersion protocolVersion);
|
||||
|
||||
public final void sendMessage(String message) throws IOException, ClassNotFoundException {
|
||||
client.getClientINSConnection().sendPacket(new Classic_MessagePacket(message, 0, client.getProtocolBridge()));
|
||||
client.getClientINSConnection().sendPacket(new Classic_MessagePacket(message, client.getClientServerConnection().getClientID(), client.getProtocolBridge()));
|
||||
}
|
||||
|
||||
public abstract void validationCompleted(Classic_Domain domain, INSResponseStatus insResponseStatus);
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package org.openautonomousconnection.protocol.versions.v1_0_0.classic.handlers.builtin;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.openautonomousconnection.protocol.ProtocolBridge;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.beta.INSRecordType;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.beta.INSResponseStatus;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.classic.handlers.ClassicHandlerClient;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.classic.helper.ClassicHelper;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.classic.objects.Classic_Domain;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.classic.site.Classic_SiteType;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.classic.site.Classic_WebsitesContent;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.classic.utils.Classic_ProtocolVersion;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public abstract class ClientClassic extends ClassicHandlerClient {
|
||||
@Getter
|
||||
private final ProtocolBridge bridge;
|
||||
|
||||
@Getter
|
||||
private final ClassicHelper helper;
|
||||
|
||||
public ClientClassic(ProtocolBridge bridge) {
|
||||
super(bridge.getProtocolClient());
|
||||
this.bridge = bridge;
|
||||
this.helper = new ClassicHelper(bridge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsupportedClassicPacket(String className, Object[] content) {
|
||||
bridge.getLogger().warn(
|
||||
"[Classic UnsupportedPacket] packet=" + className + " content=" + java.util.Arrays.toString(content)
|
||||
);
|
||||
|
||||
onUnsupportedClassicPacket(className, content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional callback
|
||||
*
|
||||
* @param className The class name
|
||||
* @param content The content
|
||||
*/
|
||||
public void onUnsupportedClassicPacket(String className, Object[] content) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(String message, Classic_ProtocolVersion protocolVersion) {
|
||||
bridge.getLogger().info("[ClassicHandler] Message received (Classic Version " + protocolVersion.version + "): " + message);
|
||||
onMessage(message, protocolVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional callback
|
||||
*
|
||||
* @param message The Message
|
||||
* @param protocolVersion the Classic version
|
||||
*/
|
||||
public void onMessage(String message, Classic_ProtocolVersion protocolVersion) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validationCompleted(Classic_Domain domain, INSResponseStatus insResponseStatus) {
|
||||
if (insResponseStatus == INSResponseStatus.OK) {
|
||||
try {
|
||||
bridge.getProtocolClient().sendINSQuery(domain.topLevelDomain, domain.name, null, INSRecordType.A);
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
handleHTMLContent(Classic_SiteType.CLIENT, domain, Classic_WebsitesContent.ERROR_OCCURRED(e.getMessage()));
|
||||
}
|
||||
} else {
|
||||
handleHTMLContent(Classic_SiteType.CLIENT, domain, Classic_WebsitesContent.DOMAIN_NOT_REACHABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package org.openautonomousconnection.protocol.versions.v1_0_0.classic.handlers.builtin;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.openautonomousconnection.protocol.ProtocolBridge;
|
||||
import org.openautonomousconnection.protocol.side.ins.ConnectedProtocolClient;
|
||||
import org.openautonomousconnection.protocol.side.ins.ProtocolINSServer;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.beta.INSRecord;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.beta.INSRecordType;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.classic.handlers.ClassicHandlerINSServer;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.classic.helper.ClassicHelper;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.classic.helper.ParsedDomain;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.classic.objects.Classic_Domain;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.classic.objects.Classic_RequestDomain;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.classic.utils.Classic_ProtocolVersion;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
public class INSClassic extends ClassicHandlerINSServer {
|
||||
|
||||
@Getter
|
||||
private final ProtocolBridge bridge;
|
||||
|
||||
@Getter
|
||||
private final ClassicHelper helper;
|
||||
|
||||
public INSClassic(ProtocolBridge bridge) {
|
||||
this.bridge = bridge;
|
||||
this.helper = new ClassicHelper(bridge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(ConnectedProtocolClient client, String message, Classic_ProtocolVersion protocolVersion) {
|
||||
client.getServer().getProtocolBridge().getLogger().info("[ClassicHandler] Message received from ClientID " +
|
||||
client.getPipelineConnection().getClientID() +
|
||||
" (Classic Version " + protocolVersion.version + ", Client Version: " +
|
||||
client.getClientVersion().toString() + "): " + message);
|
||||
|
||||
onMessage(client, message, protocolVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional callback.
|
||||
*
|
||||
* @param client The client sender.
|
||||
* @param message The message.
|
||||
* @param protocolVersion The classic version.
|
||||
*/
|
||||
public void onMessage(ConnectedProtocolClient client, String message, Classic_ProtocolVersion protocolVersion) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Classic_Domain getDomain(Classic_RequestDomain requestDomain) throws SQLException {
|
||||
if (!bridge.isRunningAsINSServer()) return null;
|
||||
|
||||
ParsedDomain pd = helper.parseDomain(requestDomain);
|
||||
ProtocolINSServer server = (ProtocolINSServer) bridge.getProtocolServer();
|
||||
|
||||
// IMPORTANT: resolve() already performs CNAME recursion + sorting.
|
||||
// Request A directly and pick the first (= best after sorting).
|
||||
List<INSRecord> aRecords = server.resolve(pd.tln(), pd.name(), pd.sub(), INSRecordType.A);
|
||||
if (aRecords.isEmpty()) return null;
|
||||
|
||||
INSRecord targetA = aRecords.get(0);
|
||||
return helper.buildClassicDomain(pd, targetA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Classic_Domain ping(Classic_RequestDomain req) throws SQLException {
|
||||
if (!bridge.isRunningAsINSServer()) return null;
|
||||
return new Classic_Domain(req.name, req.topLevelDomain, null, req.path, bridge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsupportedClassicPacket(String className, Object[] content, ConnectedProtocolClient client) {
|
||||
client.getServer().getProtocolBridge().getLogger().warn(
|
||||
"[Classic UnsupportedPacket] From client " + client.getPipelineConnection().getClientID() +
|
||||
": packet=" + className + " content=" + java.util.Arrays.toString(content)
|
||||
);
|
||||
|
||||
onUnsupportedClassicPacket(className, content, client);
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional callback.
|
||||
*
|
||||
* @param className The class name.
|
||||
* @param content The content.
|
||||
* @param client The client sender.
|
||||
*/
|
||||
public void onUnsupportedClassicPacket(String className, Object[] content, ConnectedProtocolClient client) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package org.openautonomousconnection.protocol.versions.v1_0_0.classic.handlers.builtin;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.openautonomousconnection.protocol.ProtocolBridge;
|
||||
import org.openautonomousconnection.protocol.side.ins.ConnectedProtocolClient;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.classic.handlers.ClassicHandlerWebServer;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.classic.utils.Classic_ProtocolVersion;
|
||||
|
||||
public class WebClassic extends ClassicHandlerWebServer {
|
||||
@Getter
|
||||
private final ProtocolBridge bridge;
|
||||
|
||||
public WebClassic(ProtocolBridge bridge) {
|
||||
this.bridge = bridge;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(ConnectedProtocolClient client, String message, Classic_ProtocolVersion protocolVersion) {
|
||||
client.getServer().getProtocolBridge().getLogger().info("[ClassicHandler] Message received from ClientID " +
|
||||
client.getPipelineConnection().getClientID() +
|
||||
" (Classic Version " + protocolVersion.version + ", Client Version: " +
|
||||
client.getClientVersion().toString() + "): " + message);
|
||||
|
||||
onMessage(client, message, protocolVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional callback
|
||||
*
|
||||
* @param client The client sender
|
||||
* @param message The Message
|
||||
* @param protocolVersion the Classic version
|
||||
*/
|
||||
public void onMessage(ConnectedProtocolClient client, String message, Classic_ProtocolVersion protocolVersion) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsupportedClassicPacket(String className, Object[] content, ConnectedProtocolClient client) {
|
||||
client.getServer().getProtocolBridge().getLogger().warn(
|
||||
"[Classic UnsupportedPacket] From client " + client.getPipelineConnection().getClientID() +
|
||||
": packet=" + className + " content=" + java.util.Arrays.toString(content)
|
||||
);
|
||||
|
||||
onUnsupportedClassicPacket(className, content, client);
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional callback
|
||||
*
|
||||
* @param className The class name
|
||||
* @param content The content
|
||||
* @param client The client sender
|
||||
*/
|
||||
public void onUnsupportedClassicPacket(String className, Object[] content, ConnectedProtocolClient client) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package org.openautonomousconnection.protocol.versions.v1_0_0.classic.helper;
|
||||
|
||||
import org.openautonomousconnection.protocol.ProtocolBridge;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.beta.INSRecord;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.classic.objects.Classic_Domain;
|
||||
import org.openautonomousconnection.protocol.versions.v1_0_0.classic.objects.Classic_RequestDomain;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public record ClassicHelper(ProtocolBridge bridge) {
|
||||
|
||||
public Classic_Domain buildClassicDomain(ParsedDomain req, INSRecord rec) {
|
||||
Classic_Domain info = new Classic_Domain(req.name(), req.tln(), req.sub(), req.path(), bridge);
|
||||
|
||||
String host = rec.value;
|
||||
int port = rec.port > 0 ? rec.port : 80;
|
||||
|
||||
return new Classic_Domain(
|
||||
req.name(), req.tln(),
|
||||
host.contains(":") ? host : host + ":" + port,
|
||||
req.path(), bridge);
|
||||
}
|
||||
|
||||
public ParsedDomain parseDomain(Classic_RequestDomain req) {
|
||||
String tln = req.topLevelDomain; // example: "net"
|
||||
String full = req.name; // example: "api.v1.example"
|
||||
|
||||
String[] parts = full.split("\\.");
|
||||
|
||||
if (parts.length == 1) {
|
||||
return new ParsedDomain(tln, full, null, req.path);
|
||||
}
|
||||
|
||||
String name = parts[parts.length - 1];
|
||||
String sub = parts.length > 1
|
||||
? String.join(".", Arrays.copyOfRange(parts, 0, parts.length - 1))
|
||||
: null;
|
||||
|
||||
return new ParsedDomain(tln, name, sub, req.path);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package org.openautonomousconnection.protocol.versions.v1_0_0.classic.helper;
|
||||
|
||||
public record ParsedDomain(String tln, String name, String sub, String path) {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.openautonomousconnection.protocol.versions.v1_0_0.classic.helper;
|
||||
|
||||
/**
|
||||
* Represents a parsed CNAME target in (tln, name, sub) form.
|
||||
*/
|
||||
public record TargetName(String tln, String name, String sub) {
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.openautonomousconnection.protocol.versions.v1_0_0.classic.objects;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.openautonomousconnection.protocol.ProtocolBridge;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
Reference in New Issue
Block a user