Search in sources :

Example 11 with ResourceDownloaderException

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

the class ResourceDownloaderMetaRefreshImpl method completed.

@Override
public boolean completed(ResourceDownloader downloader, InputStream data) {
    boolean complete = false;
    try {
        if (done_count == 1) {
            // assumption is that there is a refresh tag
            boolean marked = false;
            if (data.markSupported()) {
                data.mark(data.available());
                marked = true;
            }
            // leave file open if marked so we can recover
            HTMLPage page = HTMLPageFactory.loadPage(data, !marked);
            URL base_url = (URL) downloader.getProperty("URL_URL");
            URL redirect = page.getMetaRefreshURL(base_url);
            if (redirect == null) {
                if (!marked) {
                    failed(downloader, new ResourceDownloaderException(this, "meta refresh tag not found and input stream not recoverable"));
                } else {
                    data.reset();
                    complete = true;
                }
            } else {
                current_delegate = new ResourceDownloaderURLImpl(this, redirect);
                // informActivity( "meta-refresh -> " + current_delegate.getName());
                asyncDownload();
            }
            if (marked && !complete) {
                data.close();
            }
        } else {
            complete = true;
        }
        if (complete) {
            if (informComplete(data)) {
                result = data;
                done_sem.release();
            }
        }
    } catch (Throwable e) {
        failed(downloader, new ResourceDownloaderException(this, "meta-refresh processing fails", e));
    }
    return (true);
}
Also used : HTMLPage(com.biglybt.core.html.HTMLPage) ResourceDownloaderException(com.biglybt.pif.utils.resourcedownloader.ResourceDownloaderException) URL(java.net.URL)

Example 12 with ResourceDownloaderException

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

the class ResourceDownloaderTimeoutImpl method asyncDownload.

@Override
public void asyncDownload() {
    try {
        this_mon.enter();
        if (!cancelled) {
            current_downloader = delegate.getClone(this);
            informActivity(getLogIndent() + "Downloading: " + getName());
            current_downloader.addListener(this);
            current_downloader.asyncDownload();
            Thread t = new AEThread("ResourceDownloaderTimeout") {

                @Override
                public void runSupport() {
                    try {
                        Thread.sleep(timeout_millis);
                        cancel(new ResourceDownloaderException(ResourceDownloaderTimeoutImpl.this, "Download timeout"));
                    } catch (Throwable e) {
                        Debug.printStackTrace(e);
                    }
                }
            };
            t.setDaemon(true);
            t.start();
        }
    } finally {
        this_mon.exit();
    }
}
Also used : ResourceDownloaderException(com.biglybt.pif.utils.resourcedownloader.ResourceDownloaderException) AEThread(com.biglybt.core.util.AEThread) AEThread(com.biglybt.core.util.AEThread)

Example 13 with ResourceDownloaderException

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

the class ResourceDownloaderTorrentImpl method downloadSucceeded.

protected void downloadSucceeded(Download download, File torrent_file, File data_dir) {
    synchronized (this) {
        if (completed) {
            return;
        }
        completed = true;
    }
    reportActivity("Torrent download complete");
    // assumption is that this is a SIMPLE torrent
    File target_file = new File(data_dir, new String(torrent_holder[0].getFiles()[0].getPathComponents()[0]));
    if (!target_file.exists()) {
        File actual_target_file = new File(download.getSavePath());
        try {
            if (download_dir != null && actual_target_file.exists()) {
                FileUtil.copyFile(actual_target_file, target_file);
            }
        } catch (Throwable e) {
            Debug.printStackTrace(e);
        }
        target_file = actual_target_file;
    }
    try {
        if (!target_file.exists()) {
            throw (new Exception("File '" + target_file.toString() + "' not found"));
        }
        InputStream data = new FileInputStream(target_file);
        informComplete(data);
        result = data;
        done_sem.release();
    } catch (Throwable e) {
        Debug.printStackTrace(e);
        failed(this, new ResourceDownloaderException(this, "Failed to read downloaded torrent data: " + e.getMessage(), e));
    }
}
Also used : FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) ResourceDownloaderException(com.biglybt.pif.utils.resourcedownloader.ResourceDownloaderException) File(java.io.File) TOTorrentException(com.biglybt.core.torrent.TOTorrentException) IOException(java.io.IOException) ResourceDownloaderException(com.biglybt.pif.utils.resourcedownloader.ResourceDownloaderException) ResourceDownloaderCancelledException(com.biglybt.pif.utils.resourcedownloader.ResourceDownloaderCancelledException) FileInputStream(java.io.FileInputStream)

