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:
		
							parent
							
								
									7dff9a9499
								
							
						
					
					
						commit
						41b3eab1fd
					
				| @ -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()); | ||||
| 
 | ||||
|  | ||||
| @ -144,4 +144,8 @@ public class HttpDownloader extends Downloader { | ||||
|         return this.statusCode != 304; | ||||
|     } | ||||
| 
 | ||||
|     public int getStatusCode() { | ||||
|         return statusCode; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -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(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -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; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -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() { | ||||
|  | ||||
| @ -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) { | ||||
|  | ||||
| @ -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; | ||||
|         } | ||||
|  | ||||
| @ -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) { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Peter Serwylo
						Peter Serwylo