Android client: do Authorization pre-emptively; don't double all HTTP requests

Stupid painful Apache HttpClient.

This also bumps minimal SDK version to 8 (Froyo) instead of 4 (Donut) because I'm
lazy and wanted to use the android.util.Base64 in Froyo.  Should fix that later.
This commit is contained in:
Brad Fitzpatrick 2010-12-20 19:27:22 -08:00
parent dfc058a4c6
commit 052ba3446b
3 changed files with 51 additions and 28 deletions

View File

@ -3,10 +3,14 @@
package="com.danga.camli"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="4" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- Note: only using SDK 8 for android.util.Base64; could fix and let
Donut users (SDK 4) use this too .... -->
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="8" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.BATTERY_STATS" />
@ -37,31 +41,31 @@
</intent-filter>
</activity>
<activity android:name=".SettingsActivity">
</activity>
<activity android:name=".SettingsActivity">
</activity>
<receiver android:name=".OnBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:name=".OnBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:name=".OnAlarmReceiver">
</receiver>
<receiver android:name=".OnAlarmReceiver">
</receiver>
<receiver android:name=".WifiPowerReceiver"
android:enabled="true"
android:priority="0">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
</intent-filter>
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
</intent-filter>
</receiver>
</application>
</manifest>
</manifest>

View File

@ -8,4 +8,4 @@
# project structure.
# Project target.
target=android-4
target=android-8

View File

@ -33,6 +33,7 @@ import org.json.JSONObject;
import android.os.ParcelFileDescriptor;
import android.os.SystemClock;
import android.util.Base64;
import android.util.Log;
public class UploadThread extends Thread {
@ -40,26 +41,42 @@ public class UploadThread extends Thread {
private final UploadService mService;
private final HostPort mHostPort;
private final String mPassword;
private LinkedList<QueuedFile> mQueue;
private final AtomicBoolean mStopRequested = new AtomicBoolean(false);
private final DefaultHttpClient mUA = new DefaultHttpClient();
private static final String USERNAME = "TODO-DUMMY-USER";
public UploadThread(UploadService uploadService, HostPort hp, String password) {
mService = uploadService;
mHostPort = hp;
mPassword = password;
CredentialsProvider creds = new BasicCredentialsProvider();
creds.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("TODO-DUMMY-USER",
password));
mUA.setCredentialsProvider(creds);
// TODO: this crap results in double HTTP requests on everything.
// And the setAuthenticationPreemptive method described at
// http://hc.apache.org/httpclient-3.x/authentication.html
// doesn't seem to be available on Android. So screw it, do it by hand instead
// below, manually setting the Authorization header.
//
//CredentialsProvider creds = new BasicCredentialsProvider();
//creds.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(USERNAME,
//password));
//mUA.setCredentialsProvider(creds);
Log.d(TAG, "Authorization: " + getBasicAuthHeaderValue());
}
public void stopPlease() {
mStopRequested.set(true);
}
private String getBasicAuthHeaderValue() {
return "Basic " + Base64.encodeToString((USERNAME + ":" + mPassword).getBytes(),
Base64.NO_WRAP | Base64.NO_PADDING);
}
@Override
public void run() {
if (!mHostPort.isValid()) {
@ -104,6 +121,7 @@ public class UploadThread extends Thread {
// Do the pre-upload.
HttpPost preReq = new HttpPost("http://" + mHostPort
+ "/camli/preupload");
preReq.setHeader("Authorization", getBasicAuthHeaderValue());
List<BasicNameValuePair> uploadKeys = new ArrayList<BasicNameValuePair>();
uploadKeys.add(new BasicNameValuePair("camliversion", "1"));
@ -155,6 +173,7 @@ public class UploadThread extends Thread {
}
HttpPost uploadReq = new HttpPost(uploadUrl);
uploadReq.setHeader("Authorization", getBasicAuthHeaderValue());
MultipartEntity entity = new MultipartEntity();
uploadReq.setEntity(entity);
HttpResponse uploadRes = null;