概要
インスタンスのアクターの情報に記されている inbox へ POST される HTTP リクエストをポート(もしくは UNIX ドメインソケット)に流して、netcat で取得する。
実装
Caddyfile ファイルの
ホニャララ{ 〜 }
内に以下を加える。
ホニャララ {
(中略)
handle_path /users/aktor/inbox {
reverse_proxy localhost:1682
}
}
ポートを開けたくないなどの理由で UNIX ドメインソケットを使う場合は
reverse_proxy localhost:1682
を
reverse_proxy unix//tmp/sock
などに変える。
取り敢えずは
netcat -lk 1682
(UNIX ドメインソケットを使う場合は
netcat -Ulk /tmp/sock
など)
とすれば、@aktor@ホニャララ への反応(メンションやフォローリクエスト)などをターミナルの標準出力へ流すことが出来る。
ただしこれでは HTTP ステータスコードを返せていない。Mastodon の場合、200 または 202 を返さないとおよそ 50 時間に渡って 16 回も同じリクエストを送り続ける(https://blog.noellabo.jp/entry/2020/03/07/oq3sL7PQhFMrc6Bb )ので、202 くらいを返して止めたい。しかしネットワークの状況などによってたまにリクエストのボディがないまま送られてくることもあるので、
- ボディがあったらリクエストをファイルに取り、取り敢えず 202 を返して配送を止める
- ボディが無かったら(一応ファイルには残し) 204 を返し、再配送を求める
とすることにする。
202 204 というディレクトリと、response という名前付きパイプを使うので
mkdir 202 204
mkfifo response
と作り
#!/bin/bash
file_name=$(date "+%s")
while read -r line;
do
trline=$(echo $line | tr -d "\r\n")
echo "$trline"
content_reg='Content-Length:\s(.*?)'
[[ "$trline" =~ $content_reg ]] &&
CONTENT_LENGTH=$(echo $trline | sed -E "s/$content_reg/\1/")
[ -z "$trline" ] && break
done > $file_name
temp=$(head -c $CONTENT_LENGTH -)
echo $temp >> $file_name
if [ "$temp" ]; then
printf "HTTP/1.1 202\r\n\r\n" > response
mv $file_name ./202/$file_name
echo "anything to 202"
else
printf "HTTP/1.1 202\r\n\r\n" > response
mv $file_name ./204/$file_name
echo "anything to 204"
fi
このシェルスクリプトに netcat から流す。
このシェルスクリプトが何をやっているかの詳しいことはこの拙記事(https://qiita.com/tochu-cha/items/fb744ae3715c0807ecc6 )を見ていただきたい。
これを
bash while :; do cat temp | netcat -lN 1682 | bash response_move.sh ; done
と netcat と組み合わせて実行する。
これで Mastodon その他からの POST を 202 もしくは 204 のステータスコードを返して、 202 ディレクトリもしくは 204 ディレクトリにファイルとして残すことが出来る。
参考記事
Mastodonが配送に失敗したジョブに対処する仕組み
netcat スクリプトで curl からのリクエストを受け取りファイルに保持してステータスコードを返す