我已经为Docker API实现了一个客户端。
用于附加到容器输出的端点有点不寻常,因为您需要劫持基础TCP流,并使用该流从容器中读取输出。
API端点的文档:https://docs.docker.com/engine/api/v1.37/#operation/ContainerAttach(很遗憾,此端点的Web套接字版本为broken on OS X,所以我不能使用它。)
我一直在使用this code来访问直至和包括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())
}
}
这很好用。
但是,在最新版本中,OkHttp API发生了重大变化。像这样的东西可以在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
}
}
我意识到这是在另一种黑客之上的黑客,并且完全不受支持,但是有人对我如何实现这项工作有任何想法吗?