diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b0a0e8..a341ce1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +## [0.12.2] - 2020-05-04 +### Changed +- Invalid POST requests to action resources now generate an error status. + ## [0.12.1] - 2020-03-27 ### Added - Support OPTIONS requests to allow for CORS. @@ -24,7 +28,8 @@ ### Changed - Property, Action, and Event description now use `links` rather than `href`. - [Spec PR](https://github.com/mozilla-iot/wot/pull/119) -[Unreleased]: https://github.com/mozilla-iot/webthing-java/compare/v0.12.1...HEAD +[Unreleased]: https://github.com/mozilla-iot/webthing-java/compare/v0.12.2...HEAD +[0.12.2]: https://github.com/mozilla-iot/webthing-java/compare/v0.12.1...v0.12.2 [0.12.1]: https://github.com/mozilla-iot/webthing-java/compare/v0.12.0...v0.12.1 [0.12.0]: https://github.com/mozilla-iot/webthing-java/compare/v0.11.0...v0.12.0 [0.11.0]: https://github.com/mozilla-iot/webthing-java/compare/v0.10.0...v0.11.0 diff --git a/pom.xml b/pom.xml index 6585eab..f814cd9 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.mozilla.iot webthing - 0.12.1 + 0.12.2 WebThing Implementation of an HTTP Web Thing. diff --git a/src/main/java/org/mozilla/iot/webthing/Thing.java b/src/main/java/org/mozilla/iot/webthing/Thing.java index 4ab7b90..b74a21e 100644 --- a/src/main/java/org/mozilla/iot/webthing/Thing.java +++ b/src/main/java/org/mozilla/iot/webthing/Thing.java @@ -756,6 +756,10 @@ public boolean validateActionInput(JSONObject actionInput) { return true; } + if (actionInput == null) { + actionInput = new JSONObject(); + } + try { this.schema.validate(actionInput); } catch (ValidationException e) { diff --git a/src/main/java/org/mozilla/iot/webthing/WebThingServer.java b/src/main/java/org/mozilla/iot/webthing/WebThingServer.java index 7c867d7..0392905 100644 --- a/src/main/java/org/mozilla/iot/webthing/WebThingServer.java +++ b/src/main/java/org/mozilla/iot/webthing/WebThingServer.java @@ -1224,35 +1224,40 @@ public Response post(UriResource uriResource, } try { - JSONObject response = new JSONObject(); JSONArray actionNames = json.names(); - if (actionNames == null) { + if (actionNames == null || actionNames.length() != 1) { return corsResponse(NanoHTTPD.newFixedLengthResponse( Response.Status.BAD_REQUEST, null, null)); } - for (int i = 0; i < actionNames.length(); ++i) { - String actionName = actionNames.getString(i); - JSONObject params = json.getJSONObject(actionName); - JSONObject input = null; - if (params.has("input")) { - input = params.getJSONObject("input"); - } - - Action action = thing.performAction(actionName, input); - if (action != null) { - response.put(actionName, - action.asActionDescription() - .getJSONObject(actionName)); - - (new ActionRunner(action)).start(); - } + String actionName = actionNames.getString(0); + JSONObject params = json.getJSONObject(actionName); + JSONObject input = null; + if (params.has("input")) { + input = params.getJSONObject("input"); + } + + Action action = thing.performAction(actionName, input); + if (action != null) { + JSONObject response = new JSONObject(); + response.put(actionName, + action.asActionDescription() + .getJSONObject(actionName)); + + (new ActionRunner(action)).start(); + + return corsResponse(NanoHTTPD.newFixedLengthResponse( + Response.Status.CREATED, + "application/json", + response.toString())); + } else { + return corsResponse(NanoHTTPD.newFixedLengthResponse( + Response.Status.BAD_REQUEST, + null, + null)); } - return corsResponse(NanoHTTPD.newFixedLengthResponse(Response.Status.CREATED, - "application/json", - response.toString())); } catch (JSONException e) { return corsResponse(NanoHTTPD.newFixedLengthResponse(Response.Status.INTERNAL_ERROR, null, @@ -1352,39 +1357,47 @@ public Response post(UriResource uriResource, String actionName = this.getActionName(uriResource, session); try { - JSONObject response = new JSONObject(); JSONArray actionNames = json.names(); - if (actionNames == null) { + if (actionNames == null || actionNames.length() != 1) { + return corsResponse(NanoHTTPD.newFixedLengthResponse( + Response.Status.BAD_REQUEST, + null, + null)); + } + + String name = actionNames.getString(0); + if (!name.equals(actionName)) { return corsResponse(NanoHTTPD.newFixedLengthResponse( Response.Status.BAD_REQUEST, null, null)); } - for (int i = 0; i < actionNames.length(); ++i) { - String name = actionNames.getString(i); - if (!name.equals(actionName)) { - continue; - } - - JSONObject params = json.getJSONObject(name); - JSONObject input = null; - if (params.has("input")) { - input = params.getJSONObject("input"); - } - - Action action = thing.performAction(name, input); - if (action != null) { - response.put(name, - action.asActionDescription() - .getJSONObject(name)); - - (new ActionRunner(action)).start(); - } + JSONObject params = json.getJSONObject(name); + JSONObject input = null; + if (params.has("input")) { + input = params.getJSONObject("input"); + } + + Action action = thing.performAction(name, input); + if (action != null) { + JSONObject response = new JSONObject(); + response.put(name, + action.asActionDescription() + .getJSONObject(name)); + + (new ActionRunner(action)).start(); + + return corsResponse(NanoHTTPD.newFixedLengthResponse( + Response.Status.CREATED, + "application/json", + response.toString())); + } else { + return corsResponse(NanoHTTPD.newFixedLengthResponse( + Response.Status.BAD_REQUEST, + null, + null)); } - return corsResponse(NanoHTTPD.newFixedLengthResponse(Response.Status.CREATED, - "application/json", - response.toString())); } catch (JSONException e) { return corsResponse(NanoHTTPD.newFixedLengthResponse(Response.Status.INTERNAL_ERROR, null,