Skip to content

Commit 85e3362

Browse files
committed
protect AsyncSocketImpl.channel lateinit var
1 parent 5a302cb commit 85e3362

File tree

4 files changed

+24
-92
lines changed

4 files changed

+24
-92
lines changed

ziti/src/integrationTest/kotlin/org/openziti/net/ConnectionTests.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,4 +216,10 @@ class ConnectionTests: BaseTest() {
216216
}
217217
}
218218

219+
@Test
220+
fun closeUnconnectedSocket() = runTest(timeout = 1.seconds) {
221+
val sock = Ziti.getSocketFactory().createSocket()
222+
sock.close()
223+
assertTrue(sock.isClosed)
224+
}
219225
}

ziti/src/main/kotlin/org/openziti/net/nio/AsychChannelSocket.kt

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,11 @@ class AsychChannelSocket(internal val impl: AsyncSocketImpl = AsyncSocketImpl())
4141
connect(InetSocketAddress(address, port))
4242
}
4343

44-
override fun isConnected(): Boolean {
45-
return impl.channel.remoteAddress != null
46-
}
47-
48-
override fun isClosed(): Boolean = !impl.channel.isOpen
44+
override fun isConnected(): Boolean = impl.isConnected()
45+
override fun isClosed(): Boolean = impl.isClosed()
4946

5047
override fun close() {
51-
impl.channel.close()
48+
impl.closeInternal()
5249
}
5350

5451
override fun getInputStream(): InputStream {

ziti/src/main/kotlin/org/openziti/net/nio/AsyncSocketImpl.kt

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,14 @@ internal class AsyncSocketImpl(private val connector: Connector = DefaultConnect
177177
}
178178
}
179179

180-
override fun close() {
181-
if (::channel.isInitialized)
182-
channel.close()
180+
internal fun isConnected(): Boolean = ::channel.isInitialized && channel.remoteAddress != null
181+
fun isClosed(): Boolean = ::channel.isInitialized && !channel.isOpen
182+
183+
override fun close() = closeInternal()
184+
internal fun closeInternal() {
185+
if (!::channel.isInitialized)
186+
channel = AsynchronousSocketChannel.open()
187+
channel.close()
183188
}
184189

185190
override fun getOption(optID: Int): Any? {

ziti/src/test/kotlin/org/openziti/net/ZitiSocketFactoryTest.kt

Lines changed: 7 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -16,95 +16,19 @@
1616

1717
package org.openziti.net
1818

19-
import com.google.gson.Gson
20-
import com.google.gson.JsonObject
21-
import kotlinx.coroutines.delay
22-
import kotlinx.coroutines.runBlocking
23-
import okhttp3.*
24-
import okhttp3.MediaType.Companion.toMediaType
25-
import okhttp3.RequestBody.Companion.toRequestBody
26-
import org.junit.Assume
27-
import org.junit.BeforeClass
19+
import kotlinx.coroutines.test.runTest
2820
import org.junit.Test
21+
import org.junit.jupiter.api.Assertions.assertTrue
2922
import org.openziti.Ziti
30-
import org.openziti.Ziti.getDNSResolver
31-
import org.openziti.ZitiContext
32-
import java.net.InetAddress
33-
import java.security.KeyStore
34-
import java.util.concurrent.TimeUnit
35-
import javax.net.ssl.TrustManagerFactory
36-
import javax.net.ssl.X509TrustManager
23+
import kotlin.time.Duration.Companion.seconds
3724

3825

3926
class ZitiSocketFactoryTest {
4027

41-
companion object {
42-
lateinit var ctx: ZitiContext
43-
lateinit var tm: X509TrustManager
44-
lateinit var dns: Dns
45-
@BeforeClass
46-
@JvmStatic
47-
fun setup() {
48-
val path = System.getProperty("test.identity")
49-
Assume.assumeNotNull(path)
50-
51-
ctx = Ziti.newContext(path, charArrayOf())
52-
val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()).apply {
53-
val ks = KeyStore.getInstance(KeyStore.getDefaultType())
54-
init(ks)
55-
}
56-
tm = tmf.trustManagers[0] as X509TrustManager
57-
58-
dns = object : Dns {
59-
override fun lookup(hostname: String): List<InetAddress> =
60-
listOf(getDNSResolver().resolve(hostname) ?: InetAddress.getByName(hostname)).filterNotNull()
61-
}
62-
runBlocking {
63-
delay(4000)
64-
}
65-
}
66-
}
67-
68-
69-
@Test
70-
fun testHttpClient() {
71-
72-
val clt = OkHttpClient.Builder()
73-
.socketFactory(Ziti.getSocketFactory())
74-
.sslSocketFactory(Ziti.getSSLSocketFactory(), tm)
75-
.dns(dns)
76-
.callTimeout(5, TimeUnit.MINUTES)
77-
.build()
78-
79-
val req = Request.Builder()
80-
.post("this is request body".toRequestBody("text/plain".toMediaType()))
81-
.url("http://httpbin.ziti/anything").build()
82-
val call = clt.newCall(req)
83-
val resp = call.execute()
84-
println(resp)
85-
println(resp.headers)
86-
val respBody = Gson().fromJson(resp.body?.byteStream()?.reader(), JsonObject::class.java)
87-
println(respBody)
88-
}
89-
9028
@Test
91-
fun testConnect() {
92-
val req = "GET /json HTTP/1.1\r\n"+
93-
"Accept: */*\r\n" +
94-
"Accept-Encoding: gzip, deflate\r\n" +
95-
"Connection: close\r\n" +
96-
"Host: httpbin.org\r\n" +
97-
"User-Agent: HTTPie/1.0.2\r\n" +
98-
"\r\n"
99-
100-
val zock = ctx.connect("httpbin.ziti", 80)
101-
zock.getOutputStream().writer().apply {
102-
write(req)
103-
flush()
104-
}
105-
106-
val resp = zock.getInputStream().reader().readLines()
107-
assert(resp[0].startsWith("HTTP/1.1 200"))
108-
println(resp)
29+
fun closeUnconnectedSocket() = runTest(timeout = 1.seconds) {
30+
val sock = Ziti.getSocketFactory().createSocket()
31+
sock.close()
32+
assertTrue(sock.isClosed)
10933
}
11034
}

0 commit comments

Comments
 (0)