X Tutup
Skip to content

Commit 20cabcd

Browse files
committed
support for unix sockets
1 parent a7a1b91 commit 20cabcd

File tree

6 files changed

+553
-58
lines changed

6 files changed

+553
-58
lines changed

pom.xml

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@
3939
</developer>
4040
</developers>
4141

42+
<repositories>
43+
<repository>
44+
<id>jcenter</id>
45+
<url>http://jcenter.bintray.com</url>
46+
</repository>
47+
</repositories>
48+
4249
<properties>
4350
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
4451
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
@@ -61,9 +68,9 @@
6168
<commons-lang.version>2.6</commons-lang.version>
6269
<slf4j-api.version>1.7.5</slf4j-api.version>
6370
<jsr305.version>1.3.9</jsr305.version>
64-
<jnr.unixsocket.version>0.3</jnr.unixsocket.version>
6571
<guava.version>18.0</guava.version>
6672
<bouncycastle.version>1.51</bouncycastle.version>
73+
<unix-socket-factory.version>2014-09-26T18-52-33</unix-socket-factory.version>
6774

6875
<!--test dependencies -->
6976
<version.logback>1.0.1</version.logback>
@@ -93,12 +100,23 @@
93100
<!-- <artifactId>jersey-jetty-connector</artifactId> -->
94101
<!-- <version>${jersey.version}</version> -->
95102
<!-- </dependency> -->
103+
<dependency>
104+
<groupId>org.glassfish.jersey.connectors</groupId>
105+
<artifactId>jersey-apache-connector</artifactId>
106+
<version>${jersey.version}</version>
107+
</dependency>
96108
<dependency>
97109
<groupId>org.glassfish.jersey.core</groupId>
98110
<artifactId>jersey-client</artifactId>
99111
<version>${jersey.version}</version>
100112
</dependency>
101113

114+
<dependency>
115+
<groupId>de.gesellix</groupId>
116+
<artifactId>unix-socket-factory</artifactId>
117+
<version>${unix-socket-factory.version}</version>
118+
</dependency>
119+
102120
<dependency>
103121
<groupId>org.apache.commons</groupId>
104122
<artifactId>commons-compress</artifactId>
@@ -120,11 +138,6 @@
120138
<version>${commons-io.version}</version>
121139
</dependency>
122140

123-
<dependency>
124-
<groupId>com.github.jnr</groupId>
125-
<artifactId>jnr-unixsocket</artifactId>
126-
<version>${jnr.unixsocket.version}</version>
127-
</dependency>
128141

