1 // $Header: /home/cvs/jakarta-jmeter/src/protocol/ftp/org/apache/jmeter/protocol/ftp/sampler/FtpClient.java,v 1.10 2005/07/12 20:50:54 mstover1 Exp $ 2 /* 3 * Copyright 2001-2004 The Apache Software Foundation. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package org.apache.jmeter.protocol.ftp.sampler; 20 21 import java.io.BufferedInputStream; 22 import java.io.BufferedReader; 23 import java.io.BufferedWriter; 24 import java.io.IOException; 25 import java.io.InputStream; 26 import java.io.InputStreamReader; 27 import java.io.OutputStreamWriter; 28 import java.net.InetAddress; 29 import java.net.ServerSocket; 30 import java.net.Socket; 31 32 import org.apache.jorphan.logging.LoggingManager; 33 import org.apache.log.Logger; 34 35 /** 36 * Simple FTP client (non-passive transfers don't work yet). Kind of a hack, 37 * lots of room for optimizations. 38 * 39 * @author mike Created August 31, 2001 40 * @version $Revision: 1.10 $ Last updated: $Date: 2005/07/12 20:50:54 $ 41 */ 42 public class FtpClient { 43 transient private static Logger log = LoggingManager.getLoggerForClass(); 44 45 // File f = new File("e:\\"); 46 BufferedWriter out; 47 48 BufferedReader in; 49 50 Socket s; 51 52 boolean passive = false; 53 54 static int port = 21; 55 56 static int dataPort = 4096; 57 58 /** 59 * Constructor for the FtpClient object. 60 */ 61 public FtpClient() { 62 } 63 64 /** 65 * Set passive mode. 66 * 67 * @param flag 68 * the new Passive value 69 */ 70 public void setPassive(boolean flag) { 71 passive = flag; 72 } 73 74 /** 75 * Get a file from the server. 76 * 77 * @return the Response value 78 */ 79 public String getResponse() throws IOException { 80 StringBuffer response = new StringBuffer(); 81 String line = in.readLine(); 82 response.append(line); 83 log.info("FtpClient.getResponse(): #" + line + "#"); 84 while (line.charAt(3) == '-') { 85 line = in.readLine(); 86 response.append("\n"); 87 response.append(line); 88 log.info("FtpClient.getResponse(): #" + line + "#"); 89 } 90 log.info("return response"); 91 return response.toString(); 92 } 93 94 /** 95 * Get a file from the server. 96 */ 97 public String get(String file) throws Exception { 98 send("SYST"); 99 getResponse(); 100 send("PWD"); 101 getResponse(); 102 send("TYPE I"); 103 getResponse(); 104 String data = ""; 105 if (!passive) { 106 dataPort++; 107 int upper = getUpper(dataPort); 108 int lower = getLower(dataPort); 109 String ip = InetAddress.getLocalHost().getHostAddress().replace('.', ','); 110 String ports = ip + "," + upper + "," + lower; 111 log.info("port:" + ports); 112 send("PORT " + ports); 113 getResponse(); 114 dataGrabber grab = new dataGrabber(ip, dataPort); 115 while (!grab.isPortCreated()) { 116 } 117 send("RETR " + file); 118 String response = in.readLine(); 119 log.info(response); 120 log.info("" + dataPort); 121 data = "FTP client - File Not Found"; 122 if (!response.startsWith("5")) { 123 while (!grab.isDone()) { 124 } 125 data = grab.getData(); 126 } 127 } else { 128 send("PASV"); 129 String portResp = getResponse(); 130 while (!portResp.startsWith("227")) { 131 portResp = getResponse(); 132 } 133 int start = portResp.indexOf('('); 134 int end = portResp.indexOf(')'); 135 portResp = portResp.substring(start + 1, end); 136 int a = portResp.indexOf(','); 137 int b = portResp.indexOf(',', a + 1); 138 int c = portResp.indexOf(',', b + 1); 139 int d = portResp.indexOf(',', c + 1); 140 int e = portResp.indexOf(',', d + 1); 141 String ip = portResp.substring(0, a) + "." + portResp.substring(a + 1, b) + "." 142 + portResp.substring(b + 1, c) + "." + portResp.substring(c + 1, d); 143 int upper = Integer.parseInt(portResp.substring(d + 1, e)); 144 int lower = Integer.parseInt(portResp.substring(e + 1)); 145 send("RETR " + file); 146 dataGrabber grab = new dataGrabber(ip, getPort(upper, lower)); 147 getResponse(); 148 while (!grab.isDone()) { 149 } 150 data = grab.getData(); 151 } 152 return data; 153 } 154 155 /** 156 * Connect to server. 157 */ 158 public void connect(String host, String username, String password) throws Exception { 159 InetAddress addr = InetAddress.getByName(host); 160 s = new Socket(addr, port); 161 out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); 162 163 InputStreamReader isr = new InputStreamReader(s.getInputStream()); 164 in = new BufferedReader(isr); 165 send("USER " + username); 166 send("PASS " + password); 167 } 168 169 /** 170 * Disconnect from the server 171 */ 172 public void disconnect() { 173 try { 174 send("QUIT"); 175 getResponse(); 176 } catch (Exception e) { 177 log.error("FTP client - ", e); 178 } 179 try { 180 in.close(); 181 out.close(); 182 s.close(); 183 } catch (Exception e) { 184 log.error("FTP client - ", e); 185 } 186 } 187 188 /** 189 * Send a command to the server. 190 */ 191 public void send(String command) throws IOException { 192 for (int i = 0; i < command.length(); i++) { 193 out.write(command.charAt(i)); 194 } 195 out.write('\r'); 196 out.write('\n'); 197 out.flush(); 198 } 199 200 /** 201 * Gets the Port attribute of the FtpClient class. 202 * 203 * @return the Port value 204 */ 205 public static int getPort(int upper, int lower) { 206 return upper * 256 + lower; 207 } 208 209 /** 210 * Gets the Upper attribute of the FtpClient class. 211 * 212 * @return the Upper value 213 */ 214 public static int getUpper(int lport) { 215 return lport / 256; 216 } 217 218 /** 219 * Gets the Lower attribute of the FtpClient class. 220 * 221 * @return the Lower value 222 */ 223 public static int getLower(int lport) { 224 return lport % 256; 225 } 226 227 /** 228 * Grabs the data from the dataport. 229 * 230 * @author mike Created August 31, 2001 231 * @version $Revision: 1.10 $ Last updated: $Date: 2005/07/12 20:50:54 $ 232 */ 233 public class dataGrabber implements Runnable { 234 StringBuffer buffer = new StringBuffer(); 235 236 Socket sock; 237 238 boolean done = false; 239 240 boolean portCreated = false; 241 242 String host = ""; 243 244 int dgPort = 22; 245 246 /** 247 * Constructor for the dataGrabber object. 248 */ 249 public dataGrabber(String host, int port) throws Exception { 250 this.host = host; 251 this.dgPort = port; 252 new Thread(this).start(); 253 } 254 255 /** 256 * Gets the Done attribute of the dataGrabber object. 257 * 258 * @return the Done value 259 */ 260 public boolean isDone() { 261 return done; 262 } 263 264 /** 265 * Gets the Data attribute of the dataGrabber object. 266 * 267 * @return the Data value 268 */ 269 public String getData() { 270 return buffer.toString(); 271 } 272 273 /** 274 * Gets the PortCreated attribute of the dataGrabber object. 275 * 276 * @return the PortCreated value 277 */ 278 public boolean isPortCreated() { 279 return portCreated; 280 } 281 282 /** 283 * Main processing method for the dataGrabber object. 284 */ 285 public void run() { 286 try { 287 if (passive) { 288 sock = new Socket(host, dgPort); 289 } else { 290 log.info("creating socket on " + dgPort); 291 ServerSocket server = new ServerSocket(dgPort); 292 log.info("accepting..."); 293 portCreated = true; 294 sock = server.accept(); 295 log.info("accepted"); 296 } 297 } catch (Exception e) { 298 } 299 try { 300 InputStream inStr = sock.getInputStream(); 301 BufferedInputStream dataIn = new BufferedInputStream(inStr); 302 int bufferSize = 4096; 303 byte[] inputBuffer = new byte[bufferSize]; 304 int i = 0; 305 while ((i = dataIn.read(inputBuffer, 0, bufferSize)) != -1) { 306 buffer.append((char) i); 307 } 308 dataIn.close(); 309 sock.close(); 310 } catch (Exception e) { 311 log.error("FTP client: dataGrabber", e); 312 } 313 done = true; 314 } 315 } 316 }