Allow empty request body for POST/PUT/DELETE REST endpoints that expect List/Map as input
If a REST endpoint expects a List or a Map as input, but the user provides an empty request body we currently fail with 500 Internal Server Error, e.g.: POST /accounts/<account-id>/watched.projects Instead just create an empty List/Map and provide it to the REST endpoint. This is consistent with instantiating empty Input objects when the REST endpoint expects a non-generic input type and the user provides no body. Change-Id: I78fe66b2d0f63a6078411dd50a55196424d88490 Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
@@ -846,16 +846,25 @@ public class RestApiServlet extends HttpServlet {
|
||||
throw new BadRequestException("Expected JSON object");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Object createInstance(Type type)
|
||||
throws NoSuchMethodException, InstantiationException, IllegalAccessException,
|
||||
InvocationTargetException {
|
||||
if (type instanceof Class) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<Object> clazz = (Class<Object>) type;
|
||||
Constructor<Object> c = clazz.getDeclaredConstructor();
|
||||
c.setAccessible(true);
|
||||
return c.newInstance();
|
||||
}
|
||||
if (type instanceof ParameterizedType) {
|
||||
Type rawType = ((ParameterizedType) type).getRawType();
|
||||
if (rawType instanceof Class && List.class.isAssignableFrom((Class<Object>) rawType)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
if (rawType instanceof Class && Map.class.isAssignableFrom((Class<Object>) rawType)) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
}
|
||||
throw new InstantiationException("Cannot make " + type);
|
||||
}
|
||||
|
||||
|
||||
@@ -235,4 +235,9 @@ public class WatchedProjectsIT extends AbstractDaemonTest {
|
||||
assertThat(persistedWatchedProjects).doesNotContain(pwi);
|
||||
assertThat(persistedWatchedProjects).containsAllIn(projectsToWatch);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postWithoutBody() throws Exception {
|
||||
adminRestSession.post("/accounts/" + admin.username + "/watched.projects").assertOK();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user