1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package gnu.inet.ftp;
24
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.InterruptedIOException;
28 import java.io.OutputStream;
29 import java.net.InetAddress;
30 import java.net.ServerSocket;
31 import java.net.Socket;
32 import java.net.SocketException;
33 import java.util.zip.InflaterInputStream;
34
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37
38 /***
39 * This class implements an FTP-style data connection server thread for GETing
40 * files/data non-passively.
41 * <P>
42 * This class is used internally to the FtpClient class.
43 */
44 public class ActiveGetter extends Getter {
45
46 private final static Log log = LogFactory.getLog(ActiveGetter.class);
47
48 private InetAddress address;
49
50 private int port;
51
52 private ServerSocket server;
53
54 private int timeout;
55
56 /***
57 * Create a new ActiveGetter with the given OutputStream for data output.
58 *
59 * @throws IOException
60 * an IO error occurred with the ServerSocket
61 */
62 public ActiveGetter(OutputStream out) throws IOException {
63 super();
64
65
66 this.server = new ServerSocket(0);
67 this.timeout = 30 * 1000;
68
69 this.port = server.getLocalPort();
70 this.address = this.server.getInetAddress();
71
72 this.ostream = out;
73 }
74
75
76
77
78
79 /***
80 * get the local port this ActiveGetter is listening on
81 *
82 * @return port number
83 */
84 public synchronized int getPort() {
85 return port;
86 }
87
88 /***
89 * get the local IP address that this ActiveGetter is listening on
90 *
91 * @return server socket IP address
92 */
93 public InetAddress getInetAddress() {
94 return address;
95 }
96
97 /***
98 * Set the connection timeout in milliseconds. This method must be called
99 * before start()/run() for the value to take affect.
100 *
101 * @param milliseconds
102 * the socket timeout value in milliseconds
103 */
104 public void setTimeout(int milliseconds) {
105 timeout = milliseconds;
106 }
107
108 /***
109 * get data from server using given parameters.
110 */
111 public void run() {
112 boolean signalClosure = false;
113 Socket sock = null;
114 InputStream istream = null;
115 long amount = 0;
116 long buffer_size = 0;
117 byte buffer[] = new byte[BUFFER_SIZE];
118
119
120 try {
121
122 server.setSoTimeout(timeout);
123 if (cancelled)
124 throw new InterruptedIOException("Transfer cancelled");
125
126
127
128 sock = server.accept();
129 signalConnectionOpened(new ConnectionEvent(sock.getInetAddress(),
130 sock.getPort()));
131 signalClosure = true;
132 signalTransferStarted();
133
134 try {
135
136
137 switch (type) {
138 case FtpClientProtocol.TYPE_ASCII:
139 istream = new AsciiInputStream(sock.getInputStream());
140 break;
141 default:
142 istream = sock.getInputStream();
143 break;
144 }
145
146
147 switch (mode) {
148 case FtpClientProtocol.MODE_ZLIB:
149 istream = new InflaterInputStream(istream);
150 break;
151 case FtpClientProtocol.MODE_STREAM:
152 default:
153 break;
154 }
155
156 int len;
157 while (!cancelled && ((len = istream.read(buffer)) > 0)) {
158 ostream.write(buffer, 0, len);
159 amount += len;
160 buffer_size += len;
161 if (buffer_size >= BUFFER_SIZE) {
162 buffer_size = buffer_size % BUFFER_SIZE;
163 signalTransfered(amount);
164 }
165 yield();
166 }
167
168 ostream.flush();
169 } catch (InterruptedIOException iioe) {
170 if (!cancelled) {
171 log.error(iioe.getMessage(), iioe);
172 }
173 } catch (Exception e) {
174 log.error(e.getMessage(), e);
175 } finally {
176 log.debug("Closing inputstream");
177 if (istream != null) {
178 istream.close();
179 }
180 if (!sock.isClosed()) {
181 try {
182 log.debug("Setting socket to 0 lingering");
183 sock.setSoLinger(true, 0);
184 sock.close();
185 } catch (SocketException e) {
186
187 }
188 }
189 signalTransferCompleted();
190 }
191 } catch (InterruptedIOException eiioe) {
192 signalConnectionFailed(eiioe);
193 if (!cancelled) {
194 log.error(eiioe.getMessage(), eiioe);
195 }
196 } catch (Exception ee) {
197 signalConnectionFailed(ee);
198 log.error(ee.getMessage(), ee);
199 } finally {
200 try {
201 log.debug("Closing server socket");
202 server.close();
203 } catch (IOException ex) {
204
205 }
206 }
207
208 if (signalClosure == true && sock != null) {
209 signalConnectionClosed(new ConnectionEvent(sock.getInetAddress(),
210 sock.getPort()));
211 }
212 }
213
214 }
215
216