GNU GuileのHTTPレスポンスで日本語が文字化けする問題の解決法

目次

投稿日: 2024-11-30 土

GNU Guile でHTTPレスポンスを処理するプログラムを書いていて、 日本語が文字化けする問題ではまって1時間くらい時間を溶かしました。

公式ドキュメントをみれば分かるというのはそうなのですが、 求めている情報がどこにあるのかよく分からず迷走したので、 解決方法を備忘録として残しておきます。

結論としては、ただの port のエンコーディングの問題だったのですが、 手元のファイルを call-with-input-file などで開いたときには、 問題なく日本語を扱えることから port 側の問題だと思わず、 HTTP関連特有の問題かと思って調べたのではまりました。

1. 前提: GNU Guile の http クライアントの使い方

GNU Guile Reference Manual の 7.3 HTTP, the Web, and All That に Guile で HTTP プロトコルを扱う方法が記載されています。

たとえば、ある url に対して POST メソッドでリクエストを投げる場合は次のようにします。

(define response
  (http-request uri
                #:body body
                #:method 'POST
                #:streaming? #t))

http-request の戻りとして response というオブジェクトが得られます。 これを処理すれば、HTTPネットワーク上のリソースを扱うことができます。

(response-body-port response) でテキストのポートが得られ、 body 部を読み取ることができるのですが、 このときに日本語が文字化けしてはまりました。

2. 解決方法: port のエンコーディングを確認し変更する

GNU Guile Reference Manual の 6.12.3 Encoding の節に記載があるように、 port にはエンコーディングの仕方が設定されており、 GNU Guile では port-encoding でポートのエンコーディングの確認、 set-port-encoding! でポートのエンコーディングの変更ができます。

私の場合はポートのエンコーディングが ISO-8859-1 になっていたせいで、 文字化けが発生していました。

scheme@(guile-user)> (port-encoding (response-body-port response))
$87 = "ISO-8859-1"

これを set-port-encoding! を使って UTF-8 にすれば解決です。

scheme@(guile-user)> (define port (response-body-port response))
scheme@(guile-user)> (port-encoding port)
$89 = "ISO-8859-1"
scheme@(guile-user)> (set-port-encoding! port "UTF-8")
scheme@(guile-user)> (port-encoding port)
$90 = "UTF-8"

3. おわりに

GNU Guile の日本語の情報を増やし、 GNU Guile を使ってみようと思う人が増えればと思い記事にしてみました。

GNU Guile ではまってもドキュメントを漁ればだいたいなんとかなるので、 GNU か Scheme が好きな人は是非使ってみてください。

今後も、GNU Guile ではまったことを記事にしていき、 日本語の知見を増やしていければと思います。

著者: Masaya Tojo

Mastodon: @tojoqk

RSS を購読する

トップページに戻る