Search in sources :

Example 1 with PooledByteBuffer

use of com.biglybt.pif.utils.PooledByteBuffer in project BiglyBT by BiglySoftware.

the class ManagerUtils method browse.

public static String browse(final DownloadManager dm, DiskManagerFileInfo _file, final boolean anon, final boolean launch) {
    Properties props = new Properties();
    File save_location = dm.getSaveLocation();
    final String root_dir;
    if (save_location.isFile()) {
        root_dir = save_location.getParentFile().getAbsolutePath();
    } else {
        root_dir = save_location.getAbsolutePath();
    }
    final String url_suffix;
    boolean always_browse = COConfigurationManager.getBooleanParameter("Library.LaunchWebsiteInBrowserDirList");
    if (!always_browse) {
        if (_file == null) {
            _file = getBrowseHomePage(dm);
        }
    }
    final DiskManagerFileInfo file = _file;
    if (file == null) {
        // asked to launch a download (note that the double-click on a download that has an index.html file will by default result in
        // us getting here with the file set, not null)
        url_suffix = "";
    } else {
        String relative_path = file.getTorrentFile().getRelativePath();
        String[] bits = relative_path.replace(File.separatorChar, '/').split("/");
        String _url_suffix = "";
        int bits_to_use = always_browse ? bits.length - 1 : bits.length;
        for (int i = 0; i < bits_to_use; i++) {
            String bit = bits[i];
            if (bit.length() == 0) {
                continue;
            }
            _url_suffix += (_url_suffix == "" ? "" : "/") + UrlUtils.encode(bit);
        }
        url_suffix = _url_suffix;
    }
    synchronized (browse_plugins) {
        WebPlugin plugin = browse_plugins.get(dm);
        if (plugin == null) {
            props.put(WebPlugin.PR_PORT, 0);
            props.put(WebPlugin.PR_BIND_IP, "127.0.0.1");
            props.put(WebPlugin.PR_HOME_PAGE, "");
            props.put(WebPlugin.PR_ROOT_DIR, root_dir);
            props.put(WebPlugin.PR_ACCESS, "local");
            props.put(WebPlugin.PR_HIDE_RESOURCE_CONFIG, true);
            props.put(WebPlugin.PR_ENABLE_KEEP_ALIVE, true);
            props.put(WebPlugin.PR_ENABLE_PAIRING, false);
            props.put(WebPlugin.PR_ENABLE_UPNP, false);
            props.put(WebPlugin.PR_ENABLE_I2P, false);
            props.put(WebPlugin.PR_ENABLE_TOR, false);
            final String plugin_id = "webserver:" + dm.getInternalName();
            final String plugin_name = "Web Server for " + dm.getDisplayName();
            Properties messages = new Properties();
            messages.put("plugins." + plugin_id, plugin_name);
            PluginInitializer.getDefaultInterface().getUtilities().getLocaleUtilities().integrateLocalisedMessageBundle(messages);
            final AESemaphore waiter = new AESemaphore("waiter");
            final String[] url_holder = { null };
            plugin = new UnloadableWebPlugin(props) {

                private Map<String, Object> file_map = new HashMap<>();

                private String protocol;

                private String host;

                private int port;

                @Override
                public void initialize(PluginInterface plugin_interface) throws PluginException {
                    DiskManagerFileInfoSet file_set = dm.getDiskManagerFileInfoSet();
                    DiskManagerFileInfo[] files = file_set.getFiles();
                    Set<Object> root_dir = new HashSet<>();
                    file_map.put("", root_dir);
                    for (DiskManagerFileInfo dm_file : files) {
                        TOTorrentFile file = dm_file.getTorrentFile();
                        String path = file.getRelativePath();
                        file_map.put(path, dm_file);
                        if (path.startsWith(File.separator)) {
                            path = path.substring(1);
                        }
                        Set<Object> dir = root_dir;
                        int pos = 0;
                        while (true) {
                            int next_pos = path.indexOf(File.separatorChar, pos);
                            if (next_pos == -1) {
                                dir.add(dm_file);
                                break;
                            } else {
                                String bit = path.substring(pos, next_pos);
                                dir.add(bit);
                                String sub_path = path.substring(0, next_pos);
                                dir = (Set<Object>) file_map.get(sub_path);
                                if (dir == null) {
                                    dir = new HashSet<>();
                                    file_map.put(sub_path, dir);
                                }
                                pos = next_pos + 1;
                            }
                        }
                    }
                    Properties props = plugin_interface.getPluginProperties();
                    props.put("plugin.name", plugin_name);
                    super.initialize(plugin_interface);
                    InetAddress bind_ip = getServerBindIP();
                    if (bind_ip.isAnyLocalAddress()) {
                        host = "127.0.0.1";
                    } else {
                        host = bind_ip.getHostAddress();
                    }
                    port = getServerPort();
                    log("Assigned port: " + port);
                    protocol = getProtocol();
                    String url = protocol + "://" + host + ":" + port + "/" + url_suffix;
                    if (launch) {
                        Utils.launch(url, false, true, anon);
                    } else {
                        synchronized (url_holder) {
                            url_holder[0] = url;
                        }
                        waiter.release();
                    }
                }

                @Override
                public boolean generate(TrackerWebPageRequest request, TrackerWebPageResponse response) throws IOException {
                    try {
                        boolean res = super.generate(request, response);
                        if (!res) {
                            response.setReplyStatus(404);
                        }
                    } catch (Throwable e) {
                        response.setReplyStatus(404);
                    }
                    return (true);
                }

                @Override
                protected boolean useFile(TrackerWebPageRequest request, final TrackerWebPageResponse response, String root, String relative_url) throws IOException {
                    URL absolute_url = request.getAbsoluteURL();
                    String query = absolute_url.getQuery();
                    if (query != null) {
                        String[] args = query.split("&");
                        String vuze_source = null;
                        int vuze_file_index = -1;
                        String vuze_file_name = null;
                        List<String> networks = new ArrayList<>();
                        for (String arg : args) {
                            String[] bits = arg.split("=");
                            String lhs = bits[0];
                            String rhs = UrlUtils.decode(bits[1]);
                            if (lhs.equals("vuze_source")) {
                                if (rhs.endsWith(".torrent") || rhs.startsWith("magnet")) {
                                    vuze_source = rhs;
                                }
                            } else if (lhs.equals("vuze_file_index")) {
                                vuze_file_index = Integer.parseInt(rhs);
                            } else if (lhs.equals("vuze_file_name")) {
                                vuze_file_name = rhs;
                            } else if (lhs.equals("vuze_network")) {
                                String net = AENetworkClassifier.internalise(rhs);
                                if (net != null) {
                                    networks.add(net);
                                }
                            }
                        }
                        if (vuze_source != null) {
                            String referrer = (String) request.getHeaders().get("referer");
                            if (referrer == null || !referrer.contains("://" + host + ":" + port)) {
                                response.setReplyStatus(403);
                                return (true);
                            }
                            if (vuze_source.endsWith(".torrent")) {
                                Object file_node = file_map.get(vuze_source);
                                if (file_node instanceof DiskManagerFileInfo) {
                                    DiskManagerFileInfo dm_file = (DiskManagerFileInfo) file_node;
                                    long file_size = dm_file.getLength();
                                    File target_file = dm_file.getFile(true);
                                    boolean done = dm_file.getDownloaded() == file_size && target_file.length() == file_size;
                                    if (done) {
                                        return (handleRedirect(dm, target_file, vuze_file_index, vuze_file_name, networks, request, response));
                                    } else {
                                        try {
                                            File torrent_file = AETemporaryFileHandler.createTempFile();
                                            final FileOutputStream fos = new FileOutputStream(torrent_file);
                                            try {
                                                DiskManagerChannel chan = PluginCoreUtils.wrap(dm_file).createChannel();
                                                try {
                                                    final DiskManagerRequest req = chan.createRequest();
                                                    req.setOffset(0);
                                                    req.setLength(file_size);
                                                    req.addListener(new DiskManagerListener() {

                                                        @Override
                                                        public void eventOccurred(DiskManagerEvent event) {
                                                            int type = event.getType();
                                                            if (type == DiskManagerEvent.EVENT_TYPE_BLOCKED) {
                                                                return;
                                                            } else if (type == DiskManagerEvent.EVENT_TYPE_FAILED) {
                                                                throw (new RuntimeException(event.getFailure()));
                                                            }
                                                            PooledByteBuffer buffer = event.getBuffer();
                                                            if (buffer == null) {
                                                                throw (new RuntimeException("eh?"));
                                                            }
                                                            try {
                                                                byte[] data = buffer.toByteArray();
                                                                fos.write(data);
                                                            } catch (IOException e) {
                                                                throw (new RuntimeException("Failed to write to " + file, e));
                                                            } finally {
                                                                buffer.returnToPool();
                                                            }
                                                        }
                                                    });
                                                    req.run();
                                                } finally {
                                                    chan.destroy();
                                                }
                                            } finally {
                                                fos.close();
                                            }
                                            return (handleRedirect(dm, torrent_file, vuze_file_index, vuze_file_name, networks, request, response));
                                        } catch (Throwable e) {
                                            Debug.out(e);
                                            return (false);
                                        }
                                    }
                                } else {
                                    return (false);
                                }
                            } else {
                                URL magnet = new URL(vuze_source);
                                File torrent_file = AETemporaryFileHandler.createTempFile();
                                try {
                                    URLConnection connection = magnet.openConnection();
                                    connection.connect();
                                    FileUtil.copyFile(connection.getInputStream(), torrent_file.getAbsoluteFile());
                                    return (handleRedirect(dm, torrent_file, vuze_file_index, vuze_file_name, networks, request, response));
                                } catch (Throwable e) {
                                    Debug.out(e);
                                }
                            }
                        }
                    }
                    String path = absolute_url.getPath();
                    if (path.equals("/")) {
                        if (COConfigurationManager.getBooleanParameter("Library.LaunchWebsiteInBrowserDirList")) {
                            relative_url = "/";
                        }
                    }
                    String download_name = XUXmlWriter.escapeXML(dm.getDisplayName());
                    String relative_file = relative_url.replace('/', File.separatorChar);
                    String node_key = relative_file.substring(1);
                    Object file_node = file_map.get(node_key);
                    boolean file_node_is_parent = false;
                    if (file_node == null) {
                        int pos = node_key.lastIndexOf(File.separator);
                        if (pos == -1) {
                            node_key = "";
                        } else {
                            node_key = node_key.substring(0, pos);
                        }
                        file_node = file_map.get(node_key);
                        file_node_is_parent = true;
                    }
                    if (file_node == null) {
                        return (false);
                    }
                    if (file_node instanceof Set) {
                        if (relative_url.equals("/favicon.ico")) {
                            try {
                                InputStream stream = getClass().getClassLoader().getResourceAsStream("com/biglybt/ui/icons/favicon.ico");
                                response.useStream("image/x-icon", stream);
                                return (true);
                            } catch (Throwable e) {
                            }
                        }
                        Set<Object> kids = (Set<Object>) file_node;
                        String request_url = request.getURL();
                        if (file_node_is_parent) {
                            int pos = request_url.lastIndexOf("/");
                            if (pos == -1) {
                                request_url = "";
                            } else {
                                request_url = request_url.substring(0, pos);
                            }
                        }
                        response.setContentType("text/html");
                        OutputStream os = response.getOutputStream();
                        String title = XUXmlWriter.escapeXML(UrlUtils.decode(request_url));
                        if (title.length() == 0) {
                            title = "/";
                        }
                        os.write(("<html>" + NL + " <head>" + NL + " <meta charset=\"UTF-8\">" + NL + "  <title>" + download_name + ": Index of " + title + "</title>" + NL + " </head>" + NL + " <body>" + NL + "  <p>" + download_name + "</p>" + NL + "  <h1>Index of " + title + "</h1>" + NL + "  <pre><hr>" + NL).getBytes("UTF-8"));
                        String root_url = request_url;
                        if (!root_url.endsWith("/")) {
                            root_url += "/";
                        }
                        if (request_url.length() > 1) {
                            int pos = request_url.lastIndexOf('/');
                            if (pos == 0) {
                                pos++;
                            }
                            String parent = request_url.substring(0, pos);
                            os.write(("<a href=\"" + parent + "\">..</a>" + NL).getBytes("UTF-8"));
                        }
                        List<String[]> filenames = new ArrayList<>(kids.size());
                        int max_filename = 0;
                        int MAX_LEN = 120;
                        for (Object entry : kids) {
                            DiskManagerFileInfo file;
                            String file_name;
                            if (entry instanceof String) {
                                file = null;
                                file_name = (String) entry;
                            } else {
                                file = (DiskManagerFileInfo) entry;
                                if (file.isSkipped()) {
                                    continue;
                                }
                                file_name = file.getTorrentFile().getRelativePath();
                                int pos = file_name.lastIndexOf(File.separatorChar);
                                if (pos != -1) {
                                    file_name = file_name.substring(pos + 1);
                                }
                            }
                            String url = root_url + UrlUtils.encode(file_name);
                            if (file == null) {
                                file_name += "/";
                            }
                            int len = file_name.length();
                            if (len > MAX_LEN) {
                                file_name = file_name.substring(0, MAX_LEN - 3) + "...";
                                len = file_name.length();
                            }
                            if (len > max_filename) {
                                max_filename = len;
                            }
                            filenames.add(new String[] { url, file_name, file == null ? "" : DisplayFormatters.formatByteCountToKiBEtc(file.getLength()) });
                        }
                        max_filename = ((max_filename + 15) / 8) * 8;
                        char[] padding = new char[max_filename];
                        Arrays.fill(padding, ' ');
                        Collections.sort(filenames, new Comparator<String[]>() {

                            Comparator comp = new FormattersImpl().getAlphanumericComparator(true);

                            @Override
                            public int compare(String[] o1, String[] o2) {
                                return (comp.compare(o1[0], o2[0]));
                            }
                        });
                        for (String[] entry : filenames) {
                            String file_name = entry[1];
                            int len = file_name.length();
                            StringBuilder line = new StringBuilder(max_filename + 64);
                            line.append("<a href=\"").append(entry[0]).append("\">").append(XUXmlWriter.escapeXML(file_name)).append("</a>");
                            line.append(padding, 0, max_filename - len);
                            line.append(entry[2]);
                            line.append(NL);
                            os.write(line.toString().getBytes("UTF-8"));
                        }
                        os.write(("  <hr></pre>" + NL + "  <address>" + Constants.APP_NAME + " Web Server at " + host + " Port " + getServerPort() + "</address>" + NL + " </body>" + NL + "</html>").getBytes("UTF-8"));
                        return (true);
                    } else {
                        DiskManagerFileInfo dm_file = (DiskManagerFileInfo) file_node;
                        long file_size = dm_file.getLength();
                        File target_file = dm_file.getFile(true);
                        boolean done = dm_file.getDownloaded() == file_size && target_file.length() == file_size;
                        String file_type;
                        // Use the original torrent file name when deducing file type to
                        // avoid incomplete suffix issues etc
                        String relative_path = dm_file.getTorrentFile().getRelativePath();
                        int pos = relative_path.lastIndexOf(".");
                        if (pos == -1) {
                            file_type = "";
                        } else {
                            file_type = relative_path.substring(pos + 1);
                        }
                        if (file_size >= 512 * 1024) {
                            String content_type = HTTPUtils.guessContentTypeFromFileType(file_type);
                            if (content_type.startsWith("text/") || content_type.startsWith("image/")) {
                            // don't want to be redirecting here as (for example) .html needs
                            // to remain in the 'correct' place so that relative assets work
                            } else {
                                URL stream_url = getMediaServerContentURL(dm_file);
                                if (stream_url != null) {
                                    OutputStream os = response.getRawOutputStream();
                                    os.write(("HTTP/1.1 302 Found" + NL + "Location: " + stream_url.toExternalForm() + NL + NL).getBytes("UTF-8"));
                                    return (true);
                                }
                            }
                        }
                        if (done) {
                            if (file_size < 512 * 1024) {
                                FileInputStream fis = null;
                                try {
                                    fis = new FileInputStream(target_file);
                                    response.useStream(file_type, fis);
                                    return (true);
                                } finally {
                                    if (fis != null) {
                                        fis.close();
                                    }
                                }
                            } else {
                                OutputStream os = null;
                                InputStream is = null;
                                try {
                                    os = response.getRawOutputStream();
                                    os.write(("HTTP/1.1 200 OK" + NL + "Content-Type:" + HTTPUtils.guessContentTypeFromFileType(file_type) + NL + "Content-Length: " + file_size + NL + "Connection: close" + NL + NL).getBytes("UTF-8"));
                                    byte[] buffer = new byte[128 * 1024];
                                    is = new FileInputStream(target_file);
                                    while (true) {
                                        int len = is.read(buffer);
                                        if (len <= 0) {
                                            break;
                                        }
                                        os.write(buffer, 0, len);
                                    }
                                } catch (Throwable e) {
                                // e.printStackTrace();
                                } finally {
                                    try {
                                        os.close();
                                    } catch (Throwable e) {
                                    }
                                    try {
                                        is.close();
                                    } catch (Throwable e) {
                                    }
                                }
                                return (true);
                            }
                        } else {
                            dm_file.setPriority(10);
                            try {
                                final OutputStream os = response.getRawOutputStream();
                                os.write(("HTTP/1.1 200 OK" + NL + "Content-Type:" + HTTPUtils.guessContentTypeFromFileType(file_type) + NL + "Content-Length: " + file_size + NL + "Connection: close" + NL + "X-Vuze-Hack: X").getBytes("UTF-8"));
                                DiskManagerChannel chan = PluginCoreUtils.wrap(dm_file).createChannel();
                                try {
                                    final DiskManagerRequest req = chan.createRequest();
                                    final boolean[] header_complete = { false };
                                    final long[] last_write = { 0 };
                                    req.setOffset(0);
                                    req.setLength(file_size);
                                    req.addListener(new DiskManagerListener() {

                                        @Override
                                        public void eventOccurred(DiskManagerEvent event) {
                                            int type = event.getType();
                                            if (type == DiskManagerEvent.EVENT_TYPE_BLOCKED) {
                                                return;
                                            } else if (type == DiskManagerEvent.EVENT_TYPE_FAILED) {
                                                throw (new RuntimeException(event.getFailure()));
                                            }
                                            PooledByteBuffer buffer = event.getBuffer();
                                            if (buffer == null) {
                                                throw (new RuntimeException("eh?"));
                                            }
                                            try {
                                                boolean do_header = false;
                                                synchronized (header_complete) {
                                                    if (!header_complete[0]) {
                                                        do_header = true;
                                                        header_complete[0] = true;
                                                    }
                                                    last_write[0] = SystemTime.getMonotonousTime();
                                                }
                                                if (do_header) {
                                                    os.write((NL + NL).getBytes("UTF-8"));
                                                }
                                                byte[] data = buffer.toByteArray();
                                                os.write(data);
                                            } catch (IOException e) {
                                                throw (new RuntimeException("Failed to write to " + file, e));
                                            } finally {
                                                buffer.returnToPool();
                                            }
                                        }
                                    });
                                    final TimerEventPeriodic[] timer_event = { null };
                                    timer_event[0] = SimpleTimer.addPeriodicEvent("KeepAlive", 10 * 1000, new TimerEventPerformer() {

                                        boolean cancel_outstanding = false;

                                        @Override
                                        public void perform(TimerEvent event) {
                                            if (cancel_outstanding) {
                                                req.cancel();
                                            } else {
                                                synchronized (header_complete) {
                                                    if (header_complete[0]) {
                                                        if (SystemTime.getMonotonousTime() - last_write[0] >= 5 * 60 * 1000) {
                                                            req.cancel();
                                                        }
                                                    } else {
                                                        try {
                                                            os.write("X".getBytes("UTF-8"));
                                                            os.flush();
                                                        } catch (Throwable e) {
                                                            req.cancel();
                                                        }
                                                    }
                                                }
                                                if (!response.isActive()) {
                                                    cancel_outstanding = true;
                                                }
                                            }
                                        }
                                    });
                                    try {
                                        req.run();
                                    } finally {
                                        timer_event[0].cancel();
                                    }
                                    return (true);
                                } finally {
                                    chan.destroy();
                                }
                            } catch (Throwable e) {
                                return (false);
                            }
                        }
                    }
                }

                private boolean handleRedirect(DownloadManager dm, File torrent_file, int file_index, String file_name, List<String> networks, TrackerWebPageRequest request, TrackerWebPageResponse response) {
                    try {
                        TOTorrent torrent = TOTorrentFactory.deserialiseFromBEncodedFile(torrent_file);
                        GlobalManager gm = CoreFactory.getSingleton().getGlobalManager();
                        UIFunctions uif = UIFunctionsManager.getUIFunctions();
                        TorrentOpenOptions torrent_options = new TorrentOpenOptions(torrent_file.getAbsolutePath(), torrent, false);
                        torrent_options.setTorrent(torrent);
                        String[] existing_nets;
                        if (networks.size() == 0) {
                            // inherit networks from parent
                            existing_nets = dm.getDownloadState().getNetworks();
                        } else {
                            existing_nets = networks.toArray(new String[networks.size()]);
                        }
                        for (String net : AENetworkClassifier.AT_NETWORKS) {
                            boolean found = false;
                            for (String x : existing_nets) {
                                if (net == x) {
                                    found = true;
                                    break;
                                }
                            }
                            torrent_options.setNetworkEnabled(net, found);
                        }
                        Map<String, Object> add_options = new HashMap<>();
                        add_options.put(UIFunctions.OTO_SILENT, true);
                        if (uif.addTorrentWithOptions(torrent_options, add_options)) {
                            long start = SystemTime.getMonotonousTime();
                            while (true) {
                                DownloadManager o_dm = gm.getDownloadManager(torrent);
                                if (o_dm != null) {
                                    if (!o_dm.getDownloadState().getFlag(DownloadManagerState.FLAG_METADATA_DOWNLOAD)) {
                                        DiskManagerFileInfo[] files = o_dm.getDiskManagerFileInfoSet().getFiles();
                                        DiskManagerFileInfo o_dm_file = null;
                                        if (file_name != null) {
                                            for (DiskManagerFileInfo file : files) {
                                                String path = file.getTorrentFile().getRelativePath();
                                                if (path.equals(file_name)) {
                                                    o_dm_file = file;
                                                    break;
                                                }
                                            }
                                            if (o_dm_file == null) {
                                                o_dm_file = files[0];
                                            }
                                        } else {
                                            if (file_index < 0) {
                                                long largest = -1;
                                                for (DiskManagerFileInfo file : files) {
                                                    if (file.getLength() > largest) {
                                                        o_dm_file = file;
                                                        largest = file.getLength();
                                                    }
                                                }
                                            } else {
                                                o_dm_file = files[file_index];
                                            }
                                        }
                                        String original_path = request.getAbsoluteURL().getPath();
                                        if (original_path.endsWith(".html")) {
                                            String url = browse(o_dm, file_index < 0 ? null : o_dm_file, anon, false);
                                            OutputStream os = response.getRawOutputStream();
                                            os.write(("HTTP/1.1 302 Found" + NL + "Location: " + url + NL + NL).getBytes("UTF-8"));
                                            return (true);
                                        } else {
                                            URL stream_url = getMediaServerContentURL(o_dm_file);
                                            if (stream_url != null) {
                                                OutputStream os = response.getRawOutputStream();
                                                os.write(("HTTP/1.1 302 Found" + NL + "Location: " + stream_url.toExternalForm() + NL + NL).getBytes("UTF-8"));
                                                return (true);
                                            }
                                        }
                                    }
                                }
                                long now = SystemTime.getMonotonousTime();
                                if (now - start > 3 * 60 * 1000) {
                                    Debug.out("Timeout waiting for download to be added");
                                    return (false);
                                }
                                Thread.sleep(1000);
                            }
                        } else {
                            Debug.out("Failed to add download for some reason");
                            return (false);
                        }
                    } catch (Throwable e) {
                        Debug.out(e);
                        return (false);
                    }
                }

                @Override
                public void unload() throws PluginException {
                    synchronized (browse_plugins) {
                        browse_plugins.remove(dm);
                    }
                    super.unload();
                }
            };
            PluginManager.registerPlugin(plugin, plugin_id, plugin_id);
            browse_plugins.put(dm, plugin);
            if (launch) {
                return (null);
            } else {
                waiter.reserve(10 * 1000);
                synchronized (url_holder) {
                    return (url_holder[0]);
                }
            }
        } else {
            String protocol = plugin.getProtocol();
            InetAddress bind_ip = plugin.getServerBindIP();
            String host;
            if (bind_ip.isAnyLocalAddress()) {
                host = "127.0.0.1";
            } else {
                host = bind_ip.getHostAddress();
            }
            String url = protocol + "://" + host + ":" + plugin.getServerPort() + "/" + url_suffix;
            if (launch) {
                Utils.launch(url, false, true, anon);
                return (null);
            } else {
                return (url);
            }
        }
    }
}
Also used : TrackerWebPageRequest(com.biglybt.pif.tracker.web.TrackerWebPageRequest) TrackerWebPageResponse(com.biglybt.pif.tracker.web.TrackerWebPageResponse) DownloadManager(com.biglybt.core.download.DownloadManager) GlobalManager(com.biglybt.core.global.GlobalManager) DiskManagerListener(com.biglybt.pif.disk.DiskManagerListener) UIFunctions(com.biglybt.ui.UIFunctions) DiskManagerChannel(com.biglybt.pif.disk.DiskManagerChannel) PluginException(com.biglybt.pif.PluginException) DiskManagerFileInfoSet(com.biglybt.core.disk.DiskManagerFileInfoSet) TOTorrentFile(com.biglybt.core.torrent.TOTorrentFile) TOTorrentFile(com.biglybt.core.torrent.TOTorrentFile) InetAddress(java.net.InetAddress) DiskManagerFileInfoSet(com.biglybt.core.disk.DiskManagerFileInfoSet) URL(java.net.URL) TorrentOpenOptions(com.biglybt.core.torrent.impl.TorrentOpenOptions) PooledByteBuffer(com.biglybt.pif.utils.PooledByteBuffer) WebPlugin(com.biglybt.ui.webplugin.WebPlugin) DiskManagerFileInfo(com.biglybt.core.disk.DiskManagerFileInfo) DiskManagerRequest(com.biglybt.pif.disk.DiskManagerRequest) PluginInterface(com.biglybt.pif.PluginInterface) FormattersImpl(com.biglybt.pifimpl.local.utils.FormattersImpl) URLConnection(java.net.URLConnection) TOTorrent(com.biglybt.core.torrent.TOTorrent) DiskManagerEvent(com.biglybt.pif.disk.DiskManagerEvent)

