Skip to content

Latest commit

 

History

History
1492 lines (1041 loc) · 55.7 KB

http-client.md

File metadata and controls

1492 lines (1041 loc) · 55.7 KB

http-client API Reference


このパッケージは、RFC2616 "Hypertext Transfer Protocol - HTTP/1.1" で定義されている HTTP/1.1 に対する簡単なクライアント API を提供します。

パッケージのニックネームは以下のとおりです。

  • http-client

User-Agent ヘッダに渡される値のデフォルト値を指定するスペシャル変数です。 デフォルトは "xyzzy/(xyzzy のバージョン)" です。

各アプリケーションは適切な値を設定するようにしてください。

Accept ヘッダに渡される値のデフォルト値を指定するスペシャル変数です。 デフォルトは "*/*" です。

Variable: *http-proxy*

デフォルトのプロキシを指定するスペシャル変数です。 以下の値を設定可能です。

  • nil または :no

    プロキシサーバを利用しません。

  • :winhttp

    WinHTTP のデフォルト設定を利用します。

    WinHTTP のプロキシ設定は netsh.exe (Vista/2008 以降) または proxycfg.exe (XP/2003 以前) コマンドを用いて行います。

  • :ie

    IE のプロキシ設定を利用します。

    この場合、プロキシの解決には WPAD (Web Proxy Auto-Discovery) による自動検出および自動構成スクリプトが利用可能になりますが、 Ctrl-g が効かない同期処理になるので注意してください。

  • 文字列

    指定されたプロキシサーバを利用します。

  • リスト

    指定されたプロキシサーバとバイパスリストを利用します。

デフォルトは :winhttp です。

;; プロキシ名を指定
(setf http-client:*http-proxy* "my.proxy.com")
(setf http-client:*http-proxy* :proxy "my.proxy.com:8080")

;; プロキシ名とバイパスを指定
(setf http-client:*http-proxy*  '("my.proxy.com:8080" "192.168.*.*"))

;; IE のプロキシ設定を利用する
(setf http-client:*http-proxy* :ie)

;; WinHTTP のプロキシ設定を利用する
(setf http-client:*http-proxy* :winhttp)

;; proxy を利用しない
(setf http-client:*http-proxy* :no)
(setf http-client:*http-proxy* nil)

See Also:

リダイレクトが発生した場合のデフォルトの処理を指定スペシャル変数です。 以下の値を設定可能です。

  • :never: リダイレクトしない
  • :always: 常にリダイレクトする
  • :disallow-https-to-http: HTTPS から HTTP へのリダイレクトのみしない

デフォルトは :disallow-https-to-http です。

See Also:


Condition: http-error

HTTP 通信でエラーが発生した場合に通知されるコンディションです。

継承関係は以下のとおりです。

以下のスロットが定義されています。

  • cause

    元となったエラーが設定されます。

  • keyword

    発生したエラーをあらわすキーワードが設定されます。 キーワードは WinHTTP Error Messages のエラー名に対応します。

    例): ERROR_WINHTTP_NAME_NOT_RESOLVED なら :name-not-resolved

See Also:

Condition: http-abort-error

通信を中断した場合に通知されるコンディションです。

See Also:

サーバに接続できない場合に通知されるコンディションです。

See Also:

サーバとの通信に失敗した場合に通知されるコンディションです。

See Also:

通信中にタイムアウトが発生した場合に通知されるコンディションです。

See Also:

Accessor: http-error-cause X

http-error コンディションの cause スロットを取得します。

See Also:

Accessor: http-error-keyword X

http-error コンディションの keyword スロットを取得します。

See Also:


リクエスト・ボディの送信またはレスポンス・ボディの受信処理の進捗状況を表す構造体です。

以下のスロットが定義されています。

  • response-p

    レスポンス・ボディの受信処理の場合 t が設定されます。

  • current

    現在までに送受信したバイトサイズが設定されます。

  • total

    Content-Length ヘッダの値が設定されます。 送受信するデータが惣菜しない場合や Content-Length が不明な場合は nil が設定されます。

See Also:

Accessor: http-progress-p X

Xhttp-progress 構造体のインスタンスなら t を返します。

See Also:

http-progress 構造体の response-p スロットを取得します。

See Also:

http-progress 構造体の current スロットを取得します。

See Also:

http-progress 構造体の total スロットを取得します。

See Also:

http-progress 構造体の進捗率 (%) を整数で取得します。

total スロットが nil または 0 以下の場合は nil を返します。


Function: http-get URI &key :headers :query :encoding :auth :proxy-auth :proxy :no-redirect :receiver :wait :onprogress :oncomplete :onabort :onerror

HTTP GET リクエストを送信します。

詳細は http-request を参照してください。

