Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 41 additions & 41 deletions Sources/App/Middlewares/CommonErrorMiddleware.swift
Original file line number Diff line number Diff line change
@@ -1,49 +1,49 @@
import Vapor

final class CommonErrorMiddleware: Middleware {
func respond(to request: Request, chainingTo next: Responder) -> EventLoopFuture<Response> {
return next.respond(to: request).flatMapError { (error) in
let headers: HTTPHeaders
let status: HTTPResponseStatus
switch error {
case let abort as AbortError:
headers = abort.headers
status = abort.status
default:
headers = [:]
status = .internalServerError
}
func respond(to request: Request, chainingTo next: Responder) -> EventLoopFuture<Response> {
return next.respond(to: request).flatMapError { (error) in
let headers: HTTPHeaders
let status: HTTPResponseStatus
switch error {
case let abort as AbortError:
headers = abort.headers
status = abort.status
default:
headers = [:]
status = .internalServerError
}

let errotTitles: [UInt: String] = [
400: "Bad Request",
401: "Unauthorized",
403: "Access Denied",
404: "Resource not found",
500: "Webservice currently unavailable",
503: "Webservice currently unavailable",
]
let errotTitles: [UInt: String] = [
400: "Bad Request",
401: "Unauthorized",
403: "Access Denied",
404: "Resource not found",
500: "Webservice currently unavailable",
503: "Webservice currently unavailable",
]

let errotReasons: [UInt: String] = [
400: "The server cannot process the request due to something that is perceived to be a client error.",
401: "The requested resource requires an authentication.",
403: "The requested resource requires an authentication.",
404: "The requested resource could not be found but may be available again in the future.",
500: "An unexpected condition was encountered. Our service team has been dispatched to bring it back online.",
503: "We&#39;ve got some trouble with our backend upstream cluster. Our service team has been dispatched to bring it back online.",
]
let errotReasons: [UInt: String] = [
400: "The server cannot process the request due to something that is perceived to be a client error.",
401: "The requested resource requires an authentication.",
403: "The requested resource requires an authentication.",
404: "The requested resource could not be found but may be available again in the future.",
500: "An unexpected condition was encountered. Our service team has been dispatched to bring it back online.",
503: "We&#39;ve got some trouble with our backend upstream cluster. Our service team has been dispatched to bring it back online.",
]

if request.headers[.accept].map({ $0.lowercased() }).contains("application/json") {
return request.eventLoop.makeSucceededFuture(["error": status.code])
.encodeResponse(status: status, headers: headers, for: request)
} else {
return request.view.render("error", [
"title": "We've got some trouble",
"error": errotTitles[status.code],
"reason": errotReasons[status.code],
"status": "\(status.code)",
])
.encodeResponse(status: status, headers: headers, for: request)
}
}
if request.headers[.accept].map({ $0.lowercased() }).contains("application/json") {
return request.eventLoop.makeSucceededFuture(["error": status.code])
.encodeResponse(status: status, headers: headers, for: request)
} else {
return request.view.render("error", [
"title": "We've got some trouble",
"error": errotTitles[status.code],
"reason": errotReasons[status.code],
"status": "\(status.code)",
])
.encodeResponse(status: status, headers: headers, for: request)
}
}
}
}
12 changes: 6 additions & 6 deletions Sources/App/Middlewares/CustomHeaderMiddleware.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import Vapor

final class CustomHeaderMiddleware: Middleware {
func respond(to request: Request, chainingTo next: Responder) -> EventLoopFuture<Response> {
return next.respond(to: request).map { (response) in
response.headers.add(name: "X-Frame-Options", value: "DENY")
response.headers.add(name: "Permissions-Policy", value: "interest-cohort=()")
return response
}
func respond(to request: Request, chainingTo next: Responder) -> EventLoopFuture<Response> {
return next.respond(to: request).map { (response) in
response.headers.add(name: "X-Frame-Options", value: "DENY")
response.headers.add(name: "Permissions-Policy", value: "interest-cohort=()")
return response
}
}
}
6 changes: 3 additions & 3 deletions Sources/App/Models/ResultResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Foundation
import Vapor

struct ResultResponse: Content {
let method: RequestMethod
let result: String
let error: String
let method: RequestMethod
let result: String
let error: String
}
32 changes: 16 additions & 16 deletions Sources/App/configure.swift
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import Vapor
import Leaf

public func configure(_ app: Application) throws {
app.middleware = Middlewares()
app.middleware.use(CommonErrorMiddleware())
app.middleware.use(CustomHeaderMiddleware())
public func configure(_ app: Application) async throws {
app.middleware = Middlewares()
app.middleware.use(CommonErrorMiddleware())
app.middleware.use(CustomHeaderMiddleware())

let publicDirectory = "\(app.directory.publicDirectory)/dist"
app.middleware.use(FileMiddleware(publicDirectory: publicDirectory))

app.http.server.configuration.port = Environment.process.PORT.flatMap { Int($0) } ?? 8080
app.http.server.configuration.requestDecompression = .enabled
app.http.server.configuration.responseCompression = .enabled
app.http.server.configuration.supportPipelining = true
let publicDirectory = "\(app.directory.publicDirectory)/dist"
app.middleware.use(FileMiddleware(publicDirectory: publicDirectory))

app.views.use(.leaf)
app.leaf.configuration.rootDirectory = publicDirectory
app.leaf.cache.isEnabled = app.environment.isRelease

try routes(app)
app.http.server.configuration.port = Environment.process.PORT.flatMap { Int($0) } ?? 8080
app.http.server.configuration.requestDecompression = .enabled
app.http.server.configuration.responseCompression = .enabled
app.http.server.configuration.supportPipelining = true

app.views.use(.leaf)
app.leaf.configuration.rootDirectory = publicDirectory
app.leaf.cache.isEnabled = app.environment.isRelease

try routes(app)
}
34 changes: 10 additions & 24 deletions Sources/App/entrypoint.swift
Original file line number Diff line number Diff line change
@@ -1,35 +1,21 @@
import Vapor
import Dispatch
import Logging

/// This extension is temporary and can be removed once Vapor gets this support.
private extension Vapor.Application {
static let baseExecutionQueue = DispatchQueue(label: "vapor.codes.entrypoint")

func runFromAsyncMainEntrypoint() async throws {
try await withCheckedThrowingContinuation { continuation in
Vapor.Application.baseExecutionQueue.async { [self] in
do {
try self.run()
continuation.resume()
} catch {
continuation.resume(throwing: error)
}
}
}
}
}

@main
enum Entrypoint {
static func main() async throws {
var env = try Environment.detect()
try LoggingSystem.bootstrap(from: &env)

let app = Application(env)
defer { app.shutdown() }
let app = try await Application.make(env)

try await configure(app)
try await app.runFromAsyncMainEntrypoint()
do {
try await configure(app)
try await app.execute()
} catch {
app.logger.report(error: error)
try? await app.asyncShutdown()
throw error
}
try await app.asyncShutdown()
}
}
Loading