Example 2 with PooledByteBuffer

use of com.biglybt.pif.utils.PooledByteBuffer in project BiglyBT by BiglySoftware.

the class DiskManagerFileInfoURL method download.

public void download() {
    synchronized (lock) {
        if (file_cached) {
            return;
        }
        try {
            channel chan = createChannel();
            channel.request req = chan.createRequest();
            req.setAll();
            final FileOutputStream fos = new FileOutputStream(file);
            boolean ok = false;
            try {
                req.addListener(new DiskManagerListener() {

                    @Override
                    public void eventOccurred(DiskManagerEvent event) {
                        if (event.getType() == DiskManagerEvent.EVENT_TYPE_FAILED) {
                            throw (new RuntimeException(event.getFailure()));
                        }
                        PooledByteBuffer buffer = event.getBuffer();
                        if (buffer == null) {
                            throw (new RuntimeException("eh?"));
                        }
                        try {
                            fos.write(buffer.toByteArray());
                        } catch (IOException e) {
                            throw (new RuntimeException("Failed to write to " + file, e));
                        } finally {
                            buffer.returnToPool();
                        }
                    }
                });
                req.run();
                ok = true;
            } finally {
                try {
                    fos.close();
                } catch (Throwable e) {
                    Debug.out(e);
                }
                if (!ok) {
                    file.delete();
                } else {
                    file_cached = true;
                }
            }
        } catch (Throwable e) {
            Debug.out("Failed to cache file from " + url, e);
        }
    }
}
Also used : FileOutputStream(java.io.FileOutputStream) PooledByteBuffer(com.biglybt.pif.utils.PooledByteBuffer) IOException(java.io.IOException)