Example 14 with ResourceDownloaderException

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

the class ResourceDownloaderTorrentImpl method downloadTorrent.

protected void downloadTorrent() {
    try {
        String name = new String(torrent_holder[0].getName(), Constants.DEFAULT_ENCODING);
        informActivity(getLogIndent() + "Downloading: " + name);
        // we *don't* want this temporary file to be deleted automatically as we're
        // going to use it across the client restarts to hold the download data and
        // to seed it afterwards. Therefore we don't use AETemporaryFileHandler.createTempFile!!!!
        final File torrent_file = AETemporaryFileHandler.createSemiTempFile(name + ".torrent");
        if (download_dir != null && !download_dir.exists()) {
            FileUtil.mkdirs(download_dir);
        }
        final File data_dir = download_dir == null ? torrent_file.getParentFile() : download_dir;
        final TOTorrent torrent = torrent_holder[0];
        TorrentUtils.setFlag(torrent, TorrentUtils.TORRENT_FLAG_LOW_NOISE, true);
        boolean anon = isAnonymous();
        torrent.serialiseToBEncodedFile(torrent_file);
        try {
            Download existing = download_manager.getDownload(torrent.getHash());
            if (existing != null) {
                int existing_state = existing.getState();
                if (existing_state == Download.ST_ERROR || existing_state == Download.ST_STOPPED) {
                    informActivity(getLogIndent() + "Deleting existing stopped/error state download for " + name);
                    existing.remove(true, true);
                }
            }
        } catch (Throwable e) {
        }
        DownloadWillBeAddedListener dwbal = null;
        try {
            Torrent t = new TorrentImpl(torrent);
            if (anon) {
                dwbal = new DownloadWillBeAddedListener() {

                    @Override
                    public void initialised(Download download) {
                        try {
                            if (Arrays.equals(download.getTorrentHash(), torrent.getHash())) {
                                PluginCoreUtils.unwrap(download).getDownloadState().setNetworks(AENetworkClassifier.AT_NON_PUBLIC);
                            }
                        } catch (Throwable e) {
                            Debug.out(e);
                        }
                    }
                };
                download_manager.addDownloadWillBeAddedListener(dwbal);
            } else {
                // if torrent includes i2p url and i2p installed then enable network
                Set<String> hosts = TorrentUtils.getUniqueTrackerHosts(torrent);
                boolean has_i2p = false;
                for (String host : hosts) {
                    if (AENetworkClassifier.categoriseAddress(host) == AENetworkClassifier.AT_I2P) {
                        has_i2p = true;
                    }
                }
                if (has_i2p && I2PHelpers.isI2PInstalled()) {
                    dwbal = new DownloadWillBeAddedListener() {

                        @Override
                        public void initialised(Download download) {
                            try {
                                if (Arrays.equals(download.getTorrentHash(), torrent.getHash())) {
                                    PluginCoreUtils.unwrap(download).getDownloadState().setNetworks(new String[] { AENetworkClassifier.AT_PUBLIC, AENetworkClassifier.AT_I2P });
                                }
                            } catch (Throwable e) {
                                Debug.out(e);
                            }
                        }
                    };
                    download_manager.addDownloadWillBeAddedListener(dwbal);
                }
            }
            if (persistent) {
                download = download_manager.addDownload(t, torrent_file, data_dir);
            } else {
                download = download_manager.addNonPersistentDownload(t, torrent_file, data_dir);
            }
        } finally {
            if (dwbal != null) {
                download_manager.removeDownloadWillBeAddedListener(dwbal);
            }
        }
        download.moveTo(1);
        download.setForceStart(true);
        // Prevents any move-on-completion or move-on-removal behaviour happening.
        download.setFlag(Download.FLAG_DISABLE_AUTO_FILE_MOVE, true);
        if (COConfigurationManager.getBooleanParameter("Ip Filter Disable For Updates")) {
            download.setFlag(Download.FLAG_DISABLE_IP_FILTER, true);
        }
        download_manager.addListener(new DownloadManagerListener() {

            @Override
            public void downloadAdded(Download download) {
            }

            @Override
            public void downloadRemoved(Download _download) {
                if (download == _download) {
                    ResourceDownloaderTorrentImpl.this.downloadRemoved(torrent_file, data_dir);
                }
            }
        });
        download.addListener(new DownloadListener() {

            @Override
            public void stateChanged(final Download download, int old_state, int new_state) {
                if (new_state == Download.ST_SEEDING) {
                    download.removeListener(this);
                    PluginInitializer.getDefaultInterface().getUtilities().createThread("resource complete event dispatcher", new Runnable() {

                        @Override
                        public void run() {
                            downloadSucceeded(download, torrent_file, data_dir);
                        }
                    });
                }
            }

            @Override
            public void positionChanged(Download download, int oldPosition, int newPosition) {
            }
        });
        Thread t = new AEThread("RDTorrent percentage checker") {

            @Override
            public void runSupport() {
                int last_percentage = 0;
                while (result == null) {
                    int this_percentage = download.getStats().getDownloadCompleted(false) / 10;
                    long total = torrent.getSize();
                    if (this_percentage != last_percentage) {
                        reportPercentComplete(ResourceDownloaderTorrentImpl.this, this_percentage);
                        last_percentage = this_percentage;
                    }
                    try {
                        Thread.sleep(1000);
                    } catch (Throwable e) {
                        Debug.printStackTrace(e);
                    }
                }
            }
        };
        t.setDaemon(true);
        t.start();
        if (download.getState() == Download.ST_SEEDING) {
            downloadSucceeded(download, torrent_file, data_dir);
        }
    } catch (Throwable e) {
        failed(this, new ResourceDownloaderException(this, "Torrent download failed", e));
    }
}
Also used : TOTorrent(com.biglybt.core.torrent.TOTorrent) Torrent(com.biglybt.pif.torrent.Torrent) TorrentImpl(com.biglybt.pifimpl.local.torrent.TorrentImpl) ResourceDownloaderException(com.biglybt.pif.utils.resourcedownloader.ResourceDownloaderException) TOTorrent(com.biglybt.core.torrent.TOTorrent) File(java.io.File)

