package com.hubilon; import com.hubilon.config.ConfigService; import com.hubilon.handler.ConfigHandler; import com.hubilon.handler.ConfigsHandler; import com.hubilon.handler.PingHandler; import com.hubilon.handler.ProxyHandler; import com.hubilon.handler.StaticHandler; import com.hubilon.util.DebugState; import com.sun.net.httpserver.HttpServer; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.file.Path; import java.util.concurrent.Executors; /** Binds the embedded HTTP server, scanning ports like run.ps1 (startPort..startPort+24). */ public final class ApiDiffServer { private static final int PORT_SCAN_RANGE = 25; private final HttpServer server; private final int port; private ApiDiffServer(HttpServer server, int port) { this.server = server; this.port = port; } public static ApiDiffServer create(int startPort, Path workDir, String preferredConfig, DebugState debugState) throws IOException { HttpServer server = null; int boundPort = -1; for (int candidate = startPort; candidate < startPort + PORT_SCAN_RANGE; candidate++) { try { server = HttpServer.create(new InetSocketAddress("localhost", candidate), 0); boundPort = candidate; break; } catch (IOException e) { // port in use, try the next candidate } } if (server == null) { throw new IOException("Could not bind any port in range " + startPort + ".." + (startPort + PORT_SCAN_RANGE - 1)); } ConfigService configService = new ConfigService(workDir); configService.ensureSampleConfigExists(); server.createContext("/", new StaticHandler()); server.createContext("/configs", new ConfigsHandler(configService, preferredConfig)); server.createContext("/config", new ConfigHandler(configService, preferredConfig, debugState)); server.createContext("/proxy", new ProxyHandler(debugState)); server.createContext("/ping", new PingHandler(boundPort)); server.setExecutor(Executors.newFixedThreadPool(8)); return new ApiDiffServer(server, boundPort); } public void start() { server.start(); } public void stop() { server.stop(0); } public int getPort() { return port; } public String getBaseUrl() { return "http://localhost:" + port + "/"; } }