Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/net/URL/PerConnectionProxy.java
38812 views
/*1* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/* @test24* @bug 492052625* @summary Needs per connection proxy support for URLs26* @library ../../../sun/net/www/httptest/27* @build ClosedChannelList TestHttpServer HttpTransaction HttpCallback28* @compile PerConnectionProxy.java29* @run main/othervm -Dhttp.proxyHost=inexistant -Dhttp.proxyPort=8080 PerConnectionProxy30*/3132import java.net.*;33import java.io.*;34import sun.net.www.*;3536public class PerConnectionProxy implements HttpCallback {37static TestHttpServer server;3839public void request (HttpTransaction req) {40req.setResponseEntityBody ("Hello .");41try {42req.sendResponse (200, "Ok");43req.orderlyClose();44} catch (IOException e) {45}46}4748public static void main(String[] args) {49try {50server = new TestHttpServer (new PerConnectionProxy(), 1, 10, 0);51ProxyServer pserver = new ProxyServer(InetAddress.getByName("localhost"), server.getLocalPort());52// start proxy server53new Thread(pserver).start();5455URL url = new URL("http://localhost:"+server.getLocalPort());5657// for non existing proxy expect an IOException58try {59InetSocketAddress isa = InetSocketAddress.createUnresolved("inexistent", 8080);60Proxy proxy = new Proxy(Proxy.Type.HTTP, isa);61HttpURLConnection urlc = (HttpURLConnection)url.openConnection (proxy);62InputStream is = urlc.getInputStream ();63is.close();64throw new RuntimeException("non existing per connection proxy should lead to IOException");65} catch (IOException ioex) {66// expected67}6869// for NO_PROXY, expect direct connection70try {71HttpURLConnection urlc = (HttpURLConnection)url.openConnection (Proxy.NO_PROXY);72int respCode = urlc.getResponseCode();73urlc.disconnect();74} catch (IOException ioex) {75throw new RuntimeException("direct connection should succeed :"+ioex.getMessage());76}7778// for a normal proxy setting expect to see connection79// goes through that proxy80try {81InetSocketAddress isa = InetSocketAddress.createUnresolved("localhost", pserver.getPort());82Proxy p = new Proxy(Proxy.Type.HTTP, isa);83HttpURLConnection urlc = (HttpURLConnection)url.openConnection (p);84int respCode = urlc.getResponseCode();85urlc.disconnect();86} catch (IOException ioex) {87throw new RuntimeException("connection through a local proxy should succeed :"+ioex.getMessage());88}8990} catch (Exception e) {91throw new RuntimeException(e);92} finally {93if (server != null) {94server.terminate();95}96}9798}99100static class ProxyServer extends Thread {101private static ServerSocket ss = null;102103// client requesting for a tunnel104private Socket clientSocket = null;105106/*107* Origin server's address and port that the client108* wants to establish the tunnel for communication.109*/110private InetAddress serverInetAddr;111private int serverPort;112113public ProxyServer(InetAddress server, int port) throws IOException {114serverInetAddr = server;115serverPort = port;116ss = new ServerSocket(0);117}118119public void run() {120try {121clientSocket = ss.accept();122processRequests();123} catch (Exception e) {124System.out.println("Proxy Failed: " + e);125e.printStackTrace();126try {127ss.close();128}129catch (IOException excep) {130System.out.println("ProxyServer close error: " + excep);131excep.printStackTrace();132}133}134}135136private void processRequests() throws Exception {137// connection set to the tunneling mode138139Socket serverSocket = new Socket(serverInetAddr, serverPort);140ProxyTunnel clientToServer = new ProxyTunnel(141clientSocket, serverSocket);142ProxyTunnel serverToClient = new ProxyTunnel(143serverSocket, clientSocket);144clientToServer.start();145serverToClient.start();146System.out.println("Proxy: Started tunneling.......");147148clientToServer.join();149serverToClient.join();150System.out.println("Proxy: Finished tunneling........");151152clientToServer.close();153serverToClient.close();154155}156157/**158***************************************************************159* helper methods follow160***************************************************************161*/162public int getPort() {163return ss.getLocalPort();164}165/*166* This inner class provides unidirectional data flow through the sockets167* by continuously copying bytes from the input socket onto the output168* socket, until both sockets are open and EOF has not been received.169*/170static class ProxyTunnel extends Thread {171Socket sockIn;172Socket sockOut;173InputStream input;174OutputStream output;175176public ProxyTunnel(Socket sockIn, Socket sockOut)177throws Exception {178this.sockIn = sockIn;179this.sockOut = sockOut;180input = sockIn.getInputStream();181output = sockOut.getOutputStream();182}183184public void run() {185int BUFFER_SIZE = 400;186byte[] buf = new byte[BUFFER_SIZE];187int bytesRead = 0;188int count = 0; // keep track of the amount of data transfer189190try {191while ((bytesRead = input.read(buf)) >= 0) {192output.write(buf, 0, bytesRead);193output.flush();194count += bytesRead;195}196} catch (IOException e) {197/*198* The peer end has closed the connection199* we will close the tunnel200*/201close();202}203}204205public void close() {206try {207if (!sockIn.isClosed())208sockIn.close();209if (!sockOut.isClosed())210sockOut.close();211} catch (IOException ignored) { }212}213}214215}216}217218219