http-client.api> (http-response-values
                  (http-get "http://www.google.co.jp/search"
                            :query '(:q "xyzzy 読み方" :ie "UTF-8" :oe "Shift_JIS")
                            :encoding *encoding-utf8n*
                            :headers '(:User-Agent "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0) ")
                            :onprogress #'(lambda (p) (message "~A" p))
                            :onerror #'(lambda (err) (msgbox "Error: ~A" err))
                            :onabort #'(lambda () (msgbox "Abort"))
                            ))
"<!doctype html>
...
"
200
(("Cache-Control" . "private, max-age=0")
 ("Date" . "Wed, 08 Feb 2012 05:13:44 GMT")
 ("Transfer-Encoding" . "chunked")
 ...)
"http://www.google.co.jp/search?q=xyzzy%20%E8%AA%AD%E3%81%BF%E6%96%B9&ie=UTF-8&oe=Shift_JIS"

http-get などは Future オブジェクトを返します。

http-response-result などで値を取得しようとした時点で まだリクエストが完了していない場合はブロックします。

以下は Google に検索リクエストを並列に投げる例です。 並列でリクエストを処理しているため、検索クエリを増やしても 実行時間はほとんど増えないことに注目してください。

http-client.api> (defun google-count (keywords)
                   (let ((queries (mapcar #'(lambda (q)
                                              ;; http-get などはすぐにリターンする
                                              (cons q (http-get "http://www.google.co.jp/search"
                                                                :query `(:q ,q :ie "UTF-8" :oe "Shift_JIS")
                                                                :encoding *encoding-utf8n*
                                                                :onprogress #'(lambda (p)
                                                                                (message "~A: ~A" q p))
                                                                )))
                                          keywords)))
                     (mapcar #'(lambda (query)
                                 (cons (car query)
                                       (and (string-match "\\([0-9,]+\\) 件"
                                                          ;; この時点でブロックする
                                                          (http-response-result (cdr query)))
                                            (match-string 1))))
                             queries)))

http-client.api> (google-count '("xyzzy" "Emacs" "Vim"))
(("xyzzy" . "1,560,000") ("Emacs" . "15,700,000") ("Vim" . "159,000,000"))

http-client.api> (google-count '("xyzzy" "Emacs" "Vim" "秀丸" "TeraPad" "notepad++" "VzEditor"))
(("xyzzy" . "1,560,000") ("Emacs" . "15,700,000") ("Vim" . "159,000,000")
 ("秀丸" . "313,000") ("TeraPad" . "876,000") ("notepad++" . "7,280,000")
 ("VzEditor" . "56,000"))

Function: http-head URI &key :headers :query :encoding :auth :proxy-auth :proxy :no-redirect :receiver :wait :onprogress :oncomplete :onabort :onerror

HTTP HEAD リクエストを送信します。

詳細は http-request を参照してください。

http-client.api> (let ((client (http-head "http://www.jsdlab.co.jp/~kamei/cgi-bin/download.cgi"
                                          :onprogress #'(lambda (p) (message "~A" p))
                                          :onerror #'(lambda (err) (msgbox "Error: ~A" err))
                                          :onabort #'(lambda () (msgbox "Abort"))
                                          )))
                   (http-response-header client :last-modified))
"Wed, 07 Dec 2005 16:28:21 GMT"

Function: http-post URI BODY &key :headers :query :encoding :auth :proxy-auth :proxy :no-redirect :receiver :wait :onprogress :oncomplete :onabort :onerror

HTTP POST リクエストを送信します。

詳細は http-request を参照してください。

http-client.api> (setf *hatena-name* "miyamuko")
"miyamuko"

http-client.api> (setf *hatena-password* "xxx")
"xxx"

http-client.api> (http-response-values
                  (http-post "https://www.hatena.ne.jp/login"
                             `(:name ,*hatena-name* :password ,*hatena-password*)
                             :onprogress #'(lambda (p) (message "~A" p))
                             :onerror #'(lambda (err) (msgbox "Error: ~A" err))
                             :onabort #'(lambda () (msgbox "Abort"))
                             ))
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">
 ...
"
200
(("Cache-Control" . "no-cache")
 ("Connection" . "Keep-Alive")
 ("Date" . "Wed, 08 Feb 2012 05:17:48 GMT")
 ...)
"https://www.hatena.ne.jp/login"

Function: http-put URI BODY &key :headers :query :encoding :auth :proxy-auth :proxy :no-redirect :receiver :wait :onprogress :oncomplete :onabort :onerror

HTTP PUT リクエストを送信します。

詳細は http-request を参照してください。

Function: http-delete URI &key :headers :query :encoding :auth :proxy-auth :proxy :no-redirect :receiver :wait :onprogress :oncomplete :onabort :onerror

HTTP DELETE リクエストを送信します。

詳細は http-request を参照してください。

Function: http-request METHOD URI BODY &key :headers :query :encoding :auth :proxy-auth :proxy :no-redirect (:receiver (http-string-receiver)) :wait :onprogress :oncomplete :onabort :onerror

URIMETHOD で指定されたリクエストを送信して Future オブジェクトを返します。

引数

  • METHOD

    送信する HTTP メソッドを指定します。

  • URI

    URL を指定します。

  • BODY

    送信する HTTP レスポンス・ボディを文字列かリストで指定します。

    文字列の場合はそのまま送信します。 リストの場合は multipart/form-data 形式にエンコードして送信します。

    リストの要素は (name value) のような名前と値のリスト、 または (name :file filename :content-type type) のように 名前の後に plist を付加したものです。

    例:

    '(("submit" "OK"
      ("filename" :file "icon.png" :content-type "image/png" :content-transfer-encoding "binary"))

    plist には以下のキーワードを指定可能です。

    • :value

      パラメータの値を指定します。(name val) 形式は (name :value value) の省略形です。

    • :file

      指定された名前のファイルの中身をパラメータの値として挿入します。 ファイルのアップロードに便利です。 このオプションは :value より優先されます。

    • :content-type

      MIME タイプを指定します。 指定が無ければ Content-Type ヘッダは送信されません。

    • :content-transfer-encoding

      送信時のエンコーディングを指定します (binary のみをサポート)。 指定が無ければ Content-Transfer-Encoding ヘッダは送信されません。

    :encoding キーワード引数を指定した場合、 namevalue はまずその文字エンコーディングに変換されたのちに url エスケープされます。

  • :headers

    送信時の HTTP ヘッダを alist または plist で指定します。

    http-client.api> (http-get "https://twitter.com/"
                               :headers '(:Accept-Language "en"))
  • :query

    URL パラメータを文字列かリストで指定します。

    文字列の場合そのまま URL に追加されて送信されます。 呼び出し側で必要な文字コード変換や url エンコーディングを行う必要があります。

    リストの場合は、namevalue を alist または plist で指定します。

    namevalue の alist/plist から、application/x-www-form-urlencoded 形式の クエリ文字列を構成し URL に追加します。

    例えば次のリクエストは同じ効果を持ちます。 二番目以降の呼び出しでは url エスケープが自動的に行われることに注目してください。

    (http-get "https://www.google.co.jp/search?q=xyzzy%20%93%C7%82%DD%95%FB")
    (http-get "https://www.google.co.jp/search" :query "q=xyzzy%20%93%C7%82%DD%95%FB")
    (http-get "https://www.google.co.jp/search" :query '(:q "xyzzy 読み方"))
    (http-get "https://www.google.co.jp/search" :query '(("q" . "xyzzy 読み方")))

    :encoding キーワード引数を指定した場合、 namevalue はまずその文字エンコーディングに変換されたのちに url エスケープされます。

  • :encoding

    :queryBODY がリストで与えられた場合、パラメータの名前や値は まずこの引数で指定される文字エンコーディングへと変換され、 その後、application/x-www-form-urlencoded や multipart/form-data MIME 形式に したがったエンコーディングが行われます。

    :queryBODY に文字列を与えた場合は、文字エンコーディング変換は行われません。 呼び出し側で望みの文字コードにあらかじめ変換しておいてください。

  • :auth

    サーバに対する認証情報をリストで指定します。

:auth '(:basic "user" "pass") :auth '(:digest "user" "pass") ```

  • :proxy-auth

    プロキシに対する認証情報をリストで指定します。

:proxy-auth '(:basic "user" "pass") :proxy-auth '(:digest "user" "pass") ```

  • :proxy

    http プロキシサーバを文字列、リスト、キーワードで指定します。

    以下の値を設定可能です。

    • nil または :no

      プロキシサーバを利用しません。

    • :winhttp

      WinHTTP のデフォルト設定を利用します。

      WinHTTP のプロキシ設定は netsh.exe (Vista/2008 以降) または proxycfg.exe (XP/2003 以前) コマンドを用いて行います。

    • :ie

      IE のプロキシ設定を利用します。

      この場合、プロキシの解決には WPAD (Web Proxy Auto-Discovery) による自動検出および自動構成スクリプトが利用可能になりますが、 Ctrl-g が効かない同期処理になるので注意してください。

    • 文字列

      指定されたプロキシサーバを利用します。

    • リスト

      指定されたプロキシサーバとバイパスリストを利用します。

    何も指定しなかった場合は、*http-proxy* の設定に従います。

    ;; プロキシ名を指定
    :proxy "my.proxy.com"
    :proxy "my.proxy.com:8080"
    
    ;; プロキシ名とバイパスを指定
    :proxy '("my.proxy.com:8080" "192.168.*.*")
    
    ;; IE のプロキシ設定を利用する
    :proxy :ie
    
    ;; WinHTTP のプロキシ設定を利用する
    :proxy :winhttp
    
    ;; proxy を利用しない
    :proxy :no
    :proxy nil
  • :no-redirect

    non-nil を指定した場合、リダイレクションには従わなくなります。

    nil を指定した場合は *http-redirect-policy* の設定に従います。

  • :receiver

    レスポンス・ボディがどのように扱われるかをカスタマイズできます。 :receiver には「1 引数を受け取る関数」を返す、3 引数を受け取る関数を指定します。

    レスポンス・ヘッダを受信し終わると、:receiver を ステータスコード、レスポンス・ヘッダ、Content-Length を指定して呼び出します。

    レスポンス・ボディを受信すると、:receiver が返した関数を受信したメッセージ・ボディを 指定して呼び出します。

    レスポンス・ボディの終端に到達すると、:receiver が返した関数に nil を指定して呼び出します。 その時の戻り値が http-response-result の戻り値となります。

    :receiver のデフォルト値は http-string-receiver です。

    receiver には以下の値を指定可能です。

  • :wait

    waitnon-nil を指定した場合、同期モードで動作します。 リクエストが完了するまで関数は処理を返しません。

  • :onprogress, :oncomplete, :onabort, :onerror

    nil を指定した場合は何も呼び出されません。

    • :onprogress

      リクエスト・ボディの送信中またはレスポンス・ボディの受信中に 呼び出されます。引数は http-progress オブジェクトです。

      http-client.api> (http-get "http://www.google.co.jp/"
                                 :onprogress #'(lambda (progress)
                                                 (message "~A" progress)))
    • :oncomplete

      リクエストが完了した場合に呼び出されます。

      引数は レスポンス・ボディ、ステータスコード、レスポンス・ヘッダ、URL です。 URL はリダイレクト後の URL であるため、URI で指定した URL と違う場合があります。

    • :onabort

      リクエスト中断時に呼び出されます。 引数はコンディションです。

    • :onerror

      エラー発生時に呼び出されます。 引数はありません。

    http-client.api> (let ((client (http-get "http://www.jsdlab.co.jp/~kamei/cgi-bin/download.cgi"
                                             :receiver (http-file-receiver "c:/xyzzy.lzh")
                                             :onprogress #'(lambda (p)
                                                             (message "~A" p))
                                             :oncomplete #'(lambda (localfile status header uri)
                                                             (msgbox "ダウンロード完了~%URL: ~A~%File: ~A" uri localfile))
                                             :onerror #'(lambda (err)
                                                          (msgbox "Error: ~A" err))
                                             :onabort #'(lambda ()
                                                          (msgbox "Abort"))
                                             )))
                       (unless (http-response-wait client :timeout 3)
                         (http-request-abort client)))

戻り値

戻り値は同期・非同期にかかわらず Future オブジェクトです。

:waitnon-nil を指定しない場合、API を呼び出すとすぐに制御を返します。

  • http-response-values などで、Future オブジェクトから値を 取得しようとした時点で、まだリクエストが完了していない場合はブロックします。
  • http-response-wait で明示的にリクエストの完了を待つことが可能です。
  • リクエストが完了したかどうかは http-response-completed-p で判断できます。
  • リクエストを停止したい場合は Future オブジェクトを http-request-abort に指定します。

See Also:

Function: http-string-receiver &key (:encoding t)

レスポンス・ボディを文字列で受信するための receiver です。

  • デフォルトの receiver です。
  • :encoding にエンコーディングを指定した場合は、指定されたエンコーディングで 内部エンコーディングに変換します。
  • :encodingnon-nil を指定した場合は、Content-Type の charaset パラメータで 指定されたエンコーディングで内部エンコーディングに変換します。 charaset からエンコーディングを特定できない場合、 内部エンコーディングへの変換は行いません。
  • :encodingnil または :binary を指定した場合は、 内部エンコーディングへの変換は行いません。
  • :encoding を指定した場合、改行コードも内部コードに変換します。
  • http-response-result はレスポンス・ボディを文字列で返します。
http-client.api> (http-response-result
                  (http-get "http://zip.ricollab.jp/1120002.json"))
"{
  \"zipcode\": \"1120002\",
  \"address\": {
    \"prefecture\": \"東京都\",
    \"city\": \"文京区\",
    \"town\": \"小石川\"
  },
  \"yomi\": {
    \"prefecture\": \"トウキョウト\",
    \"city\": \"ブンキョウク\",
    \"town\": \"コイシカワ\"
  }
}
"

