diff --git a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/Package.swift b/Package.swift
index e11f7fb..bc255c9 100755
--- a/Package.swift
+++ b/Package.swift
@@ -1,13 +1,23 @@
-// swift-tools-version:5.0
+// swift-tools-version:5.2
import PackageDescription
let package = Package(
name: "CapCollectorServer",
+ platforms: [
+ .macOS(.v10_15)
+ ],
dependencies: [
- .package(url: "https://github.com/vapor/vapor.git", .upToNextMinor(from: "3.3.0")),
+ .package(url: "https://github.com/vapor/vapor.git", from: "4.0.0"),
],
targets: [
- .target(name: "App", dependencies: ["Vapor"]),
+ .target(name: "App",
+ dependencies: [.product(name: "Vapor", package: "vapor")],
+ swiftSettings: [
+ // Enable better optimizations when building in Release configuration. Despite the use of
+ // the `.unsafeFlags` construct required by SwiftPM, this flag is recommended for Release
+ // builds. See for details.
+ .unsafeFlags(["-cross-module-optimization"], .when(configuration: .release))
+ ]),
.target(name: "Run", dependencies: ["App"]),
.testTarget(name: "AppTests", dependencies: ["App"]),
]
diff --git a/Sources/App/Router+Extensions.swift b/Sources/App/Router+Extensions.swift
index 9eb1368..153794e 100644
--- a/Sources/App/Router+Extensions.swift
+++ b/Sources/App/Router+Extensions.swift
@@ -7,37 +7,37 @@
import Vapor
-extension Router {
+extension Application {
- func getCatching(_ path: PathComponentsRepresentable..., call: @escaping (Request) throws -> T) {
- self.get(path) { (request: Request) -> HTTPResponse in
+ func getCatching(_ path: PathComponent..., call: @escaping (Request) throws -> T) {
+ self.get(path) { (request: Request) -> Response in
catching(path, request: request, closure: call)
}
}
- func postCatching(_ path: PathComponentsRepresentable..., call: @escaping (Request) throws -> T) {
- self.post(path) { (request: Request) -> HTTPResponse in
+ func postCatching(_ path: PathComponent..., call: @escaping (Request) throws -> T) {
+ self.post(path) { (request: Request) -> Response in
catching(path, request: request, closure: call)
}
}
}
-private func catching(_ path: PathComponentsRepresentable..., request: Request, closure: @escaping (Request) throws -> T) -> HTTPResponse {
+private func catching(_ path: [PathComponent], request: Request, closure: @escaping (Request) throws -> T) -> Response {
- let route = path.convertToPathComponents().map { $0.string }.joined(separator: "/")
+ let route = path.map { $0.string }.joined(separator: "/")
do {
let data = try closure(request)
if let d = data as? Data {
- return HTTPResponse(status: .ok, body: d)
+ return Response(status: .ok, body: .init(data: d))
} else {
- return HTTPResponse(status: .ok)
+ return Response(status: .ok)
}
} catch let error as CapError {
log("\(route): Error \(error)")
- return HTTPResponse(status: error.response)
+ return Response(status: error.response)
} catch {
log("\(route): Unhandled error: \(error)")
- return HTTPResponse(status: .internalServerError)
+ return Response(status: .internalServerError)
}
}
diff --git a/Sources/App/boot.swift b/Sources/App/boot.swift
deleted file mode 100755
index 382f98a..0000000
--- a/Sources/App/boot.swift
+++ /dev/null
@@ -1,9 +0,0 @@
-import Routing
-import Vapor
-
-/// Called after your application has initialized.
-///
-/// [Learn More →](https://docs.vapor.codes/3.0/getting-started/structure/#bootswift)
-public func boot(_ app: Application) throws {
- // your code here
-}
diff --git a/Sources/App/configure.swift b/Sources/App/configure.swift
index 264849b..6db8263 100755
--- a/Sources/App/configure.swift
+++ b/Sources/App/configure.swift
@@ -1,17 +1,10 @@
import Vapor
-/// Called before your application initializes.
-///
-/// [Learn More →](https://docs.vapor.codes/3.0/getting-started/structure/#configureswift)
-public func configure(
- _ config: inout Config,
- _ env: inout Environment,
- _ services: inout Services
-) throws {
+// configures your application
+public func configure(_ app: Application) throws {
+ // uncomment to serve files from /Public folder
+ // app.middleware.use(FileMiddleware(publicDirectory: app.directory.publicDirectory))
// Register routes to the router
- let router = EngineRouter.default()
- try routes(router)
- services.register(router, as: Router.self)
-
+ try routes(app)
// Configure the rest of your application here
}
diff --git a/Sources/App/routes.swift b/Sources/App/routes.swift
index 9282757..7227dc9 100755
--- a/Sources/App/routes.swift
+++ b/Sources/App/routes.swift
@@ -1,4 +1,3 @@
-import Routing
import Vapor
// MARK: Paths
@@ -56,14 +55,17 @@ private func count(of cap: Int) throws -> Int {
/// Register your application's routes here.
///
/// [Learn More →](https://docs.vapor.codes/3.0/getting-started/structure/#routesswift)
-public func routes(_ router: Router) throws {
+func routes(_ app: Application) throws {
try Log.set(logFile: logFile)
try loadCapNames()
// Get the name of a cap
- router.getCatching("name", Int.parameter) { request -> Data in
- let cap = try request.parameters.next(Int.self)
+ app.getCatching("name", ":n") { request -> Data in
+ guard let cap = request.parameters.get("n", as: Int.self) else {
+ log("Invalid body data")
+ throw Abort(.badRequest)
+ }
let index = cap - 1
guard index >= 0, index < caps.count else {
log("Trying to get name for invalid cap \(cap) (\(caps.count) caps loaded)")
@@ -73,10 +75,14 @@ public func routes(_ router: Router) throws {
}
// Set the name of a cap
- router.postCatching("name", Int.parameter) { request in
- let cap = try request.parameters.next(Int.self)
+ app.postCatching("name", ":n") { request in
+ guard let cap = request.parameters.get("n", as: Int.self) else {
+ log("Invalid parameter for cap")
+ throw Abort(.badRequest)
+ }
let index = cap - 1
- guard let data = request.http.body.data, let name = String(data: data, encoding: .utf8) else {
+ guard let buffer = request.body.data, let name = String(data: Data(buffer: buffer), encoding: .utf8) else {
+ log("Invalid body data")
throw CapError.invalidBody
}
guard index <= caps.count else {
@@ -101,11 +107,16 @@ public func routes(_ router: Router) throws {
}
// Upload an image
- router.postCatching("images", Int.parameter) { request -> Data in
- let cap = try request.parameters.next(Int.self)
- guard let data = request.http.body.data else {
+ app.postCatching("images", "n") { request -> Data in
+ guard let cap = request.parameters.get("n", as: Int.self) else {
+ log("Invalid parameter for cap")
+ throw Abort(.badRequest)
+ }
+ guard let buffer = request.body.data else {
+ log("Invalid body data")
throw CapError.invalidBody
}
+ let data = Data(buffer: buffer)
let c = try count(of: cap)
let f = file(of: cap, version: c)
guard !fm.fileExists(atPath: f.path) else {
@@ -117,21 +128,30 @@ public func routes(_ router: Router) throws {
}
// Get count of a cap
- router.getCatching("count", Int.parameter) { request -> Data in
- let cap = try request.parameters.next(Int.self)
+ app.getCatching("count", ":c") { request -> Data in
+ guard let cap = request.parameters.get("c", as: Int.self) else {
+ log("Invalid parameter for cap")
+ throw Abort(.badRequest)
+ }
let c = try count(of: cap)
return "\(c)".data(using: .utf8)!
}
// Get the count of all caps
- router.getCatching("counts") { request -> Data in
- try (1...caps.count).map { UInt8(try count(of: $0)) }.convertToData()
+ app.getCatching("counts") { request -> Data in
+ Data(try (1...caps.count).map({ UInt8(try count(of: $0)) }))
}
// Set a different version as the main image
- router.getCatching("switch", Int.parameter, Int.parameter) { request in
- let cap = try request.parameters.next(Int.self)
- let version = try request.parameters.next(Int.self)
+ app.getCatching("switch", ":n", ":v") { request in
+ guard let cap = request.parameters.get("n", as: Int.self) else {
+ log("Invalid parameter for cap")
+ throw Abort(.badRequest)
+ }
+ guard let version = request.parameters.get("v", as: Int.self) else {
+ log("Invalid parameter for cap version")
+ throw Abort(.badRequest)
+ }
guard version > 0 else {
log("Not switching cap \(cap) to image \(version)")
return
diff --git a/Sources/Run/main.swift b/Sources/Run/main.swift
index e7416b7..373be5f 100755
--- a/Sources/Run/main.swift
+++ b/Sources/Run/main.swift
@@ -1,26 +1,9 @@
import App
-import Service
import Vapor
-import Foundation
-// The contents of main are wrapped in a do/catch block because any errors that get raised to the top level will crash Xcode
-do {
- var config = Config.default()
- var env = try Environment.detect()
- var services = Services.default()
-
- try App.configure(&config, &env, &services)
-
- let app = try Application(
- config: config,
- environment: env,
- services: services
- )
-
- try App.boot(app)
-
- try app.run()
-} catch {
- print(error)
- exit(1)
-}
+var env = try Environment.detect()
+try LoggingSystem.bootstrap(from: &env)
+let app = Application(env)
+defer { app.shutdown() }
+try configure(app)
+try app.run()