WIP: Bluetooth successfully sending entire HTTP responses to GET requests.

Now to move the code into a BluetoothDownloader and decide how best
to handle connections, error handling, multiple downloads over one
socket, etc.
This commit is contained in:
Peter Serwylo 2014-10-20 23:50:48 +10:30 committed by Peter Serwylo
parent 7dff9a9499
commit 41b3eab1fd
8 changed files with 64 additions and 15 deletions

View File

@ -168,6 +168,7 @@ public abstract class LocalRepoService extends Service {
}
protected abstract String getIpAddressToBindTo();
protected abstract int getPortToBindTo();
protected void startWebServer() {
Runnable webServer = new Runnable() {
@ -178,7 +179,7 @@ public abstract class LocalRepoService extends Service {
localHttpd = new LocalHTTPD(
LocalRepoService.this,
getIpAddressToBindTo(),
FDroidApp.port,
getPortToBindTo(),
getFilesDir(),
useHttps());

View File

@ -144,4 +144,8 @@ public class HttpDownloader extends Downloader {
return this.statusCode != 304;
}
public int getStatusCode() {
return statusCode;
}
}

View File

@ -151,7 +151,6 @@ public class WifiStateChangeService extends Service {
Intent intent = new Intent(BROADCAST);
LocalBroadcastManager.getInstance(WifiStateChangeService.this).sendBroadcast(intent);
WifiStateChangeService.this.stopSelf();
FDroidApp.localRepoWifi.restartIfRunning();
}
}

View File

@ -1,5 +1,7 @@
package org.fdroid.fdroid.localrepo;
import org.fdroid.fdroid.FDroidApp;
/**
* Starts the local repo service but bound to 127.0.0.1.
* Also, it does not care about whether wifi is connected or not,
@ -26,4 +28,9 @@ public class LocalRepoProxyService extends LocalRepoService {
protected String getIpAddressToBindTo() {
return "127.0.0.1";
}
@Override
protected int getPortToBindTo() {
return FDroidApp.port + 1;
}
}

View File

@ -71,6 +71,11 @@ public class LocalRepoWifiService extends LocalRepoService {
return FDroidApp.ipAddressString;
}
@Override
protected int getPortToBindTo() {
return FDroidApp.port;
}
private Preferences.ChangeListener localRepoBonjourChangeListener = new Preferences.ChangeListener() {
@Override
public void onPreferenceChange() {

View File

@ -5,6 +5,7 @@ import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.util.Log;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.net.HttpDownloader;
import org.fdroid.fdroid.net.bluetooth.httpish.Request;
@ -120,20 +121,21 @@ public class BluetoothServer extends Thread {
Log.d(TAG, "Received Bluetooth request from client, will process it now.");
try {
HttpDownloader downloader = new HttpDownloader("http://127.0.0.1/" + request.getPath(), context);
HttpDownloader downloader = new HttpDownloader("http://127.0.0.1:" + ( FDroidApp.port + 1 ) + "/" + request.getPath(), context);
Response.ResponseBuilder builder;
Response.Builder builder;
if (request.getMethod().equals(Request.Methods.HEAD)) {
builder = new Response.ResponseBuilder();
builder = new Response.Builder();
} else {
builder = new Response.ResponseBuilder(downloader.getInputStream());
builder = new Response.Builder(downloader.getInputStream());
}
// TODO: At this stage, will need to download the file to get this info.
// However, should be able to make totalDownloadSize and getCacheTag work without downloading.
return builder
.setStatusCode(200)
.setStatusCode(downloader.getStatusCode())
.setFileSize(downloader.totalDownloadSize())
.build();
} catch (IOException e) {

View File

@ -6,6 +6,7 @@ import org.fdroid.fdroid.net.bluetooth.BluetoothConnection;
import org.fdroid.fdroid.net.bluetooth.FileDetails;
import org.fdroid.fdroid.net.bluetooth.httpish.headers.Header;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
@ -41,6 +42,17 @@ public class Response {
return statusCode;
}
public int getFileSize() {
if (headers != null) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
if (entry.getKey().toLowerCase().equals("content-length")) {
return Integer.parseInt( entry.getValue()); // TODO: error handling.
}
}
}
return -1;
}
/**
* Extracts meaningful headers from the response into a more useful and safe
* {@link org.fdroid.fdroid.net.bluetooth.FileDetails} object.
@ -85,30 +97,47 @@ public class Response {
}
public static class ResponseBuilder {
public String readContents() throws IOException {
int size = getFileSize();
if (contentStream == null || getFileSize() <= 0) {
return null;
}
int pos = 0;
byte[] buffer = new byte[4096];
ByteArrayOutputStream contents = new ByteArrayOutputStream(size);
while (pos < size) {
int read = contentStream.read(buffer);
pos += read;
contents.write(buffer, 0, read);
}
return contents.toString();
}
public static class Builder {
private InputStream contentStream;
private int statusCode = 200;
private int fileSize = -1;
private String etag = null;
public ResponseBuilder() {}
public Builder() {}
public ResponseBuilder(InputStream contentStream) {
public Builder(InputStream contentStream) {
this.contentStream = contentStream;
}
public ResponseBuilder setStatusCode(int statusCode) {
public Builder setStatusCode(int statusCode) {
this.statusCode = statusCode;
return this;
}
public ResponseBuilder setFileSize(int fileSize) {
public Builder setFileSize(int fileSize) {
this.fileSize = fileSize;
return this;
}
public ResponseBuilder setETag(String etag) {
public Builder setETag(String etag) {
this.etag = etag;
return this;
}

View File

@ -133,12 +133,14 @@ public class BluetoothDeviceListFragment extends ThemeableListFragment {
Log.d(TAG, "Testing bluetooth connection (opening connection first).");
BluetoothConnection connection = client.openConnection();
Log.d(TAG, "Creating HEAD request for resource at \"/\"...");
Request head = Request.createHEAD("/", connection);
Request head = Request.createGET("/", connection);
Log.d(TAG, "Sending request...");
Response response = head.send();
Log.d(TAG, "Response from bluetooth: " + response.getStatusCode());
String contents = response.readContents();
Log.d(TAG, contents);
} catch (IOException e) {
Log.e(TAG, "Error: " + e.getMessage());
}
/*if (device.getBondState() == BluetoothDevice.BOND_NONE) {