Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/sun/net/ftp/MarkResetTest.java
38838 views
/*1* Copyright (c) 2002, 2013, 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*25* run from MarkResetTest.sh26*/2728import java.io.*;29import java.net.*;30import java.util.regex.*;3132public class MarkResetTest {3334/**35* A class that simulates, on a separate, an FTP server.36*/37private class FtpServer extends Thread {38private ServerSocket server;39private int port;40private boolean done = false;41private boolean pasvEnabled = true;42private boolean portEnabled = true;43private boolean extendedEnabled = true;4445/**46* This Inner class will handle ONE client at a time.47* That's where 99% of the protocol handling is done.48*/4950private class FtpServerHandler extends Thread {51BufferedReader in;52PrintWriter out;53Socket client;54private final int ERROR = 0;55private final int USER = 1;56private final int PASS = 2;57private final int CWD = 3;58private final int TYPE = 4;59private final int RETR = 5;60private final int PASV = 6;61private final int PORT = 7;62private final int QUIT = 8;63private final int EPSV = 9;64String[] cmds = { "USER", "PASS", "CWD",65"TYPE", "RETR", "PASV",66"PORT", "QUIT", "EPSV"};67private String arg = null;68private ServerSocket pasv = null;69private int data_port = 0;70private InetAddress data_addr = null;7172/**73* Parses a line to match it with one of the supported FTP commands.74* Returns the command number.75*/7677private int parseCmd(String cmd) {78if (cmd == null || cmd.length() < 3)79return ERROR;80int blank = cmd.indexOf(' ');81if (blank < 0)82blank = cmd.length();83if (blank < 3)84return ERROR;85String s = cmd.substring(0, blank);86if (cmd.length() > blank+1)87arg = cmd.substring(blank+1, cmd.length());88else89arg = null;90for (int i = 0; i < cmds.length; i++) {91if (s.equalsIgnoreCase(cmds[i]))92return i+1;93}94return ERROR;95}9697public FtpServerHandler(Socket cl) {98client = cl;99}100101protected boolean isPasvSet() {102if (pasv != null && !pasvEnabled) {103try {104pasv.close();105} catch (IOException ex) {106}107pasv = null;108}109if (pasvEnabled && pasv != null)110return true;111return false;112}113114/**115* Open the data socket with the client. This can be the116* result of a "PASV" or "PORT" command.117*/118119protected OutputStream getOutDataStream() {120try {121if (isPasvSet()) {122Socket s = pasv.accept();123return s.getOutputStream();124}125if (data_addr != null) {126Socket s = new Socket(data_addr, data_port);127data_addr = null;128data_port = 0;129return s.getOutputStream();130}131} catch (Exception e) {132e.printStackTrace();133}134return null;135}136137protected InputStream getInDataStream() {138try {139if (isPasvSet()) {140Socket s = pasv.accept();141return s.getInputStream();142}143if (data_addr != null) {144Socket s = new Socket(data_addr, data_port);145data_addr = null;146data_port = 0;147return s.getInputStream();148}149} catch (Exception e) {150e.printStackTrace();151}152return null;153}154155/**156* Handles the protocol exchange with the client.157*/158159public void run() {160boolean done = false;161String str;162int res;163boolean logged = false;164boolean waitpass = false;165166try {167in = new BufferedReader(new InputStreamReader(168client.getInputStream()));169out = new PrintWriter(client.getOutputStream(), true);170out.println("220 tatooine FTP server (SunOS 5.8) ready.");171} catch (Exception ex) {172return;173}174while (!done) {175try {176str = in.readLine();177res = parseCmd(str);178if ((res > PASS && res != QUIT) && !logged) {179out.println("530 Not logged in.");180continue;181}182switch (res) {183case ERROR:184out.println("500 '" + str +185"': command not understood.");186break;187case USER:188if (!logged && !waitpass) {189out.println("331 Password required for " + arg);190waitpass = true;191} else {192out.println("503 Bad sequence of commands.");193}194break;195case PASS:196if (!logged && waitpass) {197out.println("230-Welcome to the FTP server!");198out.println("ab");199out.println("230 Guest login ok, " +200"access restrictions apply.");201logged = true;202waitpass = false;203} else204out.println("503 Bad sequence of commands.");205break;206case QUIT:207out.println("221 Goodbye.");208out.flush();209out.close();210if (pasv != null)211pasv.close();212done = true;213break;214case TYPE:215out.println("200 Type set to " + arg + ".");216break;217case CWD:218out.println("250 CWD command successful.");219break;220case EPSV:221if (!extendedEnabled || !pasvEnabled) {222out.println("500 EPSV is disabled, " +223"use PORT instead.");224continue;225}226if ("all".equalsIgnoreCase(arg)) {227out.println("200 EPSV ALL command successful.");228continue;229}230try {231if (pasv == null)232pasv = new ServerSocket(0);233int port = pasv.getLocalPort();234out.println("229 Entering Extended" +235" Passive Mode (|||" + port + "|)");236} catch (IOException ssex) {237out.println("425 Can't build data connection:" +238" Connection refused.");239}240break;241242case PASV:243if (!pasvEnabled) {244out.println("500 PASV is disabled, " +245"use PORT instead.");246continue;247}248try {249if (pasv == null)250pasv = new ServerSocket(0);251int port = pasv.getLocalPort();252253// Parenthesis are optional, so let's be254// nasty and don't put them255out.println("227 Entering Passive Mode" +256" 127,0,0,1," +257(port >> 8) + "," + (port & 0xff));258} catch (IOException ssex) {259out.println("425 Can't build data connection:" +260"Connection refused.");261}262break;263case PORT:264if (!portEnabled) {265out.println("500 PORT is disabled, " +266"use PASV instead");267continue;268}269StringBuffer host;270int i = 0, j = 4;271while (j > 0) {272i = arg.indexOf(',', i + 1);273if (i < 0)274break;275j--;276}277if (j != 0) {278out.println("500 '" + arg + "':" +279" command not understood.");280continue;281}282try {283host = new StringBuffer(arg.substring(0, i));284for (j = 0; j < host.length(); j++)285if (host.charAt(j) == ',')286host.setCharAt(j, '.');287String ports = arg.substring(i+1);288i = ports.indexOf(',');289data_port = Integer.parseInt(290ports.substring(0, i)) << 8;291data_port += (Integer.parseInt(292ports.substring(i+1)));293data_addr = InetAddress.getByName(294host.toString());295out.println("200 Command okay.");296} catch (Exception ex3) {297data_port = 0;298data_addr = null;299out.println("500 '" + arg + "':" +300" command not understood.");301}302break;303case RETR:304{305File file = new File(arg);306if (!file.exists()) {307System.out.println("File not found");308out.println("200 Command okay.");309out.println("550 '" + arg +310"' No such file or directory.");311break;312}313FileInputStream fin = new FileInputStream(file);314OutputStream dout = getOutDataStream();315if (dout != null) {316out.println("150 Binary data connection" +317" for " + arg +318" (" + client.getInetAddress().319getHostAddress() + ") (" +320file.length() + " bytes).");321int c;322int len = 0;323while ((c = fin.read()) != -1) {324dout.write(c);325len++;326}327dout.flush();328dout.close();329fin.close();330out.println("226 Binary Transfer complete.");331} else {332out.println("425 Can't build data" +333" connection: Connection refused.");334}335}336break;337}338} catch (IOException ioe) {339ioe.printStackTrace();340try {341out.close();342} catch (Exception ex2) {343}344done = true;345}346}347}348}349350public FtpServer(int port) {351this.port = port;352}353354public FtpServer() {355this(21);356}357358public int getPort() {359if (server != null)360return server.getLocalPort();361return 0;362}363364/**365* A way to tell the server that it can stop.366*/367synchronized public void terminate() {368done = true;369}370371372/*373* All we got to do here is create a ServerSocket and wait for a374* connection. When a connection happens, we just have to create375* a thread that will handle it.376*/377public void run() {378try {379server = new ServerSocket(port);380Socket client;381client = server.accept();382(new FtpServerHandler(client)).start();383server.close();384} catch (Exception e) {385}386}387}388389public static void main(String[] args) throws Exception {390MarkResetTest test = new MarkResetTest();391}392393public MarkResetTest() {394FtpServer server = null;395try {396server = new FtpServer(0);397server.start();398int port = 0;399while (port == 0) {400Thread.sleep(500);401port = server.getPort();402}403404String filename = "EncDec.doc";405URL url = new URL("ftp://localhost:" + port + "/" +406filename);407408URLConnection con = url.openConnection();409System.out.println("getContent: " + con.getContent());410System.out.println("getContent-length: " + con.getContentLength());411412InputStream is = con.getInputStream();413414/**415* guessContentTypeFromStream method calls mark and reset methods416* on the given stream. Make sure that calling417* guessContentTypeFromStream repeatedly does not affect418* reading from the stream afterwards419*/420System.out.println("Call GuessContentTypeFromStream()" +421" several times..");422for (int i = 0; i < 5; i++) {423System.out.println((i + 1) + " mime-type: " +424con.guessContentTypeFromStream(is));425}426427int len = 0;428int c;429while ((c = is.read()) != -1) {430len++;431}432is.close();433System.out.println("read: " + len + " bytes of the file");434435// We're done!436server.terminate();437server.interrupt();438439// Did we pass ?440if (len != (new File(filename)).length()) {441throw new Exception("Failed to read the file correctly");442}443System.out.println("PASSED: File read correctly");444} catch (Exception e) {445e.printStackTrace();446try {447server.terminate();448server.interrupt();449} catch (Exception ex) {450}451throw new RuntimeException("FTP support error: " + e.getMessage());452}453}454}455456457