diff --git a/plugin.xml b/plugin.xml
index 8dcb990..ee3cf72 100644
--- a/plugin.xml
+++ b/plugin.xml
@@ -16,7 +16,9 @@
-
+
+
+
@@ -25,54 +27,54 @@
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/src/android/NanoHTTPDWebserver.java b/src/android/NanoHTTPDWebserver.java
new file mode 100644
index 0000000..c3c0e97
--- /dev/null
+++ b/src/android/NanoHTTPDWebserver.java
@@ -0,0 +1,99 @@
+package org.apache.cordova.plugin;
+
+
+import android.annotation.TargetApi;
+import android.os.Build;
+
+import org.apache.cordova.PluginResult;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import fi.iki.elonen.NanoHTTPD;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Iterator;
+import java.util.UUID;
+
+public class NanoHTTPDWebserver extends NanoHTTPD{
+
+ Webserver webserver;
+
+ public NanoHTTPDWebserver(int port, Webserver webserver) {
+ super("0.0.0.0", port);
+ this.webserver = webserver;
+ }
+
+ /**
+ * Create a request object
+ *
+ * [
+ * "requestId": requestUUID,
+ " body": request.jsonObject ?? "",
+ " headers": request.headers,
+ " method": request.method,
+ " path": request.url.path,
+ " query": request.url.query ?? ""
+ ]
+ *
+ * @param session
+ * @return
+ */
+ private JSONObject createJSONRequest(String requestId, IHTTPSession session) throws JSONException {
+ JSONObject jsonRequest = new JSONObject();
+ jsonRequest.put("requestId", requestId);
+ jsonRequest.put("body", session.getParameters());
+ jsonRequest.put("headers", session.getHeaders());
+ jsonRequest.put("method", session.getMethod());
+ jsonRequest.put("path", session.getUri());
+ jsonRequest.put("query", session.getQueryParameterString());
+ return jsonRequest;
+ }
+
+ @Override
+ public Response serve(IHTTPSession session) {
+ String requestUUID = UUID.randomUUID().toString();
+
+ PluginResult pluginResult = null;
+ try {
+ pluginResult = new PluginResult(
+ PluginResult.Status.OK, this.createJSONRequest(requestUUID, session));
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ pluginResult.setKeepCallback(true);
+ this.webserver.onRequestCallbackContext.sendPluginResult(pluginResult);
+
+ while (!this.webserver.responses.containsKey(requestUUID)) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ JSONObject responseObject = (JSONObject) this.webserver.responses.get(requestUUID);
+ Response response = null;
+ try {
+ response = newFixedLengthResponse(
+ Response.Status.lookup(responseObject.getInt("status")),
+ "text/plain",
+ responseObject.getString("body")
+ );
+
+ Iterator> keys = responseObject.getJSONObject("headers").keys();
+ while (keys.hasNext()) {
+ String key = (String) keys.next();
+ response.addHeader(
+ key,
+ responseObject.getJSONObject("headers").getString(key)
+ );
+ }
+
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ return response;
+ }
+}
diff --git a/src/android/Webserver.java b/src/android/Webserver.java
index d8d3982..9804f8f 100644
--- a/src/android/Webserver.java
+++ b/src/android/Webserver.java
@@ -1,21 +1,101 @@
package org.apache.cordova.plugin;
-import org.apache.cordova.api.CordovaPlugin;
-import org.apache.cordova.api.PluginResult;
+import org.apache.cordova.*;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
-/**
- * This class echoes a string called from JavaScript.
- */
+import java.io.IOException;
+import java.util.HashMap;
+
+
public class Webserver extends CordovaPlugin {
- @Override
- public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
- if ("start".equals(action)) {
- callbackContext.success();
- return true;
+
+ public HashMap responses;
+ public CallbackContext onRequestCallbackContext;
+
+ private NanoHTTPDWebserver nanoHTTPDWebserver;
+
+ @Override
+ public void initialize(CordovaInterface cordova, CordovaWebView webView) {
+ super.initialize(cordova, webView);
+ this.responses = new HashMap();
+ }
+
+ @Override
+ public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
+ if ("start".equals(action)) {
+ try {
+ this.start(args, callbackContext);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return true;
+ }
+ else if ("stop".equals(action)) {
+ this.stop(args, callbackContext);
+ return true;
+ }
+ else if ("onRequest".equals(action)) {
+ this.onRequest(args, callbackContext);
+ return true;
+ }
+ else if ("onResponse".equals(action)) {
+ this.onResponse(args, callbackContext);
+ return true;
+ }
+ return false; // Returning false results in a "MethodNotFound" error.
+ }
+
+ /**
+ * Starts the server
+ * @param args
+ * @param callbackContext
+ */
+ private void start(JSONArray args, CallbackContext callbackContext) throws JSONException, IOException {
+ int port = 8080;
+
+ if (args.length() == 1) {
+ port = args.getInt(0);
+ }
+ this.nanoHTTPDWebserver = new NanoHTTPDWebserver(port, this);
+ this.nanoHTTPDWebserver.start();
+ callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK));
+ }
+
+ /**
+ * Stops the server
+ * @param args
+ * @param callbackContext
+ */
+ private void stop(JSONArray args, CallbackContext callbackContext) throws JSONException {
+ if (this.nanoHTTPDWebserver != null) {
+ this.nanoHTTPDWebserver.stop();
+ }
+ callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK));
+ }
+
+ /**
+ * Will be called if the js context sends an response to the webserver
+ * @param args {UUID: {...}}
+ * @param callbackContext
+ * @throws JSONException
+ */
+ private void onResponse(JSONArray args, CallbackContext callbackContext) throws JSONException {
+ this.responses.put(args.getString(0), args.get(1));
+ callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK));
+ }
+
+ /**
+ * Just register the onRequest and send no result. This is needed to save the callbackContext to
+ * invoke it later
+ * @param args
+ * @param callbackContext
+ */
+ private void onRequest(JSONArray args, CallbackContext callbackContext) {
+ this.onRequestCallbackContext = callbackContext;
+ PluginResult pluginResult = new PluginResult(PluginResult.Status.NO_RESULT);
+ pluginResult.setKeepCallback(true);
+ this.onRequestCallbackContext.sendPluginResult(pluginResult);
}
- return false; // Returning false results in a "MethodNotFound" error.
- }
}