http-client.api> (http-response-result
                  (http-get "http://zip.ricollab.jp/1120002.json"
                            :receiver (http-string-receiver :encoding *encoding-utf8n*)))
"{
  \"zipcode\": \"1120002\",
  \"address\": {
    \"prefecture\": \"東京都\",
    \"city\": \"文京区\",
    \"town\": \"小石川\"
  },
  \"yomi\": {
    \"prefecture\": \"トウキョウト\",
    \"city\": \"ブンキョウク\",
    \"town\": \"コイシカワ\"
  }
}
"

http-client.api> (http-response-result
                  (http-get "http://zip.ricollab.jp/1120002.json"
                            :receiver (http-string-receiver :encoding nil)))
"{
  \"zipcode\": \"1120002\",
  \"address\": {
    \"prefecture\": \"譚ア莠ャ驛ス\",
    \"city\": \"譁?コャ蛹コ\",
    \"town\": \"蟆冗浹蟾?
  },
  \"yomi\": {
    \"prefecture\": \"繝医え繧ュ繝ァ繧ヲ繝?,
    \"city\": \"繝悶Φ繧ュ繝ァ繧ヲ繧ッ\",
    \"town\": \"繧ウ繧、繧キ繧ォ繝ッ\"
  }
}
"

See Also:

