mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-04-25 14:57:37 +00:00
Added health endpoint
This commit is contained in:
parent
a803b5ae7d
commit
420ec3117c
9 changed files with 24 additions and 13 deletions
|
|
@ -291,7 +291,7 @@ final class RustServer: ServerProtocol {
|
|||
// MARK: - Private Methods
|
||||
|
||||
private func performHealthCheck(maxAttempts: Int, delaySeconds: Double) async -> Bool {
|
||||
let healthURL = URL(string: "http://127.0.0.1:\(port)/health")!
|
||||
let healthURL = URL(string: "http://127.0.0.1:\(port)/api/health")!
|
||||
|
||||
for attempt in 1...maxAttempts {
|
||||
do {
|
||||
|
|
@ -490,4 +490,4 @@ enum RustServerError: LocalizedError {
|
|||
return "Server port is not configured"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ public final class ServerMonitor {
|
|||
guard isRunning else { return false }
|
||||
|
||||
do {
|
||||
let url = URL(string: "http://127.0.0.1:\(port)/health")!
|
||||
let url = URL(string: "http://127.0.0.1:\(port)/api/health")!
|
||||
let request = URLRequest(url: url, timeoutInterval: 2.0)
|
||||
let (_, response) = try await URLSession.shared.data(for: request)
|
||||
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ class SessionMonitor {
|
|||
private func fetchSessions() async {
|
||||
do {
|
||||
// First check if server is running
|
||||
let healthURL = URL(string: "http://127.0.0.1:\(serverPort)/health")!
|
||||
let healthURL = URL(string: "http://127.0.0.1:\(serverPort)/api/health")!
|
||||
let healthRequest = URLRequest(url: healthURL, timeoutInterval: 2.0)
|
||||
|
||||
do {
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ public class TunnelClient {
|
|||
// MARK: - Health Check
|
||||
|
||||
public func checkHealth() async throws -> TunnelSession.HealthResponse {
|
||||
let request = buildRequest(path: "/health", method: .get)
|
||||
let request = buildRequest(path: "/api/health", method: .get)
|
||||
let (data, response) = try await httpClient.data(for: request, body: nil)
|
||||
|
||||
guard response.status == .ok else {
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ public final class TunnelServer {
|
|||
router.add(middleware: LogRequestsMiddleware(.info))
|
||||
|
||||
// Health check endpoint
|
||||
router.get("/health") { _, _ -> HTTPResponse.Status in
|
||||
router.get("/api/health") { _, _ -> HTTPResponse.Status in
|
||||
.ok
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -969,7 +969,7 @@ struct DebugSettingsView: View {
|
|||
guard isServerRunning else { return false }
|
||||
|
||||
do {
|
||||
let url = URL(string: "http://127.0.0.1:\(serverPort)/health")!
|
||||
let url = URL(string: "http://127.0.0.1:\(serverPort)/api/health")!
|
||||
var request = URLRequest(url: url)
|
||||
request.timeoutInterval = 1.0 // Quick timeout for heartbeat
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
|
|||
|
||||
// Test the server after a short delay
|
||||
try await Task.sleep(for: .milliseconds(500))
|
||||
if let url = URL(string: "http://127.0.0.1:\(serverManager.port)/health") {
|
||||
if let url = URL(string: "http://127.0.0.1:\(serverManager.port)/api/health") {
|
||||
let (_, response) = try await URLSession.shared.data(from: url)
|
||||
if let httpResponse = response as? HTTPURLResponse {
|
||||
print("Server health check response: \(httpResponse.statusCode)")
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ struct TunnelClientTests {
|
|||
sessions: 3,
|
||||
version: "1.0.0"
|
||||
)
|
||||
try mockClient.configureJSON(healthResponse, for: "/health")
|
||||
try mockClient.configureJSON(healthResponse, for: "/api/health")
|
||||
|
||||
// Act
|
||||
let result = try await tunnelClient.checkHealth()
|
||||
|
|
@ -40,7 +40,7 @@ struct TunnelClientTests {
|
|||
#expect(result.version == "1.0.0")
|
||||
|
||||
// Verify request
|
||||
#expect(mockClient.wasRequested(path: "/health"))
|
||||
#expect(mockClient.wasRequested(path: "/api/health"))
|
||||
let lastRequest = mockClient.lastRequest()!
|
||||
#expect(lastRequest.request.method == .get)
|
||||
#expect(lastRequest.request.headerFields[.authorization] == "Bearer \(testAPIKey)")
|
||||
|
|
@ -49,7 +49,7 @@ struct TunnelClientTests {
|
|||
@Test("Health check handles server error")
|
||||
func testHealthCheckServerError() async throws {
|
||||
// Arrange
|
||||
mockClient.configure(for: "/health", response: .serverError)
|
||||
mockClient.configure(for: "/api/health", response: .serverError)
|
||||
|
||||
// Act & Assert
|
||||
await #expect(throws: TunnelClientError.httpError(statusCode: 500)) {
|
||||
|
|
@ -291,7 +291,7 @@ struct TunnelClientTests {
|
|||
@Test("All requests include authentication header")
|
||||
func testAuthenticationHeader() async throws {
|
||||
// Arrange
|
||||
mockClient.configure(for: "/health", response: .success)
|
||||
mockClient.configure(for: "/api/health", response: .success)
|
||||
mockClient.configure(for: "/api/sessions", response: .success)
|
||||
|
||||
// Act
|
||||
|
|
@ -365,4 +365,4 @@ struct TunnelClientTests {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -245,6 +245,7 @@ pub fn start_server(
|
|||
}
|
||||
|
||||
let response = match (method, path.as_str()) {
|
||||
(&Method::GET, "/api/health") => handle_health(),
|
||||
(&Method::GET, "/api/sessions") => handle_list_sessions(&control_path),
|
||||
(&Method::POST, "/api/sessions") => handle_create_session(&control_path, &mut req),
|
||||
(&Method::POST, "/api/cleanup-exited") => handle_cleanup_exited(&control_path),
|
||||
|
|
@ -312,6 +313,16 @@ fn json_response<T: Serialize>(status: StatusCode, data: &T) -> Response<String>
|
|||
.unwrap()
|
||||
}
|
||||
|
||||
fn handle_health() -> Response<String> {
|
||||
let response = ApiResponse {
|
||||
success: Some(true),
|
||||
message: Some("OK".to_string()),
|
||||
error: None,
|
||||
session_id: None,
|
||||
};
|
||||
json_response(StatusCode::OK, &response)
|
||||
}
|
||||
|
||||
fn handle_list_sessions(control_path: &PathBuf) -> Response<String> {
|
||||
match sessions::list_sessions(control_path) {
|
||||
Ok(sessions) => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue