1
0
mirror of https://github.com/square/okhttp.git synced 2025-08-08 23:42:08 +03:00

Add debug helper for JSSE Handshakes (#6579)

This commit is contained in:
Yuri Schimke
2021-04-03 05:22:56 +01:00
committed by GitHub
parent f8fd4d08de
commit f62173afbb
2 changed files with 99 additions and 10 deletions

View File

@@ -0,0 +1,82 @@
/*
* Copyright (C) 2021 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okhttp3
import java.io.Closeable
import java.util.logging.Handler
import java.util.logging.LogRecord
object JsseDebugLogging {
data class JsseDebugMessage(val message: String, val param: String?) {
enum class Type {
Handshake, Plaintext, Encrypted, Setup, Unknown
}
val type: Type
get() = when {
message == "adding as trusted certificates" -> Type.Setup
message == "Raw read" || message == "Raw write" -> Type.Encrypted
message == "Plaintext before ENCRYPTION" || message == "Plaintext after DECRYPTION" -> Type.Plaintext
message.startsWith("System property ") -> Type.Setup
message.startsWith("Reload ") -> Type.Setup
message == "No session to resume." -> Type.Handshake
message.startsWith("Consuming ") -> Type.Handshake
message.startsWith("Produced ") -> Type.Handshake
message.startsWith("Negotiated ") -> Type.Handshake
message.startsWith("Found resumable session") -> Type.Handshake
message.startsWith("Resuming session") -> Type.Handshake
message.startsWith("Using PSK to derive early secret") -> Type.Handshake
else -> Type.Unknown
}
override fun toString(): String {
return if (param != null) {
message + "\n" + param
} else {
message
}
}
}
private fun quietDebug(message: JsseDebugMessage) {
if (message.message.startsWith("Ignore")) {
return
}
when (message.type) {
JsseDebugMessage.Type.Setup, JsseDebugMessage.Type.Encrypted, JsseDebugMessage.Type.Plaintext -> {
println(message.message + " (skipped output)")
}
else -> println(message)
}
}
fun enableJsseDebugLogging(debugHandler: (JsseDebugMessage) -> Unit = this::quietDebug): Closeable {
System.setProperty("javax.net.debug", "")
return OkHttpDebugLogging.enable("javax.net.ssl", object : Handler() {
override fun publish(record: LogRecord) {
val param = record.parameters?.firstOrNull() as? String
debugHandler(JsseDebugMessage(record.message, param))
}
override fun flush() {
}
override fun close() {
}
})
}
}

View File

@@ -15,15 +15,17 @@
*/ */
package okhttp3 package okhttp3
import okhttp3.internal.concurrent.TaskRunner
import okhttp3.internal.http2.Http2
import java.io.Closeable
import java.util.concurrent.CopyOnWriteArraySet import java.util.concurrent.CopyOnWriteArraySet
import java.util.logging.ConsoleHandler import java.util.logging.ConsoleHandler
import java.util.logging.Handler
import java.util.logging.Level import java.util.logging.Level
import java.util.logging.LogRecord import java.util.logging.LogRecord
import java.util.logging.Logger import java.util.logging.Logger
import java.util.logging.SimpleFormatter import java.util.logging.SimpleFormatter
import kotlin.reflect.KClass import kotlin.reflect.KClass
import okhttp3.internal.concurrent.TaskRunner
import okhttp3.internal.http2.Http2
object OkHttpDebugLogging { object OkHttpDebugLogging {
// Keep references to loggers to prevent their configuration from being GC'd. // Keep references to loggers to prevent their configuration from being GC'd.
@@ -33,18 +35,23 @@ object OkHttpDebugLogging {
fun enableTaskRunner() = enable(TaskRunner::class) fun enableTaskRunner() = enable(TaskRunner::class)
fun enable(loggerClass: String) { fun logHandler() = ConsoleHandler().apply {
level = Level.FINE
formatter = object : SimpleFormatter() {
override fun format(record: LogRecord) =
String.format("[%1\$tF %1\$tT] %2\$s %n", record.millis, record.message)
}
}
fun enable(loggerClass: String, handler: Handler = logHandler()): Closeable {
val logger = Logger.getLogger(loggerClass) val logger = Logger.getLogger(loggerClass)
if (configuredLoggers.add(logger)) { if (configuredLoggers.add(logger)) {
logger.addHandler(ConsoleHandler().apply { logger.addHandler(handler)
level = Level.FINE
formatter = object : SimpleFormatter() {
override fun format(record: LogRecord) =
String.format("[%1\$tF %1\$tT] %2\$s %n", record.millis, record.message)
}
})
logger.level = Level.FINEST logger.level = Level.FINEST
} }
return Closeable {
logger.removeHandler(handler)
}
} }
fun enable(loggerClass: KClass<*>) = enable(loggerClass.java.name) fun enable(loggerClass: KClass<*>) = enable(loggerClass.java.name)