]> gitweb.stoutner.com Git - PrivacyBrowserAndroid.git/blobdiff - app/src/main/java/com/stoutner/privacybrowser/coroutines/PrepareSaveDialogCoroutine.kt
Update the file name when the URL changes in SaveDialog. https://redmine.stoutner...
[PrivacyBrowserAndroid.git] / app / src / main / java / com / stoutner / privacybrowser / coroutines / PrepareSaveDialogCoroutine.kt
index 1af0320745446da3ff92bba0d76f2a9dd768e54c..200e049204ab3acb5c8fc3f7d08ffa5450b139dd 100644 (file)
@@ -20,9 +20,6 @@
 package com.stoutner.privacybrowser.coroutines
 
 import android.content.Context
-import android.net.Uri
-import android.webkit.CookieManager
-import android.webkit.MimeTypeMap
 
 import androidx.fragment.app.DialogFragment
 import androidx.fragment.app.FragmentManager
@@ -31,16 +28,14 @@ import com.stoutner.privacybrowser.R
 import com.stoutner.privacybrowser.activities.MainWebViewActivity
 import com.stoutner.privacybrowser.dataclasses.PendingDialogDataClass
 import com.stoutner.privacybrowser.dialogs.SaveDialog
-import com.stoutner.privacybrowser.helpers.ProxyHelper
+import com.stoutner.privacybrowser.helpers.UrlHelper
+
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
 
 import java.lang.Exception