Function: http-file-receiver FILENAME &key (:encoding :binary) (:if-exists :new-version) (:share nil)

レスポンス・ボディを FILENAME で指定したファイルに保存するための receiver です。 受信しながらファイルに書き込むため、巨大なファイルをダウンロードする場合でもメモリを圧迫しません。

  • :encoding, :if-exists, :share は open 関数にそのまま指定されます。
  • :encoding のデフォルト値は :binary です。
  • :if-exists のデフォルト値は :new-version です。
  • :share のデフォルト値は nil です。
  • http-response-result はファイルのフルパスを文字列で返します。
http-client.api> (http-response-values
                  (http-get "http://www.jsdlab.co.jp/~kamei/cgi-bin/download.cgi"
                            :receiver (http-file-receiver "c:/xyzzy.lzh")
                            :onprogress #'(lambda (p) (message "~A" p))
                            :onerror #'(lambda (err) (msgbox "Error: ~A" err))
                            :onabort #'(lambda () (msgbox "Abort"))
                            ))
"c:/xyzzy.lzh"
200
(("Date" . "Tue, 07 Feb 2012 23:37:12 GMT")
 ("Server" . "Apache/2.0")
 ("Last-Modified" . "Wed, 07 Dec 2005 16:28:21 GMT")
 ...
 )
