Я реализовал клиент для Docker API.
Конечная точка для присоединения к выводу контейнера немного необычна тем, что вам нужно перехватить базовый поток TCP и использовать его для чтения вывода из контейнера.
Документация для конечной точки API: https://docs.docker.com/engine/api/v1.37/#operation/ContainerAttach (К сожалению, версия веб-сокета этой конечной точки не работает на OS X , поэтому я не могу ее использовать.)
Я использовал этот код , чтобы получить доступ к потокам вплоть до OkHttp v3.13.1 включительно:
class ConnectionHijacker : Interceptor {
var source: BufferedSource? = null
var sink: BufferedSink? = null
override fun intercept(chain: Interceptor.Chain): Response {
val connection = chain.connection() as RealConnection
val streams = connection.newWebSocketStreams(connection.allocations.single().get())
sink = streams.sink
source = streams.source
return chain.proceed(chain.request())
}
}
Это прекрасно работает.
Однако в более поздних версиях API OkHttp значительно изменился. Нечто подобное работает с v1.13.1 и компилируется с более поздними версиями, но не дает никакого вывода в потоке:
class ConnectionHijacker : Interceptor {
var source: BufferedSource? = null
var sink: BufferedSink? = null
override fun intercept(chain: Interceptor.Chain): Response {
val connection = chain.connection() as RealConnection
sink = connection.sink
source = connection.source
return chain.proceed(chain.request())
}
private val RealConnection.sink: BufferedSink
get() {
val property = RealConnection::class.declaredMemberProperties.single { it.name == "sink" }
property.isAccessible = true
return property.get(this) as BufferedSink
}
private val RealConnection.source: BufferedSource
get() {
val property = RealConnection::class.declaredMemberProperties.single { it.name == "source" }
property.isAccessible = true
return property.get(this) as BufferedSource
}
}
Я понимаю, что это взлом на вершине другого взлома и совершенно не поддерживается, но есть ли у кого-нибудь идеи о том, как я могу сделать эту работу?