summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMasaya Suzuki <masayasuzuki@google.com>2018-04-02 15:40:40 -0700
committerJonathan Nieder <jrn@google.com>2018-04-03 12:53:11 -0700
commit8271f4588c909e66746985cd621c7db3755c301d (patch)
tree397642d7b590056c5d2a1ceed75b6fa3d9968bcb
parent17783eed7010028370455030b04098ec298f3447 (diff)
Detect RawInput correctly
Some endpoints allow both JSON and raw input. parseRequest selects whether to parse to JSON using a reader or to provide the raw input as an InputStream based on the request's content-type. Since v2.15-rc0~1847^2 (Discard request HTTP bodies before writing response, 2017-03-16), on endpoints that permit raw input, we call getInputStream to obtain the rest of the response body and discard it before writing the response. When the request was JSON, this produces errors from Jetty, since calling getInputStream after getReader violates the servlet API: [HTTP-66] ERROR com.google.gerrit.httpd.restapi.RestApiServlet : Error in PUT /a/plugins/reviewers.jar java.lang.IllegalStateException: READER at org.eclipse.jetty.server.Request.getInputStream(Request.java:844) at javax.servlet.ServletRequestWrapper.getInputStream(ServletRequestWrapper.java:138) at javax.servlet.ServletRequestWrapper.getInputStream(ServletRequestWrapper.java:138) To fix it, instead of guessing whether this was a raw request based on whether the endpoint supports raw requests, use the parseRequest result to decide whether this is a raw request for which we need to discard any unconsumed content. Bug: Issue 8677 Change-Id: I1db69104f31e1c04b137d994523422a07ca5cf43 (cherry picked from commit 91136bb28ec45cbbd66e7d8aabe209a6faa7eb2a)
-rw-r--r--gerrit-httpd/src/main/java/com/google/gerrit/httpd/restapi/RestApiServlet.java23
1 files changed, 8 insertions, 15 deletions
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/restapi/RestApiServlet.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/restapi/RestApiServlet.java
index d1e4e88915..4d4ef8e92c 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/restapi/RestApiServlet.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/restapi/RestApiServlet.java
@@ -403,7 +403,11 @@ public class RestApiServlet extends HttpServlet {
Type type = inputType(m);
inputRequestBody = parseRequest(req, type);
result = m.apply(rsrc, inputRequestBody);
- consumeRawInputRequestBody(req, type);
+ if (inputRequestBody instanceof RawInput) {
+ try (InputStream is = req.getInputStream()) {
+ ServletUtils.consumeRequestBody(is);
+ }
+ }
} else {
throw new ResourceNotFoundException();
}
@@ -750,7 +754,9 @@ public class RestApiServlet extends HttpServlet {
br.skip(Long.MAX_VALUE);
}
}
- } else if (rawInputRequest(req, type)) {
+ }
+ String method = req.getMethod();
+ if (("PUT".equals(method) || "POST".equals(method)) && acceptsRawInput(type)) {
return parseRawInput(req, type);
} else if ("DELETE".equals(req.getMethod()) && hasNoBody(req)) {
return null;
@@ -773,19 +779,6 @@ public class RestApiServlet extends HttpServlet {
}
}
- private void consumeRawInputRequestBody(HttpServletRequest req, Type type) throws IOException {
- if (rawInputRequest(req, type)) {
- try (InputStream is = req.getInputStream()) {
- ServletUtils.consumeRequestBody(is);
- }
- }
- }
-
- private static boolean rawInputRequest(HttpServletRequest req, Type type) {
- String method = req.getMethod();
- return ("PUT".equals(method) || "POST".equals(method)) && acceptsRawInput(type);
- }
-
private static boolean hasNoBody(HttpServletRequest req) {
int len = req.getContentLength();
String type = req.getContentType();