move to nanohttpd
This commit is contained in:
parent
e024953ebe
commit
b565450820
8 changed files with 126 additions and 809 deletions
|
@ -408,7 +408,7 @@
|
|||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<activity android:name="androidhttpweb.ServerActivity" android:label="@string/shared_string_settings" android:configChanges="keyboardHidden|orientation" />
|
||||
<activity android:name=".activities.ServerActivity" android:label="@string/shared_string_settings" android:configChanges="keyboardHidden|orientation" />
|
||||
<activity android:name="net.osmand.plus.activities.SettingsActivity" android:label="@string/shared_string_settings" android:configChanges="keyboardHidden|orientation" />
|
||||
<activity android:name="net.osmand.plus.activities.SettingsGeneralActivity" android:configChanges="keyboardHidden|orientation" />
|
||||
<activity android:name="net.osmand.plus.activities.SettingsNavigationActivity" android:configChanges="keyboardHidden|orientation" />
|
||||
|
|
|
@ -542,6 +542,7 @@ dependencies {
|
|||
//implementation 'com.atilika.kuromoji:kuromoji-ipadic:0.9.0'
|
||||
implementation 'com.squareup.picasso:picasso:2.71828'
|
||||
implementation 'me.zhanghai.android.materialprogressbar:library:1.4.2'
|
||||
implementation 'org.nanohttpd:nanohttpd:2.2.0'
|
||||
// JS core
|
||||
implementation group: 'org.mozilla', name: 'rhino', version: '1.7.9'
|
||||
// size restrictions
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
package androidhttpweb;
|
||||
|
||||
import android.net.TrafficStats;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import net.osmand.plus.R;
|
||||
|
||||
public class ServerActivity extends AppCompatActivity {
|
||||
private boolean initialized = false;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.server_activity);
|
||||
findViewById(R.id.Button01).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (!initialized) {
|
||||
((TextView) findViewById(R.id.TextView02)).setText("Click second button to deactivate server");
|
||||
initServer();
|
||||
}
|
||||
}
|
||||
});
|
||||
findViewById(R.id.Button03).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (initialized) {
|
||||
((TextView) findViewById(R.id.TextView02)).setText("Click first button to activate server");
|
||||
deInitServer();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initServer() {
|
||||
final String ip = "localhost";
|
||||
final int port = 9000;
|
||||
final int THREAD_ID = 10000;
|
||||
TrafficStats.setThreadStatsTag(THREAD_ID);
|
||||
TinyWebServer.startServer(ip, port, "/web/public_html");
|
||||
TinyWebServer.object = ServerActivity.this;
|
||||
}
|
||||
|
||||
private void deInitServer() {
|
||||
TinyWebServer.stopServer();
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
deInitServer();
|
||||
super.onDestroy();
|
||||
}
|
||||
}
|
|
@ -1,614 +0,0 @@
|
|||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright 2018 Sonu Auti http://sonuauti.com twitter @SonuAuti
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package androidhttpweb;
|
||||
|
||||
import android.net.TrafficStats;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.InetAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URL;
|
||||
import java.net.URLDecoder;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sonu Auti @cis
|
||||
*/
|
||||
public class TinyWebServer extends Thread {
|
||||
|
||||
/**
|
||||
* @param args the command line arguments
|
||||
*/
|
||||
private static ServerSocket serverSocket;
|
||||
private final Map<String, String> lowerCaseHeader = new HashMap<>();
|
||||
|
||||
public static String CONTENT_TYPE = "text/html";
|
||||
private String CONTENT_DATE = "";
|
||||
private String CONN_TYPE = "";
|
||||
private String Content_Encoding = "";
|
||||
private String content_length = "";
|
||||
private String STATUS = "200";
|
||||
private boolean keepAlive = true;
|
||||
private String SERVER_NAME = "Firefly http server v0.1";
|
||||
private static final String MULTIPART_FORM_DATA_HEADER = "multipart/form-data";
|
||||
private static final String ASCII_ENCODING = "US-ASCII";
|
||||
private String REQUEST_TYPE = "GET";
|
||||
private String HTTP_VER = "HTTP/1.1";
|
||||
|
||||
//all status
|
||||
public static String PAGE_NOT_FOUND = "404";
|
||||
public static String OKAY = "200";
|
||||
public static String CREATED = "201";
|
||||
public static String ACCEPTED = "202";
|
||||
public static String NO_CONTENT = "204";
|
||||
public static String PARTIAL_NO_CONTENT = "206";
|
||||
public static String MULTI_STATUS = "207";
|
||||
public static String MOVED_PERMANENTLY = "301";
|
||||
public static String SEE_OTHER = "303";
|
||||
public static String NOT_MODIFIED = "304";
|
||||
public static String TEMP_REDIRECT = "307";
|
||||
public static String BAD_REQUEST = "400";
|
||||
public static String UNAUTHORIZED_REQUEST = "401";
|
||||
public static String FORBIDDEN = "403";
|
||||
public static String NOT_FOUND = "404";
|
||||
public static String METHOD_NOT_ALLOWED = "405";
|
||||
public static String NOT_ACCEPTABLE = "406";
|
||||
public static String REQUEST_TIMEOUT = "408";
|
||||
public static String CONFLICT = "409";
|
||||
public static String GONE = "410";
|
||||
public static String LENGTH_REQUIRED = "411";
|
||||
public static String PRECONDITION_FAILED = "412";
|
||||
|
||||
public static String PAYLOAD_TOO_LARGE = "413";
|
||||
public static String UNSUPPORTED_MEDIA_TYPE = "415";
|
||||
public static String RANGE_NOT_SATISFIABLE = "416";
|
||||
public static String EXPECTATION_FAILED = "417";
|
||||
public static String TOO_MANY_REQUESTS = "429";
|
||||
|
||||
public static String INTERNAL_ERROR = "500";
|
||||
public static String NOT_IMPLEMENTED = "501";
|
||||
public static String SERVICE_UNAVAILABLE = "503";
|
||||
public static String UNSUPPORTED_HTTP_VERSION = "505";
|
||||
|
||||
public static final String CONTENT_DISPOSITION_REGEX = "([ |\t]*Content-Disposition[ |\t]*:)(.*)";
|
||||
|
||||
public static final Pattern CONTENT_DISPOSITION_PATTERN = Pattern.compile(CONTENT_DISPOSITION_REGEX, Pattern.CASE_INSENSITIVE);
|
||||
|
||||
public static final String CONTENT_TYPE_REGEX = "([ |\t]*content-type[ |\t]*:)(.*)";
|
||||
|
||||
public static final Pattern CONTENT_TYPE_PATTERN = Pattern.compile(CONTENT_TYPE_REGEX, Pattern.CASE_INSENSITIVE);
|
||||
|
||||
public static final String CONTENT_DISPOSITION_ATTRIBUTE_REGEX = "[ |\t]*([a-zA-Z]*)[ |\t]*=[ |\t]*['|\"]([^\"^']*)['|\"]";
|
||||
|
||||
public static final Pattern CONTENT_DISPOSITION_ATTRIBUTE_PATTERN = Pattern.compile(CONTENT_DISPOSITION_ATTRIBUTE_REGEX);
|
||||
|
||||
public static final String CONTENT_LENGTH_REGEX = "Content-Length:";
|
||||
public static final Pattern CONTENT_LENGTH_PATTERN = Pattern.compile(CONTENT_LENGTH_REGEX, Pattern.CASE_INSENSITIVE);
|
||||
|
||||
public static final String USER_AGENT = "User-Agent:";
|
||||
public static final Pattern USER_AGENT_PATTERN = Pattern.compile(USER_AGENT, Pattern.CASE_INSENSITIVE);
|
||||
|
||||
public static final String HOST_REGEX = "Host:";
|
||||
public static final Pattern CLIENT_HOST_PATTERN = Pattern.compile(HOST_REGEX, Pattern.CASE_INSENSITIVE);
|
||||
|
||||
public static final String CONNECTION_TYPE_REGEX = "Connection:";
|
||||
public static final Pattern CONNECTION_TYPE_PATTERN = Pattern.compile(CONNECTION_TYPE_REGEX, Pattern.CASE_INSENSITIVE);
|
||||
|
||||
public static final String ACCEPT_ENCODING_REGEX = "Accept-Encoding:";
|
||||
public static final Pattern ACCEPT_ENCODING_PATTERN = Pattern.compile(ACCEPT_ENCODING_REGEX, Pattern.CASE_INSENSITIVE);
|
||||
|
||||
private static final String CONTENT_REGEX = "[ |\t]*([^/^ ^;^,]+/[^ ^;^,]+)";
|
||||
|
||||
private static final Pattern MIME_PATTERN = Pattern.compile(CONTENT_REGEX, Pattern.CASE_INSENSITIVE);
|
||||
|
||||
private static final String CHARSET_REGEX = "[ |\t]*(charset)[ |\t]*=[ |\t]*['|\"]?([^\"^'^;^,]*)['|\"]?";
|
||||
|
||||
private static final Pattern CHARSET_PATTERN = Pattern.compile(CHARSET_REGEX, Pattern.CASE_INSENSITIVE);
|
||||
|
||||
private static final String BOUNDARY_REGEX = "[ |\t]*(boundary)[ |\t]*=[ |\t]*['|\"]?([^\"^'^;^,]*)['|\"]?";
|
||||
|
||||
private static final Pattern BOUNDARY_PATTERN = Pattern.compile(BOUNDARY_REGEX, Pattern.CASE_INSENSITIVE);
|
||||
|
||||
|
||||
public static String WEB_DIR_PATH="/";
|
||||
public static String SERVER_IP="localhost";
|
||||
public static int SERVER_PORT=9000;
|
||||
public static boolean isStart=true;
|
||||
public static String INDEX_FILE_NAME="index.html";
|
||||
public static Object object;
|
||||
|
||||
public TinyWebServer(final String ip, final int port) throws IOException {
|
||||
|
||||
InetAddress addr = InetAddress.getByName(ip); ////"172.31.0.186");
|
||||
serverSocket = new ServerSocket(port, 100, addr);
|
||||
serverSocket.setSoTimeout(5000); //set timeout for listner
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
while (isStart) {
|
||||
try {
|
||||
TrafficStats.setThreadStatsTag(1);
|
||||
Socket newSocket = serverSocket.accept();
|
||||
Thread newClient = new EchoThread(newSocket);
|
||||
newClient.start();
|
||||
} catch (SocketTimeoutException s) {
|
||||
} catch (IOException e) {
|
||||
}
|
||||
|
||||
}//endof Never Ending while loop
|
||||
|
||||
}
|
||||
|
||||
public class EchoThread extends Thread {
|
||||
|
||||
protected Socket socket;
|
||||
protected boolean nb_open;
|
||||
|
||||
public EchoThread(Socket clientSocket) {
|
||||
this.socket = clientSocket;
|
||||
this.nb_open = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
try {
|
||||
DataInputStream in = null;
|
||||
DataOutputStream out = null;
|
||||
|
||||
if (socket.isConnected()) {
|
||||
in = new DataInputStream(socket.getInputStream());
|
||||
out = new DataOutputStream(socket.getOutputStream());
|
||||
}
|
||||
|
||||
byte[] data = new byte[1500];
|
||||
//socket.setSoTimeout(60 * 1000 * 5);
|
||||
|
||||
while (in.read(data) != -1) {
|
||||
String recData = new String(data).trim();
|
||||
//System.out.println("received data: \n" + recData);
|
||||
//System.out.println("------------------------------");
|
||||
String[] header = recData.split("\\r?\\n");
|
||||
|
||||
String contentLen = "0";
|
||||
String contentType = "text/html";
|
||||
String connectionType = "keep-alive";
|
||||
String hostname = "";
|
||||
String userAgent = "";
|
||||
String encoding = "";
|
||||
|
||||
String[] h1 = header[0].split(" ");
|
||||
if (h1.length == 3) {
|
||||
setRequestType(h1[0]);
|
||||
setHttpVer(h1[2]);
|
||||
}
|
||||
|
||||
for (int h = 0; h < header.length; h++) {
|
||||
String value = header[h].trim();
|
||||
|
||||
//System.out.println(header[h]+" -> "+CONTENT_LENGTH_PATTERN.matcher(header[h]).find());
|
||||
if (CONTENT_LENGTH_PATTERN.matcher(value).find()) {
|
||||
contentLen = value.split(":")[1].trim();
|
||||
} else if (CONTENT_TYPE_PATTERN.matcher(value).find()) {
|
||||
contentType = value.split(":")[1].trim();
|
||||
} else if (CONNECTION_TYPE_PATTERN.matcher(value).find()) {
|
||||
connectionType = value.split(":")[1].trim();
|
||||
} else if (CLIENT_HOST_PATTERN.matcher(value).find()) {
|
||||
hostname = value.split(":")[1].trim();
|
||||
} else if (USER_AGENT_PATTERN.matcher(value).find()) {
|
||||
for (String ua : value.split(":")) {
|
||||
if (!ua.equalsIgnoreCase("User-Agent:")) {
|
||||
userAgent += ua.trim();
|
||||
}
|
||||
}
|
||||
} else if (ACCEPT_ENCODING_PATTERN.matcher(value).find()) {
|
||||
encoding = value.split(":")[1].trim();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!REQUEST_TYPE.equals("")) {
|
||||
String postData = "";
|
||||
if (REQUEST_TYPE.equalsIgnoreCase("POST") && !contentLen.equals("0")) {
|
||||
postData = header[header.length - 1];
|
||||
if (postData.length() > 0 && contentLen.length() > 0) {
|
||||
int len = Integer.valueOf(contentLen);
|
||||
postData = postData.substring(0, len);
|
||||
// System.out.println("Post data -> " + contentLen + " ->" + postData);
|
||||
}
|
||||
}
|
||||
|
||||
// System.out.println("contentLen ->" + contentLen + "\ncontentType ->" + contentType + "\nhostname ->" + hostname + "\nconnectionType-> " + connectionType + "\nhostname ->" + hostname + "\nuserAgent -> " + userAgent);
|
||||
final String requestLocation = h1[1];
|
||||
if (requestLocation != null) {
|
||||
processLocation(out, requestLocation, postData);
|
||||
}
|
||||
//System.out.println("requestLocation "+requestLocation);
|
||||
}
|
||||
|
||||
}
|
||||
} catch (Exception er) {
|
||||
er.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void processLocation(DataOutputStream out, String location, String postData) {
|
||||
|
||||
String data = "";
|
||||
switch (location) {
|
||||
case "/":
|
||||
//root location, server index file
|
||||
CONTENT_TYPE = "text/html";
|
||||
data=readFile(WEB_DIR_PATH+"/"+INDEX_FILE_NAME);
|
||||
constructHeader(out, data.length() + "", data);
|
||||
break;
|
||||
default:
|
||||
|
||||
System.out.println("url location -> " + location);
|
||||
URL geturl = getDecodedUrl("http://localhost" + location);
|
||||
String[] dirPath = geturl.getPath().split("/");
|
||||
String fullFilePath=geturl.getPath();
|
||||
if (dirPath.length > 1) {
|
||||
String fileName = dirPath[dirPath.length - 1];
|
||||
HashMap qparms = (HashMap) splitQuery(geturl.getQuery());
|
||||
if(REQUEST_TYPE.equals("POST")){
|
||||
if (qparms==null){ qparms=new HashMap<String, String>();}
|
||||
qparms.put("_POST", postData);
|
||||
}
|
||||
//System.out.println("File name " + fileName);
|
||||
//System.out.println("url parms " + qparms);
|
||||
CONTENT_TYPE = getContentType(fileName);
|
||||
if(!CONTENT_TYPE.equals("text/plain")){
|
||||
// System.out.println("Full file path - >"+fullFilePath +" "+CONTENT_TYPE);
|
||||
|
||||
if(CONTENT_TYPE.equals("image/jpeg") || CONTENT_TYPE.equals("image/png") || CONTENT_TYPE.equals("video/mp4")){
|
||||
byte[] bytdata=readImageFiles(WEB_DIR_PATH+fullFilePath,CONTENT_TYPE);
|
||||
//System.out.println(bytdata.length);
|
||||
if(bytdata!=null){
|
||||
constructHeaderImage(out, bytdata.length+"", bytdata);
|
||||
}else{
|
||||
pageNotFound();
|
||||
}
|
||||
}else{
|
||||
data=readFile(WEB_DIR_PATH+fullFilePath);
|
||||
if(!data.equals("")){
|
||||
constructHeader(out, data.length() + "", data);
|
||||
}else{
|
||||
pageNotFound();
|
||||
}
|
||||
}
|
||||
}else{
|
||||
data = getResultByName(fileName, qparms);
|
||||
constructHeader(out, data.length() + "", data);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public URL getDecodedUrl(String parms) {
|
||||
try {
|
||||
//String decodedurl =URLDecoder.decode(parms,"UTF-8");
|
||||
URL aURL = new URL(parms);
|
||||
return aURL;
|
||||
} catch (Exception er) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static HashMap<String, String> splitQuery(String parms) {
|
||||
try {
|
||||
final HashMap<String, String> query_pairs = new HashMap<>();
|
||||
final String[] pairs = parms.split("&");
|
||||
for (String pair : pairs) {
|
||||
final int idx = pair.indexOf("=");
|
||||
final String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), "UTF-8") : pair;
|
||||
if (!query_pairs.containsKey(key)) {
|
||||
query_pairs.put(key, "");
|
||||
}
|
||||
final String value = idx > 0 && pair.length() > idx + 1 ? URLDecoder.decode(pair.substring(idx + 1), "UTF-8") : null;
|
||||
query_pairs.put(key, value);
|
||||
}
|
||||
return query_pairs;
|
||||
} catch (Exception er) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getResultByName(String name, HashMap qparms) {
|
||||
try {
|
||||
String ClassName = "appapis.queryfiles.AppApis";
|
||||
Class<?> rClass = Class.forName(ClassName); // convert string classname to class
|
||||
Object obj = rClass.newInstance(); // invoke empty constructor
|
||||
Method getNameMethod = obj.getClass().getMethod(name, HashMap.class);
|
||||
STATUS = TinyWebServer.OKAY;
|
||||
return getNameMethod.invoke(obj, qparms).toString();
|
||||
} catch (Exception er) {
|
||||
// er.printStackTrace();
|
||||
return pageNotFound();
|
||||
}
|
||||
}
|
||||
|
||||
public void setRequestType(String type) {
|
||||
// System.out.println("REQUEST TYPE " + type);
|
||||
this.REQUEST_TYPE = type;
|
||||
}
|
||||
|
||||
public void setHttpVer(String httpver) {
|
||||
// System.out.println("REQUEST ver " + httpver);
|
||||
this.HTTP_VER = httpver;
|
||||
}
|
||||
|
||||
public String getRequestType() {
|
||||
return this.REQUEST_TYPE;
|
||||
}
|
||||
|
||||
public String getHttpVer() {
|
||||
return this.HTTP_VER;
|
||||
}
|
||||
|
||||
public String pageNotFound() {
|
||||
STATUS = NOT_FOUND;
|
||||
CONTENT_TYPE = "text/html";
|
||||
//customize your page here
|
||||
return "<!DOCTYPE html>"
|
||||
+ "<html><head><title>Page not found | Firefly web server</title>"
|
||||
+ "</head><body><h3>Requested page not found</h3></body></html>";
|
||||
}
|
||||
|
||||
//hashtable initilization for content types
|
||||
static Hashtable<String, String> mContentTypes = new Hashtable();
|
||||
|
||||
{
|
||||
mContentTypes.put("js", "application/javascript");
|
||||
mContentTypes.put("php", "text/html");
|
||||
mContentTypes.put("java", "text/html");
|
||||
mContentTypes.put("json", "application/json");
|
||||
mContentTypes.put("png", "image/png");
|
||||
mContentTypes.put("jpg", "image/jpeg");
|
||||
mContentTypes.put("html", "text/html");
|
||||
mContentTypes.put("css", "text/css");
|
||||
mContentTypes.put("mp4", "video/mp4");
|
||||
mContentTypes.put("mov", "video/quicktime");
|
||||
mContentTypes.put("wmv", "video/x-ms-wmv");
|
||||
|
||||
}
|
||||
|
||||
//get request content type
|
||||
public static String getContentType(String path) {
|
||||
String type = tryGetContentType(path);
|
||||
if (type != null) {
|
||||
return type;
|
||||
}
|
||||
return "text/plain";
|
||||
}
|
||||
|
||||
//get request content type from path
|
||||
public static String tryGetContentType(String path) {
|
||||
int index = path.lastIndexOf(".");
|
||||
if (index != -1) {
|
||||
String e = path.substring(index + 1);
|
||||
String ct = mContentTypes.get(e);
|
||||
// System.out.println("content type: " + ct);
|
||||
if (ct != null) {
|
||||
return ct;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void constructHeader(DataOutputStream output, String size, String data) {
|
||||
SimpleDateFormat gmtFrmt = new SimpleDateFormat("E, d MMM yyyy HH:mm:ss 'GMT'", Locale.US);
|
||||
gmtFrmt.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||
PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(output)), false);
|
||||
pw.append("HTTP/1.1 ").append(STATUS).append(" \r\n");
|
||||
if (this.CONTENT_TYPE != null) {
|
||||
printHeader(pw, "Content-Type", this.CONTENT_TYPE);
|
||||
}
|
||||
printHeader(pw, "Date", gmtFrmt.format(new Date()));
|
||||
printHeader(pw, "Connection", (this.keepAlive ? "keep-alive" : "close"));
|
||||
printHeader(pw, "Content-Length", size);
|
||||
printHeader(pw, "Server", SERVER_NAME);
|
||||
pw.append("\r\n");
|
||||
pw.append(data);
|
||||
pw.flush();
|
||||
//pw.close();
|
||||
}
|
||||
|
||||
private void constructHeaderImage(DataOutputStream output, String size, byte[] data) {
|
||||
try{
|
||||
|
||||
SimpleDateFormat gmtFrmt = new SimpleDateFormat("E, d MMM yyyy HH:mm:ss 'GMT'", Locale.US);
|
||||
gmtFrmt.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||
PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(output)), false);
|
||||
pw.append("HTTP/1.1 ").append(STATUS).append(" \r\n");
|
||||
if (this.CONTENT_TYPE != null) {
|
||||
printHeader(pw, "Content-Type", this.CONTENT_TYPE);
|
||||
}
|
||||
printHeader(pw, "Date", gmtFrmt.format(new Date()));
|
||||
printHeader(pw, "Connection", (this.keepAlive ? "keep-alive" : "close"));
|
||||
printHeader(pw, "Content-Length", size);
|
||||
printHeader(pw, "Server", SERVER_NAME);
|
||||
pw.append("\r\n");
|
||||
pw.flush();
|
||||
output.write(data);
|
||||
output.flush();
|
||||
//System.out.println("data sent success");
|
||||
|
||||
//pw.close();
|
||||
}catch(Exception er){er.printStackTrace();}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("static-method")
|
||||
protected void printHeader(PrintWriter pw, String key, String value) {
|
||||
pw.append(key).append(": ").append(value).append("\r\n");
|
||||
}
|
||||
|
||||
public byte[] readImageFiles(String fileName, String filetype){
|
||||
try{
|
||||
File ifile=new File(fileName);
|
||||
if(ifile.exists()){
|
||||
if(filetype.equalsIgnoreCase("image/png") || filetype.equalsIgnoreCase("image/jpeg") || filetype.equalsIgnoreCase("image/gif") || filetype.equalsIgnoreCase("image/jpg")){
|
||||
FileInputStream fis = new FileInputStream(fileName);
|
||||
byte[] buffer = new byte[fis.available()];
|
||||
while (fis.read(buffer) != -1) {}
|
||||
fis.close();
|
||||
return buffer;
|
||||
}
|
||||
}else{
|
||||
|
||||
}
|
||||
}catch(Exception er){}
|
||||
return null;
|
||||
}
|
||||
public String readFile(String fileName){
|
||||
String content="";
|
||||
try{
|
||||
File ifile=new File(fileName);
|
||||
if(ifile.exists()){
|
||||
FileInputStream fis = new FileInputStream(fileName);
|
||||
byte[] buffer = new byte[10];
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (fis.read(buffer) != -1) {
|
||||
sb.append(new String(buffer));
|
||||
buffer = new byte[10];
|
||||
}
|
||||
fis.close();
|
||||
content = sb.toString();
|
||||
}else{
|
||||
pageNotFound();
|
||||
return content;
|
||||
}
|
||||
}catch(Exception er){
|
||||
pageNotFound();
|
||||
return "";
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
|
||||
public static void init(String ip, int port, String public_dir){
|
||||
|
||||
SERVER_IP=ip;
|
||||
SERVER_PORT=port;
|
||||
WEB_DIR_PATH=public_dir;
|
||||
scanFileDirectory();
|
||||
|
||||
}
|
||||
|
||||
public static void startServer(String ip, int port, String public_dir){
|
||||
try {
|
||||
|
||||
isStart=true;
|
||||
init(ip,port,public_dir);
|
||||
Thread t = new TinyWebServer(SERVER_IP, SERVER_PORT);
|
||||
t.start();
|
||||
System.out.println("Server Started !");
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
public static void stopServer(){
|
||||
if(isStart){
|
||||
try{
|
||||
isStart=false;
|
||||
serverSocket.close();
|
||||
System.out.println("Server stopped running !");
|
||||
}catch(IOException er){
|
||||
er.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//scan for index file
|
||||
public static void scanFileDirectory(){
|
||||
boolean isIndexFound=false;
|
||||
try{
|
||||
File file=new File(WEB_DIR_PATH);
|
||||
if(file.isDirectory()){
|
||||
File[] allFiles=file.listFiles();
|
||||
for (File allFile : allFiles) {
|
||||
//System.out.println(allFile.getName().split("\\.")[0]);
|
||||
if(allFile.getName().split("\\.")[0].equalsIgnoreCase("index")){
|
||||
TinyWebServer.INDEX_FILE_NAME=allFile.getName();
|
||||
isIndexFound=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}catch(Exception er){}
|
||||
|
||||
if(!isIndexFound){
|
||||
System.out.println("Index file not found !");
|
||||
}
|
||||
}
|
||||
|
||||
/* //use for testing
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
|
||||
Thread t = new TinyWebServer(SERVER_IP, SERVER_PORT);
|
||||
t.start();
|
||||
System.out.println("Server Started !");
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}*/
|
||||
|
||||
}
|
|
@ -1,134 +0,0 @@
|
|||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright 2018 Sonu Auti http://sonuauti.com twitter @SonuAuti
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package appapis.queryfiles;
|
||||
|
||||
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.apache.commons.compress.utils.IOUtils;
|
||||
|
||||
import androidhttpweb.ServerActivity;
|
||||
import androidhttpweb.TinyWebServer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Scanner;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author cis
|
||||
*/
|
||||
public class AppApis {
|
||||
|
||||
public AppApis(){
|
||||
}
|
||||
|
||||
public String helloworld(HashMap qparms){
|
||||
//demo of simple html webpage from controller method
|
||||
TinyWebServer.CONTENT_TYPE="text/html";
|
||||
return "<html><head><title>Simple HTML and Javascript Demo</title>\n" +
|
||||
" <script>\n" +
|
||||
" \n" +
|
||||
"</script>\n" +
|
||||
" \n" +
|
||||
" </head><body style=\"text-align:center;margin-top: 5%;\" cz-shortcut-listen=\"true\" class=\"\">\n" +
|
||||
" <h3>Say Hello !</h3>\n" +
|
||||
"<div style=\"text-align:center;margin-left: 29%;\">\n" +
|
||||
"<div id=\"c1\" style=\"width: 100px;height: 100px;color: gray;background: gray;border-radius: 50%;float: left;\"></div>\n" +
|
||||
"<div id=\"c2\" style=\"width: 100px;height: 100px;color: gray;background: yellow;border-radius: 50%;float: left;\"></div>\n" +
|
||||
"<div id=\"c3\" style=\"width: 100px;height: 100px;color: gray;background: skyblue;border-radius: 50%;float: left;\"></div>\n" +
|
||||
"<div id=\"c4\" style=\"width: 100px;height: 100px;color: gray;background: yellowgreen;border-radius: 50%;float: left;\"></div>\n" +
|
||||
"<div id=\"c5\" style=\"width: 100px;height: 100px;color: gray;background: red;border-radius: 50%;position: ;position: ;float: left;\" class=\"\"></div></div>\n" +
|
||||
" </body></html>";
|
||||
}
|
||||
|
||||
public String simplejson(HashMap qparms){
|
||||
//simple json output demo from controller method
|
||||
String json = "{\"name\":\"sonu\",\"age\":29}";
|
||||
return json.toString();
|
||||
}
|
||||
|
||||
public String simplegetparm(HashMap qparms){
|
||||
/*
|
||||
qparms is hashmap of get and post parameter
|
||||
|
||||
simply use qparms.get(key) to get parameter value
|
||||
user _POST as key for post data
|
||||
e.g to get post data use qparms.get("_POST"), return will be post method
|
||||
data
|
||||
*/
|
||||
|
||||
System.out.println("output in simplehelloworld "+qparms);
|
||||
String p="";
|
||||
if(qparms!=null){
|
||||
p=qparms.get("age")+"";
|
||||
}
|
||||
String json = "{\"name\":\"sonu\",\"age\":"+p+",\"isp\":yes}";
|
||||
return json.toString();
|
||||
}
|
||||
|
||||
public String main(HashMap qparams){
|
||||
TinyWebServer.CONTENT_TYPE="text/html";
|
||||
final ServerActivity act = ((ServerActivity)(TinyWebServer.object));
|
||||
InputStream stream = null;
|
||||
try {
|
||||
stream = act.getAssets().open("server/main.html");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Scanner s = new Scanner(stream).useDelimiter("\\A");
|
||||
String result = s.hasNext() ? s.next() : "";
|
||||
return result;
|
||||
}
|
||||
|
||||
public String button1Click(HashMap qparams){
|
||||
try {
|
||||
final ServerActivity act = ((ServerActivity)(TinyWebServer.object));
|
||||
act.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Toast.makeText(act,"Hello from btn1",Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
TinyWebServer.CONTENT_TYPE="text/html";
|
||||
return "<script>\n" +
|
||||
"function goBack() {\n" +
|
||||
" window.history.back()\n" +
|
||||
"}\n" +
|
||||
"goBack();" +
|
||||
"</script>";
|
||||
}
|
||||
|
||||
|
||||
public String button2Click(HashMap qparams){
|
||||
return "cancel";
|
||||
}
|
||||
//implement web callback here and access them using method name
|
||||
}
|
|
@ -36,7 +36,6 @@ import net.osmand.data.QuadRect;
|
|||
import net.osmand.data.RotatedTileBox;
|
||||
import net.osmand.map.ITileSource;
|
||||
import net.osmand.plus.dialogs.SpeedCamerasBottomSheet;
|
||||
import androidhttpweb.ServerActivity;
|
||||
import net.osmand.plus.settings.backend.ApplicationMode;
|
||||
import net.osmand.plus.ContextMenuAdapter;
|
||||
import net.osmand.plus.ContextMenuAdapter.ItemClickListener;
|
||||
|
|
95
OsmAnd/src/net/osmand/plus/activities/ServerActivity.java
Normal file
95
OsmAnd/src/net/osmand/plus/activities/ServerActivity.java
Normal file
|
@ -0,0 +1,95 @@
|
|||
package net.osmand.plus.activities;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.TrafficStats;
|
||||
import android.os.Bundle;
|
||||
import android.os.StrictMode;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.server.OsmAndHttpServer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ServerActivity extends AppCompatActivity {
|
||||
private boolean initialized = false;
|
||||
private OsmAndHttpServer server;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
enableStrictMode();
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.server_activity);
|
||||
findViewById(R.id.Button01).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (!initialized) {
|
||||
updateTextView("Click second button to deactivate server");
|
||||
initServer();
|
||||
}
|
||||
}
|
||||
});
|
||||
findViewById(R.id.Button03).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (initialized) {
|
||||
updateTextView("Click first button to activate server");
|
||||
deInitServer();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void enableStrictMode() {
|
||||
StrictMode.setThreadPolicy(
|
||||
new StrictMode.ThreadPolicy.Builder()
|
||||
.detectDiskReads()
|
||||
.detectDiskWrites()
|
||||
.detectNetwork()
|
||||
.penaltyLog()
|
||||
.build());
|
||||
StrictMode.setVmPolicy(
|
||||
new StrictMode.VmPolicy.Builder()
|
||||
.detectLeakedSqlLiteObjects()
|
||||
.penaltyLog()
|
||||
.build());
|
||||
}
|
||||
|
||||
|
||||
private void updateTextView(String text) {
|
||||
((TextView) findViewById(R.id.TextView02)).setText(text);
|
||||
}
|
||||
|
||||
private void initServer() {
|
||||
final int THREAD_ID = 10000;
|
||||
TrafficStats.setThreadStatsTag(THREAD_ID);
|
||||
try {
|
||||
server = new OsmAndHttpServer();
|
||||
initialized = true;
|
||||
updateTextView("Server started at: http://" + OsmAndHttpServer.HOSTNAME
|
||||
+ ":" + OsmAndHttpServer.PORT);
|
||||
} catch (IOException e) {
|
||||
Toast.makeText(this,
|
||||
e.getLocalizedMessage(),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void deInitServer() {
|
||||
server.closeAllConnections();
|
||||
server.stop();
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
deInitServer();
|
||||
super.onDestroy();
|
||||
}
|
||||
}
|
29
OsmAnd/src/net/osmand/plus/server/OsmAndHttpServer.java
Normal file
29
OsmAnd/src/net/osmand/plus/server/OsmAndHttpServer.java
Normal file
|
@ -0,0 +1,29 @@
|
|||
package net.osmand.plus.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import fi.iki.elonen.NanoHTTPD;
|
||||
|
||||
public class OsmAndHttpServer extends NanoHTTPD {
|
||||
public static int PORT = 24990;
|
||||
public static String HOSTNAME = "0.0.0.0";
|
||||
|
||||
public OsmAndHttpServer() throws IOException {
|
||||
super(HOSTNAME,PORT);
|
||||
start(NanoHTTPD.SOCKET_READ_TIMEOUT, false);
|
||||
System.out.println("\nRunning! Point your browsers to http://localhost:8080/ \n");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response serve(IHTTPSession session) {
|
||||
String msg = "<html><body><h1>Hello server</h1>\n";
|
||||
Map<String, String> parms = session.getParms();
|
||||
if (parms.get("username") == null) {
|
||||
msg += "<form action='?' method='get'>\n <p>Your name: <input type='text' name='username'></p>\n" + "</form>\n";
|
||||
} else {
|
||||
msg += "<p>Hello, " + parms.get("username") + "!</p>";
|
||||
}
|
||||
return newFixedLengthResponse(msg + "</body></html>\n");
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue