69 lines
2.3 KiB
Swift
69 lines
2.3 KiB
Swift
import Vapor
|
|
|
|
struct TryFilesMiddleware: AsyncMiddleware {
|
|
|
|
let publicDirectory: String
|
|
|
|
func respond(to request: Request, chainingTo next: any AsyncResponder) async throws -> Response {
|
|
let relativePath = request.url.path
|
|
let potentialPaths = [
|
|
publicDirectory + relativePath,
|
|
publicDirectory + relativePath + ".html",
|
|
publicDirectory + relativePath + "/1.html"
|
|
]
|
|
|
|
for path in potentialPaths {
|
|
var isDirectory: ObjCBool = false
|
|
guard FileManager.default.fileExists(atPath: path, isDirectory: &isDirectory),
|
|
!isDirectory.boolValue else {
|
|
continue
|
|
}
|
|
let url = URL(fileURLWithPath: path)
|
|
let data = try Data(contentsOf: url)
|
|
let response = Response(status: .ok, body: .init(data: data))
|
|
response.headers.replaceOrAdd(name: .contentType, value: url.mimeType)
|
|
response.headers.replaceOrAdd(name: .contentLength, value: "\(data.count)")
|
|
return response
|
|
}
|
|
return .init(status: .notFound)
|
|
}
|
|
}
|
|
|
|
private extension URL {
|
|
|
|
var mimeType: String {
|
|
switch pathExtension.lowercased() {
|
|
case "html": return "text/html"
|
|
case "css": return "text/css"
|
|
case "js": return "application/javascript"
|
|
case "json": return "application/json"
|
|
case "xml": return "application/xml"
|
|
case "txt": return "text/plain"
|
|
|
|
case "jpg", "jpeg": return "image/jpeg"
|
|
case "png": return "image/png"
|
|
case "gif": return "image/gif"
|
|
case "svg": return "image/svg+xml"
|
|
case "webp": return "image/webp"
|
|
case "ico": return "image/x-icon"
|
|
|
|
case "pdf": return "application/pdf"
|
|
case "zip": return "application/zip"
|
|
case "tar": return "application/x-tar"
|
|
case "gz": return "application/gzip"
|
|
case "rar": return "application/vnd.rar"
|
|
|
|
case "mp3": return "audio/mpeg"
|
|
case "wav": return "audio/wav"
|
|
case "ogg": return "audio/ogg"
|
|
|
|
case "mp4": return "video/mp4"
|
|
case "mov": return "video/quicktime"
|
|
case "avi": return "video/x-msvideo"
|
|
case "webm": return "video/webm"
|
|
|
|
default: return "application/octet-stream" // Default binary data type
|
|
}
|
|
}
|
|
}
|