No flags found
Use flags to group coverage reports by test type, project and/or folders.
Then setup custom commit statuses and notifications for each flag.
e.g., #unittest #integration
#production #enterprise
#frontend #backend
cc49498
... +5 ...
b6002c6
Use flags to group coverage reports by test type, project and/or folders.
Then setup custom commit statuses and notifications for each flag.
e.g., #unittest #integration
#production #enterprise
#frontend #backend
1 | + | /* |
|
2 | + | * -------------------------------- MIT License -------------------------------- |
|
3 | + | * |
|
4 | + | * Copyright (c) 2021 SNF4J contributors |
|
5 | + | * |
|
6 | + | * Permission is hereby granted, free of charge, to any person obtaining a copy |
|
7 | + | * of this software and associated documentation files (the "Software"), to deal |
|
8 | + | * in the Software without restriction, including without limitation the rights |
|
9 | + | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
10 | + | * copies of the Software, and to permit persons to whom the Software is |
|
11 | + | * furnished to do so, subject to the following conditions: |
|
12 | + | * |
|
13 | + | * The above copyright notice and this permission notice shall be included in all |
|
14 | + | * copies or substantial portions of the Software. |
|
15 | + | * |
|
16 | + | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
17 | + | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
18 | + | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
19 | + | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
20 | + | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
21 | + | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|
22 | + | * SOFTWARE. |
|
23 | + | * |
|
24 | + | * ----------------------------------------------------------------------------- |
|
25 | + | */ |
|
26 | + | package org.snf4j.core.proxy; |
|
27 | + | ||
28 | + | enum Socks4Status { |
|
29 | + | ||
30 | + | SUCCESS(90, "Request granted"), |
|
31 | + | REJECTED_OR_FAILED(91, "Request rejected or failed"), |
|
32 | + | IDENTD_UNREACHABLE(92, "Request rejected becasue SOCKS server cannot connect to identd on the client"), |
|
33 | + | IDENTD_AUTH_FAILURE(93, "Request rejected because the client program and identd report different user-ids"), |
|
34 | + | UNKNOWN(-1, "Unknown"); |
|
35 | + | ||
36 | + | private final int code; |
|
37 | + | ||
38 | + | private final String description; |
|
39 | + | ||
40 | + | Socks4Status(int code, String description) { |
|
41 | + | this.code = code; |
|
42 | + | this.description = description; |
|
43 | + | } |
|
44 | + | ||
45 | + | public int code() { |
|
46 | + | return code; |
|
47 | + | } |
|
48 | + | ||
49 | + | public String description() { |
|
50 | + | return description; |
|
51 | + | } |
|
52 | + | ||
53 | + | public static Socks4Status valueOf(int code) { |
|
54 | + | for (Socks4Status value: values()) { |
|
55 | + | if (value.code == code) { |
|
56 | + | return value; |
|
57 | + | } |
|
58 | + | } |
|
59 | + | return UNKNOWN; |
|
60 | + | } |
|
61 | + | } |
35 | 35 | import org.snf4j.core.factory.ISessionStructureFactory; |
|
36 | 36 | import org.snf4j.core.handler.SessionEvent; |
|
37 | 37 | import org.snf4j.core.session.ISessionConfig; |
|
38 | + | import org.snf4j.core.session.IStreamSession; |
|
38 | 39 | ||
39 | 40 | /** |
|
40 | 41 | * Handles client proxy connections via the HTTP tunneling protocol. For more |
89 | 90 | * |
|
90 | 91 | * @param uri the URI identifying the remote host to which the HTTP tunnel |
|
91 | 92 | * should be established |
|
93 | + | * @throws IllegalArgumentException if the uri is null |
|
92 | 94 | */ |
|
93 | 95 | public HttpProxyHandler(URI uri) { |
|
94 | 96 | this(uri, false, null, null); |
105 | 107 | * should be established |
|
106 | 108 | * @param config the session configuration object, or {@code null} to use the |
|
107 | 109 | * default configuration |
|
110 | + | * @throws IllegalArgumentException if the uri is null |
|
108 | 111 | */ |
|
109 | 112 | public HttpProxyHandler(URI uri, ISessionConfig config) { |
|
110 | 113 | this(uri, false, config, null); |
124 | 127 | * @param factory the factory that will be used to configure the internal |
|
125 | 128 | * structure of the associated session, or {@code null} to use |
|
126 | 129 | * the default factory |
|
130 | + | * @throws IllegalArgumentException if the uri is null |
|
127 | 131 | */ |
|
128 | 132 | public HttpProxyHandler(URI uri, ISessionConfig config, ISessionStructureFactory factory) { |
|
129 | 133 | this(uri, false, config, factory); |
143 | 147 | * terminators in the responses from a HTTP proxy |
|
144 | 148 | * server, or otherwise (default option) only CRLF |
|
145 | 149 | * will be allowed |
|
150 | + | * @throws IllegalArgumentException if the uri is null |
|
146 | 151 | */ |
|
147 | 152 | public HttpProxyHandler(URI uri, boolean allowBothTerminators) { |
|
148 | 153 | this(uri, allowBothTerminators, null, null); |
164 | 169 | * will be allowed |
|
165 | 170 | * @param config the session configuration object, or {@code null} |
|
166 | 171 | * to use the default configuration |
|
172 | + | * @throws IllegalArgumentException if the uri is null |
|
167 | 173 | */ |
|
168 | 174 | public HttpProxyHandler(URI uri, boolean allowBothTerminators, ISessionConfig config) { |
|
169 | 175 | this(uri, allowBothTerminators, config, null); |
188 | 194 | * @param factory the factory that will be used to configure the |
|
189 | 195 | * internal structure of the associated session, or |
|
190 | 196 | * {@code null} to use the default factory |
|
197 | + | * @throws IllegalArgumentException if the uri is null |
|
191 | 198 | */ |
|
192 | 199 | public HttpProxyHandler(URI uri, boolean allowBothTerminators, ISessionConfig config, ISessionStructureFactory factory) { |
|
193 | 200 | super(config, factory); |
210 | 217 | * @param connectionTimeout the proxy connection timeout in milliseconds, or |
|
211 | 218 | * {@code 0} to wait an infinite amount of time for |
|
212 | 219 | * establishing the HTTP tunnel. |
|
220 | + | * @throws IllegalArgumentException if the uri is null |
|
213 | 221 | */ |
|
214 | 222 | public HttpProxyHandler(URI uri, long connectionTimeout) { |
|
215 | 223 | this(uri, connectionTimeout, false); |
229 | 237 | * establishing the HTTP tunnel. |
|
230 | 238 | * @param config the session configuration object, or {@code null} to |
|
231 | 239 | * use the default configuration |
|
240 | + | * @throws IllegalArgumentException if the uri is null |
|
232 | 241 | */ |
|
233 | 242 | public HttpProxyHandler(URI uri, long connectionTimeout, ISessionConfig config) { |
|
234 | 243 | this(uri, connectionTimeout, false, config, null); |
251 | 260 | * @param factory the factory that will be used to configure the |
|
252 | 261 | * internal structure of the associated session, or |
|
253 | 262 | * {@code null} to use the default factory |
|
263 | + | * @throws IllegalArgumentException if the uri is null |
|
254 | 264 | */ |
|
255 | 265 | public HttpProxyHandler(URI uri, long connectionTimeout, ISessionConfig config, ISessionStructureFactory factory) { |
|
256 | 266 | this(uri, connectionTimeout, false, config, factory); |
272 | 282 | * terminators in the responses from a HTTP proxy |
|
273 | 283 | * server, or otherwise (default option) only CRLF |
|
274 | 284 | * will be allowed |
|
285 | + | * @throws IllegalArgumentException if the uri is null |
|
275 | 286 | */ |
|
276 | 287 | public HttpProxyHandler(URI uri, long connectionTimeout, boolean allowBothTerminators) { |
|
277 | 288 | this(uri, connectionTimeout, allowBothTerminators, null, null); |
296 | 307 | * will be allowed |
|
297 | 308 | * @param config the session configuration object, or {@code null} |
|
298 | 309 | * to use the default configuration |
|
310 | + | * @throws IllegalArgumentException if the uri is null |
|
299 | 311 | */ |
|
300 | 312 | public HttpProxyHandler(URI uri, long connectionTimeout, boolean allowBothTerminators, ISessionConfig config) { |
|
301 | 313 | this(uri, connectionTimeout, allowBothTerminators, config, null); |
323 | 335 | * @param factory the factory that will be used to configure the |
|
324 | 336 | * internal structure of the associated session, or |
|
325 | 337 | * {@code null} to use the default factory |
|
338 | + | * @throws IllegalArgumentException if the uri is null |
|
326 | 339 | */ |
|
327 | 340 | public HttpProxyHandler(URI uri, long connectionTimeout, boolean allowBothTerminators, ISessionConfig config, ISessionStructureFactory factory) { |
|
328 | 341 | super(connectionTimeout, config, factory); |
532 | 545 | host = toBytes(uriHost); |
|
533 | 546 | } |
|
534 | 547 | ||
548 | + | IStreamSession session = getSession(); |
|
535 | 549 | ByteBuffer frame; |
|
536 | 550 | ||
537 | 551 | synchronized (headers) { |
548 | 562 | + headersLength |
|
549 | 563 | + CRLF.length; |
|
550 | 564 | ||
551 | - | frame = getSession().allocate(length); |
|
565 | + | frame = session.allocate(length); |
|
552 | 566 | frame.put(HTTP_CONNECT); |
|
553 | 567 | frame.put(SP); |
|
554 | 568 | frame.put(fullHost); |
568 | 582 | ||
569 | 583 | frame.put(CRLF); |
|
570 | 584 | frame.flip(); |
|
571 | - | getSession().writenf(frame); |
|
585 | + | session.writenf(frame); |
|
586 | + | if (!session.isDataCopyingOptimized()) { |
|
587 | + | session.release(frame); |
|
588 | + | } |
|
572 | 589 | } |
|
573 | 590 | ||
574 | 591 | @Override |
1 | + | /* |
|
2 | + | * -------------------------------- MIT License -------------------------------- |
|
3 | + | * |
|
4 | + | * Copyright (c) 2021 SNF4J contributors |
|
5 | + | * |
|
6 | + | * Permission is hereby granted, free of charge, to any person obtaining a copy |
|
7 | + | * of this software and associated documentation files (the "Software"), to deal |
|
8 | + | * in the Software without restriction, including without limitation the rights |
|
9 | + | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
10 | + | * copies of the Software, and to permit persons to whom the Software is |
|
11 | + | * furnished to do so, subject to the following conditions: |
|
12 | + | * |
|
13 | + | * The above copyright notice and this permission notice shall be included in all |
|
14 | + | * copies or substantial portions of the Software. |
|
15 | + | * |
|
16 | + | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
17 | + | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
18 | + | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
19 | + | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
20 | + | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
21 | + | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|
22 | + | * SOFTWARE. |
|
23 | + | * |
|
24 | + | * ----------------------------------------------------------------------------- |
|
25 | + | */ |
|
26 | + | package org.snf4j.core.proxy; |
|
27 | + | ||
28 | + | import java.net.InetSocketAddress; |
|
29 | + | import java.nio.ByteBuffer; |
|
30 | + | import java.nio.charset.StandardCharsets; |
|
31 | + | ||
32 | + | import org.snf4j.core.util.NetworkUtil; |
|
33 | + | ||
34 | + | class Socks4CommandState extends AbstractSocksState implements ISocks4 { |
|
35 | + | ||
36 | + | private final static byte REPLY_VERSION = 0; |
|
37 | + | ||
38 | + | private final static int RESPONSE_SIZE = 8; |
|
39 | + | ||
40 | + | private final static byte[] DOMAIN_MARKER = new byte[] {0,0,0,1}; |
|
41 | + | ||
42 | + | final static int STATUS_INDEX = 1; |
|
43 | + | ||
44 | + | final static int IP_INDEX = 4; |
|
45 | + | ||
46 | + | final static int PORT_INDEX = 2; |
|
47 | + | ||
48 | + | private final Socks4Command command; |
|
49 | + | ||
50 | + | private final String username; |
|
51 | + | ||
52 | + | Socks4CommandState(Socks4ProxyHandler handler, Socks4Command command, String username) { |
|
53 | + | super(handler); |
|
54 | + | this.command = command; |
|
55 | + | this.username = username == null ? "" : username; |
|
56 | + | } |
|
57 | + | ||
58 | + | @Override |
|
59 | + | int responseSize() { |
|
60 | + | return RESPONSE_SIZE; |
|
61 | + | } |
|
62 | + | ||
63 | + | @Override |
|
64 | + | AbstractSocksState read(byte[] data) { |
|
65 | + | if (data[VER_INDEX] != REPLY_VERSION) { |
|
66 | + | throw new ProxyConnectionException("Unsupported SOCKS4 reply version: " + data[0] + " (expected: 0)"); |
|
67 | + | } |
|
68 | + | ||
69 | + | int statusCode = (int)data[STATUS_INDEX] & 0xff; |
|
70 | + | Socks4Status status = Socks4Status.valueOf(statusCode); |
|
71 | + | int replyCount = handler.reply(new Socks4Reply( |
|
72 | + | statusCode, NetworkUtil.ipv4ToString(data, IP_INDEX), NetworkUtil.toPort(data,PORT_INDEX))); |
|
73 | + | ||
74 | + | if (status != Socks4Status.SUCCESS) { |
|
75 | + | throw new ProxyConnectionException("SOCKS4 proxy response status code: " + statusCode); |
|
76 | + | } |
|
77 | + | if (command == Socks4Command.CONNECT || replyCount == 2) { |
|
78 | + | return null; |
|
79 | + | } |
|
80 | + | return this; |
|
81 | + | } |
|
82 | + | ||
83 | + | @Override |
|
84 | + | void handleReady() { |
|
85 | + | InetSocketAddress address = handler.getAddress(); |
|
86 | + | byte[] usernameBytes = username.getBytes(StandardCharsets.US_ASCII); |
|
87 | + | String host; |
|
88 | + | byte[] ipv4, hostBytes; |
|
89 | + | int len; |
|
90 | + | ||
91 | + | if (address.isUnresolved()) { |
|
92 | + | host = address.getHostString(); |
|
93 | + | } |
|
94 | + | else { |
|
95 | + | host = address.getAddress().getHostAddress(); |
|
96 | + | } |
|
97 | + | ||
98 | + | ipv4 = NetworkUtil.ipv4ToBytes(host); |
|
99 | + | len = 1+1+2+4+usernameBytes.length+1; |
|
100 | + | if (ipv4 != null) { |
|
101 | + | hostBytes = null; |
|
102 | + | } |
|
103 | + | else { |
|
104 | + | hostBytes = host.getBytes(StandardCharsets.US_ASCII); |
|
105 | + | ipv4 = DOMAIN_MARKER; |
|
106 | + | len += hostBytes.length + 1; |
|
107 | + | } |
|
108 | + | ||
109 | + | ByteBuffer buf = handler.getSession().allocate(len); |
|
110 | + | ||
111 | + | buf.put(VERSION); |
|
112 | + | buf.put(command.code()); |
|
113 | + | buf.putShort((short)address.getPort()); |
|
114 | + | buf.put(ipv4); |
|
115 | + | buf.put(usernameBytes); |
|
116 | + | buf.put((byte)0); |
|
117 | + | if (hostBytes != null) { |
|
118 | + | buf.put(hostBytes); |
|
119 | + | buf.put((byte)0); |
|
120 | + | } |
|
121 | + | handler.flipAndWrite(buf); |
|
122 | + | } |
|
123 | + | ||
124 | + | } |
1 | + | /* |
|
2 | + | * -------------------------------- MIT License -------------------------------- |
|
3 | + | * |
|
4 | + | * Copyright (c) 2021 SNF4J contributors |
|
5 | + | * |
|
6 | + | * Permission is hereby granted, free of charge, to any person obtaining a copy |
|
7 | + | * of this software and associated documentation files (the "Software"), to deal |
|
8 | + | * in the Software without restriction, including without limitation the rights |
|
9 | + | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
10 | + | * copies of the Software, and to permit persons to whom the Software is |
|
11 | + | * furnished to do so, subject to the following conditions: |
|
12 | + | * |
|
13 | + | * The above copyright notice and this permission notice shall be included in all |
|
14 | + | * copies or substantial portions of the Software. |
|
15 | + | * |
|
16 | + | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
17 | + | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
18 | + | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
19 | + | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
20 | + | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
21 | + | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|
22 | + | * SOFTWARE. |
|
23 | + | * |
|
24 | + | * ----------------------------------------------------------------------------- |
|
25 | + | */ |
|
26 | + | package org.snf4j.core.proxy; |
|
27 | + | ||
28 | + | /** |
|
29 | + | * An {@code enum} that defines types of commands for the SOCKS5 proxy handler. |
|
30 | + | * |
|
31 | + | * @author <a href="http://snf4j.org">SNF4J.ORG</a> |
|
32 | + | */ |
|
33 | + | public enum Socks5Command { |
|
34 | + | ||
35 | + | /** The CONNECT command */ |
|
36 | + | CONNECT((byte)1), |
|
37 | + | ||
38 | + | /** The BIND command */ |
|
39 | + | BIND((byte)2), |
|
40 | + | ||
41 | + | /** The UDP_ASSOCIATE command */ |
|
42 | + | UDP_ASSOCIATE((byte)3); |
|
43 | + | ||
44 | + | private final byte code; |
|
45 | + | ||
46 | + | Socks5Command(byte code) { |
|
47 | + | this.code = code; |
|
48 | + | } |
|
49 | + | ||
50 | + | byte code() { |
|
51 | + | return code; |
|
52 | + | } |
|
53 | + | } |
Learn more Showing 19 files with coverage changes found.
snf4j-core/src/main/java/org/snf4j/core/InternalSelectorLoop.java
snf4j-core/src/main/java/org/snf4j/core/proxy/Socks4Command.java
snf4j-core/src/main/java/org/snf4j/core/util/NetworkUtil.java
snf4j-core/src/main/java/org/snf4j/core/proxy/Socks4Status.java
snf4j-core/src/main/java/org/snf4j/core/proxy/Socks5CommandState.java
snf4j-core/src/main/java/org/snf4j/core/proxy/Socks5InitState.java
snf4j-core/src/main/java/org/snf4j/core/proxy/Socks5ProxyHandler.java
snf4j-core/src/main/java/org/snf4j/core/proxy/Socks4CommandState.java
snf4j-core/src/main/java/org/snf4j/core/proxy/Socks4ProxyHandler.java
snf4j-core/src/main/java/org/snf4j/core/proxy/Socks4Reply.java
snf4j-core/src/main/java/org/snf4j/core/proxy/AbstractSocksProxyHandler.java
snf4j-core/src/main/java/org/snf4j/core/proxy/SocksAddressType.java
snf4j-core/src/main/java/org/snf4j/core/proxy/Socks5Status.java
snf4j-core/src/main/java/org/snf4j/core/proxy/AbstractSocksState.java
snf4j-core/src/main/java/org/snf4j/core/proxy/SocksDoneState.java
snf4j-core/src/main/java/org/snf4j/core/proxy/Socks5AuthMethod.java
snf4j-core/src/main/java/org/snf4j/core/proxy/Socks5Command.java
snf4j-core/src/main/java/org/snf4j/core/proxy/Socks5PasswordAuthState.java
snf4j-core/src/main/java/org/snf4j/core/proxy/Socks5Reply.java
Files | Coverage |
---|---|
snf4j-core-log4j2/src/main/java/org/snf4j/core/logger/impl | 96.66% |
snf4j-core-slf4j/src/main/java/org/snf4j/core/logger/impl | 96.66% |
snf4j-core/src/main/java/org/snf4j/core | 0.19% 97.88% |
snf4j-sctp/src/main/java/org/snf4j/core | 98.56% |
snf4j-websocket/src/main/java/org/snf4j/websocket | 99.30% |
Project Totals (219 files) | 98.19% |
#81
b6002c6
2e9c4e2
192d0e2
fc732df
5a43386
c6f3b3c
cc49498