Improve server

This commit is contained in:
Peter Steinberger 2025-06-17 01:30:04 +02:00
parent be39ff63f0
commit 5d47d66b65
3 changed files with 66 additions and 43 deletions

View file

@ -497,9 +497,12 @@ final class RustServer: ServerProtocol {
return nil
}
let result = await group.next()
if let result = await group.next() {
group.cancelAll()
return result
}
group.cancelAll()
return result ?? nil
return nil
}
}
}

View file

@ -590,8 +590,13 @@ public final class TunnelServer {
return errorResponse(message: "File not found", status: .notFound)
}
// If it's a directory, return 404 (we don't serve directory listings)
// If it's a directory, try to serve index.html from that directory
if isDirectory.boolValue {
let indexPath = fullPath + "/index.html"
if FileManager.default.fileExists(atPath: indexPath) {
// Recursively serve the index.html file
return await serveStaticFile(path: sanitizedPath + "/index.html")
}
return errorResponse(message: "Directory access not allowed", status: .notFound)
}
@ -803,16 +808,10 @@ public final class TunnelServer {
}
if session.pid > 0 {
kill(pid_t(session.pid), SIGTERM)
DispatchQueue.global().asyncAfter(deadline: .now() + 1.0) {
if kill(pid_t(session.pid), 0) == 0 {
kill(pid_t(session.pid), SIGKILL)
}
}
kill(pid_t(session.pid), SIGKILL)
}
let response = SimpleResponse(success: true, message: "Session killed")
let response = SimpleResponse(success: true, message: "Session killed (SIGKILL)")
return jsonResponse(response)
} catch {
logger.error("Error killing session: \(error)")
@ -1182,7 +1181,7 @@ public final class TunnelServer {
do {
let content = try String(contentsOfFile: streamOutPath, encoding: .utf8)
var buffer = ByteBuffer()
buffer.writeString(content)
@ -1354,9 +1353,10 @@ public final class TunnelServer {
struct SuccessResponse: Codable {
let success: Bool
let message: String
}
let response = SuccessResponse(success: true)
let response = SuccessResponse(success: true, message: "Input sent successfully")
return jsonResponse(response)
} catch let decodingError as DecodingError {
logger.error("Error decoding input request: \(decodingError)")
@ -1448,7 +1448,11 @@ public final class TunnelServer {
let expandedPath = resolvePath(mkdirRequest.path, fallback: mkdirRequest.path)
try FileManager.default.createDirectory(atPath: expandedPath, withIntermediateDirectories: true, attributes: nil)
try FileManager.default.createDirectory(
atPath: expandedPath,
withIntermediateDirectories: true,
attributes: nil
)
let response = SimpleResponse(
success: true,
@ -1461,7 +1465,10 @@ public final class TunnelServer {
return errorResponse(message: "Invalid request body. Expected JSON with 'path' field", status: .badRequest)
} catch {
logger.error("Error creating directory: \(error)")
return errorResponse(message: "Failed to create directory: \(error.localizedDescription)", status: .internalServerError)
return errorResponse(
message: "Failed to create directory: \(error.localizedDescription)",
status: .internalServerError
)
}
}

View file

@ -6,44 +6,51 @@ enum NetworkUtility {
/// Get the primary IPv4 address of the local machine
static func getLocalIPAddress() -> String? {
var address: String?
// Create a socket to determine the local IP address
var ifaddr: UnsafeMutablePointer<ifaddrs>?
guard getifaddrs(&ifaddr) == 0 else { return nil }
defer { freeifaddrs(ifaddr) }
var ptr = ifaddr
while ptr != nil {
defer { ptr = ptr?.pointee.ifa_next }
guard let interface = ptr?.pointee else { continue }
// Skip loopback addresses
if interface.ifa_flags & UInt32(IFF_LOOPBACK) != 0 { continue }
// Check for IPv4 interface
let addrFamily = interface.ifa_addr.pointee.sa_family
if addrFamily == UInt8(AF_INET) {
// Get interface name
let name = String(cString: interface.ifa_name)
// Prefer en0 (typically Wi-Fi on Mac) or en1 (sometimes Ethernet)
// But accept any non-loopback IPv4 address
if name.hasPrefix("en") {
var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
if getnameinfo(interface.ifa_addr, socklen_t(interface.ifa_addr.pointee.sa_len),
&hostname, socklen_t(hostname.count),
nil, 0, NI_NUMERICHOST) == 0 {
if getnameinfo(
interface.ifa_addr,
socklen_t(interface.ifa_addr.pointee.sa_len),
&hostname,
socklen_t(hostname.count),
nil,
0,
NI_NUMERICHOST
) == 0 {
let ipAddress = String(cString: &hostname)
// Prefer addresses that look like local network addresses
if ipAddress.hasPrefix("192.168.") ||
ipAddress.hasPrefix("10.") ||
ipAddress.hasPrefix("172.") {
if ipAddress.hasPrefix("192.168.") ||
ipAddress.hasPrefix("10.") ||
ipAddress.hasPrefix("172.")
{
return ipAddress
}
// Store as fallback if we don't find a better one
if address == nil {
address = ipAddress
@ -52,41 +59,47 @@ enum NetworkUtility {
}
}
}
return address
}
/// Get all IPv4 addresses
static func getAllIPAddresses() -> [String] {
var addresses: [String] = []
var ifaddr: UnsafeMutablePointer<ifaddrs>?
guard getifaddrs(&ifaddr) == 0 else { return addresses }
defer { freeifaddrs(ifaddr) }
var ptr = ifaddr
while ptr != nil {
defer { ptr = ptr?.pointee.ifa_next }
guard let interface = ptr?.pointee else { continue }
// Skip loopback addresses
if interface.ifa_flags & UInt32(IFF_LOOPBACK) != 0 { continue }
// Check for IPv4 interface
let addrFamily = interface.ifa_addr.pointee.sa_family
if addrFamily == UInt8(AF_INET) {
var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
if getnameinfo(interface.ifa_addr, socklen_t(interface.ifa_addr.pointee.sa_len),
&hostname, socklen_t(hostname.count),
nil, 0, NI_NUMERICHOST) == 0 {
if getnameinfo(
interface.ifa_addr,
socklen_t(interface.ifa_addr.pointee.sa_len),
&hostname,
socklen_t(hostname.count),
nil,
0,
NI_NUMERICHOST
) == 0 {
let ipAddress = String(cString: &hostname)
addresses.append(ipAddress)
}
}
}
return addresses
}
}
}