com.liulishuo.filedownloader.connection.FileDownloadConnection Java Examples

The following examples show how to use com.liulishuo.filedownloader.connection.FileDownloadConnection. 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 File: ConnectionProfile.java    From FileDownloader with 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 #2
Source File: FileDownloadUtilsTest.java    From FileDownloader with 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 #3
Source File: FileDownloadUtils.java    From FileDownloader with 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 #4
Source File: FileDownloadUtils.java    From FileDownloader with 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 #5
Source File: FetchDataTask.java    From FileDownloader with 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 #6
Source File: FileDownloadUtils.java    From FileDownloader with 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 #7
Source File: OkHttp3Connection.java    From filedownloader-okhttp3-connection with Apache License 2.0 5 votes vote down vote up
@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 File: DownloadRunnableTest.java    From FileDownloader with 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 #9
Source File: OkHttp3Connection.java    From filedownloader-okhttp3-connection with Apache License 2.0 5 votes vote down vote up
@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 #10
Source File: FileDownloadUtils.java    From FileDownloader with 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 #11
Source File: DownloadLaunchRunnable.java    From FileDownloader with 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 #12
Source File: FileDownloadUtils.java    From FileDownloader with 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 File: ConnectTask.java    From FileDownloader with 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 #14
Source File: ConnectTask.java    From FileDownloader with 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 #15
Source File: ConnectTask.java    From FileDownloader with 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 #16
Source File: ConnectTask.java    From FileDownloader with 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 #17
Source File: CustomComponentHolder.java    From FileDownloader with Apache License 2.0 4 votes vote down vote up
public FileDownloadConnection createConnection(String url) throws IOException {
    return getConnectionCreator().create(url);
}
 
Example #18
Source File: FileDownloadUtils.java    From FileDownloader with Apache License 2.0 4 votes vote down vote up
public static long findInstanceLengthFromContentRange(FileDownloadConnection connection) {
    return parseContentRangeFoInstanceLength(getContentRangeHeader(connection));
}
 
Example #19
Source File: FileDownloadUtils.java    From FileDownloader with Apache License 2.0 4 votes vote down vote up
private static String getContentRangeHeader(FileDownloadConnection connection) {
    return connection.getResponseHeaderField("Content-Range");
}
 
Example #20
Source File: FileDownloadUtils.java    From FileDownloader with 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 #21
Source File: FetchDataTask.java    From FileDownloader with Apache License 2.0 4 votes vote down vote up
public Builder setConnection(FileDownloadConnection connection) {
    this.connection = connection;
    return this;
}
 
Example #22
Source File: DownloadRunnable.java    From FileDownloader with 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 #23
Source File: FileDownloadHelper.java    From okdownload with 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 File: FileDownloadHelper.java    From FileDownloader with 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;