"http://www.mars.dti.ne.jp/~t-kamei/xyzzy/xyzzy-0.2.2.235.lzh"

See Also:

Function: http-buffer-receiver BUFFER &key (:encoding t)

レスポンス・ボディを BUFFER で指定したバッファに書きこむための receiver です。

  • BUFFER にバッファ名を指定した場合、同名のバッファがあった場合でも新規にバッファを作成します。
  • BUFFER にバッファを指定した場合、指定したバッファの末尾に書き込みます。
  • :encoding にエンコーディングを指定した場合は、指定されたエンコーディングで 内部エンコーディングに変換します。
  • :encodingnon-nil を指定した場合は、Content-Type の charaset パラメータで 指定されたエンコーディングで内部エンコーディングに変換します。 charaset からエンコーディングを特定できない場合、 内部エンコーディングへの変換は行いません。
  • :encodingnil または :binary を指定した場合は、 内部エンコーディングへの変換は行いません。
  • :encoding を指定した場合、改行コードも内部コードに変換し、 buffer-eol-code を適切に設定します。
  • http-response-result はバッファを返します。
;; www.baidu.com  は Content-Type: text/html;charset=gb2312 なので自動判別可能だが、
;; news.baidu.com は Content-Type: text/html なので encoding を明示する必要がある
http-client.api> (http-response-values
                  (http-get "http://news.baidu.com/"
                            :receiver (http-buffer-receiver "baidu"
                                                            :encoding *encoding-euc-gb*)
                            :oncomplete #'(lambda (buffer status headers uri)
                                            (pop-to-buffer buffer)
                                            (refresh-screen))
                            :onerror #'(lambda (err) (msgbox "Error: ~A" err))
                            :onabort #'(lambda () (msgbox "Abort"))
                            ))
#<buffer: baidu>
200
(... ("Content-Type" . "text/html") ...)
"http://news.baidu.com/"

See Also:

Function: http-oport-receiver SINK FLUSHER &key (:encoding t) :close :finish-output

レスポンス・ボディを SINK で指定したストリームに書きこむための receiver です。

  • SINK には出力ストリームを、FLUSHER には SINK を引数に取る関数を指定します。
  • :encoding にエンコーディングを指定した場合は、指定されたエンコーディングで 内部エンコーディングに変換します。
  • :encodingnon-nil を指定した場合は、Content-Type の charaset パラメータで 指定されたエンコーディングで内部エンコーディングに変換します。 charaset からエンコーディングを特定できない場合、 内部エンコーディングへの変換は行いません。
  • :encodingnil または :binary を指定した場合は、 内部エンコーディングへの変換は行いません。
  • :encoding を指定した場合、改行コードも内部コードに変換します。
  • :finish-outputnon-nil を指定すると、レスポンス・ボディ終端に達した時点で SINK を finish-output します。 デフォルトは nil です。
  • :closenon-nil を指定すると、レスポンス・ボディ終端に達した時点で SINK を close します。 デフォルトは nil です。
  • http-response-resultFLUSHER の戻り値を返します。 FLUSHERnil を指定すると SINK を返します。
