Path: blob/master/test/jdk/java/net/HttpURLConnection/HttpURLConnUsingProxy.java
41149 views
/*1* Copyright (c) 2019, 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 823163225* @summary HttpURLConnection::usingProxy could specify that it lazily evaluates the fact26* @modules java.base/sun.net.www27* @library /test/lib28* @run main/othervm HttpURLConnUsingProxy29*/3031import java.io.*;32import java.net.*;33import java.nio.charset.StandardCharsets;3435import com.sun.net.httpserver.HttpExchange;36import com.sun.net.httpserver.HttpHandler;37import com.sun.net.httpserver.HttpServer;38import jdk.test.lib.net.URIBuilder;3940public class HttpURLConnUsingProxy {41static HttpServer server;42static Proxy proxy;43static InetSocketAddress isa;4445static class Handler implements HttpHandler {4647@Override48public void handle(HttpExchange exchange) throws IOException {49byte[] response = "Hello World!".getBytes(StandardCharsets.UTF_8);50try (InputStream req = exchange.getRequestBody()) {51req.readAllBytes();52}53exchange.sendResponseHeaders(200, response.length);54try (OutputStream resp = exchange.getResponseBody()) {55resp.write(response);56}57}58}5960public static void main(String[] args) {61try {62InetAddress loopbackAddress = InetAddress.getLoopbackAddress();63InetSocketAddress addr = new InetSocketAddress(loopbackAddress, 0);64server = HttpServer.create(addr, 0);65server.createContext("/HttpURLConnUsingProxy/http1/", new Handler());66server.start();6768ProxyServer pserver = new ProxyServer(loopbackAddress,69server.getAddress().getPort());70// Start proxy server71new Thread(pserver).start();7273URL url = URIBuilder.newBuilder()74.scheme("http")75.loopback()76.port(server.getAddress().getPort())77.path("/HttpURLConnUsingProxy/http1/x.html")78.toURLUnchecked();7980// NO_PROXY81try {82HttpURLConnection urlc =83(HttpURLConnection) url.openConnection(Proxy.NO_PROXY);84assertEqual(urlc.usingProxy(), false);85urlc.getResponseCode();86assertEqual(urlc.usingProxy(), false);87urlc.disconnect();88} catch (IOException ioe) {89throw new RuntimeException("Direct connection should succeed: "90+ ioe.getMessage());91}9293// Non-existing proxy94try {95isa = InetSocketAddress.createUnresolved("inexistent", 8080);96proxy = new Proxy(Proxy.Type.HTTP, isa);97HttpURLConnection urlc = (HttpURLConnection) url.openConnection(proxy);98assertEqual(urlc.usingProxy(), true);99InputStream is = urlc.getInputStream();100is.close();101throw new RuntimeException("Non-existing proxy should cause IOException");102} catch (IOException ioe) {103// expected104}105106// Normal proxy settings107try {108isa = InetSocketAddress.createUnresolved(loopbackAddress.getHostAddress(),109pserver.getPort());110proxy = new Proxy(Proxy.Type.HTTP, isa);111HttpURLConnection urlc = (HttpURLConnection) url.openConnection(proxy);112assertEqual(urlc.usingProxy(), true);113urlc.getResponseCode();114assertEqual(urlc.usingProxy(), true);115urlc.disconnect();116} catch (IOException ioe) {117throw new RuntimeException("Connection through local proxy should succeed: "118+ ioe.getMessage());119}120121// Reuse proxy with new HttpURLConnection122try {123HttpURLConnection urlc = (HttpURLConnection) url.openConnection(proxy);124assertEqual(urlc.usingProxy(), true);125urlc.getResponseCode();126assertEqual(urlc.usingProxy(), true);127read(urlc.getInputStream());128assertEqual(urlc.usingProxy(), true);129} catch (IOException ioe) {130throw new RuntimeException("Connection through local proxy should succeed: "131+ ioe.getMessage());132}133134// Reuse proxy with existing HttpURLConnection135try {136HttpURLConnection urlc = (HttpURLConnection) url.openConnection(proxy);137assertEqual(urlc.usingProxy(), true);138urlc.getResponseCode();139assertEqual(urlc.usingProxy(), true);140read(urlc.getInputStream());141assertEqual(urlc.usingProxy(), true);142urlc.disconnect();143} catch (IOException ioe) {144throw new RuntimeException("Connection through local proxy should succeed: "145+ ioe.getMessage());146}147148// ProxySelector with normal proxy settings149try {150ProxySelector.setDefault(ProxySelector.of(isa));151HttpURLConnection urlc = (HttpURLConnection) url.openConnection();152assertEqual(urlc.usingProxy(), false);153urlc.getResponseCode();154assertEqual(urlc.usingProxy(), true);155read(urlc.getInputStream());156assertEqual(urlc.usingProxy(), true);157urlc.disconnect();158assertEqual(urlc.usingProxy(), true);159} catch (IOException ioe) {160throw new RuntimeException("Connection through local proxy should succeed: "161+ ioe.getMessage());162}163164// ProxySelector with proxying disabled165try {166ProxySelector.setDefault(ProxySelector.of(null));167HttpURLConnection urlc = (HttpURLConnection) url.openConnection();168assertEqual(urlc.usingProxy(), false);169urlc.getResponseCode();170assertEqual(urlc.usingProxy(), false);171read(urlc.getInputStream());172assertEqual(urlc.usingProxy(), false);173} catch (IOException ioe) {174throw new RuntimeException("Direct connection should succeed: "175+ ioe.getMessage());176}177178// ProxySelector overwritten179try {180ProxySelector.setDefault(ProxySelector.of(isa));181HttpURLConnection urlc = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);182assertEqual(urlc.usingProxy(), false);183urlc.disconnect();184} catch (IOException ioe) {185throw new RuntimeException("Direct connection should succeed: "186+ ioe.getMessage());187}188189} catch (Exception e) {190throw new RuntimeException(e);191} finally {192if (server != null) {193server.stop(0);194}195}196}197198static class ProxyServer extends Thread {199private static ServerSocket ss = null;200201// Client requesting a tunnel202private Socket clientSocket = null;203204/*205* Origin server's address and port that the client206* wants to establish the tunnel for communication.207*/208private InetAddress serverInetAddr;209private int serverPort;210211public ProxyServer(InetAddress server, int port) throws IOException {212serverInetAddr = server;213serverPort = port;214ss = new ServerSocket(0, 0, InetAddress.getLoopbackAddress());215}216217public void run() {218while (true) {219try {220clientSocket = ss.accept();221processRequests();222} catch (Exception e) {223System.out.println("Proxy failed: " + e);224e.printStackTrace();225try {226ss.close();227} catch (IOException ioe) {228System.out.println("ProxyServer close error: " + ioe);229ioe.printStackTrace();230}231}232}233}234235private void processRequests() throws Exception {236// Connection set to tunneling mode237238Socket serverSocket = new Socket(serverInetAddr, serverPort);239ProxyTunnel clientToServer = new ProxyTunnel(240clientSocket, serverSocket);241ProxyTunnel serverToClient = new ProxyTunnel(242serverSocket, clientSocket);243clientToServer.start();244serverToClient.start();245System.out.println("Proxy: Started tunneling...");246247clientToServer.join();248serverToClient.join();249System.out.println("Proxy: Finished tunneling...");250251clientToServer.close();252serverToClient.close();253}254255/**256* **************************************************************257* Helper methods follow258* **************************************************************259*/260public int getPort() {261return ss.getLocalPort();262}263264/*265* This inner class provides unidirectional data flow through the sockets266* by continuously copying bytes from input socket to output socket267* while both sockets are open and EOF has not been received.268*/269static class ProxyTunnel extends Thread {270Socket sockIn;271Socket sockOut;272InputStream input;273OutputStream output;274275public ProxyTunnel(Socket sockIn, Socket sockOut) throws Exception {276this.sockIn = sockIn;277this.sockOut = sockOut;278input = sockIn.getInputStream();279output = sockOut.getOutputStream();280}281282public void run() {283int BUFFER_SIZE = 400;284byte[] buf = new byte[BUFFER_SIZE];285int bytesRead = 0;286int count = 0; // Keep track of amount of data transferred287288try {289while ((bytesRead = input.read(buf)) >= 0) {290output.write(buf, 0, bytesRead);291output.flush();292count += bytesRead;293}294} catch (IOException e) {295/*296* Peer end has closed connection297* so we close tunnel298*/299close();300}301}302303public void close() {304try {305if (!sockIn.isClosed())306sockIn.close();307if (!sockOut.isClosed())308sockOut.close();309} catch (IOException ignored) {310}311}312}313}314315private static void assertEqual(boolean usingProxy, boolean expected) {316if (usingProxy != expected) {317throw new RuntimeException("Expected: " + expected318+ " but usingProxy returned: " + usingProxy);319}320}321322private static String read(InputStream inputStream) throws IOException {323StringBuilder sb = new StringBuilder();324BufferedReader bufferedReader = new BufferedReader(325new InputStreamReader(inputStream, StandardCharsets.UTF_8));326int i = bufferedReader.read();327while (i != -1) {328sb.append((char) i);329i = bufferedReader.read();330}331bufferedReader.close();332return sb.toString();333}334}335336337