129142
<dependency>
130143
<groupId>org.slf4j</groupId>
Lines changed: 327 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,327 @@
1+
package com.github.dockerjava.jaxrs;
2+
/*
3+
* Copyright (c) 2014 Spotify AB.
4+
*
5+
* Licensed to the Apache Software Foundation (ASF) under one
6+
* or more contributor license agreements. See the NOTICE file
7+
* distributed with this work for additional information
8+
* regarding copyright ownership. The ASF licenses this file
9+
* to you under the Apache License, Version 2.0 (the
10+
* "License"); you may not use this file except in compliance
11+
* with the License. You may obtain a copy of the License at
12+
*
13+
* http://www.apache.org/licenses/LICENSE-2.0
14+
*
15+
* Unless required by applicable law or agreed to in writing,
16+
* software distributed under the License is distributed on an
17+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18+
* KIND, either express or implied. See the License for the
19+
* specific language governing permissions and limitations
20+
* under the License.
21+
*/
22+
23+
24+
25+
import com.google.common.collect.Queues;
26+
27+
import org.newsclub.net.unix.AFUNIXSocket;
28+
29+
import java.io.IOException;
30+
import java.io.InputStream;
31+
import java.io.OutputStream;
32+
import java.net.InetAddress;
33+
import java.net.Socket;
34+
import java.net.SocketAddress;
35+
import java.net.SocketException;
36+
import java.nio.channels.SocketChannel;
37+
import java.util.Queue;
38+
39+
/**
40+
* Provides a socket that wraps an org.newsclub.net.unix.AFUNIXSocket and delays setting options
41+
* until the socket is connected. This is necessary because the Apache HTTP client attempts to
42+
* set options prior to connecting the socket, which doesn't work for Unix sockets since options
43+
* are being set on the underlying file descriptor. Until the socket is connected, the file
44+
* descriptor doesn't exist.
45+
*
46+
* This class also noop's any calls to setReuseAddress, which is called by the Apache client but
47+
* isn't supported by AFUnixSocket.
48+
*/
49+
public class ApacheUnixSocket extends Socket {
50+
51+
private final AFUNIXSocket inner;
52+
53+
private final Queue<SocketOptionSetter> optionsToSet = Queues.newArrayDeque();
54+
55+
public ApacheUnixSocket() throws IOException {
56+
this.inner = AFUNIXSocket.newInstance();
57+
}
58+
59+
@Override
60+
public void connect(final SocketAddress endpoint) throws IOException {
61+
inner.connect(endpoint);
62+
setAllSocketOptions();
63+
}
64+
65+
@Override
66+
public void connect(final SocketAddress endpoint, final int timeout) throws IOException {
67+
inner.connect(endpoint, timeout);
68+
setAllSocketOptions();
69+
}
70+
71+
@Override
72+
public void bind(final SocketAddress bindpoint) throws IOException {
73+
inner.bind(bindpoint);
74+
setAllSocketOptions();
75+
}
76+
77+
@Override
78+
public InetAddress getInetAddress() {
79+
return inner.getInetAddress();
80+
}
81+
82+
@Override
83+
public InetAddress getLocalAddress() {
84+
return inner.getLocalAddress();
85+
}
86+
87+
@Override
88+
public int getPort() {
89+
return inner.getPort();
90+
}
91+
92+
@Override
93+
public int getLocalPort() {
94+
return inner.getLocalPort();
95+
}
96+
97+
@Override
98+
public SocketAddress getRemoteSocketAddress() {
99+
return inner.getRemoteSocketAddress();
100+
}
101+
102+
@Override
103+
public SocketAddress getLocalSocketAddress() {
104+
return inner.getLocalSocketAddress();
105+
}
106+
107+
@Override
108+
public SocketChannel getChannel() {
109+
return inner.getChannel();
110+
}
111+
112+
@Override
113+
public InputStream getInputStream() throws IOException {
114+
return inner.getInputStream();
115+
}
116+
117+
@Override
118+
public OutputStream getOutputStream() throws IOException {
119+
return inner.getOutputStream();
120+
}
121+
122+
private void setSocketOption(final SocketOptionSetter s) throws SocketException {
123+
if (inner.isConnected()) {
124+
s.run();
125+
} else {
126+
if (!optionsToSet.offer(s)) {
127+
throw new SocketException("Failed to queue option");
128+
}
129+
}
130+
}
131+
132+
private void setAllSocketOptions() throws SocketException {
133+
for (SocketOptionSetter s : optionsToSet) {
134+
s.run();
135+
}
136+
}
137+
138+
@Override
139+
public void setTcpNoDelay(final boolean on) throws SocketException {
140+
setSocketOption(new SocketOptionSetter() {
141+
@Override
142+
public void run() throws SocketException {
143+
inner.setTcpNoDelay(on);
144+
}
145+
});
146+
}
147+
148+
@Override
149+
public boolean getTcpNoDelay() throws SocketException {
150+
return inner.getTcpNoDelay();
151+
}
152+
153+
@Override
154+
public void setSoLinger(final boolean on, final int linger) throws SocketException {
155+
setSocketOption(new SocketOptionSetter() {
156+
@Override
157+
public void run() throws SocketException {
158+
inner.setSoLinger(on, linger);
159+
}
160+
});
161+
}
162+
163+
@Override
164+
public int getSoLinger() throws SocketException {
165+
return inner.getSoLinger();
166+
}
167+
168+
@Override
169+
public void sendUrgentData(final int data) throws IOException {
170+
inner.sendUrgentData(data);
171+
}
172+
173+
@Override
174+
public void setOOBInline(final boolean on) throws SocketException {
175+
setSocketOption(new SocketOptionSetter() {
176+
@Override
177+
public void run() throws SocketException {
178+
inner.setOOBInline(on);
179+
}
180+
});
181+
}
182+
183+
@Override
184+
public boolean getOOBInline() throws SocketException {
185+
return inner.getOOBInline();
186+
}
187+
188+
@Override
189+
public synchronized void setSoTimeout(final int timeout) throws SocketException {
190+
setSocketOption(new SocketOptionSetter() {
191+
@Override
192+
public void run() throws SocketException {
193+
inner.setSoTimeout(timeout);
194+
}
195+
});
196+
}
197+
198+
@Override
199+
public synchronized int getSoTimeout() throws SocketException {
200+
return inner.getSoTimeout();
201+
}
202+
203+
@Override
204+
public synchronized void setSendBufferSize(final int size) throws SocketException {
205+
setSocketOption(new SocketOptionSetter() {
206+
@Override
207+
public void run() throws SocketException {
208+
inner.setSendBufferSize(size);
209+
}
210+
});
211+
}
212+
213+
@Override
214+
public synchronized int getSendBufferSize() throws SocketException {
215+
return inner.getSendBufferSize();
216+
}
217+
218+
@Override
219+
public synchronized void setReceiveBufferSize(final int size) throws SocketException {
220+
setSocketOption(new SocketOptionSetter() {
221+
@Override
222+
public void run() throws SocketException {
223+
inner.setReceiveBufferSize(size);
224+
}
225+
});
226+
}
227+
228+
@Override
229+
public synchronized int getReceiveBufferSize() throws SocketException {
230+
return inner.getReceiveBufferSize();
231+
}
232+
233+
@Override
234+
public void setKeepAlive(final boolean on) throws SocketException {
235+
setSocketOption(new SocketOptionSetter() {
236+
@Override
237+
public void run() throws SocketException {
238+
inner.setKeepAlive(on);
239+
}
240+
});
241+
}
242+
243+
@Override
244+
public boolean getKeepAlive() throws SocketException {
245+
return inner.getKeepAlive();
246+
}
247+
248+
@Override
249+
public void setTrafficClass(final int tc) throws SocketException {
250+
setSocketOption(new SocketOptionSetter() {
251+
@Override
252+
public void run() throws SocketException {
253+
inner.setTrafficClass(tc);
254+
}
255+
});
256+
}
257+
258+
@Override
259+
public int getTrafficClass() throws SocketException {
260+
return inner.getTrafficClass();
261+
}
262+
263+
@Override
264+
public void setReuseAddress(final boolean on) throws SocketException {
265+
// not supported: Apache client tries to set it, but we want to just ignore it
266+
}
267+
268+
@Override
269+
public boolean getReuseAddress() throws SocketException {
270+
return inner.getReuseAddress();
271+
}
272+
273+
@Override
274+
public synchronized void close() throws IOException {
275+
inner.close();
276+
}
277+
278+
@Override
279+
public void shutdownInput() throws IOException {
280+
inner.shutdownInput();
281+
}
282+
283+
@Override
284+
public void shutdownOutput() throws IOException {
285+
inner.shutdownOutput();
286+
}
287+
288+
@Override
289+
public String toString() {
290+
return inner.toString();
291+
}
292+
293+
@Override
294+
public boolean isConnected() {
295+
return inner.isConnected();
296+
}
297+
298+
@Override
299+
public boolean isBound() {
300+
return inner.isBound();
301+
}
302+
303+
@Override
304+
public boolean isClosed() {
305+
return inner.isClosed();
306+
}
307+
308+
@Override
309+
public boolean isInputShutdown() {
310+
return inner.isInputShutdown();
311+
}
312+
313+
@Override
314+
public boolean isOutputShutdown() {
315+
return inner.isOutputShutdown();
316+
}
317+
318+
@Override
319+
public void setPerformancePreferences(final int connectionTime, final int latency,
320+
final int bandwidth) {
321+
inner.setPerformancePreferences(connectionTime, latency, bandwidth);
322+
}
323+
324+
interface SocketOptionSetter {
325+
void run() throws SocketException;
326+
}
327+
}

0 commit comments

Comments
 (0)
X Tutup