Example 3 with PooledByteBuffer

use of com.biglybt.pif.utils.PooledByteBuffer in project BiglyBT by BiglySoftware.

the class Utils method quickViewRAR.

private static void quickViewRAR(final DiskManagerFileInfo file) {
    boolean went_async = false;
    try {
        final com.biglybt.pif.disk.DiskManagerFileInfo plugin_file = PluginCoreUtils.wrap(file);
        final RARTOCDecoder decoder = new RARTOCDecoder(new RARTOCDecoder.DataProvider() {

            private long file_position;

            private long file_size = file.getLength();

            @Override
            public int read(final byte[] buffer) throws IOException {
                long read_from = file_position;
                int read_length = buffer.length;
                long read_to = Math.min(file_size, read_from + read_length);
                read_length = (int) (read_to - read_from);
                if (read_length <= 0) {
                    return (-1);
                }
                final int f_read_length = read_length;
                try {
                    final AESemaphore sem = new AESemaphore("rarwait");
                    final Object[] result = { null };
                    plugin_file.createRandomReadRequest(read_from, read_length, false, new DiskManagerListener() {

                        private int buffer_pos;

                        @Override
                        public void eventOccurred(DiskManagerEvent event) {
                            int event_type = event.getType();
                            if (event_type == DiskManagerEvent.EVENT_TYPE_SUCCESS) {
                                PooledByteBuffer pooled_buffer = event.getBuffer();
                                try {
                                    byte[] data = pooled_buffer.toByteArray();
                                    System.arraycopy(data, 0, buffer, buffer_pos, data.length);
                                    buffer_pos += data.length;
                                    if (buffer_pos == f_read_length) {
                                        sem.release();
                                    }
                                } finally {
                                    pooled_buffer.returnToPool();
                                }
                            } else if (event_type == DiskManagerEvent.EVENT_TYPE_FAILED) {
                                result[0] = event.getFailure();
                                sem.release();
                            }
                        }
                    });
                    sem.reserve();
                    if (result[0] instanceof Throwable) {
                        throw ((Throwable) result[0]);
                    }
                    file_position += read_length;
                    return (read_length);
                } catch (Throwable e) {
                    throw (new IOException("read failed: " + Debug.getNestedExceptionMessage(e)));
                }
            }

            @Override
            public void skip(long bytes) throws IOException {
                file_position += bytes;
            }
        });
        new AEThread2("rardecoder") {

            @Override
            public void run() {
                try {
                    decoder.analyse(new RARTOCDecoder.TOCResultHandler() {

                        private TextViewerWindow viewer;

                        private List<String> lines = new ArrayList<>();

                        private int pw_entries = 0;

                        private int pw_text = 0;

                        private volatile boolean abandon = false;

                        @Override
                        public void entryRead(final String name, final long size, final boolean password) throws IOException {
                            if (abandon) {
                                throw (new IOException("Operation abandoned"));
                            }
                            String line = name + ":    " + DisplayFormatters.formatByteCountToKiBEtc(size);
                            if (password) {
                                line += "    **** password protected ****";
                                pw_entries++;
                            }
                            if (password || name.toLowerCase().contains("password")) {
                                line = "*\t" + line;
                                pw_text++;
                            } else {
                                line = " \t" + line;
                            }
                            appendLine(line, false);
                        }

                        @Override
                        public void complete() {
                            appendLine("Done", true);
                        }

                        @Override
                        public void failed(IOException error) {
                            appendLine("Failed: " + Debug.getNestedExceptionMessage(error), true);
                        }

                        private String getInfo() {
                            if (pw_entries > 0) {
                                return (pw_entries + " password protected file(s) found");
                            } else if (pw_text > 0) {
                                return (pw_text + " file(s) mentioning 'password' found");
                            }
                            return ("");
                        }

                        private void appendLine(final String line, final boolean complete) {
                            execSWTThread(new Runnable() {

                                @Override
                                public void run() {
                                    lines.add(line);
                                    StringBuilder content = new StringBuilder();
                                    for (String l : lines) {
                                        content.append(l).append("\r\n");
                                    }
                                    if (!complete) {
                                        content.append("processing...");
                                    } else {
                                        String info = getInfo();
                                        if (info.length() > 0) {
                                            content.append(info).append("\r\n");
                                        }
                                    }
                                    if (viewer == null) {
                                        final File target_file = file.getFile(true);
                                        DownloadManager dm = file.getDownloadManager();
                                        viewer = new TextViewerWindow(MessageText.getString("MainWindow.menu.quick_view") + ": " + target_file.getName(), MessageText.getString("MainWindow.menu.quick_view.msg", new String[] { target_file.getName(), dm.getDisplayName() }), content.toString(), false);
                                    } else {
                                        if (viewer.isDisposed()) {
                                            abandon = true;
                                        } else {
                                            viewer.setText(content.toString());
                                        }
                                    }
                                }
                            });
                        }
                    });
                } catch (Throwable e) {
                    Debug.out(e);
                } finally {
                    synchronized (quick_view_active) {
                        quick_view_active.remove(file);
                    }
                }
            }
        }.start();
        went_async = true;
    } catch (Throwable e) {
        Debug.out(e);
    } finally {
        if (!went_async) {
            synchronized (quick_view_active) {
                quick_view_active.remove(file);
            }
        }
    }
}
Also used : DownloadManager(com.biglybt.core.download.DownloadManager) DiskManagerListener(com.biglybt.pif.disk.DiskManagerListener) PooledByteBuffer(com.biglybt.pif.utils.PooledByteBuffer) List(java.util.List) SWTRunnable(com.biglybt.ui.swt.utils.SWTRunnable) DiskManagerEvent(com.biglybt.pif.disk.DiskManagerEvent)

