javacordovananohttpd

Extending Nanohttp implementation to handle custom HTTP methods


I have been trying to use this cordova plugin, which uses NanoHttpd to handle requests.
By default, Nanohttpd handles some of the HTTP methods, like GET, POST, CONNECT, PROPFIND, PATCH, etc.

I have been trying to figure out how to implement a custom handler so that nanohttpd can handled more HTTP methods like: NOTIFY and SUBSCRIBE

@Override
    public Response serve(IHTTPSession session) {
        Log.d(this.getClass().getName(), "New request is incoming!");

        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(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        JSONObject responseObject = (JSONObject) this.webserver.responses.get(requestUUID);
        Log.d(this.getClass().getName(), "responseObject: " + responseObject.toString());
        Response response = null;

        try {
            response = newFixedLengthResponse(
                    Response.Status.lookup(responseObject.getInt("status")),
                    getContentType(responseObject),
                    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;
}

I added a simple notify Response to handle any incoming request, referring from here - https://stackoverflow.com/a/27645191/2096740

public Response notify(IHTTPSession session) {
        StringBuilder text = new StringBuilder("<html><body>");
        text.append("<h1>Url: ");
        text.append(session.getUri());
        text.append("</h1><br>");
        Map<String, String> queryParams = session.getParms();
        if (queryParams.size() > 0) {
            for (Map.Entry<String, String> entry : queryParams.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                text.append("<p>Param '");
                text.append(key);
                text.append("' = ");
                text.append(value);
                text.append("</p>");
            }
        } else {
            text.append("<p>no params in url</p><br>");
        }
        return newFixedLengthResponse(text.toString());
    }

But this returnsBAD REQUEST: Syntax error. HTTP verb NOTIFY unhandled.

Documentation is not clear and there is not much info circulating on extending Nanohttpd behavior on SO or via web results.

What is the correct way to do this? How can I extend it ?


Solution

  • The check for Method is actually locked in an enum. It is hardcoded and there is no other method to expand.

    The getMethod instance itself is a enum type of Method.

    Since, I couldn't find any other solution, I therefore conclude it is not possible to do this stuff in Nanohttpd. All its versions in Maven dont support this.

    The reason they have

    Some built-in support for HEAD, POST and DELETE requests. You can easily implement/customize any HTTP method, though.

    mentioned in their feature list is because the original version had method as a String. It has changed since.

    Feature list not been updated to reflect this change.