Example 15 with ResourceDownloaderException

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

the class ResourceDownloaderURLImpl method download.

@Override
public InputStream download() throws ResourceDownloaderException {
    try {
        reportActivity(this, getLogIndent() + "Downloading: " + trimForDisplay(original_url));
        try {
            this_mon.enter();
            if (download_initiated) {
                throw (new ResourceDownloaderException(this, "Download already initiated"));
            }
            download_initiated = true;
        } finally {
            this_mon.exit();
        }
        try {
            URL outer_url = new URL(original_url.toString().replaceAll(" ", "%20"));
            // some authentications screw up without an explicit port number here
            String protocol = outer_url.getProtocol().toLowerCase();
            if (protocol.equals("vuze") || protocol.equals("biglybt")) {
                outer_url = original_url;
            } else if (protocol.equals("file")) {
                File file = new File(original_url.toURI());
                FileInputStream fis = new FileInputStream(file);
                informAmountComplete(file.length());
                informPercentDone(100);
                informComplete(fis);
                return (fis);
            } else if (outer_url.getPort() == -1 && (protocol.equals("http") || protocol.equals("https"))) {
                int target_port;
                if (protocol.equals("http")) {
                    target_port = 80;
                } else {
                    target_port = 443;
                }
                try {
                    String str = original_url.toString().replaceAll(" ", "%20");
                    int pos = str.indexOf("://");
                    pos = str.indexOf("/", pos + 4);
                    if (pos == -1) {
                        outer_url = new URL(str + ":" + target_port + "/");
                    } else {
                        outer_url = new URL(str.substring(0, pos) + ":" + target_port + str.substring(pos));
                    }
                } catch (Throwable e) {
                    Debug.printStackTrace(e);
                }
            }
            outer_url = AddressUtils.adjustURL(outer_url);
            try {
                if (force_no_proxy) {
                    AEProxySelectorFactory.getSelector().startNoProxy();
                }
                if (auth_supplied) {
                    SESecurityManager.setPasswordHandler(outer_url, this);
                }
                boolean use_compression = true;
                boolean follow_redirect = true;
                boolean dh_hack = false;
                boolean internal_error_hack = false;
                Set<String> redirect_urls = new HashSet<>();
                URL current_url = outer_url;
                Proxy current_proxy = force_proxy;
                PluginProxy current_plugin_proxy = null;
                URL initial_url = current_url;
                redirect_label: while (follow_redirect) {
                    follow_redirect = false;
                    PluginProxy plugin_proxy_auto;
                    boolean ok = false;
                    if (auto_plugin_proxy || isAnonymous()) {
                        plugin_proxy_auto = AEProxyFactory.getPluginProxy("downloading resource", current_url);
                        if (plugin_proxy_auto == null) {
                            throw (new ResourceDownloaderException(this, "No plugin proxy available"));
                        }
                        current_url = plugin_proxy_auto.getURL();
                        current_proxy = plugin_proxy_auto.getProxy();
                    } else {
                        plugin_proxy_auto = null;
                    }
                    try {
                        SSLSocketFactory ssl_socket_factory = null;
                        for (int connect_loop = 0; connect_loop < 3; connect_loop++) {
                            File temp_file = null;
                            try {
                                URLConnection con;
                                current_plugin_proxy = plugin_proxy_auto == null ? AEProxyFactory.getPluginProxy(force_proxy) : plugin_proxy_auto;
                                if (current_url.getProtocol().equalsIgnoreCase("https")) {
                                    // see ConfigurationChecker for SSL client defaults
                                    HttpsURLConnection ssl_con = (HttpsURLConnection) openConnection(current_proxy, current_url);
                                    if (ssl_socket_factory != null) {
                                        ssl_con.setSSLSocketFactory(ssl_socket_factory);
                                    }
                                    if (!internal_error_hack) {
                                        // for some reason, on java 8 at least, even setting a host name verifier
                                        // causes an SSL internal_error on some websites :(
                                        // allow for certs that contain IP addresses rather than dns names
                                        ssl_con.setHostnameVerifier(new HostnameVerifier() {

                                            @Override
                                            public boolean verify(String host, SSLSession session) {
                                                return (true);
                                            }
                                        });
                                    }
                                    if (current_plugin_proxy != null) {
                                        // unfortunately the use of an intermediate host name causes
                                        // SSL to completely fail (the hostname verifier above isn't enough to
                                        // stop borkage) so what can we do?
                                        // actually, not sure why, but when I hacked in this delegator things magically
                                        // started working :(
                                        TrustManagerFactory tmf = SESecurityManager.getTrustManagerFactory();
                                        final List<X509TrustManager> default_tms = new ArrayList<>();
                                        if (tmf != null) {
                                            for (TrustManager tm : tmf.getTrustManagers()) {
                                                if (tm instanceof X509TrustManager) {
                                                    default_tms.add((X509TrustManager) tm);
                                                }
                                            }
                                        }
                                        TrustManager[] tms_delegate = SESecurityManager.getAllTrustingTrustManager(new X509TrustManager() {

                                            @Override
                                            public X509Certificate[] getAcceptedIssuers() {
                                                List<X509Certificate> result = new ArrayList<>();
                                                for (X509TrustManager tm : default_tms) {
                                                    result.addAll(Arrays.asList(tm.getAcceptedIssuers()));
                                                }
                                                return (result.toArray(new X509Certificate[result.size()]));
                                            }

                                            @Override
                                            public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                                                for (X509TrustManager tm : default_tms) {
                                                    tm.checkClientTrusted(chain, authType);
                                                }
                                            }

                                            @Override
                                            public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                                                for (X509TrustManager tm : default_tms) {
                                                    tm.checkServerTrusted(chain, authType);
                                                }
                                            }
                                        });
                                        SSLContext sc = SSLContext.getInstance("SSL");
                                        sc.init(null, tms_delegate, RandomUtils.SECURE_RANDOM);
                                        SSLSocketFactory factory = sc.getSocketFactory();
                                        ssl_con.setSSLSocketFactory(factory);
                                    }
                                    if (dh_hack) {
                                        UrlUtils.DHHackIt(ssl_con);
                                    }
                                    if (internal_error_hack && current_plugin_proxy != null) {
                                        String host = current_plugin_proxy.getURLHostRewrite();
                                        UrlUtils.HTTPSURLConnectionSNIHack(host, ssl_con);
                                    }
                                    con = ssl_con;
                                } else {
                                    con = openConnection(current_proxy, current_url);
                                }
                                if (con instanceof HttpURLConnection) {
                                    if (current_plugin_proxy != null) {
                                        // need to manually handle redirects as we need to re-proxy
                                        ((HttpURLConnection) con).setInstanceFollowRedirects(false);
                                    } else {
                                        ((HttpURLConnection) con).setInstanceFollowRedirects(true);
                                    }
                                }
                                if (current_plugin_proxy != null) {
                                    con.setRequestProperty("HOST", current_plugin_proxy.getURLHostRewrite() + (initial_url.getPort() == -1 ? "" : (":" + initial_url.getPort())));
                                }
                                ClientIDGenerator cidg = ClientIDManagerImpl.getSingleton().getGenerator();
                                if (cidg != null) {
                                    Properties props = new Properties();
                                    cidg.generateHTTPProperties(null, props);
                                    String ua = props.getProperty(ClientIDGenerator.PR_USER_AGENT);
                                    con.setRequestProperty("User-Agent", ua);
                                }
                                String connection = getStringProperty("URL_Connection");
                                if (connection != null && connection.equalsIgnoreCase("Keep-Alive")) {
                                    con.setRequestProperty("Connection", "Keep-Alive");
                                // gah, no idea what the intent behind 'skip' is!
                                } else if (connection == null || !connection.equals("skip")) {
                                    // default is close
                                    con.setRequestProperty("Connection", "close");
                                }
                                if (use_compression) {
                                    con.addRequestProperty("Accept-Encoding", "gzip");
                                }
                                setRequestProperties(con, use_compression);
                                if (post_data != null && con instanceof HttpURLConnection) {
                                    con.setDoOutput(true);
                                    String verb = (String) getStringProperty("URL_HTTP_VERB");
                                    if (verb == null) {
                                        verb = "POST";
                                    }
                                    ((HttpURLConnection) con).setRequestMethod(verb);
                                    if (post_data.length > 0) {
                                        OutputStream os = con.getOutputStream();
                                        os.write(post_data);
                                        os.flush();
                                    }
                                }
                                long connect_timeout = getLongProperty("URL_Connect_Timeout");
                                if (connect_timeout >= 0) {
                                    con.setConnectTimeout((int) connect_timeout);
                                }
                                long read_timeout = getLongProperty("URL_Read_Timeout");
                                if (read_timeout >= 0) {
                                    con.setReadTimeout((int) read_timeout);
                                }
                                boolean trust_content_length = getBooleanProperty("URL_Trust_Content_Length");
                                try {
                                    con.connect();
                                } catch (AEProxyFactory.UnknownHostException e) {
                                    throw (new UnknownHostException(e.getMessage()));
                                }
                                int response = con instanceof HttpURLConnection ? ((HttpURLConnection) con).getResponseCode() : HttpURLConnection.HTTP_OK;
                                ok = true;
                                if (response == HttpURLConnection.HTTP_MOVED_TEMP || response == HttpURLConnection.HTTP_MOVED_PERM) {
                                    // auto redirect doesn't work from http to https or vice-versa
                                    String move_to = con.getHeaderField("location");
                                    if (move_to != null) {
                                        if (redirect_urls.contains(move_to) || redirect_urls.size() > 32) {
                                            throw (new ResourceDownloaderException(this, "redirect loop"));
                                        }
                                        redirect_urls.add(move_to);
                                        try {
                                            // don't URL decode the move-to as its already in the right format!
                                            // URLDecoder.decode( move_to, "UTF-8" ));
                                            URL move_to_url = new URL(move_to);
                                            boolean follow = false;
                                            if (current_plugin_proxy != null) {
                                                PluginProxy child = current_plugin_proxy.getChildProxy("redirect", move_to_url);
                                                if (child != null) {
                                                    initial_url = move_to_url;
                                                    // use an overall property to force this through on the redirect
                                                    setProperty("URL_HOST", initial_url.getHost() + (initial_url.getPort() == -1 ? "" : (":" + initial_url.getPort())));
                                                    current_proxy = child.getProxy();
                                                    move_to_url = child.getURL();
                                                    follow = true;
                                                }
                                            }
                                            String original_protocol = current_url.getProtocol().toLowerCase();
                                            String new_protocol = move_to_url.getProtocol().toLowerCase();
                                            if (follow || !original_protocol.equals(new_protocol)) {
                                                current_url = move_to_url;
                                                try {
                                                    List<String> cookies_list = con.getHeaderFields().get("Set-cookie");
                                                    List<String> cookies_set = new ArrayList<>();
                                                    if (cookies_list != null) {
                                                        for (int i = 0; i < cookies_list.size(); i++) {
                                                            String[] cookie_bits = ((String) cookies_list.get(i)).split(";");
                                                            if (cookie_bits.length > 0) {
                                                                cookies_set.add(cookie_bits[0]);
                                                            }
                                                        }
                                                    }
                                                    if (cookies_set.size() > 0) {
                                                        String new_cookies = "";
                                                        Map properties = getLCKeyProperties();
                                                        Object obj = properties.get("url_cookie");
                                                        if (obj instanceof String) {
                                                            new_cookies = (String) obj;
                                                        }
                                                        for (String s : cookies_set) {
                                                            new_cookies += (new_cookies.length() == 0 ? "" : "; ") + s;
                                                        }
                                                        setProperty("URL_Cookie", new_cookies);
                                                    }
                                                } catch (Throwable e) {
                                                    Debug.out(e);
                                                }
                                                follow_redirect = true;
                                                continue redirect_label;
                                            }
                                        } catch (Throwable e) {
                                        }
                                    }
                                }
                                setProperty("URL_HTTP_Response", new Long(response));
                                if (response != HttpURLConnection.HTTP_CREATED && response != HttpURLConnection.HTTP_ACCEPTED && response != HttpURLConnection.HTTP_NO_CONTENT && response != HttpURLConnection.HTTP_OK) {
                                    HttpURLConnection http_con = (HttpURLConnection) con;
                                    InputStream error_stream = http_con.getErrorStream();
                                    String error_str = null;
                                    if (error_stream != null) {
                                        String encoding = con.getHeaderField("content-encoding");
                                        if (encoding != null) {
                                            if (encoding.equalsIgnoreCase("gzip")) {
                                                error_stream = new GZIPInputStream(error_stream);
                                            } else if (encoding.equalsIgnoreCase("deflate")) {
                                                error_stream = new InflaterInputStream(error_stream);
                                            }
                                        }
                                        error_str = FileUtil.readInputStreamAsString(error_stream, 512);
                                    }
                                    // grab properties anyway as they may be useful
                                    getRequestProperties(con);
                                    URL dest = current_url;
                                    if (current_plugin_proxy != null) {
                                        try {
                                            dest = new URL(current_plugin_proxy.getTarget());
                                        } catch (Throwable e) {
                                        }
                                    }
                                    throw (new ResourceDownloaderException(this, "Error on connect for '" + trimForDisplay(dest) + "': " + Integer.toString(response) + " " + http_con.getResponseMessage() + (error_str == null ? "" : (": error=" + error_str))));
                                }
                                getRequestProperties(con);
                                boolean compressed = false;
                                try {
                                    this_mon.enter();
                                    input_stream = con.getInputStream();
                                    String encoding = con.getHeaderField("content-encoding");
                                    if (encoding != null) {
                                        if (encoding.equalsIgnoreCase("gzip")) {
                                            compressed = true;
                                            input_stream = new GZIPInputStream(input_stream);
                                        } else if (encoding.equalsIgnoreCase("deflate")) {
                                            compressed = true;
                                            input_stream = new InflaterInputStream(input_stream);
                                        }
                                    }
                                } finally {
                                    this_mon.exit();
                                }
                                if (con instanceof MagnetConnection2) {
                                    // hack - status reports for magnet connections are returned
                                    List<String> errors = ((MagnetConnection2) con).getResponseMessages(true);
                                    if (errors.size() > 0) {
                                        throw (new ResourceDownloaderException(this, errors.get(0)));
                                    }
                                }
                                ByteArrayOutputStream baos = null;
                                FileOutputStream fos = null;
                                try {
                                    byte[] buf = new byte[BUFFER_SIZE];
                                    long total_read = 0;
                                    // unfortunately not all servers set content length
                                    /* From Apache's mod_deflate doc:
										 * http://httpd.apache.org/docs/2.0/mod/mod_deflate.html
												Note on Content-Length

												If you evaluate the request body yourself, don't trust the
												Content-Length header! The Content-Length header reflects
												the length of the incoming data from the client and not the
												byte count of the decompressed data stream.
										 */
                                    long size = compressed ? -1 : UrlUtils.getContentLength(con);
                                    baos = size > 0 ? new ByteArrayOutputStream(size > MAX_IN_MEM_READ_SIZE ? MAX_IN_MEM_READ_SIZE : (int) size) : new ByteArrayOutputStream();
                                    while (!cancel_download) {
                                        if (size >= 0 && total_read >= size && trust_content_length) {
                                            break;
                                        }
                                        int read = input_stream.read(buf);
                                        if (read > 0) {
                                            if (total_read > MAX_IN_MEM_READ_SIZE) {
                                                if (fos == null) {
                                                    temp_file = AETemporaryFileHandler.createTempFile();
                                                    fos = new FileOutputStream(temp_file);
                                                    fos.write(baos.toByteArray());
                                                    baos = null;
                                                }
                                                fos.write(buf, 0, read);
                                            } else {
                                                baos.write(buf, 0, read);
                                            }
                                            total_read += read;
                                            informAmountComplete(total_read);
                                            if (size > 0) {
                                                informPercentDone((int) ((100 * total_read) / size));
                                            }
                                        } else {
                                            break;
                                        }
                                    }
                                    if (size > 0 && total_read != size) {
                                        if (total_read > size) {
                                            // this has been seen with UPnP linksys - more data is read than
                                            // the content-length has us believe is coming (1 byte in fact...)
                                            Debug.outNoStack("Inconsistent stream length for '" + trimForDisplay(original_url) + "': expected = " + size + ", actual = " + total_read);
                                        } else {
                                            throw (new IOException("Premature end of stream"));
                                        }
                                    }
                                } finally {
                                    if (fos != null) {
                                        try {
                                            fos.close();
                                        } catch (Throwable e) {
                                        }
                                    }
                                    input_stream.close();
                                }
                                InputStream res;
                                if (temp_file != null) {
                                    res = new DeleteFileOnCloseInputStream(temp_file);
                                    temp_file = null;
                                } else {
                                    res = new ByteArrayInputStream(baos.toByteArray());
                                }
                                boolean handed_over = false;
                                try {
                                    if (informComplete(res)) {
                                        handed_over = true;
                                        return (res);
                                    }
                                } finally {
                                    if (!handed_over) {
                                        res.close();
                                    }
                                }
                                throw (new ResourceDownloaderException(this, "Contents downloaded but rejected: '" + trimForDisplay(original_url) + "'"));
                            } catch (SSLException e) {
                                String msg = Debug.getNestedExceptionMessage(e);
                                if (connect_loop < 3) {
                                    boolean try_again = false;
                                    if (msg.contains("DH keypair")) {
                                        if (!dh_hack) {
                                            dh_hack = true;
                                            try_again = true;
                                        }
                                    } else if (msg.contains("internal_error") || msg.contains("handshake_failure")) {
                                        if (!internal_error_hack) {
                                            internal_error_hack = true;
                                            try_again = true;
                                        }
                                    }
                                    ssl_socket_factory = SESecurityManager.installServerCertificates(current_url);
                                    if (ssl_socket_factory != null) {
                                        // certificate has been installed
                                        try_again = true;
                                    }
                                    if (try_again) {
                                        continue;
                                    }
                                }
                                throw (e);
                            } catch (ZipException e) {
                                if (connect_loop == 0) {
                                    use_compression = false;
                                    continue;
                                }
                            } catch (IOException e) {
                                if (connect_loop == 0) {
                                    String msg = e.getMessage();
                                    if (msg != null) {
                                        msg = msg.toLowerCase(MessageText.LOCALE_ENGLISH);
                                        if (msg.contains("gzip")) {
                                            use_compression = false;
                                            continue;
                                        }
                                    }
                                    URL retry_url = UrlUtils.getIPV4Fallback(current_url);
                                    if (retry_url != null) {
                                        current_url = retry_url;
                                        continue;
                                    }
                                }
                                throw (e);
                            } finally {
                                if (temp_file != null) {
                                    temp_file.delete();
                                }
                            }
                        }
                    } finally {
                        if (plugin_proxy_auto != null) {
                            plugin_proxy_auto.setOK(ok);
                        }
                    }
                }
                throw (new ResourceDownloaderException(this, "Should never get here"));
            } finally {
                if (auth_supplied) {
                    SESecurityManager.setPasswordHandler(outer_url, null);
                }
                if (force_no_proxy) {
                    AEProxySelectorFactory.getSelector().endNoProxy();
                }
            }
        } catch (java.net.MalformedURLException e) {
            throw (new ResourceDownloaderException(this, "Exception while parsing URL '" + trimForDisplay(original_url) + "':" + e.getMessage(), e));
        } catch (java.net.UnknownHostException e) {
            throw (new ResourceDownloaderException(this, "Exception while initializing download of '" + trimForDisplay(original_url) + "': Unknown Host '" + e.getMessage() + "'", e));
        } catch (java.io.IOException e) {
            throw (new ResourceDownloaderException(this, "I/O Exception while downloading '" + trimForDisplay(original_url) + "'", e));
        }
    } catch (Throwable e) {
        ResourceDownloaderException rde;
        if (e instanceof ResourceDownloaderException) {
            rde = (ResourceDownloaderException) e;
        } else {
            Debug.out(e);
            rde = new ResourceDownloaderException(this, "Unexpected error", e);
        }
        informFailed(rde);
        throw (rde);
    }
}
Also used : java.net(java.net) ClientIDGenerator(com.biglybt.pif.clientid.ClientIDGenerator) java.io(java.io) X509Certificate(java.security.cert.X509Certificate) PluginProxy(com.biglybt.core.proxy.AEProxyFactory.PluginProxy) GZIPInputStream(java.util.zip.GZIPInputStream) PluginProxy(com.biglybt.core.proxy.AEProxyFactory.PluginProxy) ResourceDownloaderException(com.biglybt.pif.utils.resourcedownloader.ResourceDownloaderException) GZIPInputStream(java.util.zip.GZIPInputStream) InflaterInputStream(java.util.zip.InflaterInputStream) InflaterInputStream(java.util.zip.InflaterInputStream) ZipException(java.util.zip.ZipException) MagnetConnection2(com.biglybt.core.util.protocol.magnet.MagnetConnection2)

Aggregations

ResourceDownloaderException (com.biglybt.pif.utils.resourcedownloader.ResourceDownloaderException)26 ResourceDownloader (com.biglybt.pif.utils.resourcedownloader.ResourceDownloader)13 InputStream (java.io.InputStream)11 URL (java.net.URL)11 ResourceDownloaderAdapter (com.biglybt.pif.utils.resourcedownloader.ResourceDownloaderAdapter)6 ResourceDownloaderFactory (com.biglybt.pif.utils.resourcedownloader.ResourceDownloaderFactory)6 IOException (java.io.IOException)5 ZipInputStream (java.util.zip.ZipInputStream)5 PluginProxy (com.biglybt.core.proxy.AEProxyFactory.PluginProxy)4 TOTorrent (com.biglybt.core.torrent.TOTorrent)4 File (java.io.File)4 ArrayList (java.util.ArrayList)4 LogEvent (com.biglybt.core.logging.LogEvent)3 VuzeFile (com.biglybt.core.vuzefile.VuzeFile)3 Update (com.biglybt.pif.update.Update)3 FileInputStream (java.io.FileInputStream)3 HTMLPage (com.biglybt.core.html.HTMLPage)2 TOTorrentException (com.biglybt.core.torrent.TOTorrentException)2 AEThread (com.biglybt.core.util.AEThread)2 ClientIDGenerator (com.biglybt.pif.clientid.ClientIDGenerator)2