diff --git a/subsonic-api/src/integrationTest/kotlin/org/moire/ultrasonic/api/subsonic/GetStreamUrlTest.kt b/subsonic-api/src/integrationTest/kotlin/org/moire/ultrasonic/api/subsonic/GetStreamUrlTest.kt index 828e7af5..e1529d3d 100644 --- a/subsonic-api/src/integrationTest/kotlin/org/moire/ultrasonic/api/subsonic/GetStreamUrlTest.kt +++ b/subsonic-api/src/integrationTest/kotlin/org/moire/ultrasonic/api/subsonic/GetStreamUrlTest.kt @@ -25,7 +25,7 @@ class GetStreamUrlTest { USERNAME, PASSWORD, V1_6_0, CLIENT_ID) val baseExpectedUrl = mockWebServerRule.mockWebServer.url("").toString() expectedUrl = "$baseExpectedUrl/rest/stream.view?id=$id&u=$USERNAME" + - "&v=${V1_6_0.restApiVersion}&c=$CLIENT_ID&f=json&p=enc:${PASSWORD.toHexBytes()}" + "&c=$CLIENT_ID&f=json&v=${V1_6_0.restApiVersion}&p=enc:${PASSWORD.toHexBytes()}" } @Test diff --git a/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicAPIClient.kt b/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicAPIClient.kt index 19eb6415..772de383 100644 --- a/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicAPIClient.kt +++ b/subsonic-api/src/main/kotlin/org/moire/ultrasonic/api/subsonic/SubsonicAPIClient.kt @@ -9,7 +9,9 @@ import okhttp3.ResponseBody import okhttp3.logging.HttpLoggingInterceptor import org.moire.ultrasonic.api.subsonic.interceptors.PasswordHexInterceptor import org.moire.ultrasonic.api.subsonic.interceptors.PasswordMD5Interceptor +import org.moire.ultrasonic.api.subsonic.interceptors.ProxyPasswordInterceptor import org.moire.ultrasonic.api.subsonic.interceptors.RangeHeaderInterceptor +import org.moire.ultrasonic.api.subsonic.interceptors.VersionInterceptor import org.moire.ultrasonic.api.subsonic.response.StreamResponse import org.moire.ultrasonic.api.subsonic.response.SubsonicResponse import retrofit2.Response @@ -28,10 +30,25 @@ private const val READ_TIMEOUT = 60_000L */ class SubsonicAPIClient(baseUrl: String, username: String, - private val password: String, - clientProtocolVersion: SubsonicAPIVersions, + password: String, + minimalProtocolVersion: SubsonicAPIVersions, clientID: String, debug: Boolean = false) { + private val versionInterceptor = VersionInterceptor(minimalProtocolVersion) { + protocolVersion = it + } + private val proxyPasswordInterceptor = ProxyPasswordInterceptor(minimalProtocolVersion, + PasswordHexInterceptor(password), PasswordMD5Interceptor(password)) + + /** + * Get currently used protocol version. + */ + var protocolVersion = minimalProtocolVersion + private set(value) { + field = value + proxyPasswordInterceptor.apiVersion = field + } + private val okHttpClient = OkHttpClient.Builder() .readTimeout(READ_TIMEOUT, MILLISECONDS) .addInterceptor { chain -> @@ -39,15 +56,15 @@ class SubsonicAPIClient(baseUrl: String, val originalRequest = chain.request() val newUrl = originalRequest.url().newBuilder() .addQueryParameter("u", username) - .addQueryParameter("v", clientProtocolVersion.restApiVersion) .addQueryParameter("c", clientID) .addQueryParameter("f", "json") .build() chain.proceed(originalRequest.newBuilder().url(newUrl).build()) } + .addInterceptor(versionInterceptor) + .addInterceptor(proxyPasswordInterceptor) .addInterceptor(RangeHeaderInterceptor()) .apply { if (debug) addLogging() } - .addPasswordQueryParam(clientProtocolVersion) .build() private val jacksonMapper = ObjectMapper() @@ -139,14 +156,4 @@ class SubsonicAPIClient(baseUrl: String, loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY this.addInterceptor(loggingInterceptor) } - - private fun OkHttpClient.Builder.addPasswordQueryParam( - clientProtocolVersion: SubsonicAPIVersions): OkHttpClient.Builder { - if (clientProtocolVersion < SubsonicAPIVersions.V1_13_0) { - this.addInterceptor(PasswordHexInterceptor(password)) - } else { - this.addInterceptor(PasswordMD5Interceptor(password)) - } - return this - } }