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.io.IOException;
32 import java.lang.ref.WeakReference;
33 import java.net.HttpURLConnection;
34 import java.net.Proxy;
36 import java.text.NumberFormat;
38 public class GetUrlSize extends AsyncTask<String, Void, String> {
39 // Define a weak reference for the calling context and fragment.
40 private WeakReference<Context> contextWeakReference;
41 private WeakReference<AlertDialog> alertDialogWeakReference;
43 // Define the class variables.
44 private String userAgent;
45 private boolean cookiesEnabled;
47 // The public constructor.
48 public GetUrlSize(Context context, AlertDialog alertDialog, String userAgent, boolean cookiesEnabled) {
49 // Populate the week references to the calling activity and fragment.
50 contextWeakReference = new WeakReference<>(context);
51 alertDialogWeakReference = new WeakReference<>(alertDialog);
53 // Store the class variables.
54 this.userAgent = userAgent;
55 this.cookiesEnabled = cookiesEnabled;
59 protected String doInBackground(String... urlToSave) {
60 // Get a handle for the context and the fragment.
61 Context context = contextWeakReference.get();
62 AlertDialog alertDialog = alertDialogWeakReference.get();
64 // Abort if the fragment is gone.
65 if (alertDialog == null) {
69 // Initialize the formatted file size string.
70 String formattedFileSize = context.getString(R.string.unknown_size);
72 // Because everything relating to requesting data from a webserver can throw errors, the entire section much catch `IOExceptions`.
74 // Get the URL from the calling fragment.
75 URL url = new URL(urlToSave[0]);
77 // Instantiate the proxy helper.
78 ProxyHelper proxyHelper = new ProxyHelper();
80 // Get the current proxy.
81 Proxy proxy = proxyHelper.getCurrentProxy(context);
83 // Open a connection to the URL. No data is actually sent at this point.
84 HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(proxy);
86 // Add the user agent to the header property.
87 httpURLConnection.setRequestProperty("User-Agent", userAgent);
89 // Add the cookies if they are enabled.
91 // Ge the cookies for the current domain.
92 String cookiesString = CookieManager.getInstance().getCookie(url.toString());
94 // Only add the cookies if they are not null.
95 if (cookiesString != null) {
96 // Add the cookies to the header property.
97 httpURLConnection.setRequestProperty("Cookie", cookiesString);
101 // 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.
103 // Exit if the task has been cancelled.
105 // Disconnect the HTTP URL connection.
106 httpURLConnection.disconnect();
108 // Return the formatted file size string.
109 return formattedFileSize;
112 // Get the status code.
113 int responseCode = httpURLConnection.getResponseCode();
115 // Exit if the task has been cancelled.
117 // Disconnect the HTTP URL connection.
118 httpURLConnection.disconnect();
120 // Return the formatted file size string.
121 return formattedFileSize;
124 // Check the response code.
125 if (responseCode >= 400) { // The response code is an error message.
126 // Set the formatted file size to indicate a bad URL.
127 formattedFileSize = context.getString(R.string.bad_url);
128 } else { // The response code is not an error message.
129 // Get the content length header.
130 String contentLengthString = httpURLConnection.getHeaderField("Content-Length");
132 // Define the file size long.
135 // Make sure the content length isn't null.
136 if (contentLengthString != null) { // The content length isn't null.
137 // Convert the content length to a long.
138 fileSize = Long.parseLong(contentLengthString);
140 // Format the file size.
141 formattedFileSize = NumberFormat.getInstance().format(fileSize) + " " + context.getString(R.string.bytes);
145 // Disconnect the HTTP URL connection.
146 httpURLConnection.disconnect();
148 } catch (IOException exception) {
149 // Set the formatted file size to indicate a bad URL.
150 formattedFileSize = context.getString(R.string.bad_url);
153 // Return the formatted file size string.
154 return formattedFileSize;
157 // `onPostExecute()` operates on the UI thread.
159 protected void onPostExecute(String fileSize) {
160 // Get a handle for the context and alert dialog.
161 AlertDialog alertDialog = alertDialogWeakReference.get();
163 // Abort if the alert dialog is gone.
164 if (alertDialog == null) {
168 // Get a handle for the file size text view.
169 TextView fileSizeTextView = alertDialog.findViewById(R.id.file_size_textview);
171 // Update the file size.
172 fileSizeTextView.setText(fileSize);