Java Code Examples for com.liulishuo.filedownloader.connection.FileDownloadConnection

The following examples show how to use com.liulishuo.filedownloader.connection.FileDownloadConnection. These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source Project: FileDownloader   Source File: FetchDataTask.java    License: Apache License 2.0 6 votes vote down vote up
private FetchDataTask(FileDownloadConnection connection, ConnectionProfile connectionProfile,
                      DownloadRunnable host, int id, int connectionIndex,
                      boolean isWifiRequired, ProcessCallback callback, String path) {
    this.callback = callback;
    this.path = path;
    this.connection = connection;
    this.isWifiRequired = isWifiRequired;
    this.hostRunnable = host;
    this.connectionIndex = connectionIndex;
    this.downloadId = id;
    this.database = CustomComponentHolder.getImpl().getDatabaseInstance();

    startOffset = connectionProfile.startOffset;
    endOffset = connectionProfile.endOffset;
    currentOffset = connectionProfile.currentOffset;
    contentLength = connectionProfile.contentLength;
}
 
Example 2
Source Project: FileDownloader   Source File: ConnectionProfile.java    License: Apache License 2.0 6 votes vote down vote up
public void processProfile(FileDownloadConnection connection) throws ProtocolException {
    if (isForceNoRange) return;

    if (isTrialConnect && FileDownloadProperties.getImpl().trialConnectionHeadMethod) {
        connection.setRequestMethod("HEAD");
    }

    final String range;
    if (endOffset == RANGE_INFINITE) {
        range = FileDownloadUtils.formatString("bytes=%d-", currentOffset);
    } else {
        range = FileDownloadUtils
                .formatString("bytes=%d-%d", currentOffset, endOffset);
    }
    connection.addHeader("Range", range);
}
 
Example 3
Source Project: FileDownloader   Source File: FileDownloadUtils.java    License: Apache License 2.0 6 votes vote down vote up
public static long findInstanceLengthForTrial(FileDownloadConnection connection) {
    long length = findInstanceLengthFromContentRange(connection);
    if (length < 0) {
        length = TOTAL_VALUE_IN_CHUNKED_RESOURCE;
        FileDownloadLog.w(FileDownloadUtils.class, "don't get instance length from"
                + "Content-Range header");
    }
    // the response of HEAD method is not very canonical sometimes(it depends on server
    // implementation)
    // so that it's uncertain the content-length is the same as the response of GET method if
    // content-length=0, so we have to filter this case in here.
    if (length == 0 && FileDownloadProperties.getImpl().trialConnectionHeadMethod) {
        length = TOTAL_VALUE_IN_CHUNKED_RESOURCE;
    }

    return length;
}
 
Example 4
Source Project: FileDownloader   Source File: FileDownloadUtils.java    License: Apache License 2.0 6 votes vote down vote up
public static String findFilename(FileDownloadConnection connection, String url)
        throws FileDownloadSecurityException {
    String filename = FileDownloadUtils.parseContentDisposition(connection.
            getResponseHeaderField("Content-Disposition"));

    if (TextUtils.isEmpty(filename)) {
        filename = findFileNameFromUrl(url);
    }

    if (TextUtils.isEmpty(filename)) {
        filename = FileDownloadUtils.generateFileName(url);
    } else if (filename.contains("../")) {
        throw new FileDownloadSecurityException(FileDownloadUtils.formatString(
                "The filename [%s] from the response is not allowable, because it contains "
                        + "'../', which can raise the directory traversal vulnerability",
                filename));
    }

    return filename;
}
 
Example 5
Source Project: FileDownloader   Source File: FileDownloadUtilsTest.java    License: Apache License 2.0 6 votes vote down vote up
@Test
public void findFilename_securityIssue() throws FileDownloadSecurityException {
    final FileDownloadConnection connection = mock(FileDownloadConnection.class);
    when(connection.getResponseHeaderField("Content-Disposition"))
            .thenReturn("attachment; filename=\"../abc\"");

    thrown.expect(FileDownloadSecurityException.class);
    FileDownloadUtils.findFilename(connection, "url");

    thrown.expect(FileDownloadSecurityException.class);
    when(connection.getResponseHeaderField("Content-Disposition"))
            .thenReturn("attachment; filename=\"a/b/../abc\"");
    FileDownloadUtils.findFilename(connection, "url");

    when(connection.getResponseHeaderField("Content-Disposition"))
            .thenReturn("attachment; filename=\"/abc/adb\"");
    assertThat(FileDownloadUtils.findFilename(connection, "url")).isEqualTo("/abc/adb");
}
 
