Skip to content

Commit ab39615

Browse files
committed
Merge branch 'develop' into release
2 parents 7a024d3 + 37edfd1 commit ab39615

5 files changed

Lines changed: 57 additions & 70 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11
# Change Log
22

3+
## Version 3.1.1 *(2020-01-25)*
4+
5+
This is hot-fix release to fix issue introduced in `3.1.0`.
6+
7+
### Summary of Changes
8+
9+
- Fixed an [issue](https://github.com/ChuckerTeam/chucker/issues/203) introduced in 3.1.0 where some of response bodies were shown as `null` and their sizes were 0 bytes.
10+
311
## Version 3.1.0 *(2020-01-24)*
412

13+
### This version shouldn't be used as dependency due to [#203](https://github.com/ChuckerTeam/chucker/issues/203). Use 3.1.1 instead.
14+
515
This is a new minor release of Chucker. Please note that this minor release contains multiple new features (see below) as well as multiple bugfixes.
616

717
### Summary of Changes

‎README.md‎

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ repositories {
4242

4343
```groovy
4444
dependencies {
45-
debugImplementation "com.github.ChuckerTeam.Chucker:library:3.0.1"
46-
releaseImplementation "com.github.ChuckerTeam.Chucker:library-no-op:3.0.1"
45+
debugImplementation "com.github.ChuckerTeam.Chucker:library:3.1.1"
46+
releaseImplementation "com.github.ChuckerTeam.Chucker:library-no-op:3.1.1"
4747
}
4848
```
4949

@@ -63,7 +63,7 @@ Don't forget to check the [changelog](CHANGELOG.md) to have a look at all the ch
6363

6464
* Compatible with **OkHTTP 4**
6565
* **API >= 16** compatible
66-
* Easy to integrate (just a 2 gradle implementation line).
66+
* Easy to integrate (just 2 gradle `implementation` lines).
6767
* Works **out of the box**, no customization needed.
6868
* **Empty release artifact** 🧼 (no traces of Chucker in your final APK).
6969
* Support for body text search with **highlighting** 🕵️‍♂️
@@ -94,9 +94,9 @@ val chuckerInterceptor = ChuckerInterceptor(
9494
context = this,
9595
// The previously created Collector
9696
collector = chuckerCollector,
97-
// The max body content length, after this responses will be truncated.
97+
// The max body content length in bytes, after this responses will be truncated.
9898
maxContentLength = 250000L,
99-
// List of headers to obfuscate in the Chucker UI
99+
// List of headers to replace with ** in the Chucker UI
100100
headersToRedact = setOf("Auth-Token"))
101101

102102
// Don't forget to plug the ChuckerInterceptor inside the OkHttpClient
@@ -107,7 +107,7 @@ val client = OkHttpClient.Builder()
107107

108108
### Throwables ☄️
109109

110-
Chucker supports also collecting and displaying **Throwables** of your application. To inform Chucker that a `Throwable` was fired you need to call the `onError` method of the `ChuckerCollector` (you need to retain an instance of your collector):
110+
Chucker can also collect and display **Throwables** of your application. To inform Chucker that a `Throwable` was fired you need to call the `onError` method of the `ChuckerCollector` (you need to retain an instance of your collector):
111111

112112
```kotlin
113113
try {
@@ -176,9 +176,8 @@ We're offering support for Chucker on the [#chucker](https://kotlinlang.slack.co
176176

177177
Short `TODO` List for new contributors:
178178

179-
- [ ] Kotlinize classes inside the `.internal` package.
180-
- [x] Have a empty state graphics/message for requests with no headers.
181-
- [ ] Increment the test coverage.
179+
- Increment the test coverage.
180+
- [Issues marked as `Help wanted`](https://github.com/ChuckerTeam/chucker/labels/help%20wanted)
182181

183182
## Acknowledgments 🌸
184183

@@ -191,18 +190,9 @@ Chucker is currently developed and maintained by the [ChuckerTeam](https://githu
191190
- [@redwarp](https://github.com/redwarp)
192191
- [@vbuberen](https://github.com/vbuberen)
193192

194-
### Contributors
193+
### Thanks
195194

196-
Big thanks to our contributors ❤️ Please add your name here once you submit a PR.
197-
198-
- [Ashok Varma](https://github.com/Ashok-Varma) Clean up
199-
- [Bernat Borrás Paronella](https://github.com/alorma) Redact headers + HTTP methods in notifications
200-
- [Hafiz Waleed Hussain](https://github.com/Hafiz-Waleed-Hussain) Search highlight in response tab
201-
- [Karol Wrótniak](https://github.com/koral--) Fix race condition + Application name retrieval
202-
- [OlliZi](https://github.com/OlliZi) Support for images
203-
- [Paul Hawke](https://github.com/psh) API Clean
204-
- [Paul Woitaschek](https://github.com/PaulWoitaschek) Fix typo in API
205-
- [SeungHun Choe](https://github.com/uOOOO) Fix memory leak
195+
Big thanks to our contributors ❤️
206196

207197
### Libraries
208198

@@ -215,7 +205,7 @@ Chucker uses the following open source libraries:
215205
## License 📄
216206

217207
```
218-
Copyright (C) 2018 Chucker Team.
208+
Copyright (C) 2018-2020 Chucker Team.
219209
Copyright (C) 2017 Jeff Gilfelt.
220210
221211
Licensed under the Apache License, Version 2.0 (the "License");

‎library/src/main/java/com/chuckerteam/chucker/api/ChuckerInterceptor.kt‎

Lines changed: 30 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,18 @@
11
package com.chuckerteam.chucker.api
22

33
import android.content.Context
4-
import android.util.Log
5-
import com.chuckerteam.chucker.api.Chucker.LOG_TAG
64
import com.chuckerteam.chucker.internal.data.entity.HttpTransaction
75
import com.chuckerteam.chucker.internal.support.IOUtils
86
import com.chuckerteam.chucker.internal.support.hasBody
97
import java.io.IOException
108
import java.nio.charset.Charset
11-
import java.nio.charset.UnsupportedCharsetException
129
import okhttp3.Headers
1310
import okhttp3.Interceptor
1411
import okhttp3.Request
1512
import okhttp3.Response
1613
import okhttp3.ResponseBody
1714
import okio.Buffer
18-
import okio.BufferedSource
15+
import okio.GzipSource
1916

2017
private const val MAX_BLOB_SIZE = 1000_000L
2118

@@ -110,7 +107,7 @@ class ChuckerInterceptor @JvmOverloads constructor(
110107
* Processes a [Response] and populates corresponding fields of a [HttpTransaction].
111108
*/
112109
private fun processResponse(response: Response, transaction: HttpTransaction) {
113-
val responseBody = response.body()
110+
val responseBody = response.body()!!
114111
val responseEncodingIsSupported = io.bodyHasSupportedEncoding(response.headers().get(CONTENT_ENCODING))
115112

116113
transaction.apply {
@@ -125,8 +122,8 @@ class ChuckerInterceptor @JvmOverloads constructor(
125122
responseCode = response.code()
126123
responseMessage = response.message()
127124

128-
responseContentType = responseBody?.contentType()?.toString()
129-
responseContentLength = responseBody?.contentLength() ?: 0L
125+
responseContentType = responseBody.contentType()?.toString()
126+
responseContentLength = responseBody.contentLength()
130127

131128
tookMs = (response.receivedResponseAtMillis() - response.sentRequestAtMillis())
132129
}
@@ -139,32 +136,36 @@ class ChuckerInterceptor @JvmOverloads constructor(
139136
/**
140137
* Processes a [ResponseBody] and populates corresponding fields of a [HttpTransaction].
141138
*/
142-
private fun processResponseBody(response: Response, responseBody: ResponseBody?, transaction: HttpTransaction) {
143-
getNativeSource(response)?.use { source ->
144-
source.request(java.lang.Long.MAX_VALUE)
145-
val buffer = source.buffer()
146-
var charset: Charset = UTF8
147-
val contentType = responseBody?.contentType()
148-
if (contentType != null) {
149-
try {
150-
charset = contentType.charset(UTF8) ?: UTF8
151-
} catch (e: UnsupportedCharsetException) {
152-
return
153-
}
139+
private fun processResponseBody(response: Response, responseBody: ResponseBody, transaction: HttpTransaction) {
140+
val contentType = responseBody.contentType()
141+
val charset: Charset = contentType?.charset(UTF8) ?: UTF8
142+
val contentLength = responseBody.contentLength()
143+
144+
val source = responseBody.source()
145+
source.request(Long.MAX_VALUE) // Buffer the entire body.
146+
var buffer = source.buffer()
147+
148+
if (io.bodyIsGzipped(response.headers()[CONTENT_ENCODING])) {
149+
GzipSource(buffer.clone()).use { gzippedResponseBody ->
150+
buffer = Buffer()
151+
buffer.writeAll(gzippedResponseBody)
154152
}
155-
if (io.isPlaintext(buffer)) {
156-
val content = io.readFromBuffer(buffer, charset, maxContentLength)
157-
transaction.responseBody = content
158-
} else {
159-
transaction.isResponseBodyPlainText = false
153+
}
154+
155+
if (io.isPlaintext(buffer)) {
156+
transaction.isResponseBodyPlainText = true
157+
if (contentLength != 0L) {
158+
transaction.responseBody = buffer.clone().readString(charset)
159+
}
160+
} else {
161+
transaction.isResponseBodyPlainText = false
160162

161-
val isImageContentType = (transaction.responseContentType?.contains(CONTENT_TYPE_IMAGE) == true)
163+
val isImageContentType =
164+
(contentType?.toString()?.contains(CONTENT_TYPE_IMAGE, ignoreCase = true) == true)
162165

163-
if (isImageContentType && buffer.size() < MAX_BLOB_SIZE) {
164-
transaction.responseImageData = buffer.readByteArray()
165-
}
166+
if (isImageContentType && buffer.size() < MAX_BLOB_SIZE) {
167+
transaction.responseImageData = buffer.readByteArray()
166168
}
167-
transaction.responseContentLength = buffer.size()
168169
}
169170
}
170171

@@ -179,24 +180,6 @@ class ChuckerInterceptor @JvmOverloads constructor(
179180
return builder.build()
180181
}
181182

182-
/**
183-
* Returns a [BufferedSource] of a [Response] and UnGzip it if necessary.
184-
*/
185-
@Throws(IOException::class)
186-
private fun getNativeSource(response: Response): BufferedSource? {
187-
if (io.bodyIsGzipped(response.headers().get(CONTENT_ENCODING))) {
188-
val source = response.peekBody(maxContentLength).source()
189-
if (source.buffer().size() < maxContentLength) {
190-
return io.getNativeSource(source, true)
191-
} else {
192-
Log.w(LOG_TAG, "gzip encoded response was too long")
193-
}
194-
}
195-
// Let's clone the response Buffer in order to don't cause an IllegalStateException: closed
196-
// if others interceptors are manipulating the body (see #192).
197-
return response.body()?.source()?.buffer()?.clone()
198-
}
199-
200183
companion object {
201184
private val UTF8 = Charset.forName("UTF-8")
202185

‎library/src/main/java/com/chuckerteam/chucker/internal/support/IOUtils.kt‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,5 +67,9 @@ internal class IOUtils(private val context: Context) {
6767
contentEncoding.equals("identity", ignoreCase = true) ||
6868
contentEncoding.equals("gzip", ignoreCase = true)
6969

70-
fun bodyIsGzipped(contentEncoding: String?) = contentEncoding?.equals("gzip", ignoreCase = true) ?: false
70+
fun bodyIsGzipped(contentEncoding: String?) = CONTENT_ENCODING_GZIP.equals(contentEncoding, ignoreCase = true)
71+
72+
private companion object {
73+
const val CONTENT_ENCODING_GZIP = "gzip"
74+
}
7175
}

‎sample/src/main/java/com/chuckerteam/chucker/sample/HttpBinClient.kt‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ class HttpBinClient(
3636
private val httpClient =
3737
OkHttpClient.Builder()
3838
// Add a ChuckerInterceptor instance to your OkHttp client
39-
.addInterceptor(chuckerInterceptor)
4039
.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
40+
.addInterceptor(chuckerInterceptor)
4141
.build()
4242

4343
private val api: HttpBinApi by lazy {

0 commit comments

Comments
 (0)