http-client.api> (http-response-result
                  (http-get "http://www.google.co.jp/"
                            :receiver (http-oport-receiver *standard-output*
                                                           #'buffer-stream-buffer)))
<!doctype html>
  :
#<buffer: *REPL*>

See Also:

レスポンス・ボディを読み捨てるための receiver です。

http-response-resultnil を返します。

See Also:

Function: http-general-receiver CALLBACK &key (:encoding t) :line

レスポンス・ボディを受信するたびに CALLBACK で指定した任意の処理を行うための receiver です。

  • :linenil を指定した場合:
    • 受信したレスポンスをそのまま CALLBACK に指定して呼び出します。
  • :linenon-nil を指定した場合:
    • 1 行ごとに分割して CALLBACK を呼び出します。
    • 受信したレスポンス・ボディに改行文字が含まれない場合、CALLBACK は呼び出さずに次のレスポンス・ボディを待ちます。 次に改行文字を受信した時点でレスポンス・ボディを結合して CALLBACK を呼び出します。
    • レスポンス・ボディの終端に達した場合は、改行文字がなくてもそれまで受信していたレスポンス・ボディを 結合して CALLBACK を呼び出します。 このときにアプリケーションレベルでは不完全なデータが CALLBACK に指定される可能性があります。 その後 CALLBACKnil を指定して呼び出します。 その時の戻り値が http-response-result の戻り値となります。
  • :encoding にエンコーディングを指定した場合は、指定されたエンコーディングで 内部エンコーディングに変換します。
  • :encodingnon-nil を指定した場合は、Content-Type の charaset パラメータで 指定されたエンコーディングで内部エンコーディングに変換します。 charaset からエンコーディングを特定できない場合、 内部エンコーディングへの変換は行いません。
  • :encodingnil または :binary を指定した場合は、 内部エンコーディングへの変換は行いません。
  • :encoding を指定した場合、または :line を指定した場合は、改行コードも内部コードに変換します。
  • レスポンス・ボディの終端に達した場合は、CALLBACKnil を指定して呼び出します。 その時の戻り値が http-response-result の戻り値となります。
http-client.api> (defun chunk-size (url &key line)
                   (let* ((chunk-size)
                          (r (http-get url
                                       :receiver (http-general-receiver
                                                  #'(lambda (chunk)
                                                      (if chunk
                                                          (push (length chunk) chunk-size)
                                                        chunk-size))
                                                  :line line))))
                     (http-response-result r)))

http-client.api> (chunk-size "http://www.jsdlab.co.jp/~kamei/" :line t)
(8 9 81 7 8 22 84 20 68 18 101 18 53 20 64 20 55 19 79 24 68 18 95 ...)

http-client.api> (chunk-size "http://www.jsdlab.co.jp/~kamei/")
(2510 574)

See Also:

Macro: http-cond-receiver (STATUS HEADERS CONTENT-LENGTH) &BODY FORMS

レスポンスで条件分岐を行い receiver を選択するためのマクロです。

200 OK の場合は http-file-receiver を利用してファイルをダウンロードし、 それ以外の場合は http-string-receiver を利用してエラーメッセージを 文字列で受信するということができます。

  • STATUS, HEADERS, CONTENT-LENGTH は receiver が受け取る引数名を指定します。
  • FORMS はそのまま cond に展開されます。
  • FORMS は receiver を返すように実装してください。
http-client.api> (defun http-download-sync (uri localfile)
                   (http-response-values
                    (http-get uri
                              :receiver (http-cond-receiver (status headers content-length)
                                          ((= status 200)
                                           (http-file-receiver localfile))
                                          (t
                                           (http-string-receiver)))
                              )))
http-download-sync

http-client.api> (http-download-sync "http://www.jsdlab.co.jp/~kamei/cgi-bin/download.cgi"
                                     "c:/xyzzy.lzh")
"c:/xyzzy.lzh"
200
(("Date" . "Wed, 01 Feb 2012 01:55:17 GMT") ("Server" . "Apache/2.0") ...)
"http://www.mars.dti.ne.jp/~t-kamei/xyzzy/xyzzy-0.2.2.235.lzh"

http-client.api> (http-download-sync "http://www.jsdlab.co.jp/~kamei/cgi-bin/download"
                                     "c:/xyzzy.lzh")
"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">
<HTML><HEAD>
<TITLE>404 Not Found</TITLE>
</HEAD><BODY>
<H1>Not Found</H1>
The requested URL /~kamei/cgi-bin/download was not found on this server.<P>
<HR>
<ADDRESS>Apache/1.3.41 Server at www.jsdlab.co.jp Port 80</ADDRESS>
</BODY></HTML>
"
404
(("DeleGate-Ver" . "7.9.6 (delay=1)") ("Date" . "Thu, 02 Feb 2012 03:25:23 GMT") ...)
"http://www.jsdlab.co.jp/~kamei/cgi-bin/download"

See Also:

Function: http-request-abort CLIENT

指定した CLIENT を中断します。

引数には以下の関数の戻り値を指定可能です。

通信を中断したなら t を返します。 既に通信が終了していたら何もせず nil を返します。

abort 処理は非同期に実行されます。 abort 呼び出し直後は http-response-completed-p は nil を返します。

http-client.api> (let ((req (http-get "http://www.google.co.jp/")))
                   (flet ((ping ()
                            (list :aborted-p (http-request-aborted-p req)
                                  :waiting-p (http-response-waiting-p req)
                                  :completed-p (http-response-completed-p req))))
                     (values
                      (ping)
                      (http-request-abort req)
                      (ping)
                      (http-response-wait req)
                      (ping)
                      )))
(:aborted-p nil :waiting-p t :completed-p nil) ;
t ;
(:aborted-p t :waiting-p t :completed-p nil) ;
t ;
(:aborted-p t :waiting-p nil :completed-p t)

See Also:

Function: http-response-wait CLIENT &key :nowait :no-redraw :sleep (:timeout 30) (:interval 0.1) (:ready-state :complete) (:abort-on-quit t) (:signal-error t)

CLIENT で指定したリクエストが完了するのを待ちます。 リクエストが完了した場合は t を返します。

  • :nowaitnon-nil を指定するとリクエストが完了していない場合は 待ち合わせをせずにすぐに nil を返します。

    デフォルトは nil です。

  • :no-redrawnon-nil を指定するとリクエストの完了待ち中に 画面の再描画を行いません。

    デフォルトは nil です。

  • :sleepnon-nil を指定するとリクエストの完了待ち中に キー入力があっても中断しません。

    :sleepnil の場合キー入力があったら待ち合わせを中断します。 中断時点でリクエスト完了していない場合は nil を返します。

    :sleep を指定した場合は画面の再描画を行いません。

    デフォルトは nil です。

  • :timeout を指定すると指定した秒数以内にリクエストが完了しない場合、 nil を返します。

    :timeoutnil を指定するとタイムアウトせずに無限に待ち合わせます。

    デフォルトは 30 秒です。

  • :interval は監視間隔です。

    デフォルトは 0.1 秒です。

  • :ready-state は待ち合わせる状態を指定します。

    • :loading を指定するとレスポンス・ヘッダの受信完了を待ち合わせます。
    • :complete を指定するとレスポンス・ボディの受信完了を待ち合わせます。

    デフォルトは :complete です。

  • :abort-on-quitnon-nil を指定すると、待ち合わせ中に Ctrl-g で停止した場合に リクエストを abort します。

    デフォルトは t です。

  • :signal-errornon-nil を指定すると、非同期処理で発生したエラーを再送します。

    デフォルトは t です。

See Also:

Function: http-request-aborted-p CLIENT

CLIENTabort した場合 t を返します。

引数には以下の関数の戻り値を指定可能です。

See Also:

Function: http-response-completed-p CLIENT

指定した CLIENT が完了したなら t を返します。

  • リクエストを abort した場合 でも t を返します。
  • リクエストを abort した直後は nil を返します。abort 処理が完了すると t を返します。
  • リクエストが完了したか abort したかは、http-request-aborted-p で区別します。

引数には以下の関数の戻り値を指定可能です。

See Also:

Function: http-response-waiting-p CLIENT

指定した CLIENT がまだ処理中なら t を返します。

引数には以下の関数の戻り値を指定可能です。

See Also:

Function: http-request-uri CLIENT

リクエストした URL を取得します。 リダイレクトした場合はリダイレクト後の URL になります。

http-client.api> (let ((r (http-get "http://goo.gl/bgggL")))
                   (http-request-uri r))
"http://www.jsdlab.co.jp/~kamei/"

Function: http-request-header CLIENT HEADER

指定したリクエスト・ヘッダを取得します。 ヘッダ名は文字列またはシンボルで指定します (case-sensitive)。

http-client.api> (let ((r (http-get "http://www.google.co.jp/")))
                   (http-request-header r "User-Agent"))
"xyzzy/0.2.2.235"

http-client.api> (let ((r (http-get "http://www.google.co.jp/")))
                   (http-request-header r :user-agent))
"xyzzy/0.2.2.235"

Function: http-request-header-alist CLIENT

すべてのリクエスト・ヘッダを alist で取得します。

http-client.api> (let ((r (http-get "http://www.google.co.jp/"
                                    :headers `(:X-Foo 1))))
                   (http-request-header-alist r))
(("X-Foo" . "1")
 ("User-Agent" . "xyzzy/0.2.2.235")
 ("Connection" . "Keep-Alive"))

Function: http-response-status CLIENT

ステータスコードを数値で取得します。

Function: http-response-status-text CLIENT

ステータスコードを文字列で取得します。

http-client.api> (let ((r (http-delete "http://www.google.co.jp/")))
                   (values (http-response-status r)
                           (http-response-status-text r)))
405 ;
"Method Not Allowed"

Function: http-response-header CLIENT HEADER

指定したレスポンス・ヘッダを取得します。 ヘッダ名は文字列またはシンボルで指定します (case-sensitive)。

http-client.api> (let ((r (http-get "http://www.jsdlab.co.jp/~kamei/")))
                   (http-response-header r "Last-Modified"))
"Wed, 07 Dec 2005 14:45:00 GMT"

http-client.api> (let ((r (http-get "http://www.jsdlab.co.jp/~kamei/")))
                   (http-response-header r :last-modified))
"Wed, 07 Dec 2005 14:45:00 GMT"

すべてのレスポンス・ヘッダを alist で取得します。

http-client.api> (let ((r (http-get "http://www.google.co.jp/")))
                   (http-response-header-alist r))
(("Cache-Control" . "private, max-age=0")
 ("Date" . "Wed, 01 Feb 2012 12:40:48 GMT")
 ("Transfer-Encoding" . "chunked")
 ...)

Function: http-response-result CLIENT

receiver が返した結果を取得します。

See Also:

Function: http-response-values CLIENT

以下の値を多値で返します。

  1. http-response-result
  2. http-response-status
  3. http-response-header-alist
  4. http-request-uri
http-client.api> (http-response-values
                  (http-get "http://www.google.co.jp/"))
"<!doctype html>
  ...
</script>"
200
(("Cache-Control" . "private, max-age=0") ("Date" . "Thu, 02 Feb 2012 12:44:32 GMT") ...)
"http://www.google.co.jp/"

Function: http-compose-query PATH PARAMS &optional ENCODING

PATHPARAMS からリクエスト URI を作成します。

  • ENCODING を指定した場合は、PARAMS のエンコーディングを変換した上で url エンコードを行います。
  • PARAMS が文字列の場合はそのままサーバに渡されるので、呼び出し側で必要な文字コード変換や url エンコーディングを行う必要があります。
http-client.api> (http-compose-query "/search"
                                     '((q "xyzzy 読み方") (num 30)))
"/search?q=xyzzy%20%93%C7%82%DD%95%FB&num=30"

http-client.api> (http-compose-query "/search"
                                     '((q "xyzzy 読み方") (num 30))
                                     *encoding-utf8n*)
"/search?q=xyzzy%20%E8%AA%AD%E3%81%BF%E6%96%B9&num=30"

http-client.api> (http-compose-query "/search"
                                     "q=xyzzy%20%93%C7%82%DD%95%FB&num=30")
"/search?q=xyzzy%20%93%C7%82%DD%95%FB&num=30"

See Also:

Function: http-compose-form-data PARAMS PORT &optional ENCODING

PARAMS から multipart/form-data 形式のリクエストを作成します。

  • PORT に output-stream を指定した場合はリクエストを PORT に書き込み、 PORT と boundary 文字列を多値で返します。
  • PORTnil を指定した場合はリクエストと boundary 文字列を多値で返します。
http-client.api> (setf body '((q "xyzzy 読み方") (num 50)))
((q "xyzzy 読み方") (num 50))

http-client.api> (http-compose-form-data
                  body nil)
"--boundary-7hcecyuy0h20wigl8hrrn0jior89i24vtfrifjebd
Content-Disposition: form-data; name=\"q\"

xyzzy 読み方
--boundary-7hcecyuy0h20wigl8hrrn0jior89i24vtfrifjebd
Content-Disposition: form-data; name=\"num\"

nil
--boundary-7hcecyuy0h20wigl8hrrn0jior89i24vtfrifjebd--
" ;
"boundary-7hcecyuy0h20wigl8hrrn0jior89i24vtfrifjebd"

http-client.api> (http-compose-form-data
                  body
                  (make-buffer-stream
                   (get-buffer-create "*form*")))
#<buffer stream 79566604> ;
"boundary-23vt3uiri0nrp4ftwbnwnuiajo4bvl6r2jcixdyv0"

See Also:

Function: http-date-from-universal-time UNIVERSAL-TIME

universal-time を RFC 1123 で定義されている日付形式に変換します。

http-client.api> (http-date-from-universal-time (encode-universal-time 1 2 3 4 5 2012 0))
"Fri, 04 May 2012 03:02:01 GMT"

See Also:

Function: http-date-to-universal-time HTTP-DATE

RFC 1123 で定義されている日付形式を universal-time に変換します。

http-client.api> (http-date-to-universal-time "Fri, 04 May 2012 03:02:01 GMT")
3545089321

http-client.api> (decode-universal-time 3545089321 0)
1 ;
2 ;
3 ;
4 ;
5 ;
2012 ;
4 ;
nil ;
0

http-client.api> (let* ((client (http-head "http://www.jsdlab.co.jp/~kamei/"))
                        (last-mod (http-response-header client :last-modified)))
                   (values last-mod
                           (http-date-to-universal-time last-mod)))
"Wed, 07 Dec 2005 14:45:00 GMT"
3342955500

See Also:

本ライブラリのバージョンを文字列で返します。

http-client.api> (http-client-version)
"1.0.0"