Search in sources :

Example 1 with MagnetURIHandlerProgressListener

use of com.biglybt.net.magneturi.MagnetURIHandlerProgressListener in project BiglyBT by BiglySoftware.

the class MagnetPlugin method initialize.

@Override
public void initialize(PluginInterface _plugin_interface) {
    plugin_interface = _plugin_interface;
    MagnetURIHandler uri_handler = MagnetURIHandler.getSingleton();
    final LocaleUtilities lu = plugin_interface.getUtilities().getLocaleUtilities();
    lu.addListener(new LocaleListener() {

        @Override
        public void localeChanged(Locale l) {
            updateLocale(lu);
        }
    });
    updateLocale(lu);
    BasicPluginConfigModel config = plugin_interface.getUIManager().createBasicPluginConfigModel(ConfigSection.SECTION_PLUGINS, PLUGIN_CONFIGSECTION_ID);
    config.addInfoParameter2("MagnetPlugin.current.port", String.valueOf(uri_handler.getPort()));
    secondary_lookup = config.addBooleanParameter2("MagnetPlugin.use.lookup.service", "MagnetPlugin.use.lookup.service", true);
    md_lookup = config.addBooleanParameter2("MagnetPlugin.use.md.download", "MagnetPlugin.use.md.download", true);
    md_lookup_delay = config.addIntParameter2("MagnetPlugin.use.md.download.delay", "MagnetPlugin.use.md.download.delay", MD_LOOKUP_DELAY_SECS_DEFAULT);
    md_lookup.addEnabledOnSelection(md_lookup_delay);
    timeout_param = config.addIntParameter2("MagnetPlugin.timeout.secs", "MagnetPlugin.timeout.secs", PLUGIN_DOWNLOAD_TIMEOUT_SECS_DEFAULT);
    sources_param = config.addStringListParameter2("MagnetPlugin.add.sources", "MagnetPlugin.add.sources", SOURCE_VALUES, SOURCE_STRINGS, SOURCE_VALUES[1]);
    sources_extra_param = config.addIntParameter2("MagnetPlugin.add.sources.extra", "MagnetPlugin.add.sources.extra", 0);
    magnet_recovery = config.addBooleanParameter2("MagnetPlugin.recover.magnets", "MagnetPlugin.recover.magnets", true);
    Parameter[] nps = new Parameter[AENetworkClassifier.AT_NETWORKS.length];
    for (int i = 0; i < nps.length; i++) {
        String nn = AENetworkClassifier.AT_NETWORKS[i];
        String config_name = "Network Selection Default." + nn;
        String msg_text = "ConfigView.section.connection.networks." + nn;
        final BooleanParameter param = config.addBooleanParameter2(config_name, msg_text, COConfigurationManager.getBooleanParameter(config_name));
        COConfigurationManager.addParameterListener(config_name, new com.biglybt.core.config.ParameterListener() {

            @Override
            public void parameterChanged(String name) {
                param.setDefaultValue(COConfigurationManager.getBooleanParameter(name));
            }
        });
        nps[i] = param;
        net_params.put(nn, param);
    }
    config.createGroup("label.default.nets", nps);
    MenuItemListener listener = new MenuItemListener() {

        @Override
        public void selected(MenuItem _menu, Object _target) {
            TableRow[] rows = (TableRow[]) _target;
            String cb_all_data = "";
            for (TableRow row : rows) {
                Torrent torrent;
                String name;
                Object ds = row.getDataSource();
                Download download = null;
                ShareResource share = null;
                if (ds instanceof ShareResourceFile) {
                    ShareResourceFile sf = (ShareResourceFile) ds;
                    try {
                        torrent = sf.getItem().getTorrent();
                    } catch (ShareException e) {
                        continue;
                    }
                    name = sf.getName();
                    share = sf;
                } else if (ds instanceof ShareResourceDir) {
                    ShareResourceDir sd = (ShareResourceDir) ds;
                    try {
                        torrent = sd.getItem().getTorrent();
                    } catch (ShareException e) {
                        continue;
                    }
                    name = sd.getName();
                    share = sd;
                } else if (ds instanceof Download) {
                    download = (Download) ds;
                    torrent = download.getTorrent();
                    name = download.getName();
                } else {
                    continue;
                }
                boolean is_share = false;
                Set<String> networks = new HashSet<>();
                if (share != null) {
                    is_share = true;
                    Map<String, String> properties = share.getProperties();
                    if (properties != null) {
                        String nets = properties.get(ShareManager.PR_NETWORKS);
                        if (nets != null) {
                            String[] bits = nets.split(",");
                            for (String bit : bits) {
                                bit = AENetworkClassifier.internalise(bit.trim());
                                if (bit != null) {
                                    networks.add(bit);
                                }
                            }
                        }
                    }
                }
                if (download != null) {
                    TorrentAttribute ta = plugin_interface.getTorrentManager().getAttribute(TorrentAttribute.TA_NETWORKS);
                    String[] nets = download.getListAttribute(ta);
                    networks.addAll(Arrays.asList(nets));
                    try {
                        byte[] hash = download.getTorrentHash();
                        if (plugin_interface.getShareManager().lookupShare(hash) != null) {
                            is_share = true;
                        }
                    } catch (Throwable e) {
                    }
                }
                String cb_data = download == null ? UrlUtils.getMagnetURI(name, torrent) : UrlUtils.getMagnetURI(download);
                if (download != null) {
                    List<Tag> tags = TagManagerFactory.getTagManager().getTagsForTaggable(TagType.TT_DOWNLOAD_MANUAL, PluginCoreUtils.unwrap(download));
                    for (Tag tag : tags) {
                        if (tag.isPublic()) {
                            cb_data += "&tag=" + UrlUtils.encode(tag.getTagName(true));
                        }
                    }
                }
                String sources = sources_param.getValue();
                boolean add_sources = sources.equals("2") || (sources.equals("1") && is_share);
                if (add_sources) {
                    if (networks.isEmpty()) {
                        for (String net : AENetworkClassifier.AT_NETWORKS) {
                            if (isNetworkEnabled(net)) {
                                networks.add(net);
                            }
                        }
                    }
                    if (networks.contains(AENetworkClassifier.AT_PUBLIC) && !cb_data.contains("xsource=")) {
                        InetAddress ip = NetworkAdmin.getSingleton().getDefaultPublicAddress();
                        InetAddress ip_v6 = NetworkAdmin.getSingleton().getDefaultPublicAddressV6();
                        int port = TCPNetworkManager.getSingleton().getTCPListeningPortNumber();
                        if (ip != null && port > 0) {
                            cb_data += "&xsource=" + UrlUtils.encode(ip.getHostAddress() + ":" + port);
                        }
                        if (ip_v6 != null && port > 0) {
                            cb_data += "&xsource=" + UrlUtils.encode(ip_v6.getHostAddress() + ":" + port);
                        }
                        int extra = sources_extra_param.getValue();
                        if (extra > 0) {
                            if (download == null) {
                                if (torrent != null) {
                                    download = plugin_interface.getDownloadManager().getDownload(torrent);
                                }
                            }
                            if (download != null) {
                                Set<String> added = new HashSet<>();
                                DownloadManager dm = PluginCoreUtils.unwrap(download);
                                PEPeerManager pm = dm.getPeerManager();
                                if (pm != null) {
                                    List<PEPeer> peers = pm.getPeers();
                                    for (PEPeer peer : peers) {
                                        String peer_ip = peer.getIp();
                                        if (AENetworkClassifier.categoriseAddress(peer_ip) == AENetworkClassifier.AT_PUBLIC) {
                                            int peer_port = peer.getTCPListenPort();
                                            if (peer_port > 0) {
                                                cb_data += "&xsource=" + UrlUtils.encode(peer_ip + ":" + peer_port);
                                                added.add(peer_ip);
                                                extra--;
                                                if (extra == 0) {
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                                if (extra > 0) {
                                    Map response_cache = dm.getDownloadState().getTrackerResponseCache();
                                    if (response_cache != null) {
                                        List<TRTrackerAnnouncerResponsePeer> peers = TRTrackerAnnouncerFactory.getCachedPeers(response_cache);
                                        for (TRTrackerAnnouncerResponsePeer peer : peers) {
                                            String peer_ip = peer.getAddress();
                                            if (AENetworkClassifier.categoriseAddress(peer_ip) == AENetworkClassifier.AT_PUBLIC) {
                                                if (!added.contains(peer_ip)) {
                                                    int peer_port = peer.getPort();
                                                    if (peer_port > 0) {
                                                        cb_data += "&xsource=" + UrlUtils.encode(peer_ip + ":" + peer_port);
                                                        added.add(peer_ip);
                                                        extra--;
                                                        if (extra == 0) {
                                                            break;
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                // removed this as well - nothing wrong with allowing magnet copy
                // for private torrents - they still can't be tracked if you don't
                // have permission
                /*if ( torrent.isPrivate()){

							cb_data = getMessageText( "private_torrent" );

						}else if ( torrent.isDecentralised()){
						*/
                // ok
                /* relaxed this as we allow such torrents to be downloaded via magnet links
							 * (as opposed to tracked in the DHT)

						}else if ( torrent.isDecentralisedBackupEnabled()){

							TorrentAttribute ta_peer_sources 	= plugin_interface.getTorrentManager().getAttribute( TorrentAttribute.TA_PEER_SOURCES );

							String[]	sources = download.getListAttribute( ta_peer_sources );

							boolean	ok = false;

							for (int i=0;i<sources.length;i++){

								if ( sources[i].equalsIgnoreCase( "DHT")){

									ok	= true;

									break;
								}
							}

							if ( !ok ){

								cb_data = getMessageText( "decentral_disabled" );
							}
						}else{

							cb_data = getMessageText( "decentral_backup_disabled" );
							*/
                // }
                // System.out.println( "MagnetPlugin: export = " + url );
                cb_all_data += (cb_all_data.length() == 0 ? "" : "\n") + cb_data;
            }
            try {
                plugin_interface.getUIManager().copyToClipBoard(cb_all_data);
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }
    };
    List<TableContextMenuItem> menus = new ArrayList<>();
    for (String table : TableManager.TABLE_MYTORRENTS_ALL) {
        TableContextMenuItem menu = plugin_interface.getUIManager().getTableManager().addContextMenuItem(table, "MagnetPlugin.contextmenu.exporturi");
        menu.addMultiListener(listener);
        menu.setHeaderCategory(MenuItem.HEADER_SOCIAL);
        menus.add(menu);
    }
    uri_handler.addListener(new MagnetURIHandlerListener() {

        @Override
        public byte[] badge() {
            InputStream is = getClass().getClassLoader().getResourceAsStream("com/biglybt/plugin/magnet/Magnet.gif");
            if (is == null) {
                return (null);
            }
            try {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                try {
                    byte[] buffer = new byte[8192];
                    while (true) {
                        int len = is.read(buffer);
                        if (len <= 0) {
                            break;
                        }
                        baos.write(buffer, 0, len);
                    }
                } finally {
                    is.close();
                }
                return (baos.toByteArray());
            } catch (Throwable e) {
                Debug.printStackTrace(e);
                return (null);
            }
        }

        @Override
        public byte[] download(MagnetURIHandlerProgressListener muh_listener, byte[] hash, String args, InetSocketAddress[] sources, long timeout) throws MagnetURIHandlerException {
            try {
                Download dl = plugin_interface.getDownloadManager().getDownload(hash);
                if (dl != null) {
                    Torrent torrent = dl.getTorrent();
                    if (torrent != null) {
                        byte[] torrent_data = torrent.writeToBEncodedData();
                        torrent_data = addTrackersAndWebSeedsEtc(torrent_data, args, new HashSet<String>());
                        return (torrent_data);
                    }
                }
            } catch (Throwable e) {
                Debug.printStackTrace(e);
            }
            return (recoverableDownload(muh_listener, hash, args, sources, timeout, false));
        }

        @Override
        public boolean download(URL url) throws MagnetURIHandlerException {
            try {
                plugin_interface.getDownloadManager().addDownload(url, false);
                return (true);
            } catch (DownloadException e) {
                throw (new MagnetURIHandlerException("Operation failed", e));
            }
        }

        @Override
        public boolean set(String name, Map values) {
            List l = listeners.getList();
            for (int i = 0; i < l.size(); i++) {
                if (((MagnetPluginListener) l.get(i)).set(name, values)) {
                    return (true);
                }
            }
            return (false);
        }

        @Override
        public int get(String name, Map values) {
            List l = listeners.getList();
            for (int i = 0; i < l.size(); i++) {
                int res = ((MagnetPluginListener) l.get(i)).get(name, values);
                if (res != Integer.MIN_VALUE) {
                    return (res);
                }
            }
            return (Integer.MIN_VALUE);
        }
    });
    plugin_interface.getUIManager().addUIListener(new UIManagerListener() {

        @Override
        public void UIAttached(UIInstance instance) {
            if (instance.getUIType().equals(UIInstance.UIT_SWT)) {
                try {
                    Class.forName("com.biglybt.plugin.magnet.swt.MagnetPluginUISWT").getConstructor(new Class[] { UIInstance.class, TableContextMenuItem[].class }).newInstance(new Object[] { instance, menus.toArray(new TableContextMenuItem[menus.size()]) });
                } catch (Throwable e) {
                    e.printStackTrace();
                }
            }
        }

        @Override
        public void UIDetached(UIInstance instance) {
        }
    });
    final List<Download> to_delete = new ArrayList<>();
    Download[] downloads = plugin_interface.getDownloadManager().getDownloads();
    for (Download download : downloads) {
        if (download.getFlag(Download.FLAG_METADATA_DOWNLOAD)) {
            to_delete.add(download);
        }
    }
    final AESemaphore delete_done = new AESemaphore("delete waiter");
    if (to_delete.size() > 0) {
        AEThread2 t = new AEThread2("MagnetPlugin:delmds", true) {

            @Override
            public void run() {
                try {
                    for (Download download : to_delete) {
                        try {
                            download.stop();
                        } catch (Throwable e) {
                        }
                        try {
                            download.remove(true, true);
                        } catch (Throwable e) {
                            Debug.out(e);
                        }
                    }
                } finally {
                    delete_done.release();
                }
            }
        };
        t.start();
    } else {
        delete_done.release();
    }
    plugin_interface.addListener(new PluginListener() {

        @Override
        public void initializationComplete() {
            // make sure DDB is initialised as we need it to register its
            // transfer types
            AEThread2 t = new AEThread2("MagnetPlugin:init", true) {

                @Override
                public void run() {
                    delete_done.reserve();
                    recoverDownloads();
                    plugin_interface.getDistributedDatabase();
                }
            };
            t.start();
        }

        @Override
        public void closedownInitiated() {
        }

        @Override
        public void closedownComplete() {
        }
    });
}
Also used : Torrent(com.biglybt.pif.torrent.Torrent) TOTorrent(com.biglybt.core.torrent.TOTorrent) PEPeer(com.biglybt.core.peer.PEPeer) ShareResourceDir(com.biglybt.pif.sharing.ShareResourceDir) InetSocketAddress(java.net.InetSocketAddress) LocaleUtilities(com.biglybt.pif.utils.LocaleUtilities) DownloadManager(com.biglybt.core.download.DownloadManager) DownloadException(com.biglybt.pif.download.DownloadException) MenuItemListener(com.biglybt.pif.ui.menus.MenuItemListener) UIInstance(com.biglybt.pif.ui.UIInstance) MagnetURIHandler(com.biglybt.net.magneturi.MagnetURIHandler) TableRow(com.biglybt.pif.ui.tables.TableRow) PEPeerManager(com.biglybt.core.peer.PEPeerManager) InetAddress(java.net.InetAddress) ShareResourceFile(com.biglybt.pif.sharing.ShareResourceFile) MagnetURIHandlerProgressListener(com.biglybt.net.magneturi.MagnetURIHandlerProgressListener) TableContextMenuItem(com.biglybt.pif.ui.tables.TableContextMenuItem) URL(java.net.URL) PluginListener(com.biglybt.pif.PluginListener) ShareException(com.biglybt.pif.sharing.ShareException) LocaleListener(com.biglybt.pif.utils.LocaleListener) Download(com.biglybt.pif.download.Download) ShareResource(com.biglybt.pif.sharing.ShareResource) InputStream(java.io.InputStream) TableContextMenuItem(com.biglybt.pif.ui.tables.TableContextMenuItem) MenuItem(com.biglybt.pif.ui.menus.MenuItem) ByteArrayOutputStream(java.io.ByteArrayOutputStream) BooleanParameter(com.biglybt.pif.ui.config.BooleanParameter) TorrentAttribute(com.biglybt.pif.torrent.TorrentAttribute) BooleanParameter(com.biglybt.pif.ui.config.BooleanParameter) Parameter(com.biglybt.pif.ui.config.Parameter) StringListParameter(com.biglybt.pif.ui.config.StringListParameter) IntParameter(com.biglybt.pif.ui.config.IntParameter) TRTrackerAnnouncerResponsePeer(com.biglybt.core.tracker.client.TRTrackerAnnouncerResponsePeer) Tag(com.biglybt.core.tag.Tag) MagnetURIHandlerListener(com.biglybt.net.magneturi.MagnetURIHandlerListener) MagnetURIHandlerException(com.biglybt.net.magneturi.MagnetURIHandlerException) UIManagerListener(com.biglybt.pif.ui.UIManagerListener) BasicPluginConfigModel(com.biglybt.pif.ui.model.BasicPluginConfigModel)

Example 2 with MagnetURIHandlerProgressListener

use of com.biglybt.net.magneturi.MagnetURIHandlerProgressListener in project BiglyBT by BiglySoftware.

the class MagnetURIHandlerImpl method process.

protected boolean process(String get, BufferedReader is, OutputStream os) throws IOException {
    // System.out.println( "get = " + get );
    // magnet:?xt=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C
    Map<String, String> original_params = new HashMap<>();
    Map<String, String> lc_params = new HashMap<>();
    List<String> source_params = new ArrayList<>();
    int pos = get.indexOf('?');
    String arg_str;
    if (pos == -1) {
        arg_str = "";
    } else {
        arg_str = get.substring(pos + 1);
        pos = arg_str.lastIndexOf(' ');
        if (pos >= 0) {
            arg_str = arg_str.substring(0, pos).trim();
        }
        StringTokenizer tok = new StringTokenizer(arg_str, "&");
        if (DEBUG) {
            System.out.println("params:" + arg_str);
        }
        while (tok.hasMoreTokens()) {
            String arg = tok.nextToken();
            pos = arg.indexOf('=');
            if (pos == -1) {
                String lhs = arg.trim();
                original_params.put(lhs, "");
                lc_params.put(lhs.toLowerCase(MessageText.LOCALE_ENGLISH), "");
            } else {
                try {
                    String lhs = arg.substring(0, pos).trim();
                    String lc_lhs = lhs.toLowerCase(MessageText.LOCALE_ENGLISH);
                    String rhs = UrlUtils.decode(arg.substring(pos + 1).trim());
                    if (lc_lhs.equals("xt")) {
                        if (rhs.toLowerCase(MessageText.LOCALE_ENGLISH).startsWith("urn:btih:")) {
                            original_params.put(lhs, rhs);
                            lc_params.put(lhs, rhs);
                        } else {
                            String existing = lc_params.get("xt");
                            if (existing == null || (!existing.toLowerCase(MessageText.LOCALE_ENGLISH).startsWith("urn:btih:") && rhs.startsWith("urn:sha1:"))) {
                                original_params.put(lhs, rhs);
                                lc_params.put(lhs, rhs);
                            }
                        }
                    } else {
                        original_params.put(lhs, rhs);
                        lc_params.put(lc_lhs, rhs);
                        if (lc_lhs.equals("xsource")) {
                            source_params.add(rhs);
                        }
                    }
                } catch (Throwable e) {
                    Debug.printStackTrace(e);
                }
            }
        }
    }
    if (get.startsWith("/magnet10/badge.img")) {
        for (MagnetURIHandlerListener listener : listeners) {
            byte[] data = listener.badge();
            if (data != null) {
                writeReply(os, "image/gif", data);
                return (true);
            }
        }
        writeNotFound(os);
        return (true);
    } else if (get.startsWith("/magnet10/canHandle.img?")) {
        String urn = (String) lc_params.get("xt");
        if (urn != null && urn.toLowerCase(MessageText.LOCALE_ENGLISH).startsWith("urn:btih:")) {
            for (MagnetURIHandlerListener listener : listeners) {
                byte[] data = listener.badge();
                if (data != null) {
                    writeReply(os, "image/gif", data);
                    return (true);
                }
            }
        }
        writeNotFound(os);
        return (true);
    } else if (get.startsWith("/azversion")) {
        writeReply(os, "text/plain", Constants.AZUREUS_VERSION);
        return (true);
    } else if (get.startsWith("/magnet10/options.js?") || get.startsWith("/magnet10/default.js?")) {
        String resp = "";
        resp += getJS("magnetOptionsPreamble");
        resp += getJSS("<a href=\\\"http://127.0.0.1:\"+(45100+magnetCurrentSlot)+\"/select/?\"+magnetQueryString+\"\\\" target=\\\"_blank\\\">");
        resp += getJSS("<img src=\\\"http://127.0.0.1:\"+(45100+magnetCurrentSlot)+\"/magnet10/badge.img\\\">");
        resp += getJSS("Download with " + Constants.APP_NAME);
        resp += getJSS("</a>");
        resp += getJS("magnetOptionsPostamble");
        resp += "magnetOptionsPollSuccesses++";
        writeReply(os, "application/x-javascript", resp);
        return (true);
    } else if (get.startsWith("/magnet10/pause")) {
        try {
            Thread.sleep(250);
        } catch (Throwable e) {
        }
        writeNotFound(os);
        return (true);
    } else if (get.startsWith("/select/")) {
        String fail_reason = "";
        boolean ok = false;
        String urn = (String) lc_params.get("xt");
        if (urn == null) {
            fail_reason = "xt missing";
        } else {
            String lc_urn = urn.toLowerCase(MessageText.LOCALE_ENGLISH);
            try {
                URL url;
                if (lc_urn.startsWith("http:") || lc_urn.startsWith("https:")) {
                    url = new URL(urn);
                } else {
                    url = new URL("magnet:?xt=" + urn);
                }
                for (MagnetURIHandlerListener listener : listeners) {
                    if (listener.download(url)) {
                        ok = true;
                        break;
                    }
                }
                if (!ok) {
                    fail_reason = "No listeners accepted the operation";
                }
            } catch (Throwable e) {
                Debug.printStackTrace(e);
                fail_reason = Debug.getNestedExceptionMessage(e);
            }
        }
        if (ok) {
            if ("image".equalsIgnoreCase((String) lc_params.get("result"))) {
                for (MagnetURIHandlerListener listener : listeners) {
                    byte[] data = listener.badge();
                    if (data != null) {
                        writeReply(os, "image/gif", data);
                        return (true);
                    }
                }
            }
            writeReply(os, "text/plain", "Download initiated");
        } else {
            writeReply(os, "text/plain", "Download initiation failed: " + fail_reason);
        }
    } else if (get.startsWith("/download/")) {
        final PrintWriter pw = new PrintWriter(new OutputStreamWriter(os, "UTF-8"));
        try {
            pw.print("HTTP/1.0 200 OK" + NL);
            pw.flush();
            String urn = (String) lc_params.get("xt");
            if (urn == null || !(urn.toLowerCase(MessageText.LOCALE_ENGLISH).startsWith("urn:sha1:") || urn.toLowerCase(MessageText.LOCALE_ENGLISH).startsWith("urn:btih:"))) {
                if (Logger.isEnabled())
                    Logger.log(new LogEvent(LOGID, LogEvent.LT_WARNING, "MagnetURIHandler: " + "invalid command - '" + get + "'"));
                throw (new IOException("Invalid magnet URI - no urn:sha1 or urn:btih argument supplied."));
            }
            String encoded = urn.substring(9);
            List<InetSocketAddress> sources = new ArrayList<>();
            for (int i = 0; i < source_params.size(); i++) {
                String source = (String) source_params.get(i);
                int p = source.indexOf(':');
                if (p != -1) {
                    try {
                        String host = source.substring(0, p);
                        int port = Integer.parseInt(source.substring(p + 1));
                        if (host.startsWith("/")) {
                            host = host.substring(1);
                        }
                        InetSocketAddress sa = new InetSocketAddress(host, port);
                        sources.add(sa);
                    } catch (Throwable e) {
                        Debug.printStackTrace(e);
                    }
                }
            }
            final InetSocketAddress[] s = sources.toArray(new InetSocketAddress[sources.size()]);
            if (Logger.isEnabled())
                Logger.log(new LogEvent(LOGID, "MagnetURIHandler: download of '" + encoded + "' starts (initial sources=" + s.length + ")"));
            byte[] _sha1 = UrlUtils.decodeSHA1Hash(encoded);
            if (_sha1 == null) {
                // dummy to still allow &fl links to work...
                _sha1 = new byte[20];
            // throw( new Exception( "Invalid info hash '" + encoded + "'" ));
            }
            final byte[] sha1 = _sha1;
            byte[] data = null;
            String verbose_str = lc_params.get("verbose");
            final boolean verbose = verbose_str != null && verbose_str.equalsIgnoreCase("true");
            final boolean[] cancel = { false };
            TimerEventPeriodic keep_alive = SimpleTimer.addPeriodicEvent("MURI:keepalive", 5000, new TimerEventPerformer() {

                @Override
                public void perform(TimerEvent event) {
                    pw.print("X-KeepAlive: YEAH!" + NL);
                    boolean failed = pw.checkError();
                    if (failed) {
                        synchronized (cancel) {
                            cancel[0] = true;
                        }
                    }
                }
            });
            try {
                final String f_arg_str = arg_str;
                final byte[][] f_data = { null };
                final Throwable[] f_error = { null };
                final AESemaphore wait_sem = new AESemaphore("download-waiter");
                List<Runnable> tasks = new ArrayList<>();
                for (final MagnetURIHandlerListener listener : listeners) {
                    tasks.add(new Runnable() {

                        @Override
                        public void run() {
                            try {
                                byte[] data = listener.download(new MagnetURIHandlerProgressListener() {

                                    @Override
                                    public void reportSize(long size) {
                                        pw.print("X-Report: " + getMessageText("torrent_size", String.valueOf(size)) + NL);
                                        pw.flush();
                                    }

                                    @Override
                                    public void reportActivity(String str) {
                                        pw.print("X-Report: " + str + NL);
                                        pw.flush();
                                    }

                                    @Override
                                    public void reportCompleteness(int percent) {
                                        pw.print("X-Report: " + getMessageText("percent", String.valueOf(percent)) + NL);
                                        pw.flush();
                                    }

                                    @Override
                                    public boolean verbose() {
                                        return (verbose);
                                    }

                                    @Override
                                    public boolean cancelled() {
                                        synchronized (cancel) {
                                            if (cancel[0]) {
                                                return (true);
                                            }
                                        }
                                        synchronized (f_data) {
                                            return (f_data[0] != null);
                                        }
                                    }
                                }, sha1, f_arg_str, s, DOWNLOAD_TIMEOUT);
                                synchronized (f_data) {
                                    if (data != null) {
                                        if (f_data[0] == null) {
                                            f_data[0] = data;
                                        }
                                    }
                                }
                            } catch (Throwable e) {
                                synchronized (f_data) {
                                    f_error[0] = e;
                                }
                            } finally {
                                wait_sem.release();
                            }
                        }
                    });
                }
                if (tasks.size() > 0) {
                    if (tasks.size() == 1) {
                        tasks.get(0).run();
                    } else {
                        for (final Runnable task : tasks) {
                            new AEThread2("MUH:dasync") {

                                @Override
                                public void run() {
                                    task.run();
                                }
                            }.start();
                        }
                        for (int i = 0; i < tasks.size(); i++) {
                            wait_sem.reserve();
                        }
                    }
                    synchronized (f_data) {
                        data = f_data[0];
                        if (data == null) {
                            if (f_error[0] != null) {
                                throw (f_error[0]);
                            }
                        }
                    }
                }
            } finally {
                keep_alive.cancel();
            }
            if (Logger.isEnabled())
                Logger.log(new LogEvent(LOGID, "MagnetURIHandler: download of '" + encoded + "' completes, data " + (data == null ? "not found" : ("found, length = " + data.length))));
            if (data != null) {
                pw.print("Content-Length: " + data.length + NL + NL);
                pw.flush();
                os.write(data);
                os.flush();
            } else {
                // HACK: don't change the "error:" message below, it is used by TorrentDownloader to detect this
                // condition
                pw.print("X-Report: error: " + getMessageText("no_sources") + NL);
                pw.flush();
                return (!lc_params.containsKey("pause_on_error"));
            }
        } catch (Throwable e) {
            // don't remove the "error:" (see above)
            pw.print("X-Report: error: " + getMessageText("error", Debug.getNestedExceptionMessage(e)) + NL);
            pw.flush();
            return (!lc_params.containsKey("pause_on_error"));
        }
    } else if (get.startsWith("/getinfo?")) {
        String name = (String) lc_params.get("name");
        if (name != null) {
            Integer info = (Integer) info_map.get(name);
            int value = Integer.MIN_VALUE;
            if (info != null) {
                value = info.intValue();
            } else {
                for (MagnetURIHandlerListener listener : listeners) {
                    // no idea why we copy, but let's keep doing so
                    HashMap paramsCopy = new HashMap();
                    paramsCopy.putAll(original_params);
                    value = listener.get(name, paramsCopy);
                    if (value != Integer.MIN_VALUE) {
                        break;
                    }
                }
            }
            if (value == Integer.MIN_VALUE) {
                // no value, see if we have a default
                String def_str = (String) lc_params.get("default");
                if (def_str != null) {
                    try {
                        value = Integer.parseInt(def_str);
                    } catch (Throwable e) {
                        Debug.printStackTrace(e);
                    }
                }
            } else {
                // have a value, see if we have a max
                String max_str = (String) lc_params.get("max");
                if (max_str != null) {
                    try {
                        int max = Integer.parseInt(max_str);
                        if (value > max) {
                            value = max;
                        }
                    } catch (Throwable e) {
                        Debug.printStackTrace(e);
                    }
                }
            }
            if (value != Integer.MIN_VALUE) {
                if (value < 0) {
                    value = 0;
                }
                if (value > 1024 * 1024) {
                    value = 1024 * 1024;
                }
                // see if we need to div/mod for clients that don't support huge images
                // e.g. http://localhost:45100/getinfo?name=Plugin.azupnpav.content_port&mod=8
                int width = value;
                int height = 1;
                // divmod -> encode div+1 as width, mod+1 as height
                String div_mod = (String) lc_params.get("divmod");
                if (div_mod != null) {
                    int n = Integer.parseInt(div_mod);
                    width = (value / n) + 1;
                    height = (value % n) + 1;
                } else {
                    String div = (String) lc_params.get("div");
                    if (div != null) {
                        width = value / Integer.parseInt(div);
                    } else {
                        String mod = (String) lc_params.get("mod");
                        if (mod != null) {
                            width = value % Integer.parseInt(mod);
                        }
                    }
                }
                String img_type = (String) lc_params.get("img_type");
                if (img_type != null && img_type.equals("png")) {
                    byte[] data = PNG.getPNGBytesForSize(width, height);
                    writeReply(os, "image/png", data);
                } else {
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    writeImage(baos, width, height);
                    byte[] data = baos.toByteArray();
                    writeReply(os, "image/bmp", data);
                }
                return (true);
            }
        }
        writeNotFound(os);
        return (true);
    } else if (get.startsWith("/setinfo?")) {
        String name = (String) lc_params.get("name");
        if (name != null) {
            boolean result = false;
            for (MagnetURIHandlerListener listener : listeners) {
                // no idea why we copy, but let's keep on doing so
                HashMap paramsCopy = new HashMap();
                paramsCopy.putAll(original_params);
                result = listener.set(name, paramsCopy);
                if (result) {
                    break;
                }
            }
            int width = result ? 20 : 10;
            int height = result ? 20 : 10;
            String img_type = (String) lc_params.get("img_type");
            if (img_type != null && img_type.equals("png")) {
                byte[] data = PNG.getPNGBytesForSize(width, height);
                writeReply(os, "image/png", data);
            } else {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                writeImage(baos, width, height);
                byte[] data = baos.toByteArray();
                writeReply(os, "image/bmp", data);
            }
            return (true);
        }
    } else if (get.equals("/browserheaders.js")) {
        String headers_str = "";
        while (true) {
            String header = is.readLine();
            if (header == null) {
                break;
            }
            header = header.trim();
            if (header.length() == 0) {
                break;
            }
            headers_str += (headers_str.length() == 0 ? "" : "\n") + header;
        }
        String script = "var headers = \"" + new String(Base64.encode(headers_str.getBytes("UTF-8"))) + "\";";
        writeReply(os, "application/x-javascript", script);
    } else if (get.startsWith("/resource.")) {
        String rid = lc_params.get("rid");
        ResourceProvider provider;
        synchronized (resources) {
            provider = resources.get(rid);
        }
        if (provider != null) {
            byte[] data = provider.getData();
            if (data != null) {
                writeReply(os, HTTPUtils.guessContentTypeFromFileType(provider.getFileType()), data);
            } else {
                writeNotFound(os);
            }
        } else {
            writeNotFound(os);
        }
    }
    return (true);
}
Also used : MagnetURIHandlerProgressListener(com.biglybt.net.magneturi.MagnetURIHandlerProgressListener) LogEvent(com.biglybt.core.logging.LogEvent) MagnetURIHandlerListener(com.biglybt.net.magneturi.MagnetURIHandlerListener)

Aggregations

MagnetURIHandlerListener (com.biglybt.net.magneturi.MagnetURIHandlerListener)2 MagnetURIHandlerProgressListener (com.biglybt.net.magneturi.MagnetURIHandlerProgressListener)2 DownloadManager (com.biglybt.core.download.DownloadManager)1 LogEvent (com.biglybt.core.logging.LogEvent)1 PEPeer (com.biglybt.core.peer.PEPeer)1 PEPeerManager (com.biglybt.core.peer.PEPeerManager)1 Tag (com.biglybt.core.tag.Tag)1 TOTorrent (com.biglybt.core.torrent.TOTorrent)1 TRTrackerAnnouncerResponsePeer (com.biglybt.core.tracker.client.TRTrackerAnnouncerResponsePeer)1 MagnetURIHandler (com.biglybt.net.magneturi.MagnetURIHandler)1 MagnetURIHandlerException (com.biglybt.net.magneturi.MagnetURIHandlerException)1 PluginListener (com.biglybt.pif.PluginListener)1 Download (com.biglybt.pif.download.Download)1 DownloadException (com.biglybt.pif.download.DownloadException)1 ShareException (com.biglybt.pif.sharing.ShareException)1 ShareResource (com.biglybt.pif.sharing.ShareResource)1 ShareResourceDir (com.biglybt.pif.sharing.ShareResourceDir)1 ShareResourceFile (com.biglybt.pif.sharing.ShareResourceFile)1 Torrent (com.biglybt.pif.torrent.Torrent)1 TorrentAttribute (com.biglybt.pif.torrent.TorrentAttribute)1