mirror of
https://codeberg.org/timelimit/timelimit-android.git
synced 2025-10-03 09:49:25 +02:00
Send Content-Length if required
This commit is contained in:
parent
80b58e134d
commit
dac0ce74fe
3 changed files with 78 additions and 11 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* TimeLimit Copyright <C> 2019 - 2020 Jonas Lochmann
|
||||
* TimeLimit Copyright <C> 2019 - 2023 Jonas Lochmann
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -31,7 +31,7 @@ val httpClient: OkHttpClient by lazy {
|
|||
if (BuildConfig.DEBUG) {
|
||||
builder.addInterceptor (HttpLoggingInterceptor {
|
||||
Log.d("HttpClient", it)
|
||||
})
|
||||
}.apply { level = HttpLoggingInterceptor.Level.HEADERS })
|
||||
}
|
||||
|
||||
builder.build()
|
||||
|
|
|
@ -23,12 +23,15 @@ import io.timelimit.android.async.Threads
|
|||
import io.timelimit.android.coroutines.executeAndWait
|
||||
import io.timelimit.android.coroutines.waitForResponse
|
||||
import io.timelimit.android.sync.network.*
|
||||
import io.timelimit.android.util.okio.LengthSink
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.Request
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.Response
|
||||
import okhttp3.internal.closeQuietly
|
||||
import okio.BufferedSink
|
||||
import okio.GzipSink
|
||||
import okio.Sink
|
||||
import okio.buffer
|
||||
import java.io.OutputStreamWriter
|
||||
|
||||
|
@ -63,24 +66,37 @@ class HttpServerApi(private val endpointWithoutSlashAtEnd: String): ServerApi {
|
|||
|
||||
private val JSON = "application/json; charset=utf-8".toMediaTypeOrNull()
|
||||
|
||||
private fun createJsonRequestBody(serialize: (writer: JsonWriter) -> Unit) = object: RequestBody() {
|
||||
override fun contentType() = JSON
|
||||
override fun writeTo(sink: BufferedSink) {
|
||||
private fun createJsonRequestBody(
|
||||
serialize: (writer: JsonWriter) -> Unit,
|
||||
measureContentLength: Boolean
|
||||
): RequestBody {
|
||||
fun write(sink: Sink) {
|
||||
val writer = JsonWriter(
|
||||
OutputStreamWriter(
|
||||
GzipSink(sink)
|
||||
.buffer().outputStream()
|
||||
)
|
||||
OutputStreamWriter(
|
||||
GzipSink(sink)
|
||||
.buffer().outputStream()
|
||||
)
|
||||
)
|
||||
|
||||
serialize(writer)
|
||||
|
||||
writer.flush()
|
||||
writer.close()
|
||||
}
|
||||
|
||||
val length =
|
||||
if (measureContentLength) LengthSink().also { write(it) }.length
|
||||
else null
|
||||
|
||||
return object: RequestBody() {
|
||||
override fun contentType() = JSON
|
||||
override fun writeTo(sink: BufferedSink) = write(sink)
|
||||
override fun contentLength(): Long = length ?: -1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var sendContentLength = false
|
||||
|
||||
override suspend fun getTimeInMillis(): Long {
|
||||
httpClient.newCall(
|
||||
Request.Builder()
|
||||
|
@ -595,10 +611,30 @@ class HttpServerApi(private val endpointWithoutSlashAtEnd: String): ServerApi {
|
|||
path: String,
|
||||
requestBody: (writer: JsonWriter) -> Unit
|
||||
): Response {
|
||||
if (!sendContentLength) {
|
||||
val response = postJsonRequest(path, requestBody, transmitContentLength = false)
|
||||
|
||||
if (response.code != 411) return response
|
||||
|
||||
Threads.network.executeAndWait { response.closeQuietly() }
|
||||
|
||||
sendContentLength = true
|
||||
}
|
||||
|
||||
return postJsonRequest(path, requestBody, transmitContentLength = true)
|
||||
}
|
||||
|
||||
private suspend fun postJsonRequest(
|
||||
path: String,
|
||||
requestBody: (writer: JsonWriter) -> Unit,
|
||||
transmitContentLength: Boolean
|
||||
): Response {
|
||||
val body = createJsonRequestBody(requestBody, transmitContentLength)
|
||||
|
||||
return httpClient.newCall(
|
||||
Request.Builder()
|
||||
.url("$endpointWithoutSlashAtEnd/$path")
|
||||
.post(createJsonRequestBody(requestBody))
|
||||
.post(body)
|
||||
.header("Content-Encoding", "gzip")
|
||||
.build()
|
||||
).waitForResponse()
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* TimeLimit Copyright <C> 2019 - 2023 Jonas Lochmann
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package io.timelimit.android.util.okio
|
||||
|
||||
import okio.Buffer
|
||||
import okio.Sink
|
||||
import okio.Timeout
|
||||
|
||||
class LengthSink: Sink {
|
||||
private var lengthInternal = 0L
|
||||
|
||||
val length get() = lengthInternal
|
||||
|
||||
override fun write(source: Buffer, byteCount: Long) { lengthInternal += byteCount }
|
||||
override fun timeout(): Timeout = Timeout.NONE
|
||||
override fun flush() = Unit
|
||||
override fun close() = Unit
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue