Search in sources :

Example 1 with DownloadError

use of de.danoeh.antennapod.core.util.DownloadError in project AntennaPod by AntennaPod.

the class FeedParserTask method call.

@Override
public FeedHandlerResult call() {
    Feed feed = new Feed(request.getSource(), request.getLastModified());
    feed.setFile_url(request.getDestination());
    feed.setId(request.getFeedfileId());
    feed.setDownloaded(true);
    feed.setPreferences(new FeedPreferences(0, true, FeedPreferences.AutoDeleteAction.GLOBAL, VolumeAdaptionSetting.OFF, request.getUsername(), request.getPassword()));
    feed.setPageNr(request.getArguments().getInt(DownloadRequest.REQUEST_ARG_PAGE_NR, 0));
    DownloadError reason = null;
    String reasonDetailed = null;
    FeedHandler feedHandler = new FeedHandler();
    FeedHandlerResult result = null;
    try {
        result = feedHandler.parseFeed(feed);
        Log.d(TAG, feed.getTitle() + " parsed");
        checkFeedData(feed);
    } catch (SAXException | IOException | ParserConfigurationException e) {
        successful = false;
        e.printStackTrace();
        reason = DownloadError.ERROR_PARSER_EXCEPTION;
        reasonDetailed = e.getMessage();
    } catch (UnsupportedFeedtypeException e) {
        e.printStackTrace();
        successful = false;
        reason = DownloadError.ERROR_UNSUPPORTED_TYPE;
        if ("html".equalsIgnoreCase(e.getRootElement())) {
            reason = DownloadError.ERROR_UNSUPPORTED_TYPE_HTML;
        }
        reasonDetailed = e.getMessage();
    } catch (InvalidFeedException e) {
        e.printStackTrace();
        successful = false;
        reason = DownloadError.ERROR_PARSER_EXCEPTION;
        reasonDetailed = e.getMessage();
    } finally {
        File feedFile = new File(request.getDestination());
        if (feedFile.exists()) {
            boolean deleted = feedFile.delete();
            Log.d(TAG, "Deletion of file '" + feedFile.getAbsolutePath() + "' " + (deleted ? "successful" : "FAILED"));
        }
    }
    if (successful) {
        downloadStatus = new DownloadStatus(feed, feed.getHumanReadableIdentifier(), DownloadError.SUCCESS, successful, reasonDetailed, request.isInitiatedByUser());
        return result;
    } else {
        downloadStatus = new DownloadStatus(feed, feed.getTitle(), reason, successful, reasonDetailed, request.isInitiatedByUser());
        return null;
    }
}
Also used : FeedPreferences(de.danoeh.antennapod.model.feed.FeedPreferences) InvalidFeedException(de.danoeh.antennapod.core.util.InvalidFeedException) UnsupportedFeedtypeException(de.danoeh.antennapod.parser.feed.UnsupportedFeedtypeException) FeedHandlerResult(de.danoeh.antennapod.parser.feed.FeedHandlerResult) IOException(java.io.IOException) SAXException(org.xml.sax.SAXException) DownloadError(de.danoeh.antennapod.core.util.DownloadError) FeedHandler(de.danoeh.antennapod.parser.feed.FeedHandler) DownloadStatus(de.danoeh.antennapod.core.service.download.DownloadStatus) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) File(java.io.File) Feed(de.danoeh.antennapod.model.feed.Feed)

Example 2 with DownloadError

use of de.danoeh.antennapod.core.util.DownloadError in project AntennaPod by AntennaPod.

the class HttpDownloader method download.

