jdk/test/sun/net/www/MarkResetTest.java
changeset 15726 27bb87e628ae
parent 15725 e0516b913894
parent 15722 b3dd9b35c97f
child 15727 e3baad90c331
equal deleted inserted replaced
15725:e0516b913894 15726:27bb87e628ae
     1 /*
       
     2  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 /*
       
    25  *
       
    26  * run from MarkResetTest.sh
       
    27  */
       
    28 
       
    29 import java.io.*;
       
    30 import java.net.*;
       
    31 import java.util.regex.*;
       
    32 
       
    33 public class MarkResetTest {
       
    34 
       
    35     /**
       
    36      * A class that simulates, on a separate, an FTP server.
       
    37      */
       
    38     private class FtpServer extends Thread {
       
    39         private ServerSocket    server;
       
    40         private int port;
       
    41         private boolean done = false;
       
    42         private boolean pasvEnabled = true;
       
    43         private boolean portEnabled = true;
       
    44         private boolean extendedEnabled = true;
       
    45 
       
    46         /**
       
    47          * This Inner class will handle ONE client at a time.
       
    48          * That's where 99% of the protocol handling is done.
       
    49          */
       
    50 
       
    51         private class FtpServerHandler extends Thread {
       
    52             BufferedReader in;
       
    53             PrintWriter out;
       
    54             Socket client;
       
    55             private final int ERROR = 0;
       
    56             private final int USER = 1;
       
    57             private final int PASS = 2;
       
    58             private final int CWD =  3;
       
    59             private final int TYPE = 4;
       
    60             private final int RETR = 5;
       
    61             private final int PASV = 6;
       
    62             private final int PORT = 7;
       
    63             private final int QUIT = 8;
       
    64             private final int EPSV = 9;
       
    65             String[] cmds = { "USER", "PASS", "CWD",
       
    66                                 "TYPE", "RETR", "PASV",
       
    67                                 "PORT", "QUIT", "EPSV"};
       
    68             private String arg = null;
       
    69             private ServerSocket pasv = null;
       
    70             private int data_port = 0;
       
    71             private InetAddress data_addr = null;
       
    72 
       
    73             /**
       
    74              * Parses a line to match it with one of the supported FTP commands.
       
    75              * Returns the command number.
       
    76              */
       
    77 
       
    78             private int parseCmd(String cmd) {
       
    79                 if (cmd == null || cmd.length() < 3)
       
    80                     return ERROR;
       
    81                 int blank = cmd.indexOf(' ');
       
    82                 if (blank < 0)
       
    83                     blank = cmd.length();
       
    84                 if (blank < 3)
       
    85                     return ERROR;
       
    86                 String s = cmd.substring(0, blank);
       
    87                 if (cmd.length() > blank+1)
       
    88                     arg = cmd.substring(blank+1, cmd.length());
       
    89                 else
       
    90                     arg = null;
       
    91                 for (int i = 0; i < cmds.length; i++) {
       
    92                     if (s.equalsIgnoreCase(cmds[i]))
       
    93                         return i+1;
       
    94                 }
       
    95                 return ERROR;
       
    96             }
       
    97 
       
    98             public FtpServerHandler(Socket cl) {
       
    99                 client = cl;
       
   100             }
       
   101 
       
   102             protected boolean isPasvSet() {
       
   103                 if (pasv != null && !pasvEnabled) {
       
   104                     try {
       
   105                         pasv.close();
       
   106                     } catch (IOException ex) {
       
   107                     }
       
   108                     pasv = null;
       
   109                 }
       
   110                 if (pasvEnabled && pasv != null)
       
   111                     return true;
       
   112                 return false;
       
   113             }
       
   114 
       
   115             /**
       
   116              * Open the data socket with the client. This can be the
       
   117              * result of a "PASV" or "PORT" command.
       
   118              */
       
   119 
       
   120             protected OutputStream getOutDataStream() {
       
   121                 try {
       
   122                     if (isPasvSet()) {
       
   123                         Socket s = pasv.accept();
       
   124                         return s.getOutputStream();
       
   125                     }
       
   126                     if (data_addr != null) {
       
   127                         Socket s = new Socket(data_addr, data_port);
       
   128                         data_addr = null;
       
   129                         data_port = 0;
       
   130                         return s.getOutputStream();
       
   131                     }
       
   132                 } catch (Exception e) {
       
   133                     e.printStackTrace();
       
   134                 }
       
   135                 return null;
       
   136             }
       
   137 
       
   138             protected InputStream getInDataStream() {
       
   139                 try {
       
   140                     if (isPasvSet()) {
       
   141                         Socket s = pasv.accept();
       
   142                         return s.getInputStream();
       
   143                     }
       
   144                     if (data_addr != null) {
       
   145                         Socket s = new Socket(data_addr, data_port);
       
   146                         data_addr = null;
       
   147                         data_port = 0;
       
   148                         return s.getInputStream();
       
   149                     }
       
   150                 } catch (Exception e) {
       
   151                     e.printStackTrace();
       
   152                 }
       
   153                 return null;
       
   154             }
       
   155 
       
   156             /**
       
   157              * Handles the protocol exchange with the client.
       
   158              */
       
   159 
       
   160             public void run() {
       
   161                 boolean done = false;
       
   162                 String str;
       
   163                 int res;
       
   164                 boolean logged = false;
       
   165                 boolean waitpass = false;
       
   166 
       
   167                 try {
       
   168                     in = new BufferedReader(new InputStreamReader(
       
   169                                                 client.getInputStream()));
       
   170                     out = new PrintWriter(client.getOutputStream(), true);
       
   171                     out.println("220 tatooine FTP server (SunOS 5.8) ready.");
       
   172                 } catch (Exception ex) {
       
   173                     return;
       
   174                 }
       
   175                 while (!done) {
       
   176                     try {
       
   177                         str = in.readLine();
       
   178                         res = parseCmd(str);
       
   179                         if ((res > PASS && res != QUIT) && !logged) {
       
   180                             out.println("530 Not logged in.");
       
   181                             continue;
       
   182                         }
       
   183                         switch (res) {
       
   184                         case ERROR:
       
   185                             out.println("500 '" + str +
       
   186                                         "': command not understood.");
       
   187                             break;
       
   188                         case USER:
       
   189                             if (!logged && !waitpass) {
       
   190                                 out.println("331 Password required for " + arg);
       
   191                                 waitpass = true;
       
   192                             } else {
       
   193                                 out.println("503 Bad sequence of commands.");
       
   194                             }
       
   195                             break;
       
   196                         case PASS:
       
   197                             if (!logged && waitpass) {
       
   198                                 out.println("230-Welcome to the FTP server!");
       
   199                                 out.println("ab");
       
   200                                 out.println("230 Guest login ok, " +
       
   201                                             "access restrictions apply.");
       
   202                                 logged = true;
       
   203                                 waitpass = false;
       
   204                             } else
       
   205                                 out.println("503 Bad sequence of commands.");
       
   206                             break;
       
   207                         case QUIT:
       
   208                             out.println("221 Goodbye.");
       
   209                             out.flush();
       
   210                             out.close();
       
   211                             if (pasv != null)
       
   212                                 pasv.close();
       
   213                             done = true;
       
   214                             break;
       
   215                         case TYPE:
       
   216                             out.println("200 Type set to " + arg + ".");
       
   217                             break;
       
   218                         case CWD:
       
   219                             out.println("250 CWD command successful.");
       
   220                             break;
       
   221                         case EPSV:
       
   222                             if (!extendedEnabled || !pasvEnabled) {
       
   223                                 out.println("500 EPSV is disabled, " +
       
   224                                                 "use PORT instead.");
       
   225                                 continue;
       
   226                             }
       
   227                             if ("all".equalsIgnoreCase(arg)) {
       
   228                                 out.println("200 EPSV ALL command successful.");
       
   229                                 continue;
       
   230                             }
       
   231                             try {
       
   232                                 if (pasv == null)
       
   233                                     pasv = new ServerSocket(0);
       
   234                                 int port = pasv.getLocalPort();
       
   235                                 out.println("229 Entering Extended" +
       
   236                                         " Passive Mode (|||" + port + "|)");
       
   237                             } catch (IOException ssex) {
       
   238                                 out.println("425 Can't build data connection:" +
       
   239                                                 " Connection refused.");
       
   240                             }
       
   241                             break;
       
   242 
       
   243                         case PASV:
       
   244                             if (!pasvEnabled) {
       
   245                                 out.println("500 PASV is disabled, " +
       
   246                                                 "use PORT instead.");
       
   247                                 continue;
       
   248                             }
       
   249                             try {
       
   250                                 if (pasv == null)
       
   251                                     pasv = new ServerSocket(0);
       
   252                                 int port = pasv.getLocalPort();
       
   253 
       
   254                                 // Parenthesis are optional, so let's be
       
   255                                 // nasty and don't put them
       
   256                                 out.println("227 Entering Passive Mode" +
       
   257                                                 " 127,0,0,1," +
       
   258                                             (port >> 8) + "," + (port & 0xff));
       
   259                             } catch (IOException ssex) {
       
   260                                 out.println("425 Can't build data connection:" +
       
   261                                                  "Connection refused.");
       
   262                             }
       
   263                             break;
       
   264                         case PORT:
       
   265                             if (!portEnabled) {
       
   266                                 out.println("500 PORT is disabled, " +
       
   267                                                 "use PASV instead");
       
   268                                 continue;
       
   269                             }
       
   270                             StringBuffer host;
       
   271                             int i = 0, j = 4;
       
   272                             while (j > 0) {
       
   273                                 i = arg.indexOf(',', i + 1);
       
   274                                 if (i < 0)
       
   275                                     break;
       
   276                                 j--;
       
   277                             }
       
   278                             if (j != 0) {
       
   279                                 out.println("500 '" + arg + "':" +
       
   280                                             " command not understood.");
       
   281                                 continue;
       
   282                             }
       
   283                             try {
       
   284                                 host = new StringBuffer(arg.substring(0, i));
       
   285                                 for (j = 0; j < host.length(); j++)
       
   286                                     if (host.charAt(j) == ',')
       
   287                                         host.setCharAt(j, '.');
       
   288                                 String ports = arg.substring(i+1);
       
   289                                 i = ports.indexOf(',');
       
   290                                 data_port = Integer.parseInt(
       
   291                                                 ports.substring(0, i)) << 8;
       
   292                                 data_port += (Integer.parseInt(
       
   293                                                 ports.substring(i+1)));
       
   294                                 data_addr = InetAddress.getByName(
       
   295                                                         host.toString());
       
   296                                 out.println("200 Command okay.");
       
   297                             } catch (Exception ex3) {
       
   298                                 data_port = 0;
       
   299                                 data_addr = null;
       
   300                                 out.println("500 '" + arg + "':" +
       
   301                                              " command not understood.");
       
   302                             }
       
   303                             break;
       
   304                         case RETR:
       
   305                             {
       
   306                                 File file = new File(arg);
       
   307                                 if (!file.exists()) {
       
   308                                    System.out.println("File not found");
       
   309                                    out.println("200 Command okay.");
       
   310                                    out.println("550 '" + arg +
       
   311                                             "' No such file or directory.");
       
   312                                    break;
       
   313                                 }
       
   314                                 FileInputStream fin = new FileInputStream(file);
       
   315                                 OutputStream dout = getOutDataStream();
       
   316                                 if (dout != null) {
       
   317                                    out.println("150 Binary data connection" +
       
   318                                                 " for " + arg +
       
   319                                                 " (" + client.getInetAddress().
       
   320                                                 getHostAddress() + ") (" +
       
   321                                                 file.length() + " bytes).");
       
   322                                     int c;
       
   323                                     int len = 0;
       
   324                                     while ((c = fin.read()) != -1) {
       
   325                                         dout.write(c);
       
   326                                         len++;
       
   327                                     }
       
   328                                     dout.flush();
       
   329                                     dout.close();
       
   330                                     fin.close();
       
   331                                    out.println("226 Binary Transfer complete.");
       
   332                                 } else {
       
   333                                     out.println("425 Can't build data" +
       
   334                                         " connection: Connection refused.");
       
   335                                 }
       
   336                             }
       
   337                             break;
       
   338                         }
       
   339                     } catch (IOException ioe) {
       
   340                         ioe.printStackTrace();
       
   341                         try {
       
   342                             out.close();
       
   343                         } catch (Exception ex2) {
       
   344                         }
       
   345                         done = true;
       
   346                     }
       
   347                 }
       
   348             }
       
   349         }
       
   350 
       
   351         public FtpServer(int port) {
       
   352             this.port = port;
       
   353         }
       
   354 
       
   355         public FtpServer() {
       
   356             this(21);
       
   357         }
       
   358 
       
   359         public int getPort() {
       
   360             if (server != null)
       
   361                 return server.getLocalPort();
       
   362             return 0;
       
   363         }
       
   364 
       
   365         /**
       
   366          * A way to tell the server that it can stop.
       
   367          */
       
   368         synchronized public void terminate() {
       
   369             done = true;
       
   370         }
       
   371 
       
   372 
       
   373         /*
       
   374          * All we got to do here is create a ServerSocket and wait for a
       
   375          * connection. When a connection happens, we just have to create
       
   376          * a thread that will handle it.
       
   377          */
       
   378         public void run() {
       
   379             try {
       
   380                 server = new ServerSocket(port);
       
   381                 Socket client;
       
   382                 client = server.accept();
       
   383                 (new FtpServerHandler(client)).start();
       
   384                 server.close();
       
   385             } catch (Exception e) {
       
   386             }
       
   387         }
       
   388     }
       
   389 
       
   390     public static void main(String[] args) throws Exception {
       
   391         MarkResetTest test = new MarkResetTest();
       
   392     }
       
   393 
       
   394     public MarkResetTest() {
       
   395         FtpServer server = null;
       
   396         try {
       
   397             server = new FtpServer(0);
       
   398             server.start();
       
   399             int port = 0;
       
   400             while (port == 0) {
       
   401                 Thread.sleep(500);
       
   402                 port = server.getPort();
       
   403             }
       
   404 
       
   405             String filename = "EncDec.doc";
       
   406             URL url = new URL("ftp://localhost:" + port + "/" +
       
   407                                 filename);
       
   408 
       
   409             URLConnection con = url.openConnection();
       
   410             System.out.println("getContent: " + con.getContent());
       
   411             System.out.println("getContent-length: " + con.getContentLength());
       
   412 
       
   413             InputStream is = con.getInputStream();
       
   414 
       
   415             /**
       
   416              * guessContentTypeFromStream method calls mark and reset methods
       
   417              * on the given stream. Make sure that calling
       
   418              * guessContentTypeFromStream repeatedly does not affect
       
   419              * reading from the stream afterwards
       
   420              */
       
   421             System.out.println("Call GuessContentTypeFromStream()" +
       
   422                                 " several times..");
       
   423             for (int i = 0; i < 5; i++) {
       
   424                 System.out.println((i + 1) + " mime-type: " +
       
   425                         con.guessContentTypeFromStream(is));
       
   426             }
       
   427 
       
   428             int len = 0;
       
   429             int c;
       
   430             while ((c = is.read()) != -1) {
       
   431                 len++;
       
   432             }
       
   433             is.close();
       
   434             System.out.println("read: " + len + " bytes of the file");
       
   435 
       
   436             // We're done!
       
   437             server.terminate();
       
   438             server.interrupt();
       
   439 
       
   440             // Did we pass ?
       
   441             if (len != (new File(filename)).length()) {
       
   442                 throw new Exception("Failed to read the file correctly");
       
   443             }
       
   444             System.out.println("PASSED: File read correctly");
       
   445         } catch (Exception e) {
       
   446             e.printStackTrace();
       
   447             try {
       
   448                 server.terminate();
       
   449                 server.interrupt();
       
   450             } catch (Exception ex) {
       
   451             }
       
   452             throw new RuntimeException("FTP support error: " + e.getMessage());
       
   453         }
       
   454     }
       
   455 }