Http - HTTP/1.0
協議客戶端的實現。
package require http ?2.4?
::http::config ?options?
::http::geturl url ?options?
::http::formatQuery list
::http::reset token
::http::wait token
::http::status token
::http::size token
::http::code token
::http::ncode token
::http::data token
::http::error token
::http::cleanup token
::http::register proto port command
::http::unregister proto
http包提供 HTTP/1.0
協議的客戶端。這個包實現了
HTTP/1.0 的 GET、POST、和 HEAD
操作。它允許配置一個代理(proxy)主機來透過防火牆。這個包與
Safesock
安全策略相容,所以可以被不可信任的
applets
用來從一些受限制的主機做
URL
取回(fetching)。可以擴充套件這個包來支援附加的
HTTP 傳輸協議,比如
HTTPS,透過
http::register,提供一個定製的
socket 命令。
::http::geturl 過程做一次 HTTP
事務(transaction)。它的
options
(選項)確定完成
GET、POST、或 HEAD
事務中的那一個。
::http::geturl
的返回值是這個事務的一個記號(token)。這個值也是在::http
名字空間中一個數組的名字,這個陣列包含關於這個事務的資訊。這個陣列的元素在狀態陣列章節中描述。
如果指定了
-command
選項,則在後臺做這個
HTTP 操作。
::http::geturl
在生成一個 HTTP
請求和在事務完成時呼叫的回撥過程(callback)之後立即返回。要使它工作,Tcl
事件迴圈必須是活躍的(active)。在
Tk
應用中總是真的。對於純
Tcl
應用,呼叫者可以在呼叫
::http::geturl 之後使用
::http::wait
來啟動事件迴圈。
-
::http::config ?options?
- 使用 ::http::config
命令來設定和查詢代理伺服器的和埠的名字,和在
HTTP
請求中使用的使用者代理(User-Agent)名字。如果未指定選項,則返回當前的配製。如果指定了一個單一的引數,則它應該是下面描述的標誌之一。在這種情況下返回設定的當前值。否則,選項應該是定義配置的一系列標誌和值:
-
-accept mimetypes
- (指定)請求的接受(型別)頭部(header)。預設是
*/*,這意味者接受所有型別的文件。否則你可以提供用逗號分隔的你想接收的
mime(多用途互連網郵件擴充套件)型別模式的一個列表。例如,"image/gif,
image/jpeg, text/*"。
-
-proxyhost hostname
- 如果有代理伺服器主機的話,它是代理伺服器主機的名字。如果這個值是空串,則直接聯絡
URL 主機。
-
-proxyport number
- 代理伺服器埠。
-
-proxyfilter command
- 這個命令設定在
::http::geturl
期間的一個回撥過程,用來決定是否為一個給定主機而要求一個代理伺服器。在呼叫它的時候,向命令
command
新增的一個引數是主機名字。如果要求一個代理伺服器,則這個回撥過程應該返回一個有兩個元素的陣列,分別是代理伺服器和代理服務埠。否則這個過濾器應該返回一個空列表。在
-proxyhost 和 -proxyport
設定非空的時候,預設的過濾器返回它們的值。
-
-useragent string
- 在 HTTP
請求中客戶代理頭部的值。預設是
"Tcl http client package 2.2."
-
::http::geturl url ?options?
-
::http::geturl
命令是包中的主過程。
-query 選項導致一個 POST
操作,而 -validate
選項導致一個 HEAD
操作;否則,進行一個
GET 操作。 ::http::geturl
命令返回一個 token
(記號)值,可用它來獲得關於這次事務的資訊。詳情參見狀態陣列和錯誤章節。除非用
-command 選項指定在 HTTP
事務完成時呼叫的一個回撥過程,否則
::http::geturl
命令在操作完成之前一直阻塞。
::http::geturl
接受一些選項:
-
-binary boolean
- Specifies whether to force interpreting the url data as
binary. Normally this is auto-detected (anything not beginning with a
text content type or whose content encoding is gzip or
compress is considered binary data).
-
-blocksize size
- 在讀 URL
時使用塊大小。一次最多讀
size
位元組。讀完每一塊之後,呼叫
-progress
回撥過程(如果指定著這個選項的話)。
-
-channel name
- 複製 URL 內容到叫
name
的通道中而不是儲存在
state(body) 中。
-
-command callback
- 在這次 HTTP
事務完成之後呼叫
callback。這個選項導致
::http::geturl
立即返回。callback
得到一個增添的引數,它是從
::http::geturl 返回的 token
(記號)。這個記號是在狀態陣列章節中描述的一個數組的名字。下面是這個回撥過程的一個模版:
proc httpCallback {token} {
upvar #0 $token state
# Access state as a Tcl array
}
-
-handler callback
- 在可獲得 HTTP
資料的時候呼叫 callback
;如果(這個回撥)存在,則不對
HTTP
資料做其他任何事情。這個過程得到兩個增添的引數:
給這些 HTTP
資料的套介面和從
::http::geturl 返回的 token
。這個記號是在狀態陣列章節中描述的一個數組的名字。回撥過程應返回從這個套介面中讀到的位元組數目。下面是這個回撥過程的一個模版:
proc httpHandlerCallback {socket token} {
upvar #0 $token state
# Access socket, and state as a Tcl array
...
(example: set data [read $socket 1000];set nbytes [string length $data])
...
return nbytes
}
-
-headers keyvaluelist
- 使用這個選項來給
HTTP
請求增加額外的頭部。
keyvaluelist
引數必須是有偶數個元素的一個列表,這些元素是交替的鍵(key)和值。這些鍵變成頭部的欄位名字。從這些值中去除(strip)換行符,所以頭部不會被中斷(corrupt)。例如,如果
keyvaluelist 是 Pragma no-cache 則在 HTTP
請求中包含下列頭部:
-
-progress callback
- 每次從 URL
傳輸資料之後呼叫這個
callback。這個呼叫得到三個增添的引數:
從 ::http::geturl 得來的
token,從 Content-Length
元(meta)資料得來的期望的內容總體大小,和迄今為止傳輸的位元組數。期望的總體大小可以是未知的,在這種情況下向這個回撥傳遞零。下面是這個回撥過程的一個模版:
proc httpProgress {token total current} {
upvar #0 $token state
}
-
-query query
- 這個標誌導致
::http::geturl
去做向伺服器傳遞
query 的一次 POST
請求。這個 query
必須是 x-url-encoding
編碼格式的一個查詢。可以使用
::http::formatQuery
過程來做格式化。
-
-queryblocksize size
- 在向 URL
傳送(post)查詢資料的時候使用這個塊大小。一次最多寫
size 位元組。
在每塊(被傳輸完畢)之後,呼叫
-queryprogress
回撥過程(如果指定了這個選項的話)。
-
-querychannel channelID
- 這個標誌導致
::http::geturl
去做向伺服器傳遞在
channelID
中包含的資料的一次
POST
請求。除非使用了下面的
-type 選項,否則在
channelID
中包含的資料必須是
x-url-encoding
編碼格式的一個查詢。如果沒有透過
-headers 選項指定
Content-Length(內容長度)頭部,則
::http::geturl
嘗試確定傳送的資料的大小來建立這個頭部。如果不能確定這個大小,它返回一個錯誤。
-
-queryprogress callback
- 在每次到 URL
的資料傳輸之後呼叫這個
callback
(例如,POST),並且表現(act)得與
-progress
選項精確的相似(回撥過程的格式相同)。
-
-timeout milliseconds
- 如果 milliseconds
是非零(的數),則
::http::geturl
設定在這個數字指定的毫秒後發生一個超時(timeout)。如果指定了
::http::reset 和 -command
回撥過程,一個超時導致對它們的呼叫。在超時發生之後,
::http::status 的返回值是
timeout。
-
-type mime-type
- 使用 mime-type 作為
Content-Type
(內容型別)的值,在一次
POST
操作期間,替換預設值(
application/x-www-form-urlencoded)。
-
-validate boolean
- 如果 boolean
是非零,則 ::http::geturl
做一次 HTTP HEAD
請求。這個請求返回關於這個
URL
的元(meta)資訊,而不返回(具體)內容。這個事務之後在
state(meta)
變數中可獲得這些元資訊。詳情參見STATE
ARRAY章節。
-
::http::formatQuery key value ?key
value ...?
- 這個過程做查詢資料的
x-url
編碼。它接受偶數個引數,它們是這個查詢的鍵和值。它編碼這些鍵和值,並生成有正確的
& 和 =
分隔符的一個字串。
結果適合於傳遞給
::http::geturl 的 -query 的值。
-
::http::reset token ?why?
- 這個命令重置用
token 標識的 HTTP
事務。如果有的話,它設定
state(status) 值為
why,它的預設值是
reset,並且接著呼叫註冊的
-command 回撥。
-
::http::wait token
- 這是阻塞並等待一個事務完成的一個方便函式。它使用了
vwait
所以只能在可信賴的程式碼中工作。還有,它對呼叫
::http::geturl 而不加 -command
選項的情況沒有用處,在這種情況下
::http::geturl 在 HTTP
事務完成之前不返回,所以不需等待。
-
::http::data token
- 這是返回狀態陣列的
body 元素(例如,URL
資料)的一個方便過程。
-
::http::error token
- 這是返回狀態陣列的
error
元素的一個方便過程。
-
::http::status token
- 這是返回狀態陣列的
status
元素的一個方便過程。
-
::http::code token
- 這是返回狀態陣列的
http
元素的一個方便過程。
-
::http::ncode token
- 這是隻返回狀態陣列的
http
元素的數值返回碼(200、404
等)的一個方便過程。
-
::http::size token
- 這是返回狀態陣列的
currentsize
元素的一個方便過程,它表示在
::http::geturl 呼叫中從 URL
接收的位元組數。
-
::http::cleanup token
- 這個過程清除與由
token
標識的連線相關的狀態。在這個呼叫之後,不能使用象
::http::data
這樣的過程得到關於這個操作的資訊。強烈建議你在做完一個特定的
HTTP
操作之後呼叫這個函式。不這樣做將導致記憶體不被釋放,如果你的應用呼叫
::http::geturl
次數足夠多,記憶體洩露(leak)將導致效能下降(hit)...或更糟。
-
::http::register proto port command
- 這個過程允許你透過註冊一個字首、預設埠、和建立
Tcl channel
(通道)的命令,提供定製的
HTTP 傳輸型別如
HTTPS。比如:
package require http
package require tls
http::register https 443 ::tls::socket
set token [http::geturl https://my.secure.site/]
-
::http::unregister proto
- 這個過程登出(unregister)以前透過
http::register註冊的一個協議處理器(handler)。
http::geturl
過程在下列情況下將引發(raise)錯誤:
無效的命令列選項、一個無效的
URL、在一個不存在的主機上的一個
URL、或在一個存在的主機的一個不良埠上的一個
URL。這些錯誤意味著它不能開始網路事務。如果它在寫出
HTTP
請求頭部期間得到了一個
I/O
錯誤,它也引發一個錯誤。對於同步
::http::geturl
呼叫(這個未指定
-command),如果它在讀 HTTP
回應頭部或資料期間得到一個
I/O
錯誤,它將引發一個錯誤。因為在這種情況下
::http::geturl
不返回一個記號,它做所有需要的清除,你的應用沒有必要呼叫
::http::cleanup。
對於非同步
::http::geturl
呼叫,除了在讀 HTTP
回應頭部或資料期間出現
I/O
錯誤之外,所有上述錯誤情況不引起(throw)例外(異常)。這是因為在寫完
HTTP 頭部之後,
::http::geturl
返回,而餘下的 HTTP
事務在後臺發生。命令的回撥過程可以透過呼叫
::http::status
來檢查狀態,檢視在讀的時候是否發生了
error
錯誤,如果有錯誤,呼叫
::http::error
來得到錯誤的訊息。
另一個選擇,如果主程式流到達需要知道非同步
HTTP
請求的結果的某點(point),它可以呼叫
::http::wait
並接著象上面的回撥過程做的那樣檢查狀態和錯誤。
在任何情況下,你必須在你做完(檢查)的時候呼叫
http::cleanup
來刪除狀態陣列。
下面描述的是用
http::status
檢查狀態能確定的 HTTP
事務的可能的結果。
- ok
- 如果 HTTP
事務完整完成,則狀態將是
ok。但是,你仍需檢查
http::code 的值來得到 HTTP
狀態。 http::ncode
過程只提供數值的錯誤(程式碼)(例如,200,404
或 500) 而 http::code
過程返回象“HTTP 404 File not
found”這樣的一個值。
- eof
- 如果伺服器關閉了套介面而不回應,則不引發錯誤,但事務的狀態將是
eof。
- error
- 錯誤訊息將被儲存在狀態陣列的
error 元素中,可透過
::http::error 訪問。
另一個錯誤的可能是
http::geturl
在伺服器響應並關閉套介面之前不能向伺服器寫出所有的
post
查詢。錯誤訊息儲存在狀態陣列的
posterror 元素中,而
http::geturl
接著嘗試完成這個事務。如果它能讀到伺服器的響應,它將以一個
ok
狀態結束,否則將有一個
eof 狀態。
::http::geturl 過程返回一個
token
,可以用它來得到一個
Tcl 陣列形式的 HTTP
事務狀態。使用下面這個構造(construct)來建立一個易用的陣列變數:
一旦與某個 url
有關的資料不再需要,應當清除這個陣列來釋放儲存(空間)。為此提供了
http::cleanup
過程。這個陣列支援下列元素:
- body
- URL
的內容。如果指定了
-channel
選項,則它將為空。用
::http::data
命令返回這個值。
- charset
- The value of the charset attribute from the
Content-Type meta-data value. If none was specified, this defaults
to the RFC standard iso8859-1, or the value of
$::http::defaultCharset. Incoming text data will be automatically
converted from this charset to utf-8.
- coding
- A copy of the Content-Encoding meta-data value.
- currentsize
- 當前從 URL
取回的位元組數。用
::http::size
命令返回這個值。
- error
- 如果定義了這個元素,這是終止
HTTP
事務時(描述)錯誤的字串。
- http
- 從伺服器回應的
HTTP 狀態。用 ::http::code
命令返回這個值。這個值的格式是:
code 是在 HTTP
標準中定義的一個三位數。程式碼
200 是 OK。以4或5開始
的程式碼指示錯誤。以3開始的程式碼是重定向錯誤。在這種情況下,
Location
元資料指定包含所需資訊的一個新
URL。
- meta
- HTTP 協議返回描述 URL
內容的元資料。狀態陣列的
meta
元素是元資料的鍵和值的一個列表。下面的格式對初始化只包含元資料的一個數組有用:
array set meta $state(meta)
下面列出一些元資料的鍵,HTTP
標準定義了更多,伺服器可自由的新增它們自己的鍵。
- Content-Type
- URL
內容的型別。例子包括
text/html、image/gif、application/postscript
和 application/x-tcl。
- Content-Length
- 內容的通告(advertise)的大小。透過
::http::geturl
獲得的實際大小作為
state(size) 來獲取。
- Location
- 包含所需的資料的一個可替代的
URL。
- posterror
- 在向伺服器寫 post
查詢時發生的錯誤。如果有的話。
- status
- 對於成功完成是
ok,對於使用者重重置(user-reset)是
reset,如果在事務完成之前發生了超時則是timeout。或在錯誤的情況下是
error。在事務(進行)期間這個值是一個空串。
- totalsize
-
Content-Length
元資料值的一個複本。
- type
-
Content-Type
元資料值的一個複本。
- url
- 請求的 URL。
# Copy a URL to a file and print meta-data
proc ::http::copy { url file {chunk 4096} } {
set out [open $file w]
set token [geturl $url -channel $out -progress ::http::Progress \
-blocksize $chunk]
close $out
# This ends the line started by http::Progress
puts stderr ""
upvar #0 $token state
set max 0
foreach {name value} $state(meta) {
if {[string length $name] > $max} {
set max [string length $name]
}
if {[regexp -nocase ^location$ $name]} {
# Handle URL redirects
puts stderr "Location:$value"
return [copy [string trim $value] $file $chunk]
}
}
incr max
foreach {name value} $state(meta) {
puts [format "%-*s %s" $max $name: $value]
}
return $token
}
proc ::http::Progress {args} {
puts -nonewline stderr . ; flush stderr
}
safe(n),
socket(n),
safesock(n)
security policy, socket
寒蟬退士
2001/09/20
http://cmpp.linuxforum.net
本頁面中文版由中文 man
手冊頁計劃提供。
中文 man 手冊頁計劃:
https://github.com/man-pages-zh/manpages-zh