From 653b680b5d3c31e9cb3e44bcad2920187c2b2a14 Mon Sep 17 00:00:00 2001 From: Simon Whitty Date: Sun, 20 Feb 2022 12:05:35 +1100 Subject: [PATCH] Improve Logging --- Sources/HTTPConnection.swift | 12 +++++++----- Sources/HTTPServer.swift | 33 ++++++++++++++++++++++++++++---- Sources/Socket/Socket.swift | 2 ++ Sources/Socket/SocketError.swift | 3 +++ 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/Sources/HTTPConnection.swift b/Sources/HTTPConnection.swift index 3d79fc25..b5780988 100644 --- a/Sources/HTTPConnection.swift +++ b/Sources/HTTPConnection.swift @@ -58,7 +58,6 @@ struct HTTPConnection { struct HTTPRequestSequence: AsyncSequence, AsyncIteratorProtocol where S.Element == UInt8 { typealias Element = HTTPRequest private let bytes: S - private var isComplete: Bool = false init(bytes: S) { self.bytes = bytes @@ -67,9 +66,12 @@ struct HTTPRequestSequence: AsyncSequence, AsyncIteratorProtoc func makeAsyncIterator() -> HTTPRequestSequence { self } mutating func next() async throws -> HTTPRequest? { - guard !isComplete else { return nil } - let request = try await HTTPRequestDecoder.decodeRequest(from: bytes) - isComplete = !request.shouldKeepAlive - return request + do { + return try await HTTPRequestDecoder.decodeRequest(from: bytes) + } catch SocketError.disconnected { + return nil + } catch { + throw error + } } } diff --git a/Sources/HTTPServer.swift b/Sources/HTTPServer.swift index 949e0f8d..43eff7db 100644 --- a/Sources/HTTPServer.swift +++ b/Sources/HTTPServer.swift @@ -103,18 +103,18 @@ public final actor HTTPServer { } private func handleConnection(_ connection: HTTPConnection) async { - logger?.logInfo("open connection: \(connection.hostname)") + logger?.logOpenConnection(connection) do { for try await request in connection.requests { + logger?.logRequest(request, on: connection) let response = await handleRequest(request) try await connection.sendResponse(response) - guard response.shouldKeepAlive else { break } } } catch { - logger?.logError("connection error: \(error.localizedDescription)") + logger?.logError(error, on: connection) } try? await connection.close() - logger?.logInfo("close connection: \(connection.hostname)") + logger?.logCloseConnection(connection) } private func handleRequest(_ request: HTTPRequest) async -> HTTPResponse { @@ -140,3 +140,28 @@ public final actor HTTPServer { } } } + +extension HTTPLogging { + + func logOpenConnection(_ connection: HTTPConnection) { + logInfo("\(connection.identifer) open connection") + } + + func logCloseConnection(_ connection: HTTPConnection) { + logInfo("\(connection.identifer) close connection") + } + + func logRequest(_ request: HTTPRequest, on connection: HTTPConnection) { + logInfo("\(connection.identifer) request: \(request.method.rawValue) \(request.path)") + } + + func logError(_ error: Error, on connection: HTTPConnection) { + logError("\(connection.identifer) error: \(error.localizedDescription)") + } +} + +private extension HTTPConnection { + var identifer: String { + "<\(hostname)>" + } +} diff --git a/Sources/Socket/Socket.swift b/Sources/Socket/Socket.swift index 3afcda9f..5375414b 100644 --- a/Sources/Socket/Socket.swift +++ b/Sources/Socket/Socket.swift @@ -125,6 +125,8 @@ struct Socket: Sendable, Hashable { let count = Socket.read(file, &byte, 1) if count == 1 { return byte + } else if count == 0 { + throw SocketError.disconnected } else if errno == EWOULDBLOCK { throw SocketError.blocked } diff --git a/Sources/Socket/SocketError.swift b/Sources/Socket/SocketError.swift index a66b96b3..f51ad352 100644 --- a/Sources/Socket/SocketError.swift +++ b/Sources/Socket/SocketError.swift @@ -34,6 +34,7 @@ import Foundation enum SocketError: LocalizedError, Equatable { case failed(type: String, errno: Int32, message: String) case blocked + case disconnected var errorDescription: String? { switch self { @@ -41,6 +42,8 @@ enum SocketError: LocalizedError, Equatable { return "SocketError. \(type)(\(errno)): \(message)" case .blocked: return "SocketError. Blocked" + case .disconnected: + return "SocketError. Disconnected" } }