@Override
protected void download() {
    File destination = new File(request.getDestination());
    final boolean fileExists = destination.exists();
    if (request.isDeleteOnFailure() && fileExists) {
        Log.w(TAG, "File already exists");
        onSuccess();
        return;
    }
    OkHttpClient httpClient = AntennapodHttpClient.getHttpClient();
    RandomAccessFile out = null;
    InputStream connection;
    ResponseBody responseBody = null;
    try {
        final URI uri = URIUtil.getURIFromRequestUrl(request.getSource());
        Request.Builder httpReq = new Request.Builder().url(uri.toURL());
        httpReq.tag(request);
        httpReq.cacheControl(new CacheControl.Builder().noStore().build());
        if (request.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
            // set header explicitly so that okhttp doesn't do transparent gzip
            Log.d(TAG, "addHeader(\"Accept-Encoding\", \"identity\")");
            httpReq.addHeader("Accept-Encoding", "identity");
            // noStore breaks CDNs
            httpReq.cacheControl(new CacheControl.Builder().noCache().build());
        }
        if (!TextUtils.isEmpty(request.getLastModified())) {
            String lastModified = request.getLastModified();
            Date lastModifiedDate = DateUtils.parse(lastModified);
            if (lastModifiedDate != null) {
                long threeDaysAgo = System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 3;
                if (lastModifiedDate.getTime() > threeDaysAgo) {
                    Log.d(TAG, "addHeader(\"If-Modified-Since\", \"" + lastModified + "\")");
                    httpReq.addHeader("If-Modified-Since", lastModified);
                }
            } else {
                Log.d(TAG, "addHeader(\"If-None-Match\", \"" + lastModified + "\")");
                httpReq.addHeader("If-None-Match", lastModified);
            }
        }
        // add range header if necessary
        if (fileExists && destination.length() > 0) {
            request.setSoFar(destination.length());
            httpReq.addHeader("Range", "bytes=" + request.getSoFar() + "-");
            Log.d(TAG, "Adding range header: " + request.getSoFar());
        }
        Response response;
        try {
            response = httpClient.newCall(httpReq.build()).execute();
        } catch (IOException e) {
            Log.e(TAG, e.toString());
            if (e.getMessage().contains("PROTOCOL_ERROR")) {
                httpClient = httpClient.newBuilder().protocols(Collections.singletonList(Protocol.HTTP_1_1)).build();
                response = httpClient.newCall(httpReq.build()).execute();
            } else {
                throw e;
            }
        }
        responseBody = response.body();
        String contentEncodingHeader = response.header("Content-Encoding");
        boolean isGzip = false;
        if (!TextUtils.isEmpty(contentEncodingHeader)) {
            isGzip = TextUtils.equals(contentEncodingHeader.toLowerCase(), "gzip");
        }
        Log.d(TAG, "Response code is " + response.code());
        if (!response.isSuccessful() && response.code() == HttpURLConnection.HTTP_NOT_MODIFIED) {
            Log.d(TAG, "Feed '" + request.getSource() + "' not modified since last update, Download canceled");
            onCancelled();
            return;
        }
        if (!response.isSuccessful() || response.body() == null) {
            final DownloadError error;
            final String details;
            if (response.code() == HttpURLConnection.HTTP_UNAUTHORIZED) {
                error = DownloadError.ERROR_UNAUTHORIZED;
                details = String.valueOf(response.code());
            } else if (response.code() == HttpURLConnection.HTTP_FORBIDDEN) {
                error = DownloadError.ERROR_FORBIDDEN;
                details = String.valueOf(response.code());
            } else if (response.code() == HttpURLConnection.HTTP_NOT_FOUND) {
                error = DownloadError.ERROR_NOT_FOUND;
                details = String.valueOf(response.code());
            } else {
                error = DownloadError.ERROR_HTTP_DATA_ERROR;
                details = String.valueOf(response.code());
            }
            onFail(error, details);
            return;
        }
        if (!StorageUtils.storageAvailable()) {
            onFail(DownloadError.ERROR_DEVICE_NOT_FOUND, null);
            return;
        }
        // the reported content length is less than 100kb (or no length is given)
        if (request.getFeedfileType() == FeedMedia.FEEDFILETYPE_FEEDMEDIA) {
            int contentLength = -1;
            String contentLen = response.header("Content-Length");
            if (contentLen != null) {
                try {
                    contentLength = Integer.parseInt(contentLen);
                } catch (NumberFormatException e) {
                    e.printStackTrace();
                }
            }
            Log.d(TAG, "content length: " + contentLength);
            String contentType = response.header("Content-Type");
            Log.d(TAG, "content type: " + contentType);
            if (contentType != null && contentType.startsWith("text/") && contentLength < 100 * 1024) {
                onFail(DownloadError.ERROR_FILE_TYPE, null);
                return;
            }
        }
        connection = new BufferedInputStream(responseBody.byteStream());
        String contentRangeHeader = (fileExists) ? response.header("Content-Range") : null;
        if (fileExists && response.code() == HttpURLConnection.HTTP_PARTIAL && !TextUtils.isEmpty(contentRangeHeader)) {
            String start = contentRangeHeader.substring("bytes ".length(), contentRangeHeader.indexOf("-"));
            request.setSoFar(Long.parseLong(start));
            Log.d(TAG, "Starting download at position " + request.getSoFar());
            out = new RandomAccessFile(destination, "rw");
            out.seek(request.getSoFar());
        } else {
            boolean success = destination.delete();
            success |= destination.createNewFile();
            if (!success) {
                throw new IOException("Unable to recreate partially downloaded file");
            }
            out = new RandomAccessFile(destination, "rw");
        }
        byte[] buffer = new byte[BUFFER_SIZE];
        int count;
        request.setStatusMsg(R.string.download_running);
        Log.d(TAG, "Getting size of download");
        request.setSize(responseBody.contentLength() + request.getSoFar());
        Log.d(TAG, "Size is " + request.getSize());
        if (request.getSize() < 0) {
            request.setSize(DownloadStatus.SIZE_UNKNOWN);
        }
        long freeSpace = StorageUtils.getFreeSpaceAvailable();
        Log.d(TAG, "Free space is " + freeSpace);
        if (request.getSize() != DownloadStatus.SIZE_UNKNOWN && request.getSize() > freeSpace) {
            onFail(DownloadError.ERROR_NOT_ENOUGH_SPACE, null);
            return;
        }
        Log.d(TAG, "Starting download");
        try {
            while (!cancelled && (count = connection.read(buffer)) != -1) {
                out.write(buffer, 0, count);
                request.setSoFar(request.getSoFar() + count);
                int progressPercent = (int) (100.0 * request.getSoFar() / request.getSize());
                request.setProgressPercent(progressPercent);
            }
        } catch (IOException e) {
            Log.e(TAG, Log.getStackTraceString(e));
        }
        if (cancelled) {
            onCancelled();
        } else {
            // written file. This check cannot be made if compression was used
            if (!isGzip && request.getSize() != DownloadStatus.SIZE_UNKNOWN && request.getSoFar() != request.getSize()) {
                onFail(DownloadError.ERROR_IO_WRONG_SIZE, "Download completed but size: " + request.getSoFar() + " does not equal expected size " + request.getSize());
                return;
            } else if (request.getSize() > 0 && request.getSoFar() == 0) {
                onFail(DownloadError.ERROR_IO_ERROR, "Download completed, but nothing was read");
                return;
            }
            String lastModified = response.header("Last-Modified");
            if (lastModified != null) {
                request.setLastModified(lastModified);
            } else {
                request.setLastModified(response.header("ETag"));
            }
            onSuccess();
        }
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
        onFail(DownloadError.ERROR_MALFORMED_URL, e.getMessage());
    } catch (SocketTimeoutException e) {
        e.printStackTrace();
        onFail(DownloadError.ERROR_CONNECTION_ERROR, e.getMessage());
    } catch (UnknownHostException e) {
        e.printStackTrace();
        onFail(DownloadError.ERROR_UNKNOWN_HOST, e.getMessage());
    } catch (IOException e) {
        e.printStackTrace();
        if (NetworkUtils.wasDownloadBlocked(e)) {
            onFail(DownloadError.ERROR_IO_BLOCKED, e.getMessage());
            return;
        }
        String message = e.getMessage();
        if (message != null && message.contains("Trust anchor for certification path not found")) {
            onFail(DownloadError.ERROR_CERTIFICATE, e.getMessage());
            return;
        }
        onFail(DownloadError.ERROR_IO_ERROR, e.getMessage());
    } catch (NullPointerException e) {
        // might be thrown by connection.getInputStream()
        e.printStackTrace();
        onFail(DownloadError.ERROR_CONNECTION_ERROR, request.getSource());
    } finally {
        IOUtils.closeQuietly(out);
        IOUtils.closeQuietly(responseBody);
    }
}
Also used : OkHttpClient(okhttp3.OkHttpClient) ByteString(okio.ByteString) URI(java.net.URI) BufferedInputStream(java.io.BufferedInputStream) DownloadError(de.danoeh.antennapod.core.util.DownloadError) UnknownHostException(java.net.UnknownHostException) BufferedInputStream(java.io.BufferedInputStream) InputStream(java.io.InputStream) Request(okhttp3.Request) IOException(java.io.IOException) Date(java.util.Date) ResponseBody(okhttp3.ResponseBody) Response(okhttp3.Response) SocketTimeoutException(java.net.SocketTimeoutException) RandomAccessFile(java.io.RandomAccessFile) CacheControl(okhttp3.CacheControl) RandomAccessFile(java.io.RandomAccessFile) File(java.io.File)

