Path: blob/master/test/jdk/java/net/Socket/ConnectionReset.java
41152 views
/*1* Copyright (c) 2019, 2020, 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/**24* @test25* @run testng ConnectionReset26* @run testng/othervm -Djdk.net.usePlainSocketImpl ConnectionReset27* @summary Test behavior of read and available when a connection is reset28*/2930import java.io.IOException;31import java.io.InputStream;32import java.net.InetAddress;33import java.net.InetSocketAddress;34import java.net.ServerSocket;35import java.net.Socket;3637import org.testng.annotations.Test;38import static org.testng.Assert.*;3940@Test41public class ConnectionReset {4243static final int REPEAT_COUNT = 5;4445/**46* Tests available before read when there are no bytes to read47*/48public void testAvailableBeforeRead1() throws IOException {49System.out.println("testAvailableBeforeRead1");50withResetConnection(null, s -> {51InputStream in = s.getInputStream();52for (int i=0; i<REPEAT_COUNT; i++) {53int bytesAvailable = in.available();54System.out.format("available => %d%n", bytesAvailable);55assertTrue(bytesAvailable == 0);56try {57int bytesRead = in.read();58if (bytesRead == -1) {59System.out.println("read => EOF");60} else {61System.out.println("read => 1 byte");62}63assertTrue(false);64} catch (IOException ioe) {65System.out.format("read => %s (expected)%n", ioe);66}67}68});69}7071/**72* Tests available before read when there are bytes to read73*/74public void testAvailableBeforeRead2() throws IOException {75System.out.println("testAvailableBeforeRead2");76byte[] data = { 1, 2, 3 };77withResetConnection(data, s -> {78InputStream in = s.getInputStream();79int remaining = data.length;80for (int i=0; i<REPEAT_COUNT; i++) {81int bytesAvailable = in.available();82System.out.format("available => %d%n", bytesAvailable);83assertTrue(bytesAvailable <= remaining);84try {85int bytesRead = in.read();86if (bytesRead == -1) {87System.out.println("read => EOF");88assertTrue(false);89} else {90System.out.println("read => 1 byte");91assertTrue(remaining > 0);92remaining--;93}94} catch (IOException ioe) {95System.out.format("read => %s%n", ioe);96remaining = 0;97}98}99});100}101102/**103* Tests read before available when there are no bytes to read104*/105public void testReadBeforeAvailable1() throws IOException {106System.out.println("testReadBeforeAvailable1");107withResetConnection(null, s -> {108InputStream in = s.getInputStream();109for (int i=0; i<REPEAT_COUNT; i++) {110try {111int bytesRead = in.read();112if (bytesRead == -1) {113System.out.println("read => EOF");114} else {115System.out.println("read => 1 byte");116}117assertTrue(false);118} catch (IOException ioe) {119System.out.format("read => %s (expected)%n", ioe);120}121int bytesAvailable = in.available();122System.out.format("available => %d%n", bytesAvailable);123assertTrue(bytesAvailable == 0);124}125});126}127128/**129* Tests read before available when there are bytes to read130*/131public void testReadBeforeAvailable2() throws IOException {132System.out.println("testReadBeforeAvailable2");133byte[] data = { 1, 2, 3 };134withResetConnection(data, s -> {135InputStream in = s.getInputStream();136int remaining = data.length;137for (int i=0; i<REPEAT_COUNT; i++) {138try {139int bytesRead = in.read();140if (bytesRead == -1) {141System.out.println("read => EOF");142assertTrue(false);143} else {144System.out.println("read => 1 byte");145assertTrue(remaining > 0);146remaining--;147}148} catch (IOException ioe) {149System.out.format("read => %s%n", ioe);150remaining = 0;151}152int bytesAvailable = in.available();153System.out.format("available => %d%n", bytesAvailable);154assertTrue(bytesAvailable <= remaining);155}156});157}158159/**160* Tests available and read on a socket closed after connection reset161*/162public void testAfterClose() throws IOException {163System.out.println("testAfterClose");164withResetConnection(null, s -> {165InputStream in = s.getInputStream();166try {167in.read();168assertTrue(false);169} catch (IOException ioe) {170// expected171}172s.close();173try {174int bytesAvailable = in.available();175System.out.format("available => %d%n", bytesAvailable);176assertTrue(false);177} catch (IOException ioe) {178System.out.format("available => %s (expected)%n", ioe);179}180try {181int n = in.read();182System.out.format("read => %d%n", n);183assertTrue(false);184} catch (IOException ioe) {185System.out.format("read => %s (expected)%n", ioe);186}187});188}189190interface ThrowingConsumer<T> {191void accept(T t) throws IOException;192}193194/**195* Invokes a consumer with a Socket connected to a peer that has closed the196* connection with a "connection reset". The peer sends the given data bytes197* before closing (when data is not null).198*/199static void withResetConnection(byte[] data, ThrowingConsumer<Socket> consumer)200throws IOException201{202var loopback = InetAddress.getLoopbackAddress();203try (var listener = new ServerSocket()) {204listener.bind(new InetSocketAddress(loopback, 0));205try (var socket = new Socket()) {206socket.connect(listener.getLocalSocketAddress());207try (Socket peer = listener.accept()) {208if (data != null) {209peer.getOutputStream().write(data);210}211peer.setSoLinger(true, 0);212}213consumer.accept(socket);214}215}216}217}218219220