swift - 如何为具有给定前缀的 URL 提供文件?
问题描述
语境
我一直通过 Vapor (v4) 成功地提供文件:
func configure(_ app: Application) throws {
// ...
app.middleware.use(FileMiddleware(publicDirectory: app.directory.publicDirectory))
// ...
}
问题
- 这会尝试映射任何/每个与 publicDirectory 中的文件匹配的 URL。
- 如何将“范围”限制
FileMiddleware
为仅请求其 URL 具有特定前缀的请求?(说/files/
)
就像,如果我有,一个人会通过while/Public/foobar.txt
请求它,但不会匹配任何东西。GET /files/foobar.txt
GET /foobar.txt
考虑的方法
- 我的理解是在
Middleware
服务器范围内应用(影响每个“路由”)而不是子集......所以这不起作用。 - 移动
/Public/foobar.txt
到/Public/files/foobar.txt
不是解决方案,因为我试图限制可能映射到文件系统的 URL... - 重定向
GET /files/foobar.txt
到GET /foobar.txt
也是不可接受的。同样,我需要限制映射到文件系统的潜在 URL。
解决方案
似乎它FileMiddleware
只能在全局范围内工作,而不是像中间件实例通常那样附加到路由组。
如果您在项目文件夹中有一个名为 Private 的文件夹(即保存您的 Public 文件夹的同一文件夹),那么访问其中包含的文件很简单:
public func configure(_ app: Application) throws {
app.get("files", "**") { req -> Response in
let filepath = req.parameters.getCatchall()
let workPath = DirectoryConfiguration.detect().workingDirectory
var fileURL = URL(fileURLWithPath: workPath)
.appendingPathComponent("Private", isDirectory: true)
.appendingPathComponent(filepath.joined(separator: "/"), isDirectory: false)
return req.fileio.streamFile(at: fileURL.path)
}
}
假设您正在运行这个最小的项目localhost:8080
,它将通过 URL 提供文件:
http://localhost:8080/files/path/to/myFile.txt
编辑
OP 仅表示平面文件。根据评论,使其适用于Private/
. 如果文件/路径不存在,我会让您添加操作。
推荐阅读
- python - 轻微挑战。需要优化代码。原版太长了:(
- f# - 在 F# 中使用显式数据类型创建新运算符
- php - 来自 4 个表的 Laravel 查询
- html - HTML div 多余的空格
- c# - Stream Reader 无法正确读取标点符号
- assembly - Division and modulo on unsigned integers with 6 registers
- r - 将相同的值分散到多个列中
- .net - 如何解决 enitiy framwork 的错误包括
- scala - 使用作为类对象的属性实现 scala 特征
- java - checkmarx - 如何解决存储的绝对路径遍历问题?