-import java.net.HttpURLConnection
-import java.net.URL
-import java.text.NumberFormat
 
 object PrepareSaveDialogCoroutine {
     @JvmStatic
@@ -49,108 +44,13 @@ object PrepareSaveDialogCoroutine {
         CoroutineScope(Dispatchers.Main).launch {
             // Make the network requests on the IO thread.
             withContext(Dispatchers.IO) {
-                // Define the strings.
-                var formattedFileSize: String
-                var fileNameString: String
-
-                // Populate the file size and name strings.
-                if (urlString.startsWith("data:")) {  // The URL contains the entire data of an image.
-                    // Remove `data:` from the beginning of the URL.
-                    val urlWithoutData = urlString.substring(5)
-
-                    // Get the URL MIME type, which ends with a `;`.
-                    val urlMimeType = urlWithoutData.substring(0, urlWithoutData.indexOf(";"))
-
-                    // Get the Base64 data, which begins after a `,`.
-                    val base64DataString = urlWithoutData.substring(urlWithoutData.indexOf(",") + 1)
-
-                    // Calculate the file size of the data URL.  Each Base64 character represents 6 bits.
-                    formattedFileSize = NumberFormat.getInstance().format(base64DataString.length * 3L / 4) + " " + context.getString(R.string.bytes)
-
-                    // Set the file name according to the MIME type.
-                    fileNameString = context.getString(R.string.file) + "." + MimeTypeMap.getSingleton().getExtensionFromMimeType(urlMimeType)
-                } else {  // The URL refers to the location of the data.
-                    // Initialize the formatted file size string.
-                    formattedFileSize = context.getString(R.string.unknown_size)
-
-                    // Because everything relating to requesting data from a webserver can throw errors, the entire section must catch exceptions.
-                    try {
-                        // Convert the URL string to a URL.
-                        val url = URL(urlString)
-
-                        // Instantiate the proxy helper.
-                        val proxyHelper = ProxyHelper()
-
-                        // Get the current proxy.
-                        val proxy = proxyHelper.getCurrentProxy(context)
-
-                        // Open a connection to the URL.  No data is actually sent at this point.
-                        val httpUrlConnection = url.openConnection(proxy) as HttpURLConnection
-
-                        // Add the user agent to the header property.
-                        httpUrlConnection.setRequestProperty("User-Agent", userAgent)
-
-                        // Add the cookies if they are enabled.
-                        if (cookiesEnabled) {
-                            // Get the cookies for the current domain.
-                            val cookiesString = CookieManager.getInstance().getCookie(url.toString())
-
-                            // Add the cookies if they are not null.
-                            if (cookiesString != null)
-                                httpUrlConnection.setRequestProperty("Cookie", cookiesString)
-                        }
-
-                        // The actual network request is in a `try` bracket so that `disconnect()` is run in the `finally` section even if an error is encountered in the main block.
-                        try {
-                            // Get the status code.  This initiates a network connection.
-                            val responseCode = httpUrlConnection.responseCode
-
-                            // Check the response code.
-                            if (responseCode >= 400) {  // The response code is an error message.
-                                // Set the formatted file size to indicate a bad URL.
-                                formattedFileSize = context.getString(R.string.invalid_url)
-
-                                // Set the file name according to the URL.
-                                fileNameString = getFileNameFromUrl(context, urlString, null)
-                            } else {  // The response code is not an error message.
-                                // Get the headers.
-                                val contentLengthString = httpUrlConnection.getHeaderField("Content-Length")
-                                val contentDispositionString = httpUrlConnection.getHeaderField("Content-Disposition")
-                                var contentTypeString = httpUrlConnection.contentType
-
-                                // Remove anything after the MIME type in the content type string.
-                                if (contentTypeString.contains(";"))
-                                    contentTypeString = contentTypeString.substring(0, contentTypeString.indexOf(";"))
-
-                                // Only process the content length string if it isn't null.
-                                if (contentLengthString != null) {
-                                    // Convert the content length string to a long.
-                                    val fileSize = contentLengthString.toLong()
-
-                                    // Format the file size.
-                                    formattedFileSize = NumberFormat.getInstance().format(fileSize) + " " + context.getString(R.string.bytes)
-                                }
-
-                                // Get the file name string from the content disposition.
-                                fileNameString = getFileNameFromHeaders(context, contentDispositionString, contentTypeString, urlString)
-                            }
-                        } finally {
-                            // Disconnect the HTTP URL connection.
-                            httpUrlConnection.disconnect()
-                        }
-                    } catch (exception: Exception) {
-                        // Set the formatted file size to indicate a bad URL.
-                        formattedFileSize = context.getString(R.string.invalid_url)
-
-                        // Set the file name according to the URL.
-                        fileNameString = getFileNameFromUrl(context, urlString, null)
-                    }
-                }
+                // Get the file name and size.
+                val fileNameAndSize = UrlHelper.getNameAndSize(context, urlString, userAgent, cookiesEnabled)
 
                 // Display the dialog on the main thread.
                 withContext(Dispatchers.Main) {
                     // Instantiate the save dialog.
-                    val saveDialogFragment: DialogFragment = SaveDialog.saveUrl(urlString, formattedFileSize, fileNameString, userAgent, cookiesEnabled)
+                    val saveDialogFragment: DialogFragment = SaveDialog.saveUrl(urlString, fileNameAndSize.first, fileNameAndSize.second, userAgent, cookiesEnabled)
 
                     // Try to show the dialog.  Sometimes the window is not active.
                     try {
@@ -164,63 +64,4 @@ object PrepareSaveDialogCoroutine {
             }
         }
     }
-
-    // Content dispositions can contain other text besides the file name, and they can be in any order.
-    // Elements are separated by semicolons.  Sometimes the file names are contained in quotes.
-    @JvmStatic
-    fun getFileNameFromHeaders(context: Context, contentDispositionString: String?, contentTypeString: String?, urlString: String): String {
-        // Define a file name string.
-        var fileNameString: String
-
-        // Only process the content disposition string if it isn't null.
-        if (contentDispositionString != null) {  // The content disposition is not null.
-            // Check to see if the content disposition contains a file name.
-            if (contentDispositionString.contains("filename=")) {  // The content disposition contains a filename.
-                // Get the part of the content disposition after `filename=`.
-                fileNameString = contentDispositionString.substring(contentDispositionString.indexOf("filename=") + 9)
-
-                // Remove any `;` and anything after it.  This removes any entries after the filename.
-                if (fileNameString.contains(";"))
-                    fileNameString = fileNameString.substring(0, fileNameString.indexOf(";") - 1)
-
-                // Remove any `"` at the beginning of the string.
-                if (fileNameString.startsWith("\""))
-                    fileNameString = fileNameString.substring(1)
-
-                // Remove any `"` at the end of the string.
-                if (fileNameString.endsWith("\""))
-                    fileNameString = fileNameString.substring(0, fileNameString.length - 1)
-            } else {  // The headers contain no useful information.
-                // Get the file name string from the URL.
-                fileNameString = getFileNameFromUrl(context, urlString, contentTypeString)
-            }
-        } else {  // The content disposition is null.
-            // Get the file name string from the URL.
-            fileNameString = getFileNameFromUrl(context, urlString, contentTypeString)
-        }
-
-        // Return the file name string.
-        return fileNameString
-    }
-
-    private fun getFileNameFromUrl(context: Context, urlString: String, contentTypeString: String?): String {
-        // Convert the URL string to a URI.
-        val uri = Uri.parse(urlString)
-
-        // Get the last path segment.
-        var lastPathSegment = uri.lastPathSegment
-
-        // Use a default file name if the last path segment is null.
-        if (lastPathSegment == null) {
-            // Set the last path segment to be the generic file name.
-            lastPathSegment = context.getString(R.string.file)
-
-            // Add a file extension if it can be detected.
-            if (MimeTypeMap.getSingleton().hasMimeType(contentTypeString))
-                lastPathSegment = lastPathSegment + "." + MimeTypeMap.getSingleton().getExtensionFromMimeType(contentTypeString)
-        }
-
-        // Return the last path segment as the file name.
-        return lastPathSegment
-    }
 }