2 * Copyright © 2020 Soren Stoutner <soren@stoutner.com>.
4 * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
6 * Privacy Browser is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * Privacy Browser is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Privacy Browser. If not, see <http://www.gnu.org/licenses/>.
20 package com.stoutner.privacybrowser.asynctasks;
22 import android.app.AlertDialog;
23 import android.content.Context;
24 import android.os.AsyncTask;
25 import android.webkit.CookieManager;
26 import android.widget.TextView;
28 import com.stoutner.privacybrowser.R;
29 import com.stoutner.privacybrowser.helpers.ProxyHelper;
31 import java.lang.ref.WeakReference;
32 import java.net.HttpURLConnection;
33 import java.net.Proxy;
35 import java.text.NumberFormat;
37 public class GetUrlSize extends AsyncTask<String, Void, String> {
38 // Define a weak reference for the calling context and fragment.
39 private WeakReference<Context> contextWeakReference;
40 private WeakReference<AlertDialog> alertDialogWeakReference;
42 // Define the class variables.
43 private String userAgent;
44 private boolean cookiesEnabled;
46 // The public constructor.
47 public GetUrlSize(Context context, AlertDialog alertDialog, String userAgent, boolean cookiesEnabled) {
48 // Populate the week references to the calling activity and fragment.
49 contextWeakReference = new WeakReference<>(context);
50 alertDialogWeakReference = new WeakReference<>(alertDialog);
52 // Store the class variables.
53 this.userAgent = userAgent;
54 this.cookiesEnabled = cookiesEnabled;
58 protected String doInBackground(String... urlToSave) {
59 // Get a handle for the context and the fragment.
60 Context context = contextWeakReference.get();
61 AlertDialog alertDialog = alertDialogWeakReference.get();
63 // Abort if the fragment is gone.
64 if (alertDialog == null) {
68 // Initialize the formatted file size string.
69 String formattedFileSize = context.getString(R.string.unknown_size);
71 // Because everything relating to requesting data from a webserver can throw errors, the entire section much catch `IOExceptions`.
73 // Get the URL from the calling fragment.
74 URL url = new URL(urlToSave[0]);
76 // Instantiate the proxy helper.
77 ProxyHelper proxyHelper = new ProxyHelper();
79 // Get the current proxy.
80 Proxy proxy = proxyHelper.getCurrentProxy(context);
82 // Open a connection to the URL. No data is actually sent at this point.
83 HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection(proxy);
85 // Add the user agent to the header property.
86 httpUrlConnection.setRequestProperty("User-Agent", userAgent);
88 // Add the cookies if they are enabled.
90 // Ge the cookies for the current domain.
91 String cookiesString = CookieManager.getInstance().getCookie(url.toString());
93 // Only add the cookies if they are not null.
94 if (cookiesString != null) {
95 // Add the cookies to the header property.
96 httpUrlConnection.setRequestProperty("Cookie", cookiesString);
100 // 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.
102 // Exit if the task has been cancelled.
104 // Disconnect the HTTP URL connection.
105 httpUrlConnection.disconnect();
107 // Return the formatted file size string.
108 return formattedFileSize;
111 // Get the status code.
112 int responseCode = httpUrlConnection.getResponseCode();
114 // Exit if the task has been cancelled.
116 // Disconnect the HTTP URL connection.
117 httpUrlConnection.disconnect();
119 // Return the formatted file size string.
120 return formattedFileSize;
123 // Check the response code.
124 if (responseCode >= 400) { // The response code is an error message.
125 // Set the formatted file size to indicate a bad URL.
126 formattedFileSize = context.getString(R.string.invalid_url);
127 } else { // The response code is not an error message.
128 // Get the content length header.
129 String contentLengthString = httpUrlConnection.getHeaderField("Content-Length");
131 // Define the file size long.
134 // Make sure the content length isn't null.
135 if (contentLengthString != null) { // The content length isn't null.
136 // Convert the content length to a long.
137 fileSize = Long.parseLong(contentLengthString);
139 // Format the file size.
140 formattedFileSize = NumberFormat.getInstance().format(fileSize) + " " + context.getString(R.string.bytes);
144 // Disconnect the HTTP URL connection.
145 httpUrlConnection.disconnect();
147 } catch (Exception exception) {
148 // Set the formatted file size to indicate a bad URL.
149 formattedFileSize = context.getString(R.string.invalid_url);
152 // Return the formatted file size string.
153 return formattedFileSize;
156 // `onPostExecute()` operates on the UI thread.
158 protected void onPostExecute(String fileSize) {
159 // Get a handle for the context and alert dialog.
160 AlertDialog alertDialog = alertDialogWeakReference.get();
162 // Abort if the alert dialog is gone.
163 if (alertDialog == null) {
167 // Get a handle for the file size text view.
168 TextView fileSizeTextView = alertDialog.findViewById(R.id.file_size_textview);
170 // Update the file size.
171 fileSizeTextView.setText(fileSize);