Cowboy 用户指南 (十一) - Static files

静态文件

Cowboy附带了一个可用于提供静态文件的处理程序。它是为了方便在开发过程中提供文件。

对于生产中的系统,考虑使用市场上可用的多种内容分发网络(CDN)中的一种,因为它们是提供文件服务的最佳解决方案。

静态处理程序可以为给定目录中的一个文件或所有文件提供服务。可以配置etag生成和mime类型。

提供一个文件

您可以使用静态处理程序为应用程序私有目录中的特定文件提供服务。这对于提供索引特别有用。例如,当客户端请求/ path时。配置的路径是相对于给定应用程序的私有目录的。

下面的规则将会提供一个文件static/index.html 。当path / 被访问时,从应用程序my_app的priv目录中获取html:

{"/", cowboy_static, {priv_file, my_app, "static/index.html"}}

你也可以指定一个文件的绝对路径,或者文件的路径相对于当前目录:

{"/", cowboy_static, {file, "/var/www/index.html"}}

从一个目录中提供所有文件

您还可以使用静态处理程序来提供可以在配置目录中找到的所有文件。处理程序将使用path_info信息来解析文件位置,这意味着你的路由必须以[…]模式,让它工作。提供所有文件,包括可能在子文件夹中找到的文件。

你可以指定相对于应用程序的私有目录的目录(例如my_app/priv)。

下面的规则将会提供任何在my_app应用程序私有目录下my_app/priv/static/assets文件夹下的文件,只要请求的路径以/assets/开头:

{"/assets/[...]", cowboy_static, {priv_dir, my_app, "static/assets"}}

你也可以指定目录的绝对路径,或者设置它相对于当前目录:

{"/assets/[...]", cowboy_static, {dir, "/var/www/assets"}}

自定义mimetype检测

MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的因特网标准。MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。包含有多种类型,可参考https://www.w3school.com.cn/media/media_mimeref.asp 下面类型用mimetype表示。

默认情况下,Cowboy会尝试通过查看扩展名来识别静态文件的mimetype。

您可以覆盖计算静态文件的mimetype的函数。当Cowboy缺少需要处理的mimetype时,或者当您希望减少列表以加快查找速度时,它会很有用。您还可以提供一个硬编码的mimetype,它将被无条件使用。

Cowboy有两个内置功能。默认函数只处理在构建Web应用程序时使用的常见文件类型。另一个函数是一个包含数百个mimetype的扩展列表,可以满足几乎所有的需求。当然,您可以创建自己的函数。

要使用默认函数,您不需要配置任何东西,因为它是默认的。不过,如果你坚持的话,下面的方法就可以了:

{"/assets/[...]", cowboy_static, {priv_dir, my_app, "static/assets",
    [{mimetypes, cow_mimetypes, web}]}}

如您所见,有一个可选字段,它可能包含一个较少使用的选项列表,如mimetypes或etag。所有的选项类型都有这个可选字段。

要使用这个函数来检测几乎所有的mimetype,可以使用以下配置:

{"/assets/[...]", cowboy_static, {priv_dir, my_app, "static/assets",
    [{mimetypes, cow_mimetypes, all}]}}

你现在可能已经注意到了这个模式。该配置需要一个模块和一个函数名,所以你可以使用你自己的任何函数来代替:

{"/assets/[...]", cowboy_static, {priv_dir, my_app, "static/assets",
    [{mimetypes, Module, Function}]}}

执行mimetype检测的函数接收一个参数,该参数是磁盘上文件的路径。建议以元组形式返回mimetype,但也允许使用二进制字符串(但需要额外处理)。如果函数不能计算出mimetype,那么它应该返回{<<"application">>, <<"octet-stream">>,[]}。

当静态处理程序无法找到扩展名时,它将以application/octet-stream的形式发送文件。接收到该文件的浏览器将尝试将其直接下载到磁盘。

最后,可以为所有文件硬编码mimetype。这在结合file和priv_file选项时特别有用,因为它可以避免不必要的计算:

{"/", cowboy_static, {priv_file, my_app, "static/index.html",
    [{mimetypes, {<<"text">>, <<"html">>, []}}]}}

生成一个 etag

什么是ETag?参考https://www.cnblogs.com/happy4java/p/11206015.html

Etag是 Entity tag的缩写,可以理解为“被请求变量的实体值”,Etag是服务端的一个资源的标识,在 HTTP 响应头中将其传送到客户端。所谓的服务端资源可以是一个Web页面,也可以是JSON或XML等。服务器单独负责判断记号是什么及其含义,并在HTTP响应头中将其传送到客户端。比如,浏览器第一次请求一个资源的时候,服务端给予返回,并且返回了ETag: "50b1c1d4f775c61:df3" 这样的字样给浏览器,当浏览器再次请求这个资源的时候,浏览器会将If-None-Match: W/"50b1c1d4f775c61:df3" 传输给服务端,服务端拿到该ETAG,对比资源是否发生变化,如果资源未发生改变,则返回304HTTP状态码,不返回具体的资源。

默认情况下,静态处理程序将根据大小和修改时间生成一个etag头值。但是,这种解决方案并不能适用于所有的系统。例如,在一个节点集群上,它的性能会很差,因为文件元数据会因服务器而异,在每个服务器上给出不同的etag。

不过,你可以改变etag的计算方式:

{"/assets/[...]", cowboy_static, {priv_dir, my_app, "static/assets",
    [{etag, Module, Function}]}}

这个函数将接收三个参数:磁盘上文件的路径、文件的大小和最后一次修改时间。在分布式设置中,您通常会使用文件路径来检索所有服务器上相同的etag值。

你也可以完全禁用etag处理:

{"/assets/[...]", cowboy_static, {priv_dir, my_app, "static/assets",
    [{etag, false}]}}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值