Example 6
@Override
public FileDownloadConnection create(String url) throws IOException {
    if (mClient == null) {
        synchronized (Creator.class) {
            if (mClient == null) {
                mClient = mBuilder != null ? mBuilder.build() : new OkHttpClient();
                mBuilder = null;
            }
        }
    }

    return new OkHttp3Connection(url, mClient);
}
 
Example 7
@Override
public FileDownloadConnection create(String url) throws IOException {
    if (mClient == null) {
        synchronized (Creator.class) {
            if (mClient == null) {
                mClient = mBuilder != null ? mBuilder.build() : new OkHttpClient();
                mBuilder = null;
            }
        }
    }

    return new OkHttp3Connection(url, mClient);
}
 
Example 8
Source Project: FileDownloader   Source File: DownloadLaunchRunnable.java    License: Apache License 2.0 5 votes vote down vote up
private void trialConnect() throws IOException, RetryDirectly, IllegalAccessException,
        FileDownloadSecurityException {
    FileDownloadConnection trialConnection = null;
    try {
        final ConnectionProfile trialConnectionProfile;
        if (isNeedForceDiscardRange) {
            trialConnectionProfile = ConnectionProfile.ConnectionProfileBuild
                    .buildTrialConnectionProfileNoRange();
        } else {
            trialConnectionProfile = ConnectionProfile.ConnectionProfileBuild
                    .buildTrialConnectionProfile();
        }
        final ConnectTask trialConnectTask = new ConnectTask.Builder()
                .setDownloadId(model.getId())
                .setUrl(model.getUrl())
                .setEtag(model.getETag())
                .setHeader(userRequestHeader)
                .setConnectionProfile(trialConnectionProfile)
                .build();
        trialConnection = trialConnectTask.connect();
        handleTrialConnectResult(trialConnectTask.getRequestHeader(),
                trialConnectTask, trialConnection);

    } finally {
        if (trialConnection != null) trialConnection.ending();
    }
}
 
Example 9
Source Project: FileDownloader   Source File: ConnectTask.java    License: Apache License 2.0 5 votes vote down vote up
FileDownloadConnection connect() throws IOException, IllegalAccessException {
    FileDownloadConnection connection = CustomComponentHolder.getImpl().createConnection(url);

    addUserRequiredHeader(connection);
    addRangeHeader(connection);
    fixNeededHeader(connection);

    // init request
    // get the request header in here, because of there are many connection
    // component(such as HttpsURLConnectionImpl, HttpURLConnectionImpl in okhttp3) don't
    // allow access to the request header after it connected.
    requestHeader = connection.getRequestHeaderFields();
    if (FileDownloadLog.NEED_LOG) {
        FileDownloadLog.d(this, "<---- %s request header %s", downloadId, requestHeader);
    }

    connection.execute();
    redirectedUrlList = new ArrayList<>();
    connection = RedirectHandler.process(requestHeader, connection, redirectedUrlList);

    if (FileDownloadLog.NEED_LOG) {
        FileDownloadLog.d(this, "----> %s response header %s", downloadId,
                connection.getResponseHeaderFields());
    }

    return connection;
}
 
Example 10
Source Project: FileDownloader   Source File: ConnectTask.java    License: Apache License 2.0 5 votes vote down vote up
private void addUserRequiredHeader(FileDownloadConnection connection) {
    final HashMap<String, List<String>> additionHeaders;
    if (header != null) {
        additionHeaders = header.getHeaders();

        if (additionHeaders != null) {
            if (FileDownloadLog.NEED_LOG) {
                FileDownloadLog.v(this, "%d add outside header: %s",
                        downloadId, additionHeaders);
            }

            String name;
            List<String> list;

            // add addition headers which is provided by the user
            Set<Map.Entry<String, List<String>>> entries = additionHeaders.entrySet();
            for (Map.Entry<String, List<String>> e : entries) {
                name = e.getKey();
                list = e.getValue();
                if (list != null) {
                    for (String value : list) {
                        connection.addHeader(name, value);
                    }
                }
            }

        }
    }
}
 
Example 11
Source Project: FileDownloader   Source File: ConnectTask.java    License: Apache License 2.0 5 votes vote down vote up
private void addRangeHeader(FileDownloadConnection connection) throws ProtocolException {
    if (connection.dispatchAddResumeOffset(etag, profile.startOffset)) {
        return;
    }

    if (!TextUtils.isEmpty(etag)) {
        connection.addHeader("If-Match", etag);
    }
    profile.processProfile(connection);
}
 
