@@ -29,6 +29,7 @@ final class TunnelingJdkSocket extends Socket {
29
29
private InetSocketAddress inetSocketAddress ;
30
30
31
31
private SocketChannel unixSocketChannel ;
32
+ private Selector selector ;
32
33
33
34
private int timeout ;
34
35
private boolean shutIn ;
@@ -90,6 +91,9 @@ public synchronized int getSoTimeout() throws SocketException {
90
91
91
92
@ Override
92
93
public void connect (final SocketAddress endpoint ) throws IOException {
94
+ if (endpoint == null ) {
95
+ throw new IllegalArgumentException ("Endpoint cannot be null" );
96
+ }
93
97
if (isClosed ()) {
94
98
throw new SocketException ("Socket is closed" );
95
99
}
@@ -105,6 +109,12 @@ public void connect(final SocketAddress endpoint) throws IOException {
105
109
// https://github.com/jnr/jnr-unixsocket/blob/master/src/main/java/jnr/unixsocket/UnixSocket.java#L89-L97
106
110
@ Override
107
111
public void connect (final SocketAddress endpoint , final int timeout ) throws IOException {
112
+ if (endpoint == null ) {
113
+ throw new IllegalArgumentException ("Endpoint cannot be null" );
114
+ }
115
+ if (timeout < 0 ) {
116
+ throw new IllegalArgumentException ("Timeout cannot be negative" );
117
+ }
108
118
if (isClosed ()) {
109
119
throw new SocketException ("Socket is closed" );
110
120
}
@@ -122,17 +132,19 @@ public SocketChannel getChannel() {
122
132
123
133
@ Override
124
134
public void setSendBufferSize (int size ) throws SocketException {
135
+ if (size <= 0 ) {
136
+ throw new IllegalArgumentException ("Invalid send buffer size" );
137
+ }
125
138
if (isClosed ()) {
126
139
throw new SocketException ("Socket is closed" );
127
140
}
128
- if (size < 0 ) {
129
- throw new IllegalArgumentException ("Invalid send buffer size" );
130
- }
141
+ sendBufferSize = size ;
131
142
try {
132
143
unixSocketChannel .setOption (java .net .StandardSocketOptions .SO_SNDBUF , size );
133
- sendBufferSize = size ;
134
144
} catch (IOException e ) {
135
- throw new SocketException ("Failed to set send buffer size" );
145
+ SocketException se = new SocketException ("Failed to set send buffer size socket option" );
146
+ se .initCause (e );
147
+ throw se ;
136
148
}
137
149
}
138
150
@@ -149,17 +161,19 @@ public int getSendBufferSize() throws SocketException {
149
161
150
162
@ Override
151
163
public void setReceiveBufferSize (int size ) throws SocketException {
164
+ if (size <= 0 ) {
165
+ throw new IllegalArgumentException ("Invalid receive buffer size" );
166
+ }
152
167
if (isClosed ()) {
153
168
throw new SocketException ("Socket is closed" );
154
169
}
155
- if (size < 0 ) {
156
- throw new IllegalArgumentException ("Invalid receive buffer size" );
157
- }
170
+ receiveBufferSize = size ;
158
171
try {
159
172
unixSocketChannel .setOption (java .net .StandardSocketOptions .SO_RCVBUF , size );
160
- receiveBufferSize = size ;
161
173
} catch (IOException e ) {
162
- throw new SocketException ("Failed to set receive buffer size" );
174
+ SocketException se = new SocketException ("Failed to set receive buffer size socket option" );
175
+ se .initCause (e );
176
+ throw se ;
163
177
}
164
178
}
165
179
@@ -196,14 +210,14 @@ public InputStream getInputStream() throws IOException {
196
210
throw new SocketException ("Socket input is shutdown" );
197
211
}
198
212
213
+ if (selector == null ) {
214
+ selector = Selector .open ();
215
+ unixSocketChannel .configureBlocking (false );
216
+ unixSocketChannel .register (selector , SelectionKey .OP_READ );
217
+ }
218
+
199
219
return new InputStream () {
200
220
private final ByteBuffer buffer = ByteBuffer .allocate (getStreamBufferSize ());
201
- private final Selector selector = Selector .open ();
202
-
203
- {
204
- unixSocketChannel .configureBlocking (false );
205
- unixSocketChannel .register (selector , SelectionKey .OP_READ );
206
- }
207
221
208
222
@ Override
209
223
public int read () throws IOException {
@@ -213,6 +227,9 @@ public int read() throws IOException {
213
227
214
228
@ Override
215
229
public int read (byte [] b , int off , int len ) throws IOException {
230
+ if (isInputShutdown ()) {
231
+ return -1 ;
232
+ }
216
233
buffer .clear ();
217
234
218
235
int readyChannels = selector .select (timeout );
@@ -241,7 +258,7 @@ public int read(byte[] b, int off, int len) throws IOException {
241
258
242
259
@ Override
243
260
public void close () throws IOException {
244
- selector .close ();
261
+ TunnelingJdkSocket . this .close ();
245
262
}
246
263
};
247
264
}
@@ -254,7 +271,7 @@ public OutputStream getOutputStream() throws IOException {
254
271
if (!isConnected ()) {
255
272
throw new SocketException ("Socket is not connected" );
256
273
}
257
- if (isInputShutdown ()) {
274
+ if (isOutputShutdown ()) {
258
275
throw new SocketException ("Socket output is shutdown" );
259
276
}
260
277
@@ -267,12 +284,19 @@ public void write(int b) throws IOException {
267
284
268
285
@ Override
269
286
public void write (byte [] b , int off , int len ) throws IOException {
287
+ if (isOutputShutdown ()) {
288
+ throw new IOException ("Stream closed" );
289
+ }
270
290
ByteBuffer buffer = ByteBuffer .wrap (b , off , len );
271
-
272
291
while (buffer .hasRemaining ()) {
273
292
unixSocketChannel .write (buffer );
274
293
}
275
294
}
295
+
296
+ @ Override
297
+ public void close () throws IOException {
298
+ TunnelingJdkSocket .this .close ();
299
+ }
276
300
};
277
301
}
278
302
@@ -308,6 +332,9 @@ public void shutdownOutput() throws IOException {
308
332
309
333
@ Override
310
334
public InetAddress getInetAddress () {
335
+ if (!isConnected ()) {
336
+ return null ;
337
+ }
311
338
return inetSocketAddress .getAddress ();
312
339
}
313
340
@@ -316,8 +343,31 @@ public void close() throws IOException {
316
343
if (isClosed ()) {
317
344
return ;
318
345
}
319
- if (null != unixSocketChannel ) {
320
- unixSocketChannel .close ();
346
+ // Ignore possible exceptions so that we continue closing the socket
347
+ try {
348
+ if (!isInputShutdown ()) {
349
+ shutdownInput ();
350
+ }
351
+ } catch (IOException e ) {
352
+ }
353
+ try {
354
+ if (!isOutputShutdown ()) {
355
+ shutdownOutput ();
356
+ }
357
+ } catch (IOException e ) {
358
+ }
359
+ try {
360
+ if (selector != null ) {
361
+ selector .close ();
362
+ selector = null ;
363
+ }
364
+ } catch (IOException e ) {
365
+ }
366
+ try {
367
+ if (unixSocketChannel != null ) {
368
+ unixSocketChannel .close ();
369
+ }
370
+ } catch (IOException e ) {
321
371
}
322
372
closed = true ;
323
373
}
0 commit comments