新浪SAE如何处理泛域名的问题

阅读更多

 

新浪SAE 如何处理泛域名的问题

今天看到论坛社区总有人问这个问题,特意整理了一下。

针对 qmei.sinaapp.com以及qlove.sinaapp.com这个例子,如何做到点击链接后,跳转到其他网站。

如图

 

 

 

 

 

 

 

 

 

 

 

这样子就可以实现这个功能了。

另附录上 config.yaml文件常见配置

 

使用指南

 设置

    例子:

    name: saetest

    version: 1 

    编辑saetest/1/config.yaml ,增加 handle 段,如:

    name: saetest

    version: 1

    handle:

    - rewrite: if(!is_dir() && !is_file()) goto "index.php?%{QUERY_STRING}" 

    编辑完成后,通过 SVN代码部署 工具提交即可生效。或者你也可以通过 在线代码编辑器 修改config.yaml

    如果通过SVN 部署,只需要在默认版本所在目录下,如,您的应用名为 devapp ,默认版本是 3 ,那么请在 devapp/3/ 下创建 config.yaml 文件,按下以下语法编写,然后通过 svn commit 部署完成即可生效。

 语法说明

     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 有如下形式:

    1) in_header["header_name"] op string_or_digit

    2) out_header["header_name"] op string_or_digit

    3) path op string

    4) query_string op string

    5) is_file()

    6) is_dir()

    关于以上形式说明如下:

    1) in_header 是请求头, out_header  是响应头, header_name  是  header  的名字,具体的请求头和响应头参考 RFC 官方文档

    2) op 是操作符,有  ~ (正则匹配)  !~ (正则不匹配)  == (相等,用于字符串和数字)  != (不相等,用于字符串和数字)  >, >=, <, <= (比较操作符仅用于整形数字)

    3) string 是形如  "xxxx"  的字符串

    4) string_or_digit 表示  string  或者  digit ,根据  op  的种类,后面跟  string  或者  digit

    5) path 是系统宏,表示用户请求的  url  去掉主机部分和查询串后剩下的部分

    6) query_string 是系统宏,表示查询串,一般是 url 中问号后面的内容

    7) 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"] >= 10240) 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

    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"

 

    在 expire  和  mime  中  single_express  表示单一的表达式,不能用  &&  复合, in_header path  都可以出现在  single_express  中,并且  op  只能是  或者  == ,即只支持正则匹配和字符串比较。

 

   基于主机的访问控制

    禁止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" 允许 10 打头的所有 IP 

 

 

    对于屏蔽一组IP 地址,可以写成子网掩码形式,或者将多个 IP 之间加以空格。子网掩码形式如下:

    - hostaccess: if(path ~ "/cron/") deny "108.192.8.0/24" 屏蔽 108.192.8 打头的所有 IP 

    多个IP 形式如下:

    - hostaccess: allow "108.134.13.24 108.122.122.13" 允许 108.134.13.24 108.122.122.13 这两个 IP

    或:

    - hostaccess: allow "108.134.13.24","108.122.122.13"

 

 

    (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"

 

 

    在 hostaccess  和  passwdaccess  中  single_express  表示单一的表达式,不能用  &&  复合, in_header path  都可以出现在 single_express  中,并且  op  只能是  或者  == ,即只支持正则匹配和字符串比较,并且  if  语句可以省略,表示无条件执行访问控制

 

备注和说明

    更多例子:

 目录默认页面

    当访问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 

 压缩

    当页面内容大于 10K 字节时压缩

    - compress: if(out_header["Content-Length"] >= 10240) 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  是题中之意。

    压缩配置注意事项

    通常情况,我们根据响应头Content-length ,判断是否需要压缩,例如: if(out_header["Content-Length"]>=10240) compress, 这个静态页面,如 js,css,html 都是没有问题的。

    但是对php 脚本,响应 header 中,没有 Content-length 这个头,它使用 Transfer-Encoding: chunked ,这个头表示页面输出用 chunked 编码。此时要实现压缩,可以通过配置 appconfig ,同时在php 脚本中输出相应头的方式实现。

    例如在 appconfig 中写 if(out_header["Use-Compress"] == "1") compress ,在需要压缩的 php 脚本中写

    压缩生效检查

    检查是不是输出了响应头:Content-Encoding: gzip

    IE下的 HttpWatch FireFox 下的 Firebug 都可以查看页面的响应 header

 页面重定向

    当 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 

 

FAQ

    1. 如果有形如  path ~ "^(.*)$"  类的请求,一定要加上  is_file  或  is_dir  之类的判断,防止无穷的 rewrite 。 

    2. path 是用户请求的资源路径,比如请求  http://qlove.sinaapp.com/b/index.php?a=4 ,那么 path 就是  /b/index.php 。 

    3.  goto 语句中,虽然某些时候可以不以 / 开头,但是强烈建议以 / 开头。 

    生效检查

    检查是不是输出了响应头:Cache-Control IE 下的 HttpWatch FireFox 下的 Firebug 都可以查看页面的响应 header

你可能感兴趣的:(SAE)