63

I am using okhttp 2.0 in my Android app and didn't find a way to set some common User Agent for all outgoing requests.

I thought I could do something like

OkHttpClient client = new OkHttpClient();
client.setDefaultUserAgent(...)

...but there's no such method or similar. Of course I could provide some extension utility method which would wrap a RequestBuilder to attach .header("UserAgent") and then I would use it for building all my requests, but I thought maybe I missed some existing and simpler way?

7 Answers 7

108

You can use an interceptor to add the User-Agent header to all your requests.

For more information about okHttp interceptors see http://square.github.io/okhttp/interceptors/

Example implementation of this interceptor:

/* This interceptor adds a custom User-Agent. */
public class UserAgentInterceptor implements Interceptor {

    private final String userAgent;

    public UserAgentInterceptor(String userAgent) {
        this.userAgent = userAgent;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request originalRequest = chain.request();
        Request requestWithUserAgent = originalRequest.newBuilder()
            .header("User-Agent", userAgent)
            .build();
        return chain.proceed(requestWithUserAgent);
    }
}

Test for the UserAgentInterceptor:

public void testUserAgentIsSetInRequestHeader() throws Exception {

    MockWebServer server = new MockWebServer();
    server.enqueue(new MockResponse().setBody("OK"));
    server.play();
    String url = server.getUrl("/").toString();

    OkHttpClient client = new OkHttpClient();
    client.networkInterceptors().add(new UserAgentInterceptor("foo/bar"));
    Request testRequest = new Request.Builder().url(url).build()
    String result = client.newCall(testRequest).execute().body().string();
    assertEquals("OK", result);

    RecordedRequest request = server.takeRequest();
    assertEquals("foo/bar", request.getHeader("User-Agent"));
}
2
  • 9
    That is so much work is there no default implementation for this kind of thing? Jun 24, 2015 at 17:12
  • 1
    Is this still the best way for okhttp3?
    – Janusz
    Feb 6, 2020 at 13:22
36

In case anyone is looking for this working with OkHttp 3 and in Kotlin:

val client = OkHttpClient.Builder()
    .addNetworkInterceptor { chain ->
      chain.proceed(
          chain.request()
              .newBuilder()
              .header("User-Agent", "COOL APP 9000")
              .build()
      )
    }
    .build()
4
  • Thanks! First I tried addInterceptor, but that was wrong.
    – CoolMind
    Oct 14, 2019 at 16:49
  • 1
    addInterceptor should work as well (It did for me). Perhaps you couldn't see it in the logs if you had a logging interceptor added first.
    – Matt Wolfe
    Aug 22, 2020 at 15:46
  • somehow for me adding interceptor while creating the http client worked, But when i tried adding the header in the authenticationInterceptor, It did not work Sep 1, 2021 at 10:30
  • Another example of how simple and clear Kotlin is.
    – Greelings
    Jun 26, 2022 at 13:53
10

OkHttp v2.1 which is set to be released in the next few weeks will automatically set a User-Agent header if one is not already set.

As of now there isn't a good way to add this header to every request in a centralized way. The only workaround is to include the header manually for every Request that is created.

3
  • Thanks, good to know I didn't miss anything. Yes, I saw a github issues regarding the auto setting of User-Agent.
    – dimsuz
    Oct 23, 2014 at 9:47
  • 1
    Can you update the answer to include how to do it? Thanks :)
    – djunod
    Jul 11, 2016 at 12:17
  • Because of this, please take care to use header(...) instead of addHeader(...) so you will not have duplicate User-Agent header May 2, 2019 at 12:06
10

Based on @josketres answer, here is a similar Interceptor for OkHttp version 3

public class UserAgentInterceptor implements Interceptor {
    private final String mUserAgent;

    public UserAgentInterceptor(String userAgent) {
        mUserAgent = userAgent;
    }

    @Override
    public Response intercept(@NonNull Chain chain) throws IOException {
        Request request = chain.request()
                .newBuilder()
                .header("User-Agent", mUserAgent)
                .build();
        return chain.proceed(request);
    }
}

Plus the updated test:

@Test
public void testUserAgentIsSetInRequestHeader() throws IOException, InterruptedException {
    final String expectedUserAgent = "foo/bar";

    MockWebServer server = new MockWebServer();
    server.enqueue(new MockResponse().setBody("OK"));
    server.start();

    OkHttpClient.Builder okHttpBuilder = new OkHttpClient.Builder();
    okHttpBuilder.addInterceptor(new UserAgentInterceptor(expectedUserAgent));
    Request request = new Request.Builder().url(server.url("/").url()).build();
    ResponseBody result = okHttpBuilder.build().newCall(request).execute().body();
    assertNotNull(result);
    assertEquals("OK", result.string());

    assertEquals(expectedUserAgent, server.takeRequest().getHeader("User-Agent"));
}
7

Using an intercepter is no longer required in the newer versions of OkHttp. Adding a user agent is as simple as:

Request request = new Request.Builder()
    .url("http://www.publicobject.com/helloworld.txt")
    .header("User-Agent", "OkHttp Example")
    .build();

Source: OkHttp wiki.

3
  • 5
    But that would require you do it for every request you send. An accepted answer has the same code you provided, only run inside an interceptor which is a nicer solution for the case where all the requests must have a certain User Agent.
    – dimsuz
    Mar 27, 2017 at 22:30
  • 1
    Yes, this is useful only if you have a fixed header.
    – Saket
    Mar 28, 2017 at 11:37
  • requestBuilder.addHeader() don't work but requestBuilder.header() do...
    – HSMKU
    Sep 15, 2023 at 19:51
7

You have to use builder in newer versions. (Sep 2021)

    client = new OkHttpClient.Builder()
            .addInterceptor(new Interceptor() {
                @NotNull
                @Override
                public Response intercept(@NotNull Chain chain) throws IOException {
                    Request originalRequest = chain.request();
                    Request requestWithUserAgent = originalRequest.newBuilder()
                            .header("User-Agent", "My Agent is so cool")
                            .build();
                    return chain.proceed(requestWithUserAgent);
                }
            })
            .build();
0

Adding an interceptor with Kotlin,

private val client = OkHttpClient.Builder()
   .addInterceptor(object: Interceptor{
       override fun intercept(chain: Interceptor.Chain): Response {
           val request = chain.request()
           val reqBuilder = request.newBuilder()
               .header("Accept-Language", Locale.getDefault().language)
               .header("User-Agent", "New User-Agent String")
           return chain.proceed(reqBuilder.build())
       }
   })
  .build()

private val retrofit: Retrofit = Retrofit.Builder()
   .baseUrl(Constants.BASE_URL)
   .client(client)
   .addConverterFactory(GsonConverterFactory.create())
   .build()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.