Skip to content

Commit

Permalink
add https support (fix #53)
Browse files Browse the repository at this point in the history
  • Loading branch information
bertrandmartel committed Nov 12, 2017
1 parent 218762b commit b7ea312
Show file tree
Hide file tree
Showing 6 changed files with 228 additions and 28 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Check a [non-exhaustive list](./server_list.md) of compatible speed test server.
* with Gradle, from jcenter or mavenCentral :

```gradle
compile 'fr.bmartel:jspeedtest:1.31.2'
compile 'fr.bmartel:jspeedtest:1.31.3'
```

## Usage
Expand Down
2 changes: 1 addition & 1 deletion jspeedtest/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'com.jfrog.bintray'

group 'fr.bmartel'
version '1.31.2'
version '1.31.3'

apply plugin: 'java'
targetCompatibility = '1.7'
Expand Down
48 changes: 32 additions & 16 deletions jspeedtest/src/main/java/fr/bmartel/speedtest/SpeedTestTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;

import javax.net.ssl.SSLSocketFactory;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
Expand Down Expand Up @@ -64,6 +65,11 @@ public class SpeedTestTask {
*/
private int mPort;

/**
* Protocol used (http/https/ftp...).
*/
private String mProtocol;

/**
* proxy URL.
*/
Expand Down Expand Up @@ -240,8 +246,11 @@ public void startDownloadRequest(final String uri) {
try {
final URL url = new URL(uri);

switch (url.getProtocol()) {
mProtocol = url.getProtocol();

switch (mProtocol) {
case "http":
case "https":
String downloadRequest;

if (mProxyUrl != null) {
Expand All @@ -251,7 +260,11 @@ public void startDownloadRequest(final String uri) {
"\r\nProxy-Connection: Keep-Alive" + "\r\n\r\n";
} else {
this.mHostname = url.getHost();
this.mPort = url.getPort() != -1 ? url.getPort() : 80;
if (url.getProtocol().equals("http")) {
this.mPort = url.getPort() != -1 ? url.getPort() : 80;
} else {
this.mPort = url.getPort() != -1 ? url.getPort() : 443;
}
downloadRequest = "GET " + uri + " HTTP/1.1\r\n" + "Host: " + url.getHost() + "\r\n\r\n";
}
writeDownload(downloadRequest.getBytes());
Expand Down Expand Up @@ -299,6 +312,7 @@ public void startUploadRequest(final String uri, final int fileSizeOctet) {

switch (url.getProtocol()) {
case "http":
case "https":
writeUpload(uri, fileSizeOctet);
break;
case "ftp":
Expand Down Expand Up @@ -337,12 +351,18 @@ public void writeUpload(final String uri, final int fileSizeOctet) {
try {
final URL url = new URL(uri);

mProtocol = url.getProtocol();

if (mProxyUrl != null) {
this.mHostname = mProxyUrl.getHost();
this.mPort = mProxyUrl.getPort() != -1 ? mProxyUrl.getPort() : 8080;
} else {
this.mHostname = url.getHost();
this.mPort = url.getPort() != -1 ? url.getPort() : 80;
if ("http".equals(mProtocol)) {
this.mPort = url.getPort() != -1 ? url.getPort() : 80;
} else {
this.mPort = url.getPort() != -1 ? url.getPort() : 443;
}
}
mUploadFileSize = new BigDecimal(fileSizeOctet);

Expand Down Expand Up @@ -519,8 +539,12 @@ private void connectAndExecuteTask(final Runnable task, final boolean download,
closeSocket();
}
try {
/* create a basic mSocket connection */
mSocket = new Socket();
if ("https".equals(mProtocol)) {
final SSLSocketFactory ssf = (SSLSocketFactory) SSLSocketFactory.getDefault();
mSocket = ssf.createSocket();
} else {
mSocket = new Socket();
}

if (mSocketInterface.getSocketTimeout() != 0 && download) {
mSocket.setSoTimeout(mSocketInterface.getSocketTimeout());
Expand All @@ -543,7 +567,7 @@ private void connectAndExecuteTask(final Runnable task, final boolean download,
public void run() {

if (download) {
startSocketDownloadTask(mHostname);
startSocketDownloadTask(mProtocol, mHostname);
} else {
startSocketUploadTask(mHostname, uploadSize);
}
Expand Down Expand Up @@ -575,7 +599,7 @@ public void run() {
*
* @String hostname hostname to reach
*/
private void startSocketDownloadTask(final String hostname) {
private void startSocketDownloadTask(final String protocol, final String hostname) {

mDownloadTemporaryPacketSize = 0;
mDlComputationTempPacketSize = 0;
Expand Down Expand Up @@ -638,15 +662,7 @@ private void startSocketDownloadTask(final String hostname) {
if (location.charAt(0) == '/') {
mReportInterval = false;
finishTask();
startDownloadRequest("http://" + hostname + location);
} else if (location.startsWith("https")) {
//unsupported protocol
mReportInterval = false;
for (int i = 0; i < mListenerList.size(); i++) {
mListenerList.get(i).onError(SpeedTestError.UNSUPPORTED_PROTOCOL, "unsupported protocol : " +
"https");
}
finishTask();
startDownloadRequest(protocol + "://" + hostname + location);
} else {
mReportInterval = false;
finishTask();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,6 @@ public void downloadErrorTest() throws TimeoutException {
testError(SpeedTestError.MALFORMED_URI, "://" + SPEED_TEST_SERVER_HOST + ":" +
SPEED_TEST_SERVER_PORT +
SPEED_TEST_SERVER_URI_DL_1MO, true);
testError(SpeedTestError.UNSUPPORTED_PROTOCOL, "https://" + SPEED_TEST_SERVER_HOST + ":" +
SPEED_TEST_SERVER_PORT +
SPEED_TEST_SERVER_URI_DL_1MO, true);
stopTask();
}

Expand Down Expand Up @@ -225,9 +222,6 @@ public void uploadErrorTest() throws TimeoutException {
testError(SpeedTestError.MALFORMED_URI, "://" + SPEED_TEST_SERVER_HOST + ":" +
SPEED_TEST_SERVER_PORT +
SPEED_TEST_SERVER_URI_DL_1MO, false);
testError(SpeedTestError.UNSUPPORTED_PROTOCOL, "https://" + SPEED_TEST_SERVER_HOST + ":" +
SPEED_TEST_SERVER_PORT +
SPEED_TEST_SERVER_URI_DL_1MO, false);
stopTask();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
/*
* The MIT License (MIT)
* <p/>
* Copyright (c) 2016-2017 Bertrand Martel
* <p/>
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* <p/>
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* <p/>
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package fr.bmartel.speedtest.test;

import fr.bmartel.speedtest.SpeedTestReport;
import fr.bmartel.speedtest.SpeedTestSocket;
import fr.bmartel.speedtest.inter.ISpeedTestListener;
import fr.bmartel.speedtest.model.SpeedTestError;
import fr.bmartel.speedtest.model.UploadStorageType;
import fr.bmartel.speedtest.test.server.ServerRetryTest;
import fr.bmartel.speedtest.test.utils.TestCommon;
import net.jodah.concurrentunit.Waiter;
import org.junit.Assert;
import org.junit.Test;

import java.math.BigDecimal;
import java.util.concurrent.TimeoutException;

import static java.util.concurrent.TimeUnit.SECONDS;

/**
* HTTPS test.
*
* @author Bertrand Martel
*/
public class SpeedTestHttpsTest extends ServerRetryTest {

/**
* default timeout waiting time for long operation such as DL / UL
*/
private final static int WAITING_TIMEOUT_LONG_OPERATION = 10;

/**
* transfer rate value received in ops.
*/
private BigDecimal mExpectedTransferRateOps;

/**
* transfer rate value received in bps.
*/
private BigDecimal mExpectedTransferRateBps;

/**
* Common waiter for functional test.
*/
private Waiter mWaiter;

@Test
public void downloadHttpsTest() throws TimeoutException {
initTask(true);
testDownload(TestCommon.SPEED_TEST_SERVER_URI_HTTPS);
stopTask();
}

@Test
public void downloadHttpsRedirectTest() throws TimeoutException {
initTask(true);
testDownload(TestCommon.SPEED_TEST_SERVER_URI_REDIRECT_HTTPS);
stopTask();
}

@Test
public void uploadHttpsTest() throws TimeoutException {
initTask(false);
testUpload(TestCommon.SPEED_TEST_SERVER_URI_HTTPS, 1000000, true);
stopTask();
}

private void initTask(final boolean download) throws TimeoutException {
mSocket = new SpeedTestSocket();

mSocket.setSocketTimeout(TestCommon.DEFAULT_SOCKET_TIMEOUT);

mWaiter = new Waiter();

mSocket.addSpeedTestListener(new ISpeedTestListener() {

@Override
public void onProgress(final float percent, final SpeedTestReport report) {
//called to notify download progress
}

@Override
public void onCompletion(final SpeedTestReport report) {
mExpectedTransferRateOps = report.getTransferRateOctet();
mExpectedTransferRateBps = report.getTransferRateBit();
mWaiter.resume();
}

@Override
public void onError(final SpeedTestError speedTestError, final String errorMessage) {
if (mExpectedError != null && speedTestError == mExpectedError) {
mWaiter.resume();
} else {
if (download) {
mWaiter.fail(TestCommon.DOWNLOAD_ERROR_STR + speedTestError);
} else {
mWaiter.fail(TestCommon.UPLOAD_ERROR_STR + speedTestError);
}
mWaiter.resume();
}
}
});
}

private void stopTask() {
stopServer();
mSocket.setProxyServer(null);
mSocket.clearListeners();
}


/**
* Test download with given URI.
*
* @param uri
*/
private void testDownload(final String uri) throws TimeoutException {

mWaiter = new Waiter();

mSocket.startDownload(uri);

mWaiter.await(WAITING_TIMEOUT_LONG_OPERATION, SECONDS);

testTransferRate();

mSocket.forceStopTask();
}

/**
* Compare transfer rate calculated to expected value.
*/
private void testTransferRate() {
Assert.assertNotNull(mExpectedTransferRateOps);
Assert.assertNotNull(mExpectedTransferRateBps);

Assert.assertTrue(mExpectedTransferRateBps.intValue() > 0);
Assert.assertTrue(mExpectedTransferRateOps.intValue() > 0);
}

/**
* Test upload with given packet size.
*
* @param size
*/
private void testUpload(final String url, final int size, final boolean useFileStorage) throws TimeoutException {

mWaiter = new Waiter();

if (useFileStorage) {
mSocket.setUploadStorageType(UploadStorageType.FILE_STORAGE);
}

mSocket.startUpload(url, size);

mWaiter.await(WAITING_TIMEOUT_LONG_OPERATION, SECONDS);

testTransferRate();

mSocket.forceStopTask();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
package fr.bmartel.speedtest.test.utils;

/**
* Commong vars for tests.
* Common vars for tests.
*
* @author Bertrand Martel
*/
Expand Down Expand Up @@ -64,7 +64,7 @@ public class TestCommon {
/**
* proxy server used.
*/
public final static String SPEED_TEST_PROXY_SERVER = "http://216.56.48.118:9000";
public final static String SPEED_TEST_PROXY_SERVER = "http://120.194.18.90:81";

/**
* redirect server.
Expand All @@ -87,9 +87,14 @@ public class TestCommon {
public final static String SPEED_TEST_SERVER_URI_DL_1MO = "/fichiers/1Mo.dat";

/**
* A fake uri to test connection error.
* sample URI for https test.
*/
public final static String SPEED_TEST_SERVER_FAKE_URI = "/fichiers/qsdqdqsdqsd";
public final static String SPEED_TEST_SERVER_URI_HTTPS = "https://www.example.com/";

/**
* sample URI redirect for https test.
*/
public final static String SPEED_TEST_SERVER_URI_REDIRECT_HTTPS = "https://stackoverflow.com/users/2614364";

/**
* speed examples server port.
Expand Down

0 comments on commit b7ea312

Please sign in to comment.