Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/net/Socket/HttpProxy.java
38812 views
1
/*
2
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
/*
25
* @test
26
* @bug 6370908
27
* @summary Add support for HTTP_CONNECT proxy in Socket class
28
*/
29
30
import java.io.IOException;
31
import java.io.InputStream;
32
import java.io.OutputStream;
33
import java.io.PrintWriter;
34
import static java.lang.System.out;
35
import java.net.InetAddress;
36
import java.net.InetSocketAddress;
37
import java.net.Proxy;
38
import java.net.ServerSocket;
39
import java.net.Socket;
40
import sun.net.www.MessageHeader;
41
42
public class HttpProxy {
43
final String proxyHost;
44
final int proxyPort;
45
static final int SO_TIMEOUT = 15000;
46
47
public static void main(String[] args) throws Exception {
48
String host;
49
int port;
50
if (args.length == 0) {
51
// Start internal proxy
52
ConnectProxyTunnelServer proxy = new ConnectProxyTunnelServer();
53
proxy.start();
54
host = "localhost";
55
port = proxy.getLocalPort();
56
out.println("Running with internal proxy: " + host + ":" + port);
57
} else if (args.length == 2) {
58
host = args[0];
59
port = Integer.valueOf(args[1]);
60
out.println("Running against specified proxy server: " + host + ":" + port);
61
} else {
62
System.err.println("Usage: java HttpProxy [<proxy host> <proxy port>]");
63
return;
64
}
65
66
HttpProxy p = new HttpProxy(host, port);
67
p.test();
68
}
69
70
public HttpProxy(String proxyHost, int proxyPort) {
71
this.proxyHost = proxyHost;
72
this.proxyPort = proxyPort;
73
}
74
75
void test() throws Exception {
76
InetSocketAddress proxyAddress = new InetSocketAddress(proxyHost, proxyPort);
77
Proxy httpProxy = new Proxy(Proxy.Type.HTTP, proxyAddress);
78
79
try (ServerSocket ss = new ServerSocket(0);
80
Socket sock = new Socket(httpProxy)) {
81
sock.setSoTimeout(SO_TIMEOUT);
82
sock.setTcpNoDelay(false);
83
84
InetSocketAddress externalAddress =
85
new InetSocketAddress(InetAddress.getLocalHost(), ss.getLocalPort());
86
87
out.println("Trying to connect to server socket on " + externalAddress);
88
sock.connect(externalAddress);
89
try (Socket externalSock = ss.accept()) {
90
// perform some simple checks
91
check(sock.isBound(), "Socket is not bound");
92
check(sock.isConnected(), "Socket is not connected");
93
check(!sock.isClosed(), "Socket should not be closed");
94
check(sock.getSoTimeout() == SO_TIMEOUT,
95
"Socket should have a previously set timeout");
96
check(sock.getTcpNoDelay() == false, "NODELAY should be false");
97
98
simpleDataExchange(sock, externalSock);
99
}
100
}
101
}
102
103
static void check(boolean condition, String message) {
104
if (!condition) out.println(message);
105
}
106
107
static Exception unexpected(Exception e) {
108
out.println("Unexcepted Exception: " + e);
109
e.printStackTrace();
110
return e;
111
}
112
113
// performs a simple exchange of data between the two sockets
114
// and throws an exception if there is any problem.
115
void simpleDataExchange(Socket s1, Socket s2) throws Exception {
116
try (final InputStream i1 = s1.getInputStream();
117
final InputStream i2 = s2.getInputStream();
118
final OutputStream o1 = s1.getOutputStream();
119
final OutputStream o2 = s2.getOutputStream()) {
120
startSimpleWriter("simpleWriter1", o1, 100);
121
startSimpleWriter("simpleWriter2", o2, 200);
122
simpleRead(i2, 100);
123
simpleRead(i1, 200);
124
}
125
}
126
127
void startSimpleWriter(String threadName, final OutputStream os, final int start) {
128
(new Thread(new Runnable() {
129
public void run() {
130
try { simpleWrite(os, start); }
131
catch (Exception e) {unexpected(e); }
132
}}, threadName)).start();
133
}
134
135
void simpleWrite(OutputStream os, int start) throws Exception {
136
byte b[] = new byte[2];
137
for (int i=start; i<start+100; i++) {
138
b[0] = (byte) (i / 256);
139
b[1] = (byte) (i % 256);
140
os.write(b);
141
}
142
}
143
144
void simpleRead(InputStream is, int start) throws Exception {
145
byte b[] = new byte [2];
146
for (int i=start; i<start+100; i++) {
147
int x = is.read(b);
148
if (x == 1)
149
x += is.read(b,1,1);
150
if (x!=2)
151
throw new Exception("read error");
152
int r = bytes(b[0], b[1]);
153
if (r != i)
154
throw new Exception("read " + r + " expected " +i);
155
}
156
}
157
158
int bytes(byte b1, byte b2) {
159
int i1 = (int)b1 & 0xFF;
160
int i2 = (int)b2 & 0xFF;
161
return i1 * 256 + i2;
162
}
163
164
static class ConnectProxyTunnelServer extends Thread {
165
166
private final ServerSocket ss;
167
168
public ConnectProxyTunnelServer() throws IOException {
169
ss = new ServerSocket(0);
170
}
171
172
@Override
173
public void run() {
174
try (Socket clientSocket = ss.accept()) {
175
processRequest(clientSocket);
176
} catch (Exception e) {
177
out.println("Proxy Failed: " + e);
178
e.printStackTrace();
179
} finally {
180
try { ss.close(); } catch (IOException x) { unexpected(x); }
181
}
182
}
183
184
/**
185
* Returns the port on which the proxy is accepting connections.
186
*/
187
public int getLocalPort() {
188
return ss.getLocalPort();
189
}
190
191
/*
192
* Processes the CONNECT request
193
*/
194
private void processRequest(Socket clientSocket) throws Exception {
195
MessageHeader mheader = new MessageHeader(clientSocket.getInputStream());
196
String statusLine = mheader.getValue(0);
197
198
if (!statusLine.startsWith("CONNECT")) {
199
out.println("proxy server: processes only "
200
+ "CONNECT method requests, recieved: "
201
+ statusLine);
202
return;
203
}
204
205
// retrieve the host and port info from the status-line
206
InetSocketAddress serverAddr = getConnectInfo(statusLine);
207
208
//open socket to the server
209
try (Socket serverSocket = new Socket(serverAddr.getAddress(),
210
serverAddr.getPort())) {
211
Forwarder clientFW = new Forwarder(clientSocket.getInputStream(),
212
serverSocket.getOutputStream());
213
Thread clientForwarderThread = new Thread(clientFW, "ClientForwarder");
214
clientForwarderThread.start();
215
send200(clientSocket);
216
Forwarder serverFW = new Forwarder(serverSocket.getInputStream(),
217
clientSocket.getOutputStream());
218
serverFW.run();
219
clientForwarderThread.join();
220
}
221
}
222
223
private void send200(Socket clientSocket) throws IOException {
224
OutputStream out = clientSocket.getOutputStream();
225
PrintWriter pout = new PrintWriter(out);
226
227
pout.println("HTTP/1.1 200 OK");
228
pout.println();
229
pout.flush();
230
}
231
232
/*
233
* This method retrieves the hostname and port of the tunnel destination
234
* from the request line.
235
* @param connectStr
236
* of the form: <i>CONNECT server-name:server-port HTTP/1.x</i>
237
*/
238
static InetSocketAddress getConnectInfo(String connectStr)
239
throws Exception
240
{
241
try {
242
int starti = connectStr.indexOf(' ');
243
int endi = connectStr.lastIndexOf(' ');
244
String connectInfo = connectStr.substring(starti+1, endi).trim();
245
// retrieve server name and port
246
endi = connectInfo.indexOf(':');
247
String name = connectInfo.substring(0, endi);
248
int port = Integer.parseInt(connectInfo.substring(endi+1));
249
return new InetSocketAddress(name, port);
250
} catch (Exception e) {
251
out.println("Proxy recieved a request: " + connectStr);
252
throw unexpected(e);
253
}
254
}
255
}
256
257
/* Reads from the given InputStream and writes to the given OutputStream */
258
static class Forwarder implements Runnable
259
{
260
private final InputStream in;
261
private final OutputStream os;
262
263
Forwarder(InputStream in, OutputStream os) {
264
this.in = in;
265
this.os = os;
266
}
267
268
@Override
269
public void run() {
270
try {
271
byte[] ba = new byte[1024];
272
int count;
273
while ((count = in.read(ba)) != -1) {
274
os.write(ba, 0, count);
275
}
276
} catch (IOException e) {
277
unexpected(e);
278
}
279
}
280
}
281
}
282
283