sae没有htaccess功能,所以采用了AppConfig
服务概要
AppConfig服务是SAE为开发者提供的对web服务器进行自定义配置的功能,使用AppConfig,开发者可以很方便的实现以下功能:
- 目录默认页面
- 自定义错误页面
- 压缩
- 页面重定向
- 页面过期
- 设置响应头的content-type
- 设置页面访问权限
从上面的说明可以看出,AppConfig可以完全代替htaccess的常见功能,其实AppConfig正是SAE为了替代传统apache htaccess而实现的功能,原因有两点:
- 传统htaccess效率不高,因为其针对所有目录进行递归merge
- 传统htaccess过于复杂,学习成本高。AppConfig具有效率高而且学习成本低的特点,AppConfig只在App访问时针对根目录生成一次规则,而且AppConfig采用类自然语言的规则描述,开发者只需要参考几个简单的例子即可熟悉使用
使用指南
设置
例子:
appname: saetest
version: 1
编辑saetest/1/config.yaml,增加handle段,如:
name: saetest
version: 1
handle:
- rewrite: if(!is_dir() && !is_file()) goto “index.php?%{QUERY_STRING}”
语法说明
AppConfig的语法分两种,一种是简单的参数罗列方式,一种是灵活的表达式语法,不同的功能会用到不同的类型的语法。
参数方式
目录默认页面
- directoryindex: file_list
file_list 中各个文件名以空格分隔,directoryindex在 yaml 文件中仅有一项
例子:
- directoryindex: aaa.php bbb.html
自定义错误页面
- errordoc: httpcode error_file
httpcode 是诸如404、302之类的http响应码,error_file是服务器以 httpcode响应请求时响应的文件。errordoc在yaml中可以配置多项。
- errordoc: 404 /path/404.html
- errordoc: 403 /path/403.html
表达式语法
其他功能需要用到表达式语法,其形式为:
if (expression) do_something
expression 有如下形式
in_header["header_name"] op string_or_digit
out_header["header_name"] op string_or_digit
path op string
query_string op string
is_file()
is_dir()
关于以上形式说明如下:
in_header 是请求 header,out_header 是响应 header,header_name 是 header 的名字
op 是操作符,有 ~(正则匹配) !~(正则不匹配) ==(相等,用于字符串和数字) !=(不相等,用于字符串和数字) > >= < <=(比较操作符仅用于整形数字) string 是形如 “xxxx” 的字符串 string_or_digit 表示 string 或者 digit,根据 op 的种类,后面跟 string 或者 digit path 是系统宏,表示用户请求的 url 去掉主机部分和查询串后剩下的部分 query_string 是系统宏,表示查询串 is_file() 和 is_dir 是系统函数,判断 path 是文件还是目录,!is_file(),!is_dir() 分别是其否定形式。 表达式语法用于以下功能:
压缩
- compress: if (single_express) compress 在 compress 中 single_express 表示单一的表达式,不能用 && 做复合,in_header,out_header,path 都可以出现在 single_express 中 例如: – compress: if(out_header["Content-Length"] >= 500) compress
- compress: if(in_header["Referer"] == “gphone”) compress
- compress: if(path ~ “/big/”) compress
URL重写
- rewrite: if (complex_express) goto target_url
在 rewrite 中,complex_express 可以用 && 连接,组成复合表达式。除 out_header (没办法根据响应 header 做重定向) 外都可以出现在 rewrite 的 if 中,并且 path 只能出现一个(如果有多个,只有最后一个生效,其它被忽略),当省略 path 时,表示任意请求。
target_url 表示重定向的目标url,在target_url 可以以 $N 的形式表示 path 中匹配到的内容,%N 的形式表示最后一个query_string 中匹配到的内容,因为query_string 可以在 if 中出现多次,以%{QUERY_STRING} 表示查询串。
例如:
- rewrite: if(query_string ~ “^(so)$” && path ~ “zhaochou$”) goto “/url/%1″
- rewrite: if(is_dir( ) && path ~ “urldir/(.*)”) goto “/url/$1″
- rewrite: if( !is_file() && !is_dir()) goto “index.php?%{QUERY_STRING}”
指定过期时间和头信息
- expire: if (single_express) time seconds
- mime: if (single_express) type content-type
在 expire 和 mime 中 single_express 表示单一的表达式,不能用 && 复合,in_header,path 都可以出现在 single_express 中,并且 op 只能是 ~ 或者 ==,即只支持正则匹配和字符串比较
seconds 是秒数,content-type 是表示文档类型的字符串。
例如:
- expire: if(in_header["referer"] ~ “sina”) time 10
- mime: if(path ~ “\.pdf2$”) type “application/pdf”
设置响应 header Content-Type
如果 url 请求文件的扩展名是 pdf2,设置 Content-Type 为 application/pdf
- mime: if(path ~ “\.pdf2$”) type “application/pdf”
只要请求 header referer 包含字符串 sina,就设置 Content-Type 为 text/plain
- mime: if(in_header["referer"] ~ “sina”) type “text/plain”
基于主机的访问控制
禁止127.0.0.1 访问private目录
- hostaccess: if(path ~ “/private/”) deny “127.0.0.1″
只允许127.0.0.1 访问.conf结尾的文件
- hostaccess: if(path ~ “\.conf$”) allow “127.0.0.1″
禁止127.0.0.1 的所有访问(这个要慎用)
- hostaccess: deny “127.0.0.1″
对cron任务保护,防止被外部抓取,我们将cron任务放在cron目录下(sae中cron服务执行时,走的是内部网络)
- hostaccess: if(path ~ “/cron/”) allow “10.0.0.0/8″
(ip地址需要加引号,all代表所有IP地址,具体可以参考apache配置.allow是白名单方式,deny是黑名单)
简单的认证
访问secret目录需要密码,允许用户test用密码123qwe访问,用户coder用密码123asd访问
- passwdaccess: if(path ~ “/secret/”) passwd “test:123qwe coder:123asd”
访问.text结尾的文件需要密码,允许用户writer用密码123zxc
- passwdaccess: if(path ~ “\.text$”) passwd “writer:123zxc”
所有访问都要密码,允许用户writer用密码123zxc访问
- passwdaccess: passwd “write:123zxc”
用户的网站后台程序都放在admin目录下,需要对admin目录做密码保护
- passwdaccess: if(path ~ “/admin/”) passwd “admin:admin123″
备注和说明
更多例子:
目录默认页面
当访问url没有指定文件时,返回aaa.php,如果其不存在,则返回bbb.html
- directoryindex: aaa.php bbb.html
自定义错误页面
遇到 404 错误,返回 /path/404.html 文件。遇到 403 错误,返回 /path/404.html 文件
- errordoc: 404 /path/404.html
- errordoc: 403 /path/403.html
压缩
当页面内容大于 500 byte 时压缩
- compress: if(out_header["Content-Length"] >= 500) compress
当请求 header Content-Type 中包含 text 时压缩
- compress: if(out_header["Content-Type"] ~ “text”) compress
当响应 header Referer 等于 gphone 时压缩
- compress: if(in_header["Referer"] == “gphone”) compress
当请求的 url 包含“/big/” 时压缩
- compress: if(path ~ “/big/”) compress
注:对所有的压缩,请求 header Accept-Encoding 包含 gzip,deflate 是题中之意。
页面重定向
当 url 匹配 urldir/(.*) ,并且 输入 header referer 等于 sina 时,跳转至页面 /usr/$1,$1 表示刚刚匹配的 urldir/(.*) 中的 (.*) 部分。
- rewrite: if (path ~ “urldir/(.*)” && in_header["referer"] == “sina”) goto “/url/$1″
当 url 匹配 urldir/(.*),并且请求的是一个目录时,跳转至 /url/$1
- rewrite: if(is_dir( ) && path ~ “urldir/(.*)”) goto “/url/$1″
当 url 匹配 path,并且请求的不是一个文件时,跳转至 /url/query.php
- rewrite: if(! is_file() && path ~ “path”) goto “/url/query.php”
当查询串等于so,并且 url 以 zhaochou 结尾时,跳转至 /url/%1,%1 表示 query_string 匹配到的部分。
- rewrite: if(query_string ~ “^(so)$” && path ~ “zhaochou$”) goto “/url/%1″
当查询串不包含sohu,并且 url 以 zhaochou 结尾时,跳转至 /url/query.php?%{QUERY_STRING},%{QUERY_STRING} 表示查询串。
- rewrite: if(query_string !~ “sohu” && path ~ “zhaochou$”) goto “/url/query.php?${QUERY_STRING}”
如果 url 既不是文件,也不是目录,跳转至 index.php?%{QUERY_STRING}
- rewrite: if( !is_file() && !is_dir()) goto “index.php?%{QUERY_STRING}”
设置响应头的mime类型
如果 url 请求文件的扩展名是 pdf2,设置 Content-Type 为 application/pdf
- mime: if(path ~ “\.pdf2$”) type “application/pdf”
只要请求 header referer 包含字符串 sina,就设置 Content-Type 为 text/plain
- mime: if(in_header["referer"] ~ “sina”) type “text/plain”
页面过期
如果请求 header Referer 包含 字符串sina,设置过期时间10s
- expire: if(in_header["referer"] ~ “sina”) time 10
如果 url 以 lib\.js 结尾,设置过期时间100s
- expire: if(path ~ “lib\.js$”) time 100
第三方工具
第三方开发的生成AppConfig的小工具 http://saetools.sinaapp.com/appconfig.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述