Example 12
Source Project: FileDownloader   Source File: FileDownloadUtils.java    License: Apache License 2.0 5 votes vote down vote up
public static String findEtag(final int id, FileDownloadConnection connection) {
    if (connection == null) {
        throw new RuntimeException("connection is null when findEtag");
    }

    final String newEtag = connection.getResponseHeaderField("Etag");

    if (FileDownloadLog.NEED_LOG) {
        FileDownloadLog.d(FileDownloadUtils.class, "etag find %s for task(%d)", newEtag, id);
    }

    return newEtag;
}
 
Example 13
Source Project: FileDownloader   Source File: FileDownloadUtils.java    License: Apache License 2.0 5 votes vote down vote up
public static boolean isAcceptRange(int responseCode, FileDownloadConnection connection) {
    if (responseCode == HttpURLConnection.HTTP_PARTIAL
            || responseCode == FileDownloadConnection.RESPONSE_CODE_FROM_OFFSET) return true;

    final String acceptRanges = connection.getResponseHeaderField("Accept-Ranges");
    return "bytes".equals(acceptRanges);
}
 
Example 14
Source Project: FileDownloader   Source File: FileDownloadUtils.java    License: Apache License 2.0 5 votes vote down vote up
public static long findContentLength(final int id, FileDownloadConnection connection) {
    long contentLength = convertContentLengthString(
            connection.getResponseHeaderField("Content-Length"));
    final String transferEncoding = connection.getResponseHeaderField("Transfer-Encoding");

    if (contentLength < 0) {
        final boolean isEncodingChunked = transferEncoding != null && transferEncoding
                .equals("chunked");
        if (!isEncodingChunked) {
            // not chunked transfer encoding data
            if (FileDownloadProperties.getImpl().httpLenient) {
                // do not response content-length either not chunk transfer encoding,
                // but HTTP lenient is true, so handle as the case of transfer encoding chunk
                contentLength = TOTAL_VALUE_IN_CHUNKED_RESOURCE;
                if (FileDownloadLog.NEED_LOG) {
                    FileDownloadLog
                            .d(FileDownloadUtils.class, "%d response header is not legal but "
                                    + "HTTP lenient is true, so handle as the case of "
                                    + "transfer encoding chunk", id);
                }
            } else {
                throw new FileDownloadGiveUpRetryException("can't know the size of the "
                        + "download file, and its Transfer-Encoding is not Chunked "
                        + "either.\nyou can ignore such exception by add "
                        + "http.lenient=true to the filedownloader.properties");
            }
        } else {
            contentLength = TOTAL_VALUE_IN_CHUNKED_RESOURCE;
        }
    }

    return contentLength;
}
 
Example 15
Source Project: FileDownloader   Source File: DownloadRunnableTest.java    License: Apache License 2.0 5 votes vote down vote up
@Test
public void run_responseCodeNotMet_error() throws IOException, IllegalAccessException {
    final FileDownloadConnection connection = mock(FileDownloadConnection.class);
    when(connection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_PRECON_FAILED);
    when(mockConnectTask.connect()).thenReturn(connection);

    downloadRunnable.run();

    // retry first.
    verify(mockCallback).onRetry(any(Exception.class));

    // then callback error.
    verify(mockCallback).onError(any(Exception.class));
}
 
Example 16
Source Project: FileDownloader   Source File: DownloadRunnable.java    License: Apache License 2.0 4 votes vote down vote up
@Override
public void run() {
    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

    FileDownloadConnection connection = null;
    final long beginOffset = connectTask.getProfile().currentOffset;
    boolean isConnected = false;
    do {

        try {
            if (paused) {
                return;
            }

            isConnected = false;
            connection = connectTask.connect();
            final int code = connection.getResponseCode();

            if (FileDownloadLog.NEED_LOG) {
                FileDownloadLog
                        .d(this, "the connection[%d] for %d, is connected %s with code[%d]",
                                connectionIndex, downloadId, connectTask.getProfile(), code);
            }

            if (code != HttpURLConnection.HTTP_PARTIAL && code != HttpURLConnection.HTTP_OK) {
                throw new SocketException(FileDownloadUtils.
                        formatString(
                                "Connection failed with request[%s] response[%s] "
                                        + "http-state[%d] on task[%d-%d], which is changed"
                                        + " after verify connection, so please try again.",
                                connectTask.getRequestHeader(),
                                connection.getResponseHeaderFields(),
                                code, downloadId, connectionIndex));
            }

            isConnected = true;
            final FetchDataTask.Builder builder = new FetchDataTask.Builder();

            if (paused) return;
            fetchDataTask = builder
                    .setDownloadId(downloadId)
                    .setConnectionIndex(connectionIndex)
                    .setCallback(callback)
                    .setHost(this)
                    .setWifiRequired(isWifiRequired)
                    .setConnection(connection)
                    .setConnectionProfile(this.connectTask.getProfile())
                    .setPath(path)
                    .build();

            fetchDataTask.run();

            if (paused) fetchDataTask.pause();
            break;

        } catch (IllegalAccessException | IOException | FileDownloadGiveUpRetryException
                | IllegalArgumentException e) {
            if (callback.isRetry(e)) {
                if (isConnected && fetchDataTask == null) {
                    // connected but create fetch data task failed, give up directly.
                    FileDownloadLog.w(this, "it is valid to retry and connection is valid but"
                            + " create fetch-data-task failed, so give up directly with %s", e);
                    callback.onError(e);
                    break;
                } else {
                    if (fetchDataTask != null) {
                        //update currentOffset in ConnectionProfile
                        final long downloadedOffset = getDownloadedOffset();
                        if (downloadedOffset > 0) {
                            connectTask.updateConnectionProfile(downloadedOffset);
                        }
                    }
                    callback.onRetry(e);
                }
            } else {
                callback.onError(e);
                break;
            }

        } finally {
            if (connection != null) connection.ending();
        }
    } while (true);

}
 
Example 17
Source Project: FileDownloader   Source File: CustomComponentHolder.java    License: Apache License 2.0 4 votes vote down vote up
public FileDownloadConnection createConnection(String url) throws IOException {
    return getConnectionCreator().create(url);
}
 
Example 18
Source Project: FileDownloader   Source File: FetchDataTask.java    License: Apache License 2.0 4 votes vote down vote up
public Builder setConnection(FileDownloadConnection connection) {
    this.connection = connection;
    return this;
}
 
Example 19
Source Project: FileDownloader   Source File: ConnectTask.java    License: Apache License 2.0 4 votes vote down vote up
private void fixNeededHeader(FileDownloadConnection connection) {
    if (header == null || header.getHeaders().get("User-Agent") == null) {
        connection.addHeader("User-Agent", FileDownloadUtils.defaultUserAgent());
    }
}
 
Example 20
Source Project: FileDownloader   Source File: FileDownloadUtils.java    License: Apache License 2.0 4 votes vote down vote up
public static long findInstanceLengthFromContentRange(FileDownloadConnection connection) {
    return parseContentRangeFoInstanceLength(getContentRangeHeader(connection));
}
 
Example 21
Source Project: FileDownloader   Source File: FileDownloadUtils.java    License: Apache License 2.0 4 votes vote down vote up
private static String getContentRangeHeader(FileDownloadConnection connection) {
    return connection.getResponseHeaderField("Content-Range");
}
 
Example 22
Source Project: FileDownloader   Source File: FileDownloadUtils.java    License: Apache License 2.0 4 votes vote down vote up
public static long findContentLengthFromContentRange(FileDownloadConnection connection) {
    final String contentRange = getContentRangeHeader(connection);
    long contentLength = parseContentLengthFromContentRange(contentRange);
    if (contentLength < 0) contentLength = TOTAL_VALUE_IN_CHUNKED_RESOURCE;
    return contentLength;
}
 
Example 23
Source Project: okdownload   Source File: FileDownloadHelper.java    License: Apache License 2.0 2 votes vote down vote up
/**
 * The connection creator is used for creating {@link FileDownloadConnection} component
 * which is used to use some protocol to connect to the remote server.
 *
 * @param url the uniform resource locator, which direct the aim resource we need to connect
 * @return The connection creator.
 * @throws IOException if an I/O exception occurs.
 */
FileDownloadConnection create(String url) throws IOException;
 
Example 24
Source Project: FileDownloader   Source File: FileDownloadHelper.java    License: Apache License 2.0 2 votes vote down vote up
/**
 * The connection creator is used for creating {@link FileDownloadConnection} component
 * which is used to use some protocol to connect to the remote server.
 *
 * @param url the uniform resource locator, which direct the aim resource we need to connect
 * @return The connection creator.
 * @throws IOException if an I/O exception occurs.
 */
FileDownloadConnection create(String url) throws IOException;