square / retrofit

A type-safe HTTP client for Android and the JVM
https://square.github.io/retrofit/
Apache License 2.0
43.01k stars 7.3k forks source link

`:` not being Url Encoded #3126

Closed AndrewReitz closed 5 years ago

AndrewReitz commented 5 years ago
const val EXAMPLE_API_TOKEN = "12345123:QkJGb3VsSUdCYk1tdkNFOHJWVm-ak"

fun main() {
    val service = Retrofit.Builder()
            .baseUrl("https://api.telegram.org/")
            .addConverterFactory(MoshiConverterFactory.create())
            .build()
            .create(TelegramBotService::class.java)

    service.getUpdates(EXAMPLE_API_TOKEN).execute()
}

interface TelegramBotService {
    @GET("bot{token}/getUpdates")
    fun getUpdates(@Path("token") token: String): Call<Any>
}

This will fail with:

Exception in thread "main" java.lang.IllegalArgumentException: Malformed URL. Base: https://api.telegram.org/, Relative: bot12345123:QkJGb3VsSUdCYk1tdkNFOHJWVm-ak/getUpdates at retrofit2.RequestBuilder.get(RequestBuilder.java:232) at retrofit2.RequestFactory.create(RequestFactory.java:120) at retrofit2.OkHttpCall.createRawCall(OkHttpCall.java:192) at retrofit2.OkHttpCall.execute(OkHttpCall.java:175) at cash.andrew.retrofit.AppKt.main(App.kt:22) at cash.andrew.retrofit.AppKt.main(App.kt)

By url encoding the api-token and changing the Path annotation to (@Path("token", encoded = true) this will work.

Seems like something that I would expect to be done by retrofit automatically. Let me know if I can provide any more details.

AndrewReitz commented 5 years ago

Possibly related to #2940

swankjesse commented 5 years ago

Try this:

interface TelegramBotService { @GET("/bot{token}/getUpdates") fun getUpdates(@Path("token") token: String): Call<Any> } 

Note the leading /.

JakeWharton commented 5 years ago

This is a dupe of #3080 actually. We need to make ./stuff work since the base URL is guaranteed to end in a / it's not path traversal