Aggregations

DownloadError (de.danoeh.antennapod.core.util.DownloadError)2 File (java.io.File)2 IOException (java.io.IOException)2 DownloadStatus (de.danoeh.antennapod.core.service.download.DownloadStatus)1 InvalidFeedException (de.danoeh.antennapod.core.util.InvalidFeedException)1 Feed (de.danoeh.antennapod.model.feed.Feed)1 FeedPreferences (de.danoeh.antennapod.model.feed.FeedPreferences)1 FeedHandler (de.danoeh.antennapod.parser.feed.FeedHandler)1 FeedHandlerResult (de.danoeh.antennapod.parser.feed.FeedHandlerResult)1 UnsupportedFeedtypeException (de.danoeh.antennapod.parser.feed.UnsupportedFeedtypeException)1 BufferedInputStream (java.io.BufferedInputStream)1 InputStream (java.io.InputStream)1 RandomAccessFile (java.io.RandomAccessFile)1 SocketTimeoutException (java.net.SocketTimeoutException)1 URI (java.net.URI)1 UnknownHostException (java.net.UnknownHostException)1 Date (java.util.Date)1 ParserConfigurationException (javax.xml.parsers.ParserConfigurationException)1 CacheControl (okhttp3.CacheControl)1 OkHttpClient (okhttp3.OkHttpClient)1