Example 4 with PooledByteBuffer

use of com.biglybt.pif.utils.PooledByteBuffer in project BiglyBT by BiglySoftware.

the class SESTSConnectionImpl method sendContent.

protected void sendContent(PooledByteBuffer message) throws MessageException {
    if (outgoing_cipher != null) {
        try {
            byte[] plain = message.toByteArray();
            byte[] enc = outgoing_cipher.doFinal(plain);
            PooledByteBuffer temp = new PooledByteBufferImpl(enc);
            try {
                connection.send(temp);
                // successfull send -> release caller's buffer
                message.returnToPool();
            } catch (Throwable e) {
                // failed semantics are to not release the caller's buffer
                temp.returnToPool();
                throw (e);
            }
        } catch (Throwable e) {
            throw (new MessageException("Failed to encrypt data", e));
        }
    } else {
        if (block_crypto != SESecurityManager.BLOCK_ENCRYPTION_NONE) {
            connection.close();
            throw (new MessageException("Crypto isn't setup"));
        }
        connection.send(message);
    }
}
Also used : PooledByteBufferImpl(com.biglybt.pifimpl.local.utils.PooledByteBufferImpl) MessageException(com.biglybt.pif.messaging.MessageException) PooledByteBuffer(com.biglybt.pif.utils.PooledByteBuffer)

