I'm using Retrofit (version 2.9.0) to make request to the API server. This library by default adds Content-Length
header to the request. Unfortunately server rejects this header for "security" purposes - I don't have affect to this. Is it possible to remove this header from request using Retrofit? Or do I have to create my own rest api client?
removeHeader("Content-Length")
function of Request.Builder
does not works, it looks like library adds it after request build. I can change value of this header calling addHeader("Content-Length", "any-value")
but it's not what I need.
override fun intercept(chain: Interceptor.Chain): Response {
val builder = chain.request().newBuilder().apply {
removeHeader("Content-Length") // Doesn't works
}
return chain.proceed(builder.build())
}
#Edit
For the people below. I already confirmed that with logging interceptor, so there is no need to write useless code here. And the fuction above is from... Interceptor
... but If you want and that can help:
HeaderInterceptor
class HeaderInterceptor() : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val builder = chain.request().newBuilder().apply {
removeHeader("Content-Length") // Doesn't works
}
return chain.proceed(builder.build())
}
}
Building Retrofit Client
@Singleton
@Provides
fun providesUserApi(headerInterceptor: HeaderInterceptor): UsersApi {
val loggingInterceptor = HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}
val client = OkHttpClient.Builder().apply {
addInterceptor(tokenInterceptor)
addInterceptor(headerInterceptor)
}.build()
return Retrofit.Builder()
.baseUrl(Constants.BASE_USERS_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client).build()
.create(UsersApi::class.java)
}
API Interface
interface UsersApi {
@POST("/api/auth/login")
suspend fun login(@Body user: LoginRequest): Response<LoginResponse>
}
LoginRequest
is simple POJO data class which holds login/password fields and LoginResponse
is data returned by server.
Logcat
I/okhttp.OkHttpClient: --> POST https://this_is_api_server.com/api/auth/login
I/okhttp.OkHttpClient: Content-Length: 60
I/okhttp.OkHttpClient: {"device_type":"ANDROID","email":"admin","password":"admin"}
I/okhttp.OkHttpClient: --> END POST (60-byte body)
I/okhttp.OkHttpClient: <-- HTTP FAILED: java.net.SocketException: socket failed: EPERM (Operation not permitted)
Event log from client
I masked domain name and IP addresses with XXX.
I/okhttp.OkHttpClient: [2 ms] callStart: Request{method=POST, url=https://securedapiserver.com/api/auth/v1/loginByEmail, tags={class retrofit2.Invocation=package.name.api.UsersApi.login() [LoginRequest(device_type=ANDROID, email=test, password=test)]}}
I/okhttp.OkHttpClient: --> POST https://securedapiserver.com/api/auth/v1/loginByEmail
I/okhttp.OkHttpClient: Content-Length: 58
I/okhttp.OkHttpClient: {"device_type":"ANDROID","email":"test","password":"test"}
I/okhttp.OkHttpClient: --> END POST (58-byte body)
I/okhttp.OkHttpClient: [98 ms] proxySelectStart: https://securedapiserver.com/
I/okhttp.OkHttpClient: [103 ms] proxySelectEnd: [DIRECT]
I/okhttp.OkHttpClient: [105 ms] dnsStart: securedapiserver.com
I/okhttp.OkHttpClient: [158 ms] dnsEnd: [securedapiserver.com/XXX.XXX.XXX.XXX, securedapiserver.com/XXX.XXX.XXX.XXX, securedapiserver.com/XXX.XXX.XXX.XXX, securedapiserver.com/XXX.XXX.XXX.XXX, securedapiserver.com/XXX:XXX:XXX:XXX, securedapiserver.com/XXX:XXX:XXX:XXX, securedapiserver.com/XXX:XXX:XXX:XXX, securedapiserver.com/XXX:XXX:XXX:XXX, securedapiserver.com/XXX:XXX:XXX:XXX, securedapiserver.com/XXX:XXX:XXX:XXX, securedapiserver.com/XXX:XXX:XXX:XXX, securedapiserver.com/XXX:XXX:XXX:XXX]
I/okhttp.OkHttpClient: [175 ms] connectStart: securedapiserver.com/XXX.XXX.XXX.XXX:443 DIRECT
I/okhttp.OkHttpClient: [176 ms] connectFailed: null java.net.SocketException: socket failed: EPERM (Operation not permitted)
I/okhttp.OkHttpClient: [178 ms] connectStart: securedapiserver.com/XXX.XXX.XXX.XXX:443 DIRECT
I/okhttp.OkHttpClient: [179 ms] connectFailed: null java.net.SocketException: socket failed: EPERM (Operation not permitted)
I/okhttp.OkHttpClient: [180 ms] connectStart: securedapiserver.com/XXX.XXX.XXX.XXX:443 DIRECT
I/okhttp.OkHttpClient: [181 ms] connectFailed: null java.net.SocketException: socket failed: EPERM (Operation not permitted)
I/okhttp.OkHttpClient: [182 ms] connectStart: securedapiserver.com/XXX.XXX.XXX.XXX:443 DIRECT
I/okhttp.OkHttpClient: [183 ms] connectFailed: null java.net.SocketException: socket failed: EPERM (Operation not permitted)
I/okhttp.OkHttpClient: [184 ms] connectStart: securedapiserver.com/XXX:XXX:XXX:XXX:443 DIRECT
I/okhttp.OkHttpClient: [184 ms] connectFailed: null java.net.SocketException: socket failed: EPERM (Operation not permitted)
I/okhttp.OkHttpClient: [186 ms] connectStart: securedapiserver.com/XXX:XXX:XXX:XXX:443 DIRECT
I/okhttp.OkHttpClient: [187 ms] connectFailed: null java.net.SocketException: socket failed: EPERM (Operation not permitted)
I/okhttp.OkHttpClient: [188 ms] connectStart: securedapiserver.com/XXX:XXX:XXX:XXX:443 DIRECT
I/okhttp.OkHttpClient: [189 ms] connectFailed: null java.net.SocketException: socket failed: EPERM (Operation not permitted)
I/okhttp.OkHttpClient: [191 ms] connectStart: securedapiserver.com/XXX:XXX:XXX:XXX:443 DIRECT
I/okhttp.OkHttpClient: [194 ms] connectFailed: null java.net.SocketException: socket failed: EPERM (Operation not permitted)
I/okhttp.OkHttpClient: [196 ms] connectStart: securedapiserver.com/XXX:XXX:XXX:XXX:443 DIRECT
I/okhttp.OkHttpClient: [197 ms] connectFailed: null java.net.SocketException: socket failed: EPERM (Operation not permitted)
I/okhttp.OkHttpClient: [198 ms] connectStart: securedapiserver.com/XXX:XXX:XXX:XXX:443 DIRECT
I/okhttp.OkHttpClient: [199 ms] connectFailed: null java.net.SocketException: socket failed: EPERM (Operation not permitted)
I/okhttp.OkHttpClient: [201 ms] connectStart: securedapiserver.com/XXX:XXX:XXX:XXX:443 DIRECT
I/okhttp.OkHttpClient: [201 ms] connectFailed: null java.net.SocketException: socket failed: EPERM (Operation not permitted)
I/okhttp.OkHttpClient: [202 ms] connectStart: securedapiserver.com/XXX:XXX:XXX:XXX:443 DIRECT
I/okhttp.OkHttpClient: [203 ms] connectFailed: null java.net.SocketException: socket failed: EPERM (Operation not permitted)
I/System.out: [java.net.SocketException: socket failed: EPERM (Operation not permitted), java.net.SocketException: socket failed: EPERM (Operation not permitted), java.net.SocketException: socket failed: EPERM (Operation not permitted), java.net.SocketException: socket failed: EPERM (Operation not permitted), java.net.SocketException: socket failed: EPERM (Operation not permitted), java.net.SocketException: socket failed: EPERM (Operation not permitted), java.net.SocketException: socket failed: EPERM (Operation not permitted), java.net.SocketException: socket failed: EPERM (Operation not permitted), java.net.SocketException: socket failed: EPERM (Operation not permitted), java.net.SocketException: socket failed: EPERM (Operation not permitted), java.net.SocketException: socket failed: EPERM (Operation not permitted)]
I/okhttp.OkHttpClient: <-- HTTP FAILED: java.net.SocketException: socket failed: EPERM (Operation not permitted)
I/okhttp.OkHttpClient: [212 ms] callFailed: java.net.SocketException: socket failed: EPERM (Operation not permitted)
E/NetworkCall: socket failed: EPERM (Operation not permitted)
** EDIT 2021-03-19 **
Thanks to @Yuri Schimke the problem was solved. I had to completely remove emulator and create new one. It looks like there was problem with http stack?
from Retrofit: Remove Content-Length header
No comments:
Post a Comment