Added functionality to use the next available port (#1913)

* Added [Feature Request]: command flag to use the next available port #1882

* Added [Feature Request]: command flag to use the next available port #1882

* minor changes - build successful

* Update: port finding starts from 0 instead of default 8080 port

* Update: port finding starts from 0 instead of default 8080 port

---------

Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
This commit is contained in:
Akhil Sharma 2024-09-23 04:17:11 +05:30 committed by GitHub
parent f47ed3b42e
commit fde1f626eb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 35 additions and 16 deletions

View file

@ -1,6 +1,7 @@
package stirling.software.SPDF; package stirling.software.SPDF;
import java.io.IOException; import java.io.IOException;
import java.net.ServerSocket;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
@ -30,15 +31,36 @@ public class SPdfApplication {
private static final Logger logger = LoggerFactory.getLogger(SPdfApplication.class); private static final Logger logger = LoggerFactory.getLogger(SPdfApplication.class);
@Autowired private Environment env; @Autowired private Environment env;
@Autowired ApplicationProperties applicationProperties; @Autowired ApplicationProperties applicationProperties;
private static String serverPortStatic; private static String serverPortStatic;
@Value("${server.port:8080}") @Value("${server.port:8080}")
public void setServerPortStatic(String port) { public void setServerPortStatic(String port) {
if (port.equalsIgnoreCase("auto")) {
// Use Spring Boot's automatic port assignment (server.port=0)
SPdfApplication.serverPortStatic = "0"; // This will let Spring Boot assign an available port
} else {
SPdfApplication.serverPortStatic = port; SPdfApplication.serverPortStatic = port;
} }
}
// Optionally keep this method if you want to provide a manual port-incrementation fallback.
private static String findAvailablePort(int startPort) {
int port = startPort;
while (!isPortAvailable(port)) {
port++;
}
return String.valueOf(port);
}
private static boolean isPortAvailable(int port) {
try (ServerSocket socket = new ServerSocket(port)) {
return true;
} catch (IOException e) {
return false;
}
}
@PostConstruct @PostConstruct
public void init() { public void init() {
@ -47,13 +69,17 @@ public class SPdfApplication {
boolean browserOpen = browserOpenEnv != null && "true".equalsIgnoreCase(browserOpenEnv); boolean browserOpen = browserOpenEnv != null && "true".equalsIgnoreCase(browserOpenEnv);
if (browserOpen) { if (browserOpen) {
try { try {
String url = "http://localhost:" + getNonStaticPort(); String url = "http://localhost:" + getStaticPort();
String os = System.getProperty("os.name").toLowerCase(); String os = System.getProperty("os.name").toLowerCase();
Runtime rt = Runtime.getRuntime(); Runtime rt = Runtime.getRuntime();
if (os.contains("win")) { if (os.contains("win")) {
// For Windows // For Windows
SystemCommand.runCommand(rt, "rundll32 url.dll,FileProtocolHandler " + url); SystemCommand.runCommand(rt, "rundll32 url.dll,FileProtocolHandler " + url);
} else if (os.contains("mac")) {
rt.exec("open " + url);
} else if (os.contains("nix") || os.contains("nux")) {
rt.exec("xdg-open " + url);
} }
} catch (Exception e) { } catch (Exception e) {
logger.error("Error opening browser: {}", e.getMessage()); logger.error("Error opening browser: {}", e.getMessage());
@ -69,15 +95,13 @@ public class SPdfApplication {
app.addInitializers(new ConfigInitializer()); app.addInitializers(new ConfigInitializer());
Map<String, String> propertyFiles = new HashMap<>(); Map<String, String> propertyFiles = new HashMap<>();
// stirling pdf settings file // External config files
if (Files.exists(Paths.get("configs/settings.yml"))) { if (Files.exists(Paths.get("configs/settings.yml"))) {
propertyFiles.put("spring.config.additional-location", "file:configs/settings.yml"); propertyFiles.put("spring.config.additional-location", "file:configs/settings.yml");
} else { } else {
logger.warn( logger.warn("External configuration file 'configs/settings.yml' does not exist.");
"External configuration file 'configs/settings.yml' does not exist. Using default configuration and environment configuration instead.");
} }
// custom javs settings file
if (Files.exists(Paths.get("configs/custom_settings.yml"))) { if (Files.exists(Paths.get("configs/custom_settings.yml"))) {
String existingLocation = String existingLocation =
propertyFiles.getOrDefault("spring.config.additional-location", ""); propertyFiles.getOrDefault("spring.config.additional-location", "");
@ -100,19 +124,14 @@ public class SPdfApplication {
app.run(args); app.run(args);
try { // Ensure directories are created
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("Thread interrupted while sleeping", e);
}
try { try {
Files.createDirectories(Path.of("customFiles/static/")); Files.createDirectories(Path.of("customFiles/static/"));
Files.createDirectories(Path.of("customFiles/templates/")); Files.createDirectories(Path.of("customFiles/templates/"));
} catch (Exception e) { } catch (Exception e) {
logger.error("Error creating directories: {}", e.getMessage()); logger.error("Error creating directories: {}", e.getMessage());
} }
printStartupLogs(); printStartupLogs();
} }

View file

@ -15,7 +15,7 @@ import stirling.software.SPDF.utils.CheckProgramInstall;
@Tag(name = "Convert", description = "Convert APIs") @Tag(name = "Convert", description = "Convert APIs")
public class ConverterWebController { public class ConverterWebController {
@ConditionalOnExpression("#{bookAndHtmlFormatsInstalled}") @ConditionalOnExpression("${bookAndHtmlFormatsInstalled}")
@GetMapping("/book-to-pdf") @GetMapping("/book-to-pdf")
@Hidden @Hidden
public String convertBookToPdfForm(Model model) { public String convertBookToPdfForm(Model model) {
@ -60,7 +60,7 @@ public class ConverterWebController {
// PDF TO...... // PDF TO......
@ConditionalOnExpression("#{bookAndHtmlFormatsInstalled}") @ConditionalOnExpression("${bookAndHtmlFormatsInstalled}")
@GetMapping("/pdf-to-book") @GetMapping("/pdf-to-book")
@Hidden @Hidden
public String convertPdfToBookForm(Model model) { public String convertPdfToBookForm(Model model) {