package edu.washington.cs.oneswarm.ui.gwt.server.handlers; import java.io.BufferedWriter; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.List; import java.util.logging.Logger; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.gudy.azureus2.core3.download.DownloadManager; import org.gudy.azureus2.core3.torrent.TOTorrentException; import org.gudy.azureus2.core3.util.Base32; import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo; import org.gudy.azureus2.plugins.download.Download; import org.gudy.azureus2.plugins.download.DownloadException; import org.gudy.azureus2.plugins.torrent.TorrentFile; import org.mortbay.jetty.servlet.ServletHandler; import com.aelitis.azureus.core.impl.AzureusCoreImpl; import edu.washington.cs.oneswarm.ui.gwt.CoreInterface; import edu.washington.cs.oneswarm.ui.gwt.CoreTools; import edu.washington.cs.oneswarm.ui.gwt.rpc.OneSwarmConstants; public class BrowseHandler extends ServletHandler { private static Logger logger = Logger.getLogger(BrowseHandler.class.getName()); private final static String BROWSE = OneSwarmConstants.BROWSE_SHARE_PATH; private final static String DOWNLOAD = OneSwarmConstants.DOWNLOAD_SHARE_PATH; public BrowseHandler() { } public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) throws IOException, ServletException { if (target.startsWith(BROWSE)) { handleBrowse(target, request, response, dispatch); } else if (target.startsWith(DOWNLOAD)) { handleDownload(target, request, response, dispatch); } else { throw new IOException("not browse share path: " + target); } } public void handleBrowse(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) throws IOException, ServletException { String path = target.substring(BROWSE.length()); logger.finest("got browse request for: " + path); response.setCharacterEncoding("UTF-8"); BufferedWriter out = new BufferedWriter(new OutputStreamWriter(response.getOutputStream(), "UTF-8")); response.setContentType("text/html"); if (path.equals("") || path.equals("/")) { /* return root */ List<DownloadManager> dms = AzureusCoreImpl.getSingleton().getGlobalManager() .getDownloadManagers(); writeHeader("List of shared swarms", out); out.append("<body>\n"); out.append("<table border='0'>\n"); out.append("<tr><th>Swarm name</th><th>Swarm size</th></tr>\n"); for (DownloadManager dm : dms) { try { out.append("\t<tr>\n"); if (dm.getTorrent().getFiles().length == 1) { out.append("\t\t<td><a href=" + OneSwarmConstants.DOWNLOAD_SHARE_PATH + "/" + Base32.encode(dm.getTorrent().getHash()) + "/" + URLEncoder.encode( dm.getTorrent().getFiles()[0].getRelativePath(), "UTF-8") + ">" + dm.getDisplayName() + "</a><td>\n"); } else { out.append("\t\t<td><a href=" + OneSwarmConstants.BROWSE_SHARE_PATH + "/" + Base32.encode(dm.getTorrent().getHash()) + "/" + ">" + dm.getDisplayName() + "</a><td>\n"); } out.append("\t\t<td>" + dm.getSize() + "</td>\n"); out.append("\t</tr>\n"); } catch (TOTorrentException e) { // TODO Auto-generated catch block e.printStackTrace(); } } out.append("</table>"); out.append("</body>"); out.close(); } else { try { Download torrent = getTorrent(target); writeHeader(torrent.getName(), out); out.append("<body>\n"); out.append("<h2>" + torrent.getName() + "</h2>\n"); out.append("<table border='0'>\n"); out.append("<tr><th>File name</th><th>File size</th></tr>\n"); for (TorrentFile file : torrent.getTorrent().getFiles()) { out.append("\t<tr>\n"); out.append("\t\t<td><a href=" + OneSwarmConstants.DOWNLOAD_SHARE_PATH + "/" + Base32.encode(torrent.getTorrent().getHash()) + "/" + URLEncoder.encode(file.getName(), "UTF-8") + ">" + file.getName() + "</a><td>\n"); out.append("\t\t<td>" + file.getSize() + "</td>\n"); out.append("\t</tr>\n"); } out.append("</table>\n"); out.append("</body>\n"); out.close(); } catch (IOException e) { // expected sometimes, just go back to writeHeader("error", out); out.append("<body>"); out.append(e.getMessage()); out.append("</body>"); out.close(); } } } private static void writeHeader(String title, BufferedWriter out) throws IOException { out.append("<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'\n"); out.append("'http://www.w3.org/TR/html4/loose.dtd'>\n"); out.append("<html>\n"); out.append("<head>"); out.append("<meta http-equiv='Content-Type' content='text/html'; charset='UTF-8'>\n"); out.append("<title>" + title + "</title>\n"); out.append("</head>\n\n"); } public void handleDownload(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) throws IOException, ServletException { Download download = getTorrent(target); DiskManagerFileInfo diskManagerFile = CoreTools.getDiskManagerFileInfo( getTorrentFile(target, download), download); new SharedFileHandler(diskManagerFile, download).process(response, request); } public static Download getTorrent(String target) throws IOException { logger.finest("locating torrent file for target=" + target); if (target.startsWith("/")) { target = target.substring(1); } if (target.endsWith("/")) { target = target.substring(0, target.length() - 1); } String[] split = target.split("/"); if (split.length > 1) { logger.finest("torrent=" + split[1]); byte[] torrentHash = Base32.decode(split[1]); try { CoreInterface coreInterface = new CoreInterface(AzureusCoreImpl.getSingleton() .getPluginManager().getDefaultPluginInterface()); Download d = coreInterface.getDownloadManager().getDownload(torrentHash); if (d == null) { throw new IOException("Torrent not found: " + split[1]); } return d; } catch (DownloadException e) { throw new IOException("Download problem: " + e.getMessage()); } } else { throw new IOException("Invalid path"); } } public static TorrentFile getTorrentFile(String target, Download download) throws IOException { logger.finest("target=" + target); for (int i = 0; i < 3; i++) { if (target.contains("/")) { target = target.substring(target.indexOf("/") + 1); } else { throw new IOException("unable to get path"); } } String file = target; if (file == null) { throw new IOException("unable to get file target"); } try { file = URLDecoder.decode(file, "UTF-8"); } catch (UnsupportedEncodingException e) { throw new IOException("URL decode problem"); } logger.finest("file=" + file); if (download == null) { throw new IOException("torrent not found"); } TorrentFile activeFile = CoreTools.getTorrentFile(download, file); if (activeFile == null) { throw new IOException("file not found in torrent"); } return activeFile; } }