AppConfig服務是SAE為開發者提供的對web伺服器進行自定義配置的功能。
基本介紹
- 中文名:AppConfig
- 類型:服務功能
- 功能:目錄默認頁面
- 提供者:SAE
服務概要,PHP使用指南,參數方式,自定義錯誤頁面,壓縮,URL重寫,訪問控制,簡單的認證,備註和說明,壓縮,壓縮生效檢查,頁面重定向,頁面過期,FAQ,配置工具,
服務概要
使用AppConfig,開發者可以很方便的實現以下功能:
目錄默認頁面
自定義錯誤頁面
壓縮
頁面重定向
頁面過期
設定回響頭的content-type
設定頁面訪問許可權
從上面的說明可以看出,AppConfig可以完全代替htaccess的常見功能,其實AppConfig正是SAE為了替代傳統apache htaccess而實現的功能,原因有兩點:
1、傳統htaccess效率不高,因為其針對所有目錄進行遞歸merge
2、傳統htaccess過於複雜,學習成本高。AppConfig具有效率高而且學習成本低的特點,AppConfig只在App訪問時針對根目錄生成一次規則,而且AppConfig採用類自然語言的規則描述,開發者幾棵籃判只需要參考幾個簡單的例子即可熟悉使用。
PHP使用指南
例子:
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
- mme: 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://localhost/b/index.php?a=4,那么path就是 /b/index.php。
3、在goto語句中,雖然某些時候可以不以/開頭,但是強烈建議以/開頭。 生效檢查
檢查是不是輸出了回響頭:Cache-Control。IE下的HttpWatch和FireFox下的Firebug都可以查看頁面的回響header。
配置工具
SAE已支持在套用管理平台對AppConfig進行配置.
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
- mme: 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://localhost/b/index.php?a=4,那么path就是 /b/index.php。
3、在goto語句中,雖然某些時候可以不以/開頭,但是強烈建議以/開頭。 生效檢查
檢查是不是輸出了回響頭:Cache-Control。IE下的HttpWatch和FireFox下的Firebug都可以查看頁面的回響header。
配置工具
SAE已支持在套用管理平台對AppConfig進行配置.