Zar E Ahmer
Zar E Ahmer

Reputation: 34370

Host interceptor HttpUrl.parse IllegalArguementException in latest Okhttp

I have to intercept host at run time . As my url is dynamic. below code is working fine in old okhttp3

Working with old Okhttp

class HostSelectionInterceptor @Inject constructor(val chiPrefs: ChiPrefs): Interceptor{

    override fun intercept(chain: Interceptor.Chain): Response {
        var request: Request = chain.request()

        var host = String.format(Locale.ENGLISH, "https://%s.cognitiveintl.com",
            chiPrefs.sitePrefix())

        request.url().pathSegments().forEach {
            host += "/$it"
        }

        if(host.isNotEmpty()){
            val newUrl = HttpUrl.parse(host)
            request = request.newBuilder().url(newUrl!!).build()
        }
        return chain.proceed(request)
    }
}

but after upgrading it to latest version .

val newUrl = HttpUrl.parse(host) // deprecated..

HttpUrl.parse. become deprecated..

After r & d , I update my code like

val newUrl = request.url.newBuilder()
    .host(host) ///crashed at this line 
    .build()
request = request.newBuilder()
    .url(newUrl)
    .build()

It give IllegalArguementException . Suggest a solution to it.

Crash :

FATAL EXCEPTION: OkHttp Dispatcher
    Process: com.chi.doctorapp.dev, PID: 2906
    java.lang.IllegalArgumentException: unexpected host: https://chi-dev1.cognitiveintl.com/api/doctor_app/GetProfile
        at okhttp3.HttpUrl$Builder.host(HttpUrl.kt:961)
        at com.chi.doctorapp.di.interceptors.HostSelectionInterceptor.intercept(HostSelectionInterceptor.kt:28)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100)

Upvotes: 5

Views: 2017

Answers (2)

Adrian K
Adrian K

Reputation: 4833

Using

 request.url.newBuilder()
    .host(host)
    .build()

would be the correct way.

The reason this crashes for you, is that pass a complete url as host.
For example for the url https://subdomain.example.com/some/path the host is subdomain.example.com

So instead try this:

class HostSelectionInterceptor @Inject constructor(val chiPrefs: ChiPrefs): Interceptor{

    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        
        //Notice the removed "https://"
        val host = String.format(Locale.ENGLISH, "%s.weburlintl.com",
            chiPrefs.sitePrefix())

        // This will keep the path, query parameters, etc.
        val newUrl = request.url.newBuilder()
            .host(host)
            .build()

        val newRequest = request
            .newBuilder()
            .url(newUrl)
            .build()

        return chain.proceed(newRequest)
    }
}

Upvotes: 1

Jesse Wilson
Jesse Wilson

Reputation: 40593

Replace this:

HttpUrl.parse(host)

With this:

host.toHttpUrlOrNull()

You'll need this import:

import okhttp3.HttpUrl.Companion.toHttpUrlOrNull()

This is documented in the upgrade guide.

Upvotes: 6

Related Questions