-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add project with abstract class + 2 concrete implementations
- Loading branch information
1 parent
5b17266
commit 563794b
Showing
9 changed files
with
568 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
gen/ | ||
.idea/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
package="github.daneren2005.serverproxy"> | ||
|
||
<uses-sdk android:targetSdkVersion="19" | ||
android:minSdkVersion="8" /> | ||
|
||
</manifest> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,12 @@ | ||
SocketProxy | ||
ServerProxy | ||
=========== | ||
|
||
ServerProxy is a Android library to provide easy to use classes to create a local server proxies. The following classes exist: | ||
|
||
ServerProxy: abstract class which creates a socket and has methods to get a url to reference it. | ||
-start: Start the proxy listening for requests | ||
-stop: Stop the proxy listening for requests | ||
-getPrivateAddress: Get a local url good for being passed internally to another application on the same device | ||
-getPublicAddress: Get a url good for being passed to another device on the same LAN | ||
FileProxy: Streams whichever file is referenced in the url. Can handle multiple concurrent streams | ||
BufferProxy: Streams a file which is being concurrently downloaded. Takes a BufferProgress object to determine when the file is finished downloading. This is useful for serving a song to a MediaPlayer which is still being downloaded. Can only handle one at a time. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<module type="JAVA_MODULE" version="4"> | ||
<component name="FacetManager"> | ||
<facet type="android" name="Android"> | ||
<configuration> | ||
<option name="LIBRARY_PROJECT" value="true" /> | ||
</configuration> | ||
</facet> | ||
</component> | ||
<component name="NewModuleRootManager" inherit-compiler-output="true"> | ||
<exclude-output /> | ||
<content url="file://$MODULE_DIR$"> | ||
<sourceFolder url="file://$MODULE_DIR$/gen" isTestSource="false" generated="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> | ||
</content> | ||
<orderEntry type="inheritedJdk" /> | ||
<orderEntry type="sourceFolder" forTests="false" /> | ||
</component> | ||
</module> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
## This file is automatically generated by Android Studio. | ||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED! | ||
# | ||
# This file must *NOT* be checked into Version Control Systems, | ||
# as it contains information specific to your local configuration. | ||
# | ||
# Location of the SDK. This is only used by Gradle. | ||
# For customization when using a Version Control System, please read the | ||
# header note. | ||
#Fri Feb 21 20:10:39 PST 2014 | ||
sdk.dir=C\:\\Program Files (x86)\\Android\\android-studio\\sdk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/* | ||
This file is part of ServerProxy. | ||
SocketProxy is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 3 of the License, or | ||
(at your option) any later version. | ||
Subsonic is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with Subsonic. If not, see <http://www.gnu.org/licenses/>. | ||
Copyright 2014 (C) Scott Jackson | ||
*/ | ||
|
||
package github.daneren2005.serverproxy; | ||
|
||
import java.io.File; | ||
|
||
public interface BufferFile { | ||
File getFile(); | ||
Long getContentLength(); | ||
long getEstimatedSize(); | ||
boolean isWorkDone(); | ||
void onStart(); | ||
void onStop(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/* | ||
This file is part of ServerProxy. | ||
SocketProxy is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 3 of the License, or | ||
(at your option) any later version. | ||
Subsonic is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with Subsonic. If not, see <http://www.gnu.org/licenses/>. | ||
Copyright 2014 (C) Scott Jackson | ||
*/ | ||
|
||
package github.daneren2005.serverproxy; | ||
|
||
import java.io.File; | ||
import java.net.Socket; | ||
|
||
import android.content.Context; | ||
|
||
public class BufferProxy extends FileProxy { | ||
private static final String TAG = BufferProxy.class.getSimpleName(); | ||
protected BufferFile progress; | ||
|
||
public BufferProxy(Context context) { | ||
super(context); | ||
} | ||
|
||
protected ProxyTask getTask(Socket client) { | ||
return new BufferFileTask(client); | ||
} | ||
|
||
public void setBufferFile(BufferFile progress) { | ||
this.progress = progress; | ||
} | ||
|
||
protected class BufferFileTask extends StreamFileTask { | ||
public BufferFileTask(Socket client) { | ||
super(client); | ||
} | ||
|
||
@Override | ||
File getFile(String path) { | ||
return progress.getFile(); | ||
} | ||
|
||
@Override | ||
Long getContentLength() { | ||
Long contentLength = progress.getContentLength(); | ||
if(contentLength == null && progress.isWorkDone()) { | ||
contentLength = file.length(); | ||
} | ||
return contentLength; | ||
} | ||
@Override | ||
long getFileSize() { | ||
return progress.getEstimatedSize(); | ||
} | ||
|
||
@Override | ||
public void onStart() { | ||
progress.onStart(); | ||
} | ||
@Override | ||
public void onStop() { | ||
progress.onStop(); | ||
} | ||
|
||
@Override | ||
public boolean isWorkDone() { | ||
return progress.isWorkDone() && cbSkip >= file.length(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
/* | ||
This file is part of ServerProxy. | ||
SocketProxy is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 3 of the License, or | ||
(at your option) any later version. | ||
Subsonic is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with Subsonic. If not, see <http://www.gnu.org/licenses/>. | ||
Copyright 2014 (C) Scott Jackson | ||
*/ | ||
|
||
package github.daneren2005.serverproxy; | ||
|
||
import java.io.BufferedOutputStream; | ||
import java.io.File; | ||
import java.io.FileInputStream; | ||
import java.io.IOException; | ||
import java.io.OutputStream; | ||
import java.net.Socket; | ||
import java.net.SocketException; | ||
|
||
import android.content.Context; | ||
import android.util.Log; | ||
|
||
public class FileProxy extends ServerProxy { | ||
private static final String TAG = FileProxy.class.getSimpleName(); | ||
|
||
public FileProxy(Context context) { | ||
super(context); | ||
} | ||
|
||
protected ProxyTask getTask(Socket client) { | ||
return new StreamFileTask(client); | ||
} | ||
|
||
protected class StreamFileTask extends ProxyTask { | ||
File file; | ||
|
||
public StreamFileTask(Socket client) { | ||
super(client); | ||
} | ||
|
||
@Override | ||
public boolean processRequest() { | ||
if(!super.processRequest()) { | ||
return false; | ||
} | ||
|
||
Log.i(TAG, "Processing request for file " + path); | ||
file = getFile(path); | ||
if (!file.exists()) { | ||
Log.e(TAG, "File " + path + " does not exist"); | ||
return false; | ||
} | ||
|
||
// Make sure to not try to read past where the file is downloaded | ||
if(cbSkip != 0 && cbSkip >= file.length()) { | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
File getFile(String path) { | ||
return new File(path); | ||
} | ||
|
||
Long getContentLength() { | ||
return file.length(); | ||
} | ||
long getFileSize() { | ||
return file.length(); | ||
} | ||
|
||
@Override | ||
public void run() { | ||
Long contentLength = getContentLength(); | ||
|
||
// Create HTTP header | ||
String headers; | ||
if(cbSkip == 0) { | ||
headers = "HTTP/1.0 200 OK\r\n"; | ||
} else { | ||
headers = "HTTP/1.0 206 OK\r\n;"; | ||
headers += "Content-Range: bytes " + cbSkip + "-" + (file.length() - 1) + "/"; | ||
if(contentLength == null) { | ||
headers += "*"; | ||
} else { | ||
headers += contentLength; | ||
} | ||
|
||
Log.i(TAG, "Streaming starts from: " + cbSkip); | ||
} | ||
headers += "Content-Type: " + "application/octet-stream" + "\r\n"; | ||
|
||
long fileSize; | ||
if(contentLength == null) { | ||
fileSize = getFileSize(); | ||
} else { | ||
fileSize = contentLength; | ||
headers += "Content-Length: " + fileSize + "\r\n"; | ||
} | ||
Log.i(TAG, "Streaming fileSize: " + fileSize); | ||
|
||
headers += "Connection: close\r\n"; | ||
headers += "\r\n"; | ||
Log.d(TAG, headers); | ||
|
||
long cbToSend = fileSize - cbSkip; | ||
OutputStream output = null; | ||
byte[] buff = new byte[64 * 1024]; | ||
try { | ||
output = new BufferedOutputStream(client.getOutputStream(), 32*1024); | ||
output.write(headers.getBytes()); | ||
|
||
// Make sure to have file lock | ||
onStart(); | ||
|
||
// Loop as long as there's stuff to send | ||
while (isRunning && !client.isClosed()) { | ||
|
||
// See if there's more to send | ||
int cbSentThisBatch = 0; | ||
if (file.exists()) { | ||
FileInputStream input = new FileInputStream(file); | ||
input.skip(cbSkip); | ||
int cbToSendThisBatch = input.available(); | ||
while (cbToSendThisBatch > 0) { | ||
int cbToRead = Math.min(cbToSendThisBatch, buff.length); | ||
int cbRead = input.read(buff, 0, cbToRead); | ||
if (cbRead == -1) { | ||
break; | ||
} | ||
cbToSendThisBatch -= cbRead; | ||
cbToSend -= cbRead; | ||
output.write(buff, 0, cbRead); | ||
output.flush(); | ||
cbSkip += cbRead; | ||
cbSentThisBatch += cbRead; | ||
} | ||
input.close(); | ||
} | ||
|
||
// Done regardless of whether or not it thinks it is | ||
if(isWorkDone()) { | ||
break; | ||
} | ||
|
||
// If we did nothing this batch, block for a second | ||
if (cbSentThisBatch == 0) { | ||
Log.d(TAG, "Blocking until more data appears (" + cbToSend + ")"); | ||
Thread.sleep(1000); | ||
} | ||
} | ||
|
||
// Release file lock, use of stream proxy means nothing else is using it | ||
onStop(); | ||
} | ||
catch (SocketException socketException) { | ||
Log.e(TAG, "SocketException() thrown, proxy client has probably closed. This can exit harmlessly"); | ||
|
||
// Release file lock, use of stream proxy means nothing else is using it | ||
onStop(); | ||
} | ||
catch (Exception e) { | ||
Log.e(TAG, "Exception thrown from streaming task:"); | ||
Log.e(TAG, e.getClass().getName() + " : " + e.getLocalizedMessage()); | ||
} | ||
|
||
// Cleanup | ||
try { | ||
if (output != null) { | ||
output.close(); | ||
} | ||
client.close(); | ||
} | ||
catch (IOException e) { | ||
Log.e(TAG, "IOException while cleaning up streaming task:"); | ||
Log.e(TAG, e.getClass().getName() + " : " + e.getLocalizedMessage()); | ||
} | ||
} | ||
|
||
public void onStart() { | ||
|
||
} | ||
public void onStop() { | ||
|
||
} | ||
public boolean isWorkDone() { | ||
return cbSkip >= file.length(); | ||
} | ||
} | ||
} |
Oops, something went wrong.