Got java.net.ProtocolException: Unexpected status line: '� HTTP/1.1 200 OK' while SOCKS5 return command response with address type 'DOMAIN'
Here is my test case
The SocksServer comes from Netty's sample https://github.com/netty/netty/blob/4.1/example/src/main/java/io/netty/example/socksproxy/SocksServer.java
And I just make it can start programatically
MockWebServer server = new MockWebServer();
server.enqueue(new MockResponse().setResponseCode(200).setBody("HelloWorld!"));
server.start();
SocksServer proxy = new SocksServer();
proxy.start();
OkHttpClient client = new OkHttpClient.Builder()
.proxy(new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("127.0.0.1", proxy.port())))
.build();
Response response = client.newCall(new Request.Builder()
.url(new URL("http://127.0.0.1:" + server.getPort()))
.build())
.execute();
assertTrue(response.isSuccessful());
assertEquals(200, response.code());
assertEquals("OK", response.message());
assertEquals("HelloWorld!", response.body().string());
Here is the tcpdump traffics follow tcp stream with port 1080, printed in Hex Dump format
00000000 05 02 00 02 ....
00000000 05 00 ..
00000004 05 01 00 03 09 31 32 37 2e 30 2e 30 2e 31 e7 2e .....127 .0.0.1..
00000002 05 00 00 03 09 31 32 37 2e 30 2e 30 2e 31 e7 2e .....127 .0.0.1..
00000014 47 45 54 20 2f 20 48 54 54 50 2f 31 2e 31 0d 0a GET / HT TP/1.1..
00000024 48 6f 73 74 3a 20 31 32 37 2e 30 2e 30 2e 31 3a Host: 12 7.0.0.1:
00000034 35 39 31 38 32 0d 0a 43 6f 6e 6e 65 63 74 69 6f 59182..C onnectio
00000044 6e 3a 20 4b 65 65 70 2d 41 6c 69 76 65 0d 0a 41 n: Keep- Alive..A
00000054 63 63 65 70 74 2d 45 6e 63 6f 64 69 6e 67 3a 20 ccept-En coding:
00000064 67 7a 69 70 0d 0a 55 73 65 72 2d 41 67 65 6e 74 gzip..Us er-Agent
00000074 3a 20 6f 6b 68 74 74 70 2f 34 2e 32 2e 32 0d 0a : okhttp /4.2.2..
00000084 0d 0a ..
00000012 48 54 54 50 2f 31 2e 31 20 32 30 30 20 4f 4b 0d HTTP/1.1 200 OK.
00000022 0a 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a .Content -Length:
00000032 20 31 31 0d 0a 0d 0a 48 65 6c 6c 6f 57 6f 72 6c 11....H elloWorl
00000042 64 21 d!
The response line is 05 00 00 03 09 31 32 37 2e 30 2e 30 2e 31 e7 2e 05: socks ver 00: success 00: reserved 03: address type domain name 09: string len 31 32 37 2e 30 2e 30 2e 31: string '127.0.0.1' e7 2e: port 59182
According to https://tools.ietf.org/html/rfc1928, section 6. Replies The address type 03 is a valid value
The SOCKS request information is sent by the client as soon as it has
established a connection to the SOCKS server, and completed the
authentication negotiations. The server evaluates the request, and
returns a reply formed as follows:
+----+-----+-------+------+----------+----------+
|VER | REP | RSV | ATYP | BND.ADDR | BND.PORT |
+----+-----+-------+------+----------+----------+
| 1 | 1 | X'00' | 1 | Variable | 2 |
+----+-----+-------+------+----------+----------+
Where:
o VER protocol version: X'05'
o REP Reply field:
o X'00' succeeded
o X'01' general SOCKS server failure
o X'02' connection not allowed by ruleset
o X'03' Network unreachable
o X'04' Host unreachable
o X'05' Connection refused
o X'06' TTL expired
o X'07' Command not supported
o X'08' Address type not supported
o X'09' to X'FF' unassigned
o RSV RESERVED
o ATYP address type of following address
o IP V4 address: X'01'
o DOMAINNAME: X'03'
o IP V6 address: X'04'
o BND.ADDR server bound address
o BND.PORT server bound port in network octet order
Fields marked RESERVED (RSV) must be set to X'00'.
If the chosen method includes encapsulation for purposes of
authentication, integrity and/or confidentiality, the replies are
encapsulated in the method-dependent encapsulation.
Here is another tcpdump traffics, the socks server was 'SSH -vHD 1080' It returns '05 00 00 01 00 00 00 00 00 00' to accept the CONNECT command request which is the same as https://github.com/square/okhttp/blob/5a344e663ce40df9373eb62e9354d225323577e3/okhttp/src/test/java/okhttp3/SocksProxy.java did It set the address type with 0x01(IPv4), and the OkHttpClient can works correctly
00000000 05 02 00 02 ....
00000000 05 00 ..
00000004 05 01 00 03 09 31 32 37 2e 30 2e 30 2e 31 d7 e8 .....127 .0.0.1..
00000002 05 00 00 01 00 00 00 00 00 00 ........ ..
00000014 47 45 54 20 2f 20 48 54 54 50 2f 31 2e 31 0d 0a GET / HT TP/1.1..
00000024 48 6f 73 74 3a 20 31 32 37 2e 30 2e 30 2e 31 3a Host: 12 7.0.0.1:
00000034 35 35 32 37 32 0d 0a 43 6f 6e 6e 65 63 74 69 6f 55272..C onnectio
00000044 6e 3a 20 4b 65 65 70 2d 41 6c 69 76 65 0d 0a 41 n: Keep- Alive..A
00000054 63 63 65 70 74 2d 45 6e 63 6f 64 69 6e 67 3a 20 ccept-En coding:
00000064 67 7a 69 70 0d 0a 55 73 65 72 2d 41 67 65 6e 74 gzip..Us er-Agent
00000074 3a 20 6f 6b 68 74 74 70 2f 34 2e 32 2e 32 0d 0a : okhttp /4.2.2..
00000084 0d 0a ..
0000000C 48 54 54 50 2f 31 2e 31 20 32 30 30 20 4f 4b 0d HTTP/1.1 200 OK.
0000001C 0a 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a .Content -Length:
0000002C 20 31 31 0d 0a 0d 0a 48 65 6c 6c 6f 57 6f 72 6c 11....H elloWorl
0000003C 64 21 d!
Current behavior is only response with address type 0x01, the OkHttpClient can works as expected.
Once the socks server response with type 0x03, no matter it followed by a non-empty string domain like '05 00 00 03 09 31 32 37 2e 30 2e 30 2e 31 e7 2e', nor an empty string like '05 00 00 03 00 00 00', it all failed by exception
Unexpected status line: �HTTP/1.1 200 OK
java.net.ProtocolException: Unexpected status line: �HTTP/1.1 200 OK
~~Embedding the Netty SOCKS for our testing is probably a good way to validate our client. I’ll take a look at adding some tests.~~
Just noticed Socks5ProxyHandler, so avoiding extra deps for now.
Is this related to #3662 , I still got the error:
java.net.ProtocolException: Unexpected status line: achefly.cachefly.net��PHTTP/1.1 200 OK
I also encountered this issue on an Android app when the address type of socks server is IPV6.
The root cause is SocksSocketImpl.java of openjdk got the length of ipv6 and domain address wrong.
And it has been fixed in this commit about 10 years ago but not Android.
I reported this bug to AOSP team and they have help to import the change from openjdk.
So if you encountered this issue on Android, there are 2 workarounds:
- make the address type of socks server is IPV4
- use a custom
SocketFactoryfor socks proxy
Nice result