てくてくてっく

おそらく技術ブログ

OkHttpのUserAgentにGitのタグバージョンを入れる

OkHttpでリクエストを発行した際のUserAgentはデフォルトで okhttp/4.10.0 のようにクライアントのバージョンが設定されます。
ここにアプリ自体のバージョン情報をのせることができると、サーバー側でのログ調査がスムーズかと思います。

目次

  • OkHttpのUserAgentの設定方法
  • GradleでGitのタグ情報をSystemPropertyに設定
  • SystemPropertyの取得

OkHttpのUserAgentの設定方法

UserAgentヘッダーの設定方法はいくつかあるかと思いますが、今回は下記のようにInterceptorでリクエストを上書きする形をとります。

まずはokhttp3.Interceptor のインターフェースを実装し、リクエストヘッダーを上書きします。

public class UserAgentInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();

        // ヘッダーの上書き 
        Request withHeaderRequest = request.newBuilder()
            .addHeader("User-Agent", "myapp/" + "v0.0.0-dummy")
            .build();

        Response response = chain.proceed(withHeaderRequest);
        return response;
    }
}

作成したInterceptor をOkHttpのクライアント生成時に設定します。

public class OkhttpSample {
    public static void main(String[] args) {
        OkHttpClient client = new OkHttpClient.Builder()
            .addInterceptor(new UserAgentInterceptor()) // Interceptorを追加
            .build();
        Request request = new Request.Builder()
            .url("https://httpbin.org/get")
            .build();
        
        try {
            Response response =  client.newCall(request).execute();
            System.out.println(response.body().string());
        } catch (IOException e) {
            // TODO: handle exception
        }
    }
}

動作確認

上記サンプルでは httpbin.org をURLに設定しており、このエンドポイントはヘッダーの中身を返却してくれます。
下記のようにUserAgentが上書きできていることがわかります。

gradle run

> Task :run
{
  "args": {}, 
  "headers": {
    "Accept-Encoding": "gzip", 
    "Host": "httpbin.org", 
    "User-Agent": "myapp/v0.0.0-dummy", 
    "X-Amzn-Trace-Id": "Root=1-631f59b2-69d9c7ba558ff76856acebdc"
  }, 
  "origin": "*.*.*.*", 
  "url": "https://httpbin.org/get"
}

GradleでGitのタグ情報をSystemPropertyに設定

つづいて、Gitのタグ情報取得についてです。こちらは gradle-git-version というGradleプラグインがありこちらを利用します。

利用は簡単でbuild.gradleに下記のようにプラグインを追加し、

plugins {
    id 'com.palantir.git-version' version '0.15.0'
}

あとは追加される gitVersion() をコールします。今回はrunタスク内でシステムプロパティとして設定してみます。 runの部分は適宜ビルドに用いているタスクに合わせて置き換えてください。

run {
    systemProperties['app.version'] = gitVersion()
}

SystemPropertyの取得とUserAgentの上書き

最後にGitのタグ情報を設定したプロパティを取得し、ヘッダーを上書きします。
今回は lightbend/config を使ってプロパティを読み取りました。この辺りはプロジェクトで普段使っているプロパティ系のライブラリでよいかと思います。 build..gradleに依存を追加し、

dependencies {
    implementation('com.typesafe:config:1.4.2')
}

Interceptorのコンストラクタで読み取りました。

public class UserAgentInterceptor implements Interceptor {
    private static String appVersion;
    public UserAgentInterceptor() {
        Config conf = ConfigFactory.load();
        appVersion = conf.getString("app.version");
    }
    // ...

あとはinterceptのヘッダーを上書きしてあげれば完成です。

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();

        Request withHeaderRequest = request.newBuilder()
            .addHeader("User-Agent", "myapp/" + appVersion) // コンストラクタで設定した値に変更 ☆
            .build();

        Response response = chain.proceed(withHeaderRequest);
        return response;
    }

動作確認

あとは git tag v0.0.3 のようにタグをうち、
Gradleタスクを実行すれば、UserAgentが動的に書き換わっていることが確認できます。

gradle run

> Task :run
{
  "args": {}, 
  "headers": {
    "Accept-Encoding": "gzip", 
    "Host": "httpbin.org", 
    "User-Agent": "myapp/v0.0.3", 
    "X-Amzn-Trace-Id": "Root=1-631f5df8-4723b5e342497eb9317bf8e4"
  }, 
  "origin": "*.*.*.*", 
  "url": "https://httpbin.org/get"
}


BUILD SUCCESSFUL in 4s

コードサンプル

今回紹介したコードはGitHubで公開しています。

github.com

参考文献