Example 5 with PooledByteBuffer

use of com.biglybt.pif.utils.PooledByteBuffer in project BiglyBT by BiglySoftware.

the class SESTSConnectionImpl method receiveContent.

protected void receiveContent(PooledByteBuffer message) throws MessageException {
    boolean buffer_handled = false;
    try {
        if (incoming_cipher != null) {
            try {
                byte[] enc = message.toByteArray();
                byte[] plain = incoming_cipher.doFinal(enc);
                PooledByteBuffer temp = new PooledByteBufferImpl(plain);
                message.returnToPool();
                buffer_handled = true;
                message = temp;
            } catch (Throwable e) {
                throw (new MessageException("Failed to decrypt data", e));
            }
        } else if (block_crypto != SESecurityManager.BLOCK_ENCRYPTION_NONE) {
            throw (new MessageException("Crypto isn't setup"));
        }
        List listeners_ref = listeners.getList();
        MessageException last_error = null;
        for (int i = 0; i < listeners_ref.size(); i++) {
            PooledByteBuffer message_to_deliver;
            if (i == 0) {
                message_to_deliver = message;
            } else {
                // unlikely we'll ever have > 1 receiver....
                message_to_deliver = new PooledByteBufferImpl(message.toByteArray());
            }
            try {
                ((GenericMessageConnectionListener) listeners_ref.get(i)).receive(this, message_to_deliver);
                if (message_to_deliver == message) {
                    buffer_handled = true;
                }
            } catch (Throwable e) {
                message_to_deliver.returnToPool();
                if (message_to_deliver == message) {
                    buffer_handled = true;
                }
                if (e instanceof MessageException) {
                    last_error = (MessageException) e;
                } else {
                    last_error = new MessageException("Failed to process message", e);
                }
            }
        }
        if (last_error != null) {
            throw (last_error);
        }
    } finally {
        if (!buffer_handled) {
            message.returnToPool();
        }
    }
}
Also used : GenericMessageConnectionListener(com.biglybt.pif.messaging.generic.GenericMessageConnectionListener) PooledByteBufferImpl(com.biglybt.pifimpl.local.utils.PooledByteBufferImpl) MessageException(com.biglybt.pif.messaging.MessageException) PooledByteBuffer(com.biglybt.pif.utils.PooledByteBuffer) ArrayList(java.util.ArrayList) List(java.util.List) GenericMessageEndpoint(com.biglybt.pif.messaging.generic.GenericMessageEndpoint)

Aggregations

PooledByteBuffer (com.biglybt.pif.utils.PooledByteBuffer)8 MessageException (com.biglybt.pif.messaging.MessageException)4 PooledByteBufferImpl (com.biglybt.pifimpl.local.utils.PooledByteBufferImpl)4 DiskManagerEvent (com.biglybt.pif.disk.DiskManagerEvent)3 DiskManagerListener (com.biglybt.pif.disk.DiskManagerListener)3 DownloadManager (com.biglybt.core.download.DownloadManager)2 DiskManagerChannel (com.biglybt.pif.disk.DiskManagerChannel)2 DiskManagerRequest (com.biglybt.pif.disk.DiskManagerRequest)2 GenericMessageConnectionListener (com.biglybt.pif.messaging.generic.GenericMessageConnectionListener)2 GenericMessageEndpoint (com.biglybt.pif.messaging.generic.GenericMessageEndpoint)2 URL (java.net.URL)2 List (java.util.List)2 DiskManagerFileInfo (com.biglybt.core.disk.DiskManagerFileInfo)1 DiskManagerFileInfoSet (com.biglybt.core.disk.DiskManagerFileInfoSet)1 DownloadManagerState (com.biglybt.core.download.DownloadManagerState)1 GlobalManager (com.biglybt.core.global.GlobalManager)1 PEPeerManager (com.biglybt.core.peer.PEPeerManager)1 TOTorrent (com.biglybt.core.torrent.TOTorrent)1 TOTorrentFile (com.biglybt.core.torrent.TOTorrentFile)1 TorrentOpenOptions (com.biglybt.core.torrent.impl.TorrentOpenOptions)1