LoginSignup
0
0

More than 3 years have passed since last update.

Slack に Java のライブラリがどのようなリクエストを投げているかを調べるため Charles を使って HTTP トレースをとった話

Posted at

概要

レガシーの Java アプリケーションが slack-api を使って通知していましたが、2020 年 3 月初旬になったら通知に失敗するようになりました。
Mac でトラブルシュートをするため、通知に失敗しているリクエストのペイロードがどのような内容であるかを確かめたいと考えました。
Fiddler を使ってトレースを取ろうとしましたが、乗ってきてくれないので、Charles を使うことに。
curl では、こちら を参考に、localhost:8888 へのプロキシを -x で指定すると、Chales でログが取得できました。

curl -x localhost:8888 -X POST --data-urlencode "payload={\"channel\": \"#general\", \"username\": \"gpedro Bot\", \"text\": \"これは #general に投稿されています。\", \"icon_emoji\": \":ghost:\"}" https://hooks.slack.com/services/<YOUR>/<TOKEN>

Java アプリケーションでは、どのように Charles で Http トレースをとるのか、というのがいまいちわからなかったので調べることにしました。

やり方

私のアプリケーションは、このライブラリ を使っていてました。随分メンテナンスが放って置かれていますし、マイナー感がでていますので、このライブラリについては、この記事をご覧になられている方々はまちがいなく使われていないのではないかと思います。
ただ、Proxy クラス やあるいはそれに相当する設定を実施して、なんらかの形で HTTP リクエストを Proxy 経由で送信する方法は、どのライブラリでも存在しているのではと考えています。1
このライブラリを使う際についても、デフォルトで API をコールするインスタンスを生成するのではなく、Proxy クラス を指定して、インスタンスを作ることができました。この方法でインスタンスを生成すると、Charles を使ってこのライブラリのリクエストの HTTP トレースをとることができました。もしも、トラブルシュートをしたいライブラリので、なんらかの形で参考になれば幸いです。

Charles のインストール

こちらの記事 を参考にインストールします。キーチェーンに入った、Charles Proxy.... という証明書を信頼します。

Charles の証明書をエクスポート

キーチェーンにて、Charles Proxy... の証明書を右クリック -> [Charles Proxy CA を書き出す] にて証明書をエクスポートします。
証明書の名前にはエスケープ文字が多く含まれるので、必要に応じて名前をシンプルなものに変更します。

JDK のライブラリへ証明書インポート

こちらの記事 の通り、インポートします。
私の場合は、AWS Corretto 8 を使っていたので下記でインポートしました。パスワードは上述の記事の通りでした。

sudo keytool -import -trustcacerts -file ~/Documents/charles_proxy.cer  -keystore /Library/Java/JavaVirtualMachines/amazon-corretto-8.jdk/Contents/Home/jre/lib/security/cacerts -alias ca

Proxy を指定してリクエストする

curl のときと同様に、Charles のポート 8888 を指定して、リクエストします。
このライブラリでは、

import net.gpedro.integrations.slack.SlackApi;
import net.gpedro.integrations.slack.SlackMessage;

import java.net.InetSocketAddress;
import java.net.Proxy;

public class SlackExecute {

    public static void main(String[] args) {

        SlackMessage slackMessage = new SlackMessage(
                "#genearal",
                "gpedro Bot",
                "gpedro で Slack リクエストできますか"
        );
        slackMessage.setIcon(":ghost:");
        SlackApi api = new SlackApi(
                "https://hooks.slack.com/services/<SOME>/<TOKEN>", 
                new Proxy(
                    Proxy.Type.HTTP,
                    new InetSocketAddress("localhost", 8888)
                )
         );
        api.call(slackMessage);
    }
}

Charles を起動してアプリケーションを実行

これで、Charles の左ペーンに、https://hooks.slack.com が現れて内容をトレースできます。

{
    "channel": "#genearal",
    "username": "gpedro Bot",
    "icon_emoji": ":ghost:",
    "unfurl_media": false,
    "unfurl_links": false,
    "link_names": false,
    "text": "gpedro でリクエストできますか"
}

  1. 例えば Spring 5 にはリクエストを行う WebClient インターフェース があり、この記事 にプロキシの指定の仕方が記載されています。このクラスの場合、WebClient.Builder#clientConnector メソッドがあります。このメソッドの引数には、ClientHttpConnector クラス が指定できます。この実装クラスの ReactorClientHttpConnectorコンストラクタ には、HttpClient が指定できます。HttpClienttcpConfiguration メソッド は、TcpClient クラス を引数にとる関数を引数にし、TcpClient クラス の、proxy メソッド は、ProxyProvider.TypeSpec の実装を引数とする関数を引数に取ります。ProxyProvider.TypeSpec インターフェースの type メソッド で、Proxy のタイプを、ProxyProvider.TypeSpec インターフェースの type メソッドの戻り値の ProxyProvider.AddressSpec の実装で、ホストまたは InetSocketAddress クラス を指定できます。Proxy クラス を使いませんが、同じことを実現しています。 

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0