檢視原始碼 httpd 行為 (inets v9.3.1)
HTTP 伺服器 API
一個符合 RFC 2616 定義的 HTTP 1.1 相容網頁伺服器實作。提供網頁伺服器啟動選項、管理功能和 Erlang 回呼 API。
資料類型
在此模組中多次使用的類型定義
boolean() = true | false
string/0
= ASCII 字元列表
path() = string()
代表檔案或目錄路徑
ip_address() = {N1,N2,N3,N4} % IPv4 | {K1,K2,K3,K4,K5,K6,K7,K8} % IPv6
hostname() = string()
代表主機,例如 "foo.bar.com"
property() = atom()
HTTP 伺服器服務啟動 & 停止
可以設定網頁伺服器在啟動 Inets
應用程式時啟動,或者在執行階段透過呼叫 Inets
應用程式 API inets:start(httpd, ServiceConfig)
或 inets:start(httpd, ServiceConfig, How)
動態啟動,請參閱 inets
。組態選項(也稱為屬性)如下:
檔案屬性
當網頁伺服器在應用程式啟動時啟動時,這些屬性將從組態檔中擷取,該檔案可以包含常規的 Erlang 屬性列表,即 [{Option, Value}]
,其中 Option = property()
和 Value = term()
,並以句點結尾。如果網頁伺服器在執行階段動態啟動,仍然可以指定檔案,但也可以指定完整的屬性列表。
注意
注意:在 OTP-23 中,已刪除對具有 Apache 語法的舊版組態檔的支援。
強制屬性
{port, integer()}
HTTP 伺服器監聽的連接埠。如果將連接埠指定為零,則會選取任意可用的連接埠,並且可以使用函式httpd:info/2
來確定選取了哪個連接埠。{server_root, path()}
定義伺服器的主目錄,可以在其中儲存記錄檔等等。其他屬性中指定的相對路徑會參考此目錄。
通訊屬性
{server_name, string()}
伺服器的名稱,通常是完整合格的網域名稱。如果未提供,則預設為
net_adm:localhost()
。{profile, atom()}
與bind_address
和port
一起使用,以唯一識別 HTTP 伺服器。這在虛擬化環境中非常有用,在這種環境中,可能有多個伺服器具有相同的 bind_address 和連接埠。如果未明確設定此屬性,則會假設bind_address
和port
唯一識別 HTTP 伺服器。{socket_type, ip_comm | {ip_comm, Config::proplist()} | {ssl, Config::proplist()}}
有關ip_comm
組態選項,請參閱gen_tcp:listen/2
,某些 httpd 內部使用的選項無法設定。有關
SSL
組態選項,請參閱ssl:listen/2
。預設值為
ip_comm
。注意
OTP-25 棄用了通訊屬性
{socket_type, ip_comm | {ip_comm, Config::proplist()} | {essl, Config::proplist()}}
,並將其替換為{socket_type, ip_comm | {ip_comm, Config::proplist()} | {ssl, Config::proplist()}}
。{ipfamily, inet | inet6}
預設值為inet
,舊版選項inet6fb4
不再有意義,將轉換為 inet。{minimum_bytes_per_second, integer()}
如果給定,則為連線設定每秒位元組數的最小值。如果未達到該值,則該連線的通訊端將關閉。
此選項有助於降低「慢速 DoS」攻擊的風險。
Erlang 網頁伺服器 API 模組
-
{modules, [atom()]}
定義 HTTP 伺服器在處理請求時使用的模組。預設值為[mod_alias, mod_auth, mod_esi, mod_actions, mod_cgi, mod_dir, mod_get, mod_head, mod_log, mod_disk_log]
。請注意,某些mod
模組依賴於其他模組,因此順序不能完全任意。有關詳細資訊,請參閱《使用者指南》中的 Inets 網頁伺服器模組。
限制屬性
{customize, atom()}
用於自訂 inets HTTP 伺服器行為的回呼模組,請參閱httpd_custom_api
{disable_chunked_transfer_encoding_send, boolean()}
允許您在將回應傳送到 HTTP/1.1 用戶端時停用區塊式傳輸編碼。預設值為false
。{keep_alive, boolean()}
指示伺服器在用戶端聲稱符合 HTTP/1.1 時是否使用持續性連線。預設值為true
。{keep_alive_timeout, integer()}
伺服器在關閉連線之前等待用戶端後續請求的秒數。預設值為150
。{max_content_length, integer()}
傳入請求中的最大內容長度(以位元組為單位)。內容大於此值的請求會以狀態 413 回應。預設值為100000000
(100 MB)。{max_keep_alive_request, integer()}
用戶端可以在一個連線上執行的請求數。當伺服器已回應由max_keep_alive_requests
定義的請求數時,伺服器會關閉連線。即使有排隊的請求,伺服器也會關閉連線。預設值為無限制。{max_client_body_chunk, integer()}
強制將 HTTP PUT 或 POST 主體資料分塊傳遞到 mod_esi 回呼。請注意,mod_cgi 不支援此功能。預設值為無限制,即整個主體作為一個實體傳遞,這可能會非常消耗記憶體。mod_esi
。
管理屬性
{mime_types, [{MimeType, Extension}] | path()}
MimeType = string()
和Extension = string()
。根據 RFC 1590,傳遞給用戶端的檔案會經過 MIME 類型化。檔案副檔名會在檔案傳遞之前對應到 MIME 類型。可以在屬性列表中指定檔案副檔名和 MIME 類型之間的對應。也可以從檔案中讀取 MIME 類型。檔案應包含格式為
MediaType [Extensions...]
的行,例如text/html html htm
。若要設定此功能,請指定檔案路徑,例如{mime_types, "/etc/mime.types"}
。如果未設定,將使用
server_root
下的conf/mime.types
(如果存在),否則預設值為[{"html","text/html"},{"htm","text/html"}]
。{mime_type, string()}
當伺服器被要求提供 MIME 類型設定無法確定的文件類型時,伺服器會使用此預設類型。{server_admin, string()}
定義伺服器管理員的電子郵件地址,該地址將包含在伺服器傳回的任何錯誤訊息中。{server_tokens, none|prod|major|minor|minimal|os|full|{private, string()}}
定義伺服器標頭的值的外觀。範例:假設
Inets
的版本為 5.8.1,則伺服器標頭字串對於不同的 server-tokens 值可以如下所示none
- "" % 不會產生 Server: headerprod
- "inets"major
- "inets/5"minor
- "inets/5.8"minimal
- "inets/5.8.1"os
- "inets/5.8.1 (unix)"full
- "inets/5.8.1 (unix/linux) OTP/R15B"{private, "foo/bar"}
- "foo/bar"
預設值與之前相同,即
minimal
。{logger, Options::list()}
目前僅支援一個選項{error, ServerID::atom()}
- 在階層式 logger domain:[otp, inets, httpd, ServerID, error]
下,於 logger level error 產生 logger 事件。內建的 logger 格式化函式會從錯誤報告產生日誌條目。#{server_name => string() protocol => internal | 'TCP' | 'TLS' | 'HTTP', transport => "TCP" | "TLS", %% Present when protocol = 'HTTP' uri => string(), %% Present when protocol = 'HTTP' and URI is valid peer => inet:peername(), host => inet:hostname(), reason => term() }
以下為僅使用 logger 預設設定的日誌條目範例
=ERROR REPORT==== 9-Oct-2019::09:33:27.350235 === Server: My Server Protocol: HTTP Transport: TLS URI: /not_there Host: 127.0.1.1:80 Peer: 127.0.0.1:45253 Reason: [{statuscode,404},{description,"Object Not Found"}]
使用此選項會使 mod_log 和 mod_disk_log 的錯誤日誌變得多餘。
將篩選器加入
{fun logger_filters:domain/2, {log,equal,[otp,inets, httpd, ServerID, error]}
適當的 logger 處理器來處理事件。例如,若要將 ServerID 為
my_server
的 httpd 伺服器的錯誤日誌寫入檔案,您可以使用以下 sys.config 設定[{kernel, [{logger, [{handler, http_error_test, logger_std_h, #{config => #{ file => "log/http_error.log" }, filters => [{inets_httpd, {fun logger_filters:domain/2, {log, equal, [otp, inets, httpd, my_server, error] }}}], filter_default => stop }}]}]}].
或者,如果您想透過 API 將其加入預設 logger
logger:add_handler_filter(default, inets_httpd, {fun logger_filters:domain/2, {log, equal, [otp, inets, httpd, my_server, error]}}).
{log_format, common | combined}
定義是否要根據common
日誌格式或擴展的 common 日誌格式寫入存取日誌。common
格式為單行,如下所示:remotehost rfc931 authuser [date] "request" status bytes
。其中
remotehost
- 遠端主機。rfc931
- 用戶端的遠端使用者名稱 (RFC 931)。authuser
- 用於驗證的使用者名稱。[date]
- 請求的日期和時間 (RFC 1123)。"request"
- 從用戶端接收到的請求行 (RFC 1945)。status
- 返回給用戶端的 HTTP 狀態碼 (RFC 1945)。bytes
- 傳輸的文件內容長度。
combined
格式為單行,如下所示:remotehost rfc931 authuser [date] "request" status bytes "referer" "user_agent"
除了前面的以外
"referer"
- 用戶端在請求 URL 之前所在的 URL (如果無法確定,則在此欄位中放置減號)。"user_agent"
- 用戶端聲稱正在使用的軟體 (如果無法確定,則在此欄位中放置減號)。
這會影響
mod_log
和mod_disk_log
寫入的存取日誌。{error_log_format, pretty | compact}
預設值為pretty
。如果錯誤日誌是要讓人直接閱讀,則pretty
是最佳選擇。pretty
的格式對應於io:format("[~s] ~s, reason: ~n ~p ~n~n", [Date, Msg, Reason]).
compact
的格式對應於io:format("[~s] ~s, reason: ~w ~n", [Date, Msg, Reason]).
這會影響
mod_log
和mod_disk_log
寫入的錯誤日誌。
URL 別名屬性 - 需要 mod_alias
{alias, {Alias, RealName}}
Alias = string()
和RealName = string()
。alias
允許文件儲存在本機檔案系統中,而不是document_root
位置。路徑開頭為 url-path 的 URL 會對應到本機檔案,其開頭為 directory-filename,例如{alias, {"/image", "/ftp/pub/image"}}
存取 http://your.server.org/image/foo.gif 會參照檔案 /ftp/pub/image/foo.gif。
{re_write, {Re, Replacement}}
Re = string()
和Replacement = string()
。re_write
允許文件儲存在本機檔案系統中,而不是document_root
位置。URL 會透過re:replace/3
重新寫入,以產生本機檔案系統中的路徑,例如{re_write, {"^/[~]([^/]+)(.*)$", "/home/\\1/public\\2"}}
存取 http://your.server.org/~bob/foo.gif 會參照檔案 /home/bob/public/foo.gif。
{directory_index, [string()]}
directory_index
指定當用戶端使用目錄名稱結尾的/
請求目錄時要尋找的資源清單。file
描述目錄中檔案的名稱。可以指定多個檔案,在這種情況下,伺服器會返回它找到的第一個檔案,例如{directory_index, ["index.html", "welcome.html"]}
存取 http://your.server.org/docs/ 會返回 http://your.server.org/docs/index.html 或 http://your.server.org/docs/welcome.html,如果 index.html 不存在。
CGI 屬性 - 需要 mod_cgi
{script_alias, {Alias, RealName}}
Alias = string()
和RealName = string()
。其行為與屬性alias
相同,只是它們也將目標目錄標記為包含 CGI 腳本。路徑開頭為 url-path 的 URL 會對應到開頭為 directory-filename 的腳本,例如{script_alias, {"/cgi-bin/", "/web/cgi-bin/"}}
存取 http://your.server.org/cgi-bin/foo 會導致伺服器執行腳本 /web/cgi-bin/foo。
{script_re_write, {Re, Replacement}}
Re = string()
和Replacement = string()
。其行為與屬性re_write
相同,只是它們也將目標目錄標記為包含 CGI 腳本。路徑開頭為 url-path 的 URL 會對應到開頭為 directory-filename 的腳本,例如{script_re_write, {"^/cgi-bin/(\\d+)/", "/web/\\1/cgi-bin/"}}
存取 http://your.server.org/cgi-bin/17/foo 會導致伺服器執行腳本 /web/17/cgi-bin/foo。
{script_nocache, boolean()}
如果將script_nocache
設定為true
,HTTP 伺服器預設會新增必要的標頭欄位,以防止 Proxy 快取頁面。一般來說,這是較好的做法。預設值為false
。{script_timeout, integer()}
Web 伺服器在每次從腳本接收資料區塊之間等待的時間 (以秒為單位)。如果 CGI 腳本在逾時之前未傳送任何資料,則會關閉與用戶端的連線。預設值為15
。{action, {MimeType, CgiScript}}
- 需要mod_actions
MimeType = string()
和CgiScript = string()
。action
會新增一個動作,每當請求特定 MIME 類型檔案時,就會啟動 CGI 腳本。它會使用標準 CGI PATH_INFO 和 PATH_TRANSLATED 環境變數傳播所請求文件的 URL 和檔案路徑。範例
{action, {"text/plain", "/cgi-bin/log_and_deliver_text"}}
{script, {Method, CgiScript}}
- 需要mod_actions
Method = string()
和CgiScript = string()
。script
會新增一個動作,每當使用特定 HTTP 方法請求檔案時,就會啟動 CGI 腳本。方法為 GET 或 POST,如 RFC 1945 中所定義。它會使用標準 CGI PATH_INFO 和 PATH_TRANSLATED 環境變數傳播所請求文件的 URL 和檔案路徑。範例
{script, {"PUT", "/cgi-bin/put"}}
ESI 屬性 - 需要 mod_esi
{erl_script_alias, {URLPath, [AllowedModule]}}
URLPath = string()
和AllowedModule = atom()
。erl_script_alias
會將所有與 url-path 相符的 URL 標記為 erl 配置腳本。相符的 URL 會對應到特定的模組和函式,例如{erl_script_alias, {"/cgi-bin/example", [httpd_example]}}
對 http://your.server.org/cgi-bin/example/httpd_example:yahoo 的請求會參照 httpd_example:yahoo/3,如果不存在則會參照 httpd_example:yahoo/2,而 http://your.server.org/cgi-bin/example/other:yahoo 則不允許執行。
{erl_script_nocache, boolean()}
如果將erl_script_nocache
設定為true
,伺服器會新增 HTTP 標頭欄位,以防止 Proxy 快取頁面。對於動態內容來說,這通常是一個好主意,因為內容在每次請求之間通常會有所不同。預設值為false
。{erl_script_timeout, integer()}
如果erl_script_timeout
設定伺服器在透過mod_esi:deliver/2
傳送每個資料區塊之間等待的時間 (以秒為單位)。預設值為15
。這僅適用於使用 erl 配置的腳本。
日誌屬性 - 需要 mod_log
{error_log, path()}
定義用於記錄伺服器錯誤的錯誤日誌檔名。如果檔名不是以斜線 (/) 開頭,則會假設為相對於server_root
的位置。{security_log, path()}
定義用於記錄安全性事件的存取日誌檔名。如果檔名不是以斜線 (/) 開頭,則會假設為相對於server_root
的位置。{transfer_log, path()}
定義用於記錄傳入請求的存取日誌檔案名稱。如果檔名不是以斜線 (/) 開頭,則會假設為相對於server_root
的路徑。
磁碟日誌屬性 - 需要 mod_disk_log
{disk_log_format, internal | external}
定義日誌檔案的檔案格式。詳細資訊請參閱disk_log
。如果使用內部檔案格式,則會在當機後修復日誌檔案。修復日誌檔案時,資料可能會遺失。如果使用外部檔案格式,則當日誌檔案損壞時,httpd
不會啟動。預設值為external
。{error_disk_log, path()}
定義用於記錄伺服器錯誤的 (disk_log
) 錯誤日誌檔案名稱。如果檔名不是以斜線 (/) 開頭,則會假設為相對於server_root
的路徑。{error_disk_log_size, {MaxBytes, MaxFiles}}
MaxBytes = integer()
和MaxFiles = integer()
。定義 (disk_log
) 錯誤日誌檔案的屬性。此檔案類型為環狀日誌,每個檔案會寫入最大位元組數,並在第一個檔案被截斷和重複使用前使用最大檔案數。{security_disk_log, path()}
定義用於記錄傳入安全性事件(即已驗證的請求)的 (disk_log
) 存取日誌檔案名稱。如果檔名不是以斜線 (/) 開頭,則會假設為相對於server_root
的路徑。{security_disk_log_size, {MaxBytes, MaxFiles}}
MaxBytes = integer()
和MaxFiles = integer()
。定義disk_log
存取日誌檔案的屬性。此檔案類型為環狀日誌,每個檔案會寫入最大位元組數,並在第一個檔案被截斷和重複使用前使用最大檔案數。{transfer_disk_log, path()}
定義用於記錄傳入請求的 (disk_log
) 存取日誌檔案名稱。如果檔名不是以斜線 (/) 開頭,則會假設為相對於server_root
的路徑。{transfer_disk_log_size, {MaxBytes, MaxFiles}}
MaxBytes = integer()
和MaxFiles = integer()
。定義disk_log
存取日誌檔案的屬性。此檔案類型為環狀日誌,每個檔案會寫入最大位元組數,並在第一個檔案被截斷和重複使用前使用最大檔案數。
驗證屬性 - 需要 mod_auth
{directory, {path(), [{property(), term()}]}}
目錄的屬性如下:
{allow_from, all | [RegxpHostString]}
定義一組要授予對特定目錄存取權的主機,例如{allow_from, ["123.34.56.11", "150.100.23"]}
允許主機
123.34.56.11
和150.100.23
子網上的所有電腦存取。{deny_from, all | [RegxpHostString]}
定義一組要拒絕存取特定目錄的主機,例如{deny_from, ["123.34.56.11", "150.100.23"]}
不允許主機
123.34.56.11
和150.100.23
子網上的所有電腦存取。{auth_type, plain | dets | mnesia}
設定用於目錄的驗證資料庫類型。不同方法之間的主要區別在於,當使用 Mnesia 和 Dets 時,可以儲存動態資料。{auth_user_file, path()}
設定包含使用者和密碼清單以進行使用者驗證的檔案名稱。檔案名稱可以是絕對路徑或相對於server_root
的路徑。如果使用純文字儲存方法,則此檔案是一個純文字檔案,其中每一行都包含一個使用者名稱,後面接著一個冒號,再接著未加密的密碼。如果使用者名稱重複,則行為未定義。範例
ragnar:s7Xxv7 edward:wwjau8
如果使用 Dets 儲存方法,則使用者資料庫由 Dets 維護,不得手動編輯。使用模組
mod_auth
中的 API 函數來建立/編輯使用者資料庫。如果使用 Mnesia 儲存方法,則會忽略此指令。為了安全起見,請確保auth_user_file
儲存在網路伺服器的文件樹之外。如果將其放置在其保護的目錄中,則用戶端可以下載它。{auth_group_file, path()}
設定包含用於使用者驗證的使用者群組清單的檔案名稱。檔案名稱可以是絕對路徑或相對於server_root
的路徑。如果使用純文字儲存方法,則群組檔案是一個純文字檔案,其中每一行都包含一個群組名稱,後面接著一個冒號,再接著以空格分隔的成員使用者名稱。範例
group1: bob joe ante
如果使用 Dets 儲存方法,則群組資料庫由 Dets 維護,不得手動編輯。使用模組
mod_auth
的 API 來建立/編輯群組資料庫。如果使用 Mnesia 儲存方法,則會忽略此指令。為了安全起見,請確保auth_group_file
儲存在網路伺服器的文件樹之外。如果將其放置在其保護的目錄中,則用戶端可以下載它。{auth_name, string()}
設定目錄的授權領域(驗證網域)名稱。此字串會告知用戶端要使用哪個使用者名稱和密碼。{auth_access_password, string()}
如果設定為"NoPassword"
以外的值,則所有 API 呼叫都需要密碼。如果密碼設定為"DummyPassword"
,則必須在任何其他 API 呼叫之前變更密碼。為了保護驗證資料,必須在啟動網路伺服器後變更密碼。否則,它會以明文形式寫入組態檔。
安全性屬性 - 需要 mod_security
{security_directory, {path(), [{property(), term()}]}}
安全性目錄的屬性如下:
{data_file, path()}
安全性資料檔案的名稱。檔案名稱可以是絕對路徑或相對於server_root
的路徑。此檔案用於儲存模組mod_security
的持續性資料。{max_retries, integer()}
指定使用者被封鎖之前驗證使用者的最大嘗試次數。如果使用者在被封鎖時成功驗證,則使用者會收到來自伺服器的 403 (禁止) 回應。如果使用者在被封鎖時進行失敗的嘗試,則伺服器會出於安全考量而傳回 401 (未經授權)。預設值為3
。可以設定為無限大。{block_time, integer()}
指定使用者被封鎖的分鐘數。經過這段時間後,使用者會自動重新獲得存取權。預設值為60
。{fail_expire_time, integer()}
指定記住使用者驗證失敗的分鐘數。如果使用者在經過這段時間後進行驗證,則會忘記先前的驗證失敗。預設值為30
。{auth_timeout, integer()}
指定記住使用者成功驗證的秒數。經過這段時間後,驗證將不再回報。預設值為30
。
網路伺服器 API 資料類型
Erlang 網路伺服器 API 資料類型如下:
ModData = #mod{}
-record(mod, {
data = [],
socket_type = ip_comm,
socket,
config_db,
method,
absolute_uri,
request_uri,
http_version,
request_line,
parsed_header = [],
entity_body,
connection
}).
若要存取回呼模組中的記錄,請使用:
-include_lib("inets/include/httpd.hrl").
記錄 mod
的欄位具有以下含義:
data
- 類型[{InteractionKey,InteractionValue}]
用於在模組之間傳播資料。在函數類型宣告中描繪為interaction_data()
。socket_type
-socket_type()
表示它是 IP Socket 還是ssl
Socket。socket
- Socket,格式為ip_comm
或ssl
,具體取決於socket_type
。config_db
- 組態檔案指令以鍵值組的形式儲存在 ETS 表格中。在函數類型宣告中描繪為config_db()
。method
- 類型"GET" | "POST" | "HEAD" | "TRACE"
,即 HTTP 方法。absolute_uri
- 如果請求是 HTTP/1.1 請求,則 URI 可以是絕對 URI 格式。在這種情況下,httpd
會將絕對 URI 儲存在此欄位中。絕對 URI 的範例為"http://ServerName:Part/cgi-bin/find.pl?person=jocke"
request_uri
- RFC 1945 中定義的Request-URI
,例如"/cgi-bin/find.pl?person=jocke"
。http_version
- 請求的HTTP
版本,即 "HTTP/1.0" 或 "HTTP/1.1"。request_line
- RFC 1945 中定義的Request-Line
,例如"GET /cgi-bin/find.pl?person=jocke HTTP/1.0"
。parsed_header
- 類型[{HeaderKey,HeaderValue}]
。parsed_header
包含 HTTP 請求中所有 HTTP 標頭欄位,並以鍵值元組列表的形式儲存。有關所有標頭欄位的列表,請參閱 RFC 2616。例如,日期欄位會儲存為{"date","Wed, 15 Oct 1997 14:35:17 GMT"}
。RFC 2616 定義 HTTP 是一個不區分大小寫的協定,標頭欄位可以使用小寫或大寫。httpd
確保所有標頭欄位名稱都使用小寫。entity_body
- 如 RFC 2616 中定義的entity-Body
,例如,使用 POST 方法從 CGI 腳本傳送的資料。connection
-true | false
。如果設定為true
,則與客戶端的連線是持續連線,並且在處理請求後不會關閉。
另請參閱
摘要
回呼函式
當有效的請求到達 httpd
時,它會呼叫每個模組中由 Module
的設定選項定義的 do/1
函式。該函式可以為其他模組產生資料,或產生可以傳回給客戶端的響應。
當 httpd
關閉時,它會嘗試在每個 Erlang Web 伺服器回呼模組中執行 remove/1
函式。程式設計師可以使用此函式來清除在 store 函式中建立的資源。
在將組態選項儲存到內部資料庫之前,會檢查其有效性。此函式也可能產生副作用,也就是設定組態選項所暗示的必要額外資源。它還可以透過變更選項的值來解決組態選項之間可能存在的依賴關係。此函式只需要用於此特定回呼模組實作的選項子句。
Web 伺服器 API 輔助函式
parse_query/1
會將傳入的資料解析為標準 URL 格式中定義的 erl
和 eval
指令碼(請參閱 mod_esi
),也就是說,'+' 會變成 'space',並解碼十六進位字元 (%xx
)。
函式
取得有關 HTTP 伺服器的資訊。當僅使用 pid 呼叫時,會取得所有屬性。當使用特定屬性列表呼叫時,會取得這些屬性。可用的屬性與伺服器的啟動選項相同。
取得有關 HTTP 伺服器的資訊。當僅使用 Address
和 Port
呼叫時,會取得所有屬性。當使用特定屬性列表呼叫時,會取得這些屬性。可用的屬性與伺服器的啟動選項相同。
重新載入 HTTP 伺服器組態,而無需重新啟動伺服器。在重新載入期間,會以暫時關閉訊息回覆傳入的請求。
類型
回呼函式
-callback do(ModData) -> {proceed, OldData} | {proceed, NewData} | {break, NewData} | done when ModData :: [{data, NewData} | {'Body', Body} | {'Head', Head}], OldData :: list(), NewData :: [{response, {StatusCode, Body}}], StatusCode :: integer(), Body :: iolist() | nobody | {Fun, FunArg}, Head :: [HeaderOption], HeaderOption :: {Option, Value} | {code, StatusCode}, Option :: accept_ranges | allow, Value :: string(), FunArg :: [term()], Fun :: fun((FunArg) -> sent | close | Body).
當有效的請求到達 httpd
時,它會呼叫每個模組中由 Module
的設定選項定義的 do/1
函式。該函式可以為其他模組產生資料,或產生可以傳回給客戶端的響應。
ModData
中的欄位 data
是一個列表。此列表是上次呼叫 do/1
所傳回的列表。
Body
是傳回給客戶端的 HTTP 響應主體。適當的標頭會附加到訊息中。StatusCode
是響應的狀態碼,有關適當的值,請參閱 RFC 2616。
Head
是 HTTP 標頭欄位的鍵值列表。伺服器會從此資料建構 HTTP 標頭。有關每個標頭欄位的適當值,請參閱 RFC 2616。如果客戶端是 HTTP/1.0 客戶端,則伺服器會篩選列表,以便僅將 HTTP/1.0 標頭欄位傳回給客戶端。
如果傳回的 Body
等於 {Fun,Arg}
,則 Web 伺服器會嘗試在 Fun
上使用 Arg
作為引數來執行 apply/2
。Web 伺服器預期該 fun 要麼傳回一個列表 (Body)
,該列表是一個 HTTP 響應,或者傳回原子 sent
(如果 HTTP 響應已傳回給客戶端)。如果從 fun 傳回 close
,則表示發生錯誤,並且伺服器會透過關閉連線向客戶端發出信號。
當 httpd
關閉時,它會嘗試在每個 Erlang Web 伺服器回呼模組中執行 remove/1
函式。程式設計師可以使用此函式來清除在 store 函式中建立的資源。
-callback store({Option, Value}, Config) -> {ok, {Option, NewValue}} | {error, Reason} when Option :: property(), Config :: [{Option, Value}], Value :: term(), NewValue :: term(), Reason :: term().
在將組態選項儲存到內部資料庫之前,會檢查其有效性。此函式也可能產生副作用,也就是設定組態選項所暗示的必要額外資源。它還可以透過變更選項的值來解決組態選項之間可能存在的依賴關係。此函式只需要用於此特定回呼模組實作的選項子句。
Web 伺服器 API 輔助函式
-spec parse_query(QueryString) -> QueryList | uri_string:error() when QueryString :: string(), QueryList :: [{unicode:chardata(), unicode:chardata() | true}].
parse_query/1
會將傳入的資料解析為標準 URL 格式中定義的 erl
和 eval
指令碼(請參閱 mod_esi
),也就是說,'+' 會變成 'space',並解碼十六進位字元 (%xx
)。
函式
-spec info(Pid) -> HttpInformation when Pid :: pid(), Path :: file:name_all(), HttpInformation :: [CommonOption] | [CommunicationOption] | [ModOption] | [LimitOption] | [AdminOption], CommonOption :: {port, non_neg_integer()} | {server_name, string()} | {server_root, Path} | {document_root, Path}, CommunicationOption :: {bind_address, inet:ip_address() | inet:hostname() | any} | {profile, atom()} | {socket_type, ip_comm | {ip_comm, ssl:tls_option() | gen_tcp:option()} | {ssl, ssl:tls_option() | gen_tcp:option()}} | {ipfamily, inet | inet6} | {minimum_bytes_per_second, integer()}, ModOption :: {modules, atom()}, LimitOption :: {customize, atom()} | {disable_chunked_transfer_encoding_send, boolean()} | {keep_alive, boolean()} | {keep_alive_timeout, integer()} | {max_body_size, integer()} | {max_clients, integer()} | {max_header_size, integer()} | {max_content_length, integer()} | {max_uri_size, integer()} | {max_keep_alive_request, integer()} | {max_client_body_chunk, integer()}, AdminOption :: {mime_types, [{MimeType :: string(), Extension :: string()}] | Path} | {mime_type, string()} | {server_admin, string()} | {server_tokens, none | prod | major | minor | minimal | os | full | {private, string()}} | {logger, Options :: list()} | {log_format, common | combined} | {error_log_format, pretty | compact}.
等同於 info/2
。
-spec info(Pid, Properties) -> HttpInformation when Pid :: pid(), Properties :: [atom()], HttpInformation :: [CommonOption] | [CommunicationOption] | [ModOption] | [LimitOption] | [AdminOption], CommonOption :: {port, non_neg_integer()} | {server_name, string()} | {server_root, Path} | {document_root, Path}, CommunicationOption :: {bind_address, inet:ip_address() | inet:hostname() | any} | {profile, atom()} | {socket_type, ip_comm | {ip_comm, ssl:tls_option() | gen_tcp:option()} | {ssl, ssl:tls_option() | gen_tcp:option()}} | {ipfamily, inet | inet6} | {minimum_bytes_per_second, integer()}, ModOption :: {modules, atom()}, LimitOption :: {customize, atom()} | {disable_chunked_transfer_encoding_send, boolean()} | {keep_alive, boolean()} | {keep_alive_timeout, integer()} | {max_body_size, integer()} | {max_clients, integer()} | {max_header_size, integer()} | {max_content_length, integer()} | {max_uri_size, integer()} | {max_keep_alive_request, integer()} | {max_client_body_chunk, integer()}, AdminOption :: {mime_types, [{MimeType :: string(), Extension :: string()}] | Path} | {mime_type, string()} | {server_admin, string()} | {server_tokens, none | prod | major | minor | minimal | os | full | {private, string()}} | {logger, Options :: list()} | {log_format, common | combined} | {error_log_format, pretty | compact}; (Address, Port) -> HttpInformation when Address :: inet:ip_address(), Port :: integer(), Path :: file:name_all(), HttpInformation :: [CommonOption] | [CommunicationOption] | [ModOption] | [LimitOption] | [AdminOption], CommonOption :: {port, non_neg_integer()} | {server_name, string()} | {server_root, Path} | {document_root, Path}, CommunicationOption :: {bind_address, inet:ip_address() | inet:hostname() | any} | {profile, atom()} | {socket_type, ip_comm | {ip_comm, ssl:tls_option() | gen_tcp:option()} | {ssl, ssl:tls_option() | gen_tcp:option()}} | {ipfamily, inet | inet6} | {minimum_bytes_per_second, integer()}, ModOption :: {modules, atom()}, LimitOption :: {customize, atom()} | {disable_chunked_transfer_encoding_send, boolean()} | {keep_alive, boolean()} | {keep_alive_timeout, integer()} | {max_body_size, integer()} | {max_clients, integer()} | {max_header_size, integer()} | {max_content_length, integer()} | {max_uri_size, integer()} | {max_keep_alive_request, integer()} | {max_client_body_chunk, integer()}, AdminOption :: {mime_types, [{MimeType :: string(), Extension :: string()}] | Path} | {mime_type, string()} | {server_admin, string()} | {server_tokens, none | prod | major | minor | minimal | os | full | {private, string()}} | {logger, Options :: list()} | {log_format, common | combined} | {error_log_format, pretty | compact}.
取得有關 HTTP 伺服器的資訊。當僅使用 pid 呼叫時,會取得所有屬性。當使用特定屬性列表呼叫時,會取得這些屬性。可用的屬性與伺服器的啟動選項相同。
注意
Pid 是從
inets:start/[2,3]
傳回的 pid。也可以從inets:services/0
和inets:services_info/0
取得,請參閱inets
。
-spec info(Address, Port, Profile) -> HttpInformation when Address :: inet:ip_address() | any, Port :: integer(), Profile :: atom(), Path :: file:name_all(), HttpInformation :: [CommonOption] | [CommunicationOption] | [ModOption] | [LimitOption] | [AdminOption], CommonOption :: {port, non_neg_integer()} | {server_name, string()} | {server_root, Path} | {document_root, Path}, CommunicationOption :: {bind_address, inet:ip_address() | inet:hostname() | any} | {profile, atom()} | {socket_type, ip_comm | {ip_comm, ssl:tls_option() | gen_tcp:option()} | {ssl, ssl:tls_option() | gen_tcp:option()}} | {ipfamily, inet | inet6} | {minimum_bytes_per_second, integer()}, ModOption :: {modules, atom()}, LimitOption :: {customize, atom()} | {disable_chunked_transfer_encoding_send, boolean()} | {keep_alive, boolean()} | {keep_alive_timeout, integer()} | {max_body_size, integer()} | {max_clients, integer()} | {max_header_size, integer()} | {max_content_length, integer()} | {max_uri_size, integer()} | {max_keep_alive_request, integer()} | {max_client_body_chunk, integer()}, AdminOption :: {mime_types, [{MimeType :: string(), Extension :: string()}] | Path} | {mime_type, string()} | {server_admin, string()} | {server_tokens, none | prod | major | minor | minimal | os | full | {private, string()}} | {logger, Options :: list()} | {log_format, common | combined} | {error_log_format, pretty | compact}; (Address, Port, Properties) -> HttpInformation when Address :: inet:ip_address() | any, Port :: integer(), Properties :: [atom()], Path :: file:name_all(), HttpInformation :: [CommonOption] | [CommunicationOption] | [ModOption] | [LimitOption] | [AdminOption], CommonOption :: {port, non_neg_integer()} | {server_name, string()} | {server_root, Path} | {document_root, Path}, CommunicationOption :: {bind_address, inet:ip_address() | inet:hostname() | any} | {profile, atom()} | {socket_type, ip_comm | {ip_comm, ssl:tls_option() | gen_tcp:option()} | {ssl, ssl:tls_option() | gen_tcp:option()}} | {ipfamily, inet | inet6} | {minimum_bytes_per_second, integer()}, ModOption :: {modules, atom()}, LimitOption :: {customize, atom()} | {disable_chunked_transfer_encoding_send, boolean()} | {keep_alive, boolean()} | {keep_alive_timeout, integer()} | {max_body_size, integer()} | {max_clients, integer()} | {max_header_size, integer()} | {max_content_length, integer()} | {max_uri_size, integer()} | {max_keep_alive_request, integer()} | {max_client_body_chunk, integer()}, AdminOption :: {mime_types, [{MimeType :: string(), Extension :: string()}] | Path} | {mime_type, string()} | {server_admin, string()} | {server_tokens, none | prod | major | minor | minimal | os | full | {private, string()}} | {logger, Options :: list()} | {log_format, common | combined} | {error_log_format, pretty | compact}.
等同於 info/4
。
-spec info(Address, Port, Profile, Properties) -> HttpInformation when Address :: inet:ip_address() | any, Port :: integer(), Profile :: atom(), Properties :: [atom()], Path :: file:name_all(), HttpInformation :: [CommonOption] | [CommunicationOption] | [ModOption] | [LimitOption] | [AdminOption], CommonOption :: {port, non_neg_integer()} | {server_name, string()} | {server_root, Path} | {document_root, Path}, CommunicationOption :: {bind_address, inet:ip_address() | inet:hostname() | any} | {profile, atom()} | {socket_type, ip_comm | {ip_comm, ssl:tls_option() | gen_tcp:option()} | {ssl, ssl:tls_option() | gen_tcp:option()}} | {ipfamily, inet | inet6} | {minimum_bytes_per_second, integer()}, ModOption :: {modules, atom()}, LimitOption :: {customize, atom()} | {disable_chunked_transfer_encoding_send, boolean()} | {keep_alive, boolean()} | {keep_alive_timeout, integer()} | {max_body_size, integer()} | {max_clients, integer()} | {max_header_size, integer()} | {max_content_length, integer()} | {max_uri_size, integer()} | {max_keep_alive_request, integer()} | {max_client_body_chunk, integer()}, AdminOption :: {mime_types, [{MimeType :: string(), Extension :: string()}] | Path} | {mime_type, string()} | {server_admin, string()} | {server_tokens, none | prod | major | minor | minimal | os | full | {private, string()}} | {logger, Options :: list()} | {log_format, common | combined} | {error_log_format, pretty | compact}.
取得有關 HTTP 伺服器的資訊。當僅使用 Address
和 Port
呼叫時,會取得所有屬性。當使用特定屬性列表呼叫時,會取得這些屬性。可用的屬性與伺服器的啟動選項相同。
注意
Address
必須是 IP 位址,不能是主機名稱。
-spec reload_config(Config, Mode) -> ok | {error, Reason} | no_return() when Config :: file:name_all() | [{Option, Value}], Mode :: non_disturbing | disturbing | blocked, Option :: atom(), Value :: term(), Reason :: term().
重新載入 HTTP 伺服器組態,而無需重新啟動伺服器。在重新載入期間,會以暫時關閉訊息回覆傳入的請求。
注意
可用的屬性與伺服器的啟動選項相同,但是不能變更屬性
bind_address
和port
。
如果模式為 disturbing,則會強制封鎖伺服器,所有正在進行的請求都會終止,並立即開始重新載入。如果模式為 non-disturbing,則不會接受新的連線,但會允許正在進行的請求在重新載入完成之前完成。