aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/server/Download.kt
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/kotlin/xyz/brysonsteck/serverfordummies/server/Download.kt')
-rw-r--r--app/src/main/kotlin/xyz/brysonsteck/serverfordummies/server/Download.kt119
1 files changed, 119 insertions, 0 deletions
diff --git a/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/server/Download.kt b/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/server/Download.kt
new file mode 100644
index 0000000..d7e5aed
--- /dev/null
+++ b/app/src/main/kotlin/xyz/brysonsteck/serverfordummies/server/Download.kt
@@ -0,0 +1,119 @@
+package xyz.brysonsteck.serverfordummies.server
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+class Download: Runnable {
+ public enum class Status {
+ DOWNLOADING, PAUSED, COMPLETE, CANCELLED, ERROR
+ }
+ public var size: Int
+ public var downloaded: Int
+ public var contentLength: Int
+ public var status: Status
+
+ private final val MAX_BUFFER_SIZE: Number = 1024
+
+ private var url: URL
+ private var dir: String
+
+ constructor (url: URL, dir: String) {
+ this.url = url
+ this.dir = dir
+ size = -1
+ downloaded = 0
+ status = Status.DOWNLOADING
+ contentLength = 1
+ }
+
+ public fun start() {
+ val thread = Thread(this)
+ thread.start()
+ }
+
+ private fun getFilename(url: URL): String {
+ val filename = url.getFile()
+ return filename.substring(filename.lastIndexOf('/') + 1)
+ }
+
+ override fun run() {
+ var stream: InputStream? = null
+ var file: RandomAccessFile? = null
+
+ try {
+ // Open connection to URL.
+ var connection = url.openConnection() as HttpURLConnection;
+
+ // Specify what portion of file to download.
+ connection.setRequestProperty("Range", "bytes=" + downloaded + "-");
+
+ // Connect to server.
+ connection.connect();
+
+ // Make sure response code is in the 200 range.
+ if (connection.responseCode / 100 != 2) {
+ status = Status.ERROR
+ }
+
+ // Check for valid content length.
+ contentLength = connection.getContentLength();
+ if (contentLength < 1) {
+ status = Status.ERROR
+ }
+
+ /* Set the size for this download if it
+ hasn't been already set. */
+ if (size == -1) {
+ size = contentLength;
+ }
+
+ // Open file and seek to the end of it.
+ file = RandomAccessFile(dir + getFilename(url), "rw");
+ file.seek(downloaded.toLong());
+
+ stream = connection.getInputStream();
+ while (status == Status.DOWNLOADING) {
+ /* Size buffer according to how much of the
+ file is left to download. */
+ val buffer: ByteArray;
+ if (size - downloaded > MAX_BUFFER_SIZE as Int) {
+ buffer = ByteArray(MAX_BUFFER_SIZE)
+ } else {
+ buffer = ByteArray(size - downloaded);
+ }
+
+ // Read from server into buffer.
+ val read = stream.read(buffer);
+ if (read == -1)
+ break;
+
+ // Write buffer to file.
+ file.write(buffer, 0, read);
+ downloaded += read;
+ }
+
+ /* Change status to complete if this point was
+ reached because downloading has finished. */
+ if (status == Status.DOWNLOADING) {
+ status = Status.COMPLETE;
+ }
+ } catch (e: Exception) {
+ status = Status.ERROR
+ } finally {
+ // Close file.
+ if (file != null) {
+ try {
+ file.close();
+ } catch (e: Exception) {}
+ }
+
+ // Close connection to server.
+ if (stream != null) {
+ try {
+ stream.close();
+ } catch (e: Exception) {}
+ }
+ }
+ }
+}