001: package vicazh.hyperpool.stream.net.http.html;
002:
003: import java.io.*;
004: import java.net.*;
005: import java.text.*;
006: import java.util.*;
007: import vicazh.hyperpool.Start;
008: import vicazh.hyperpool.stream.*;
009: import vicazh.hyperpool.stream.net.http.*;
010:
011: public class FtpStream extends ClientStream implements Runnable {
012: public FtpStream() {
013: }
014:
015: FtpStream(Session session, OutputStream outputstream) {
016: super (session, outputstream);
017: }
018:
019: private List<String[]> list;
020:
021: public List<String[]> getList() {
022: return list;
023: }
024:
025: public void setList(List<String[]> list) {
026: this .list = list;
027: }
028:
029: private String name;
030:
031: public String getName() {
032: return name;
033: }
034:
035: public void setName(String name) {
036: this .name = name;
037: }
038:
039: private String ver;
040:
041: public String getVer() {
042: return ver;
043: }
044:
045: public void setVer(String ver) {
046: this .ver = ver;
047: }
048:
049: private String time;
050:
051: public String getTime() {
052: return time;
053: }
054:
055: public void setTime(String time) {
056: this .time = time;
057: }
058:
059: private enum Status {
060: PAGE, RETR, OTHR
061: };
062:
063: private Status status = Status.OTHR;
064:
065: private Socket socket;
066:
067: private PrintStream p;
068:
069: private BufferedReader r;
070:
071: private Socket socket2;
072:
073: private OutputStream out;
074:
075: private InputStream in;
076:
077: private int code;
078:
079: private String result;
080:
081: private long b = 0;
082:
083: public void head(String method, String file, String version)
084: throws IOException {
085: URL url = new URL(file);
086: String pwd = "";
087: int port = url.getPort();
088: socket = new Socket(url.getHost(), port == -1 ? url
089: .getDefaultPort() : port);
090: socket.setSoTimeout(((FtpService) connection.element).timeout);
091: p = new PrintStream(socket.getOutputStream());
092: outputstream = new NullStream(p);
093: r = new BufferedReader(new InputStreamReader(socket
094: .getInputStream()));
095: receive();
096: String user = "USER";
097: String pass = "PASS";
098: String userinfo = url.getUserInfo();
099: if (userinfo == null) {
100: user += " anonymous";
101: pass += " anonymous";
102: } else {
103: StringTokenizer st = new StringTokenizer(url.getUserInfo(),
104: ":");
105: user += " " + st.nextToken();
106: pwd = st.nextToken();
107: pass += " " + pwd;
108: }
109: send(user);
110: send(pass);
111: if (result.startsWith("530 ") || result.startsWith("503 ")) {
112: super .head(method, file, version);
113: code = ServerStream.UNAUTHORIZED;
114: return;
115: }
116: send("TYPE I");
117: send("PASV");
118: StringTokenizer st = new StringTokenizer(result.substring(
119: result.indexOf('(') + 1, result.indexOf(')')), ",");
120: socket2 = new Socket(st.nextToken() + '.' + st.nextToken()
121: + '.' + st.nextToken() + '.' + st.nextToken(), Integer
122: .valueOf(st.nextToken()).intValue()
123: * 256 + Integer.parseInt(st.nextToken()));
124: socket2.setSoTimeout(((FtpService) connection.element).timeout);
125: out = new BufferedOutputStream(socket2.getOutputStream());
126: in = new BufferedInputStream(socket2.getInputStream());
127: if (method.equalsIgnoreCase("get")) {
128: if (file.charAt(file.length() - 1) == '/') {
129: String p = url.getPath();
130: send("CWD " + p.substring(0, p.length() - 1));
131: } else {
132: String r = (String) getFields().get("range");
133: code = ServerStream.OK;
134: if (r != null && r.startsWith("bytes")) {
135: b = Long.parseLong(r.substring(r.indexOf('=') + 1,
136: r.indexOf('-')));
137: send("REST " + b);
138: if (result.startsWith("350 "))
139: code = ServerStream.PARTIAL_CONTENT;
140: }
141: send("RETR " + new URL(file).getPath());
142: if (result.startsWith("125 ")
143: || result.startsWith("150 ")) {
144: super .head(method, file, version);
145: status = Status.RETR;
146: return;
147: }
148: send("CWD " + url.getPath());
149: }
150: if (result.startsWith("550 ")) {
151: super .head(method, file, version);
152: code = ServerStream.FORBIDDEN;
153: return;
154: }
155: send("LIST");
156: BufferedReader r = new BufferedReader(
157: new InputStreamReader(in));
158: list = new ArrayList<String[]>();
159: String s;
160: while ((s = r.readLine()) != null) {
161: Thread.yield();
162: char fc = s.charAt(0);
163: if (fc == 't')
164: continue;
165: boolean u = fc == 'd' || fc == '-';
166: boolean d = u ? fc == 'd' : s.indexOf("<DIR>") != -1;
167: int j1 = 0;
168: int j2 = 0;
169: if (u) {
170: j1 = s.indexOf(' ');
171: while (s.charAt(++j1) == ' ')
172: ;
173: j1 = s.indexOf(' ', j1);
174: while (s.charAt(++j1) == ' ')
175: ;
176: j1 = s.indexOf(' ', j1);
177: while (s.charAt(++j1) == ' ')
178: ;
179: j1 = s.indexOf(' ', j1);
180: j2 = j1;
181: while (s.charAt(++j2) == ' ')
182: ;
183: j2 = s.indexOf(' ', j2);
184: while (s.charAt(++j2) == ' ')
185: ;
186: }
187: j2 = s.indexOf(' ', j2);
188: while (s.charAt(++j2) == ' ')
189: ;
190: j2 = s.indexOf(' ', j2);
191: while (s.charAt(++j2) == ' ')
192: ;
193: j2 = s.indexOf(' ', j2);
194: while (s.charAt(++j2) == ' ')
195: ;
196: String name = s.substring(j2);
197: String[] l = new String[3];
198: l[0] = name + (d ? "/" : "");
199: l[1] = (d ? '[' + name + ']' : name);
200: l[2] = s.substring(j1, j2 - 1);
201: list.add(l);
202: }
203: name = Start.NAME;
204: ver = Start.VERSION;
205: time = DateFormat.getDateTimeInstance().format(new Date());
206: outputstream = new XMLService(this ).get(connection
207: .getServer());
208: super .head(method, ((FtpService) connection.element).page,
209: version);
210: setFile(file.replace(':' + pwd + '@', "@"));
211: status = Status.PAGE;
212: } else if (method.equalsIgnoreCase("put")) {
213: super .head(method, file, version);
214: send("STOR " + url.getPath());
215: code = ServerStream.CREATED;
216: } else if (method.equalsIgnoreCase("delete")) {
217: super .head(method, file, version);
218: send("DELE " + new URL(getFile()).getPath());
219: if (result.startsWith("250 "))
220: code = ServerStream.ACCEPTED;
221: else if (result.startsWith("550 "))
222: code = ServerStream.NOT_ACCEPTABLE;
223: else
224: code = ServerStream.SERVICE_UNAVAILABLE;
225: }
226: }
227:
228: public void content(int b) throws IOException {
229: out.write(b);
230: super .content(b);
231: }
232:
233: public void run() {
234: try {
235: switch (status) {
236: case RETR:
237: session.getServer().head("HTTP/1.0", code, "");
238: String type = ((FtpService) connection.element).map
239: .get(getFile().substring(
240: getFile().lastIndexOf('.') + 1));
241: session.getServer().field("Content-Type",
242: type == null ? "text/html" : type);
243: session.getServer().field("Server",
244: Start.NAME + "/" + Start.VERSION);
245: int i = result.indexOf('(');
246: if (i != -1) {
247: long l = Long.parseLong(result.substring(i + 1,
248: result.indexOf(' ', i)));
249: session.getServer().field("Content-Length",
250: String.valueOf(l - b));
251: if (code == ServerStream.PARTIAL_CONTENT)
252: session.getServer().field("Content-Range",
253: "bytes " + b + '-' + (l - 1) + '/' + l);
254: }
255: session.getServer().header();
256: InputStream s = new BufferedInputStream(in);
257: while ((i = s.read()) != -1) {
258: Thread.yield();
259: connection.getServer().write(i);
260: if (s.available() == 0)
261: connection.getServer().flush();
262: }
263: connection.getServer().flush();
264: connection.getServer().close();
265: break;
266: case OTHR:
267: session.getServer().head("HTTP/1.0", code, "");
268: session.getServer().field("Content-Type", "text/html");
269: session.getServer().field("Server",
270: Start.NAME + "/" + Start.VERSION);
271: session.getServer().header();
272: session.getServer().write(result.getBytes());
273: connection.getServer().flush();
274: connection.getServer().close();
275: break;
276: }
277: send("QUIT");
278: } catch (IOException e) {
279: // Start.logger.log(Level.SEVERE, e.getMessage(), e);
280: }
281: try {
282: socket.close();
283: } catch (Exception e) {
284: }
285: try {
286: socket2.close();
287: } catch (Exception e) {
288: }
289: }
290:
291: public void end() {
292: super .end();
293: if (getFile() != null)
294: new Thread(this ).start();
295: }
296:
297: public vicazh.hyperpool.stream.net.Socket getSocket() {
298: return new vicazh.hyperpool.stream.net.Socket(socket);
299: }
300:
301: private void send(String s) throws IOException {
302: p.println(s);
303: Start.logger.finer(s);
304: receive();
305: }
306:
307: private void receive() throws IOException {
308: while ((result = r.readLine()).charAt(0) == ' '
309: || result.charAt(3) != ' ') {
310: Start.logger.finer(result);
311: }
312: Start.logger.finer(result);
313: }
314: }
|