結論
パッチを投げました。
概要
EmacsのHTTPクライアント request.el というものがあります。これはcurlのラッパーみたいなもので、GETしたりPOSTしたりするのに大変便利なのですが、以下のようにマルチバイト文字の入ったJSONデータをPOSTしたりPUTしようとしたりすると死にます。POSTできませんが、elisp側でエラーは検出されません。
(request "http://httpbin.org/put" :type "PUT" :data (json-encode '(("key" . "値1") ("key2" . "値2"))) :headers '(("Content-Type" . "application/json")) :parser 'json-read :success (cl-function (lambda (&key data &allow-other-keys) (message "I sent: %S" (assoc-default 'json data)))))
直接の原因はここです。curlでデータを送信するときにテンポラリのバッファにデータを入れているのですが、このときバッファのエンコーディングが 'binary
になっているので、マルチバイト文字はユニコードに変換されたうえでHTTPリクエストされます。そのためにリクエストがエラーになってしまいます。
(when data (let ((tempfile (request--make-temp-file))) (push tempfile (request-response--tempfiles response)) (let ((file-coding-system-alist nil) (coding-system-for-write 'binary)) (with-temp-file tempfile (setq buffer-file-coding-system 'binary) (set-buffer-multibyte nil) (insert data))) (list "--data-binary" (concat "@" (request-untrampify-filename tempfile)))))
https://github.com/tkf/emacs-request/blob/master/request.el#L917-L926
んじゃあここの buffer-file-coding-system
を 'utf-8
にして、 set-buffer-multibyte
の設定をやめたらいいのでは?と思うのですが、これWindowsなど別の文字コードをベースにしてrequestするとまた別の問題が発生するかもしれないので、ココの部分を変数でもってユーザー側で変更できるようにしました。デフォルトは 'binary
なので、既存のものはそのまま使えます。
ほんとはココと結構被るのですが、テストコードやドキュメントを追加した感じになります。
と言った感じの備忘録です。
問題点
最後のメンテが2017/1で1年近くメンテされておらず、誰がメンテナーなのかわかりません。ので、取り込まれるどころかレビューされるかどうかも怪しいです。気長にまとうと思います。