/*
 * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

import java.io.*;
import java.net.*;

/*
 * @test
 * @bug 4255280
 * @summary URL.getContent() loses first six bytes for ftp URLs
 */

public class FtpGetContent {
    static int filesize = 2048;

    /**
     * A class that simulates, on a separate, an FTP server.
     */

    private class FtpServer extends Thread {
        private ServerSocket    server;
        private int port;
        private boolean done = false;
        private boolean portEnabled = true;
        private boolean pasvEnabled = true;
        private String username;
        private String password;
        private String cwd;
        private String filename;
        private String type;
        private boolean list = false;

        /**
         * This Inner class will handle ONE client at a time.
         * That's where 99% of the protocol handling is done.
         */

        private class FtpServerHandler extends Thread {
            BufferedReader in;
            PrintWriter out;
            Socket client;
            private final int ERROR = 0;
            private final int USER = 1;
            private final int PASS = 2;
            private final int CWD = 3;
            private final int CDUP = 4;
            private final int PWD = 5;
            private final int TYPE = 6;
            private final int NOOP = 7;
            private final int RETR = 8;
            private final int PASV = 9;
            private final int PORT = 10;
            private final int LIST = 11;
            private final int REIN = 12;
            private final int QUIT = 13;
            private final int STOR = 14;
            private final int NLST = 15;
            private final int RNFR = 16;
            private final int RNTO = 17;
            String[] cmds = { "USER", "PASS", "CWD", "CDUP", "PWD", "TYPE",
                              "NOOP", "RETR", "PASV", "PORT", "LIST", "REIN",
                              "QUIT", "STOR", "NLST", "RNFR", "RNTO" };
            private String arg = null;
            private ServerSocket pasv = null;
            private int data_port = 0;
            private InetAddress data_addr = null;

            /**
             * Parses a line to match it with one of the supported FTP commands.
             * Returns the command number.
             */

            private int parseCmd(String cmd) {
                if (cmd == null || cmd.length() < 3)
                    return ERROR;
                int blank = cmd.indexOf(' ');
                if (blank < 0)
                    blank = cmd.length();
                if (blank < 3)
                    return ERROR;
                String s = cmd.substring(0, blank);
                if (cmd.length() > blank+1)
                    arg = cmd.substring(blank+1, cmd.length());
                else
                    arg = null;
                for (int i = 0; i < cmds.length; i++) {
                    if (s.equalsIgnoreCase(cmds[i]))
                        return i+1;
                }
                return ERROR;
            }

            public FtpServerHandler(Socket cl) {
                client = cl;
            }

            protected boolean isPasvSet() {
                if (pasv != null && !pasvEnabled) {
                    try {
                        pasv.close();
                    } catch (IOException ex) {
                    }
                    pasv = null;
                }
                if (pasvEnabled && pasv != null)
                    return true;
                return false;
            }

            /**
             * Open the data socket with the client. This can be the
             * result of a "PASV" or "PORT" command.
             */

            protected OutputStream getOutDataStream() {
                try {
                    if (isPasvSet()) {
                        Socket s = pasv.accept();
                        return s.getOutputStream();
                    }
                    if (data_addr != null) {
                        Socket s = new Socket(data_addr, data_port);
                        data_addr = null;
                        data_port = 0;
                        return s.getOutputStream();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            }

            protected InputStream getInDataStream() {
                try {
                    if (isPasvSet()) {
                        Socket s = pasv.accept();
                        return s.getInputStream();
                    }
                    if (data_addr != null) {
                        Socket s = new Socket(data_addr, data_port);
                        data_addr = null;
                        data_port = 0;
                        return s.getInputStream();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            }

            /**
             * Handles the protocol exchange with the client.
             */

            public void run() {
                boolean done = false;
                String str;
                int res;
                boolean logged = false;
                boolean waitpass = false;

                try {
                    in = new BufferedReader(new InputStreamReader(client.getInputStream()));
                    out = new PrintWriter(client.getOutputStream(), true);
                    out.println("220 tatooine FTP server (SunOS 5.8) ready.");
                } catch (Exception ex) {
                    return;
                }
                while (!done) {
                    try {
                        str = in.readLine();
                        res = parseCmd(str);
                        if ((res > PASS && res != QUIT) && !logged) {
                            out.println("530 Not logged in.");
                            continue;
                        }
                        switch (res) {
                        case ERROR:
                            out.println("500 '" + str + "': command not understood.");
                            break;
                        case USER:
                            if (!logged && !waitpass) {
                                username = str.substring(5);
                                password = null;
                                cwd = null;
                                if ("user2".equals(username)) {
                                    out.println("230 Guest login ok, access restrictions apply.");
                                    logged = true;
                                } else {
                                    out.println("331 Password required for " + arg);
                                    waitpass = true;
                                }
                            } else {
                                out.println("503 Bad sequence of commands.");
                            }
                            break;
                        case PASS:
                            if (!logged && waitpass) {
                                out.println("230 Guest login ok, access restrictions apply.");
                                password = str.substring(5);
                                logged = true;
                                waitpass = false;
                            } else
                                out.println("503 Bad sequence of commands.");
                            break;
                        case QUIT:
                            out.println("221 Goodbye.");
                            out.flush();
                            out.close();
                            if (pasv != null)
                                pasv.close();
                            done = true;
                            break;
                        case TYPE:
                            out.println("200 Type set to " + arg + ".");
                            type = arg;
                            break;
                        case CWD:
                            out.println("250 CWD command successful.");
                            if (cwd == null)
                                cwd = str.substring(4);
                            else
                                cwd = cwd + "/" + str.substring(4);
                            break;
                        case CDUP:
                            out.println("250 CWD command successful.");
                            break;
                        case PWD:
                            out.println("257 \"" + cwd + "\" is current directory");
                            break;
                        case PASV:
                            if (!pasvEnabled) {
                                out.println("500 PASV is disabled, use PORT instead.");
                                continue;
                            }
                            try {
                                if (pasv == null)
                                    pasv = new ServerSocket(0);
                                int port = pasv.getLocalPort();
                                out.println("227 Entering Passive Mode (127,0,0,1," +
                                            (port >> 8) + "," + (port & 0xff) +")");
                            } catch (IOException ssex) {
                                out.println("425 Can't build data connection: Connection refused.");
                            }
                            break;
                        case PORT:
                            if (!portEnabled) {
                                out.println("500 PORT is disabled, use PASV instead");
                                continue;
                            }
                            StringBuffer host;
                            int i=0, j=4;
                            while (j>0) {
                                i = arg.indexOf(',', i+1);
                                if (i < 0)
                                    break;
                                j--;
                            }
                            if (j != 0) {
                                out.println("500 '" + arg + "': command not understood.");
                                continue;
                            }
                            try {
                                host = new StringBuffer(arg.substring(0,i));
                                for (j=0; j < host.length(); j++)
                                    if (host.charAt(j) == ',')
                                        host.setCharAt(j, '.');
                                String ports = arg.substring(i+1);
                                i = ports.indexOf(',');
                                data_port = Integer.parseInt(ports.substring(0,i)) << 8;
                                data_port += (Integer.parseInt(ports.substring(i+1)));
                                data_addr = InetAddress.getByName(host.toString());
                                out.println("200 Command okay.");
                            } catch (Exception ex3) {
                                data_port = 0;
                                data_addr = null;
                                out.println("500 '" + arg + "': command not understood.");
                            }
                            break;
                        case RETR:
                            {
                                filename = str.substring(5);
                                OutputStream dout = getOutDataStream();
                                if (dout != null) {
                                    out.println("200 Command okay.");
                                    BufferedOutputStream pout = new BufferedOutputStream(dout);
                                    for (int x = 0; x < filesize ; x++)
                                        pout.write(0);
                                    pout.flush();
                                    pout.close();
                                    list = false;
                                } else
                                    out.println("425 Can't build data connection: Connection refused.");
                            }
                            break;
                        case NLST:
                            filename = arg;
                        case LIST:
                            {
                                OutputStream dout = getOutDataStream();
                                if (dout != null) {
                                    out.println("200 Command okay.");
                                    PrintWriter pout = new PrintWriter(new BufferedOutputStream(dout));
                                    pout.println("total 130");
                                    pout.println("drwxrwxrwt   7 sys      sys          577 May 12 03:30 .");
                                    pout.println("drwxr-xr-x  39 root     root        1024 Mar 27 12:55 ..");
                                    pout.println("drwxrwxr-x   2 root     root         176 Apr 10 12:02 .X11-pipe");
                                    pout.println("drwxrwxr-x   2 root     root         176 Apr 10 12:02 .X11-unix");
                                    pout.println("drwxrwxrwx   2 root     root         179 Mar 30 15:09 .pcmcia");
                                    pout.println("drwxrwxrwx   2 jladen   staff        117 Mar 30 18:18 .removable");
                                    pout.println("drwxrwxrwt   2 root     root         327 Mar 30 15:08 .rpc_door");
                                    pout.println("-rw-r--r--   1 root     other         21 May  5 16:59 hello2.txt");
                                    pout.println("-rw-rw-r--   1 root     sys         5968 Mar 30 15:08 ps_data");
                                    pout.flush();
                                    pout.close();
                                    list = true;
                                } else
                                    out.println("425 Can't build data connection: Connection refused.");
                            }
                            break;
                        case STOR:
                            {
                                InputStream is = getInDataStream();
                                if (is != null) {
                                    out.println("200 Command okay.");
                                    BufferedInputStream din = new BufferedInputStream(is);
                                    int val;
                                    do {
                                        val = din.read();
                                    } while (val != -1);
                                    din.close();
                                } else
                                    out.println("425 Can't build data connection: Connection refused.");
                            }
                            break;
                        }
                    } catch (IOException ioe) {
                        ioe.printStackTrace();
                        try {
                            out.close();
                        } catch (Exception ex2) {
                        }
                        done = true;
                    }
                }
            }
        }

        public FtpServer(int port) {
            this.port = port;
            try {
              server = new ServerSocket(port);
            } catch (IOException e) {
            }
        }

        public FtpServer() {
            this(21);
        }

        public int getPort() {
            if (server != null)
                return server.getLocalPort();
            return 0;
        }

        /**
         * A way to tell the server that it can stop.
         */
        synchronized public void terminate() {
            done = true;
        }

        synchronized public void setPortEnabled(boolean ok) {
            portEnabled = ok;
        }

        synchronized public void setPasvEnabled(boolean ok) {
            pasvEnabled = ok;
        }

        String getUsername() {
            return username;
        }

        String getPassword() {
            return password;
        }

        String pwd() {
            return cwd;
        }

        String getFilename() {
            return filename;
        }

        String getType() {
            return type;
        }

        boolean getList() {
            return list;
        }

        /*
         * All we got to do here is create a ServerSocket and wait for connections.
         * When a connection happens, we just have to create a thread that will
         * handle it.
         */
        public void run() {
            try {
                Socket client;
                while (!done) {
                    client = server.accept();
                    (new FtpServerHandler(client)).start();
                }
                server.close();
            } catch(Exception e) {
            }
        }
    }
    public static void main(String[] args) throws Exception {
        FtpGetContent test = new FtpGetContent();
    }

    public FtpGetContent() throws Exception {
        FtpServer server = null;
        try {
            server = new FtpServer(0);
            server.start();
            int port = server.getPort();

            // Now let's check the URL handler

            URL url = new URL("ftp://localhost:" + port + "/pub/BigFile");
            InputStream stream = (InputStream)url.getContent();
            byte[] buffer = new byte[1024];
            int totalBytes = 0;
            int bytesRead = stream.read(buffer);
            while (bytesRead != -1) {
                totalBytes += bytesRead;
                bytesRead = stream.read(buffer);
            }
            stream.close();
            server.terminate();
            server.interrupt();
            if (totalBytes != filesize)
                throw new RuntimeException("wrong file size!");
        } catch (IOException e) {
            try {
                server.terminate();
                server.interrupt();
            } catch (Exception e2) {
            }
            throw new RuntimeException(e.getMessage());
        }
    }

}
