diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitSmartHttpTools.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitSmartHttpTools.java index 3d2aff174..8bd1704bc 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitSmartHttpTools.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitSmartHttpTools.java @@ -49,11 +49,11 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.OutputStream; import java.util.Arrays; import java.util.Collections; import java.util.List; -import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -184,24 +184,27 @@ public static void sendError(HttpServletRequest req, pck.writeString("# service=" + svc + "\n"); pck.end(); pck.writeString("ERR " + textForGit); - send(res, infoRefsResultType(svc), buf.toByteArray()); + send(req, res, infoRefsResultType(svc), buf.toByteArray()); } else if (isUploadPack(req)) { pck.writeString("ERR " + textForGit); - send(res, UPLOAD_PACK_RESULT_TYPE, buf.toByteArray()); + send(req, res, UPLOAD_PACK_RESULT_TYPE, buf.toByteArray()); } else if (isReceivePack(req)) { pck.writeString("ERR " + textForGit); - send(res, RECEIVE_PACK_RESULT_TYPE, buf.toByteArray()); + send(req, res, RECEIVE_PACK_RESULT_TYPE, buf.toByteArray()); } else { + if (httpStatus < 400) + ServletUtils.consumeRequestBody(req); res.sendError(httpStatus); } } - private static void send(HttpServletResponse res, String type, byte[] buf) - throws IOException { + private static void send(HttpServletRequest req, HttpServletResponse res, + String type, byte[] buf) throws IOException { + ServletUtils.consumeRequestBody(req); res.setStatus(HttpServletResponse.SC_OK); res.setContentType(type); res.setContentLength(buf.length); - ServletOutputStream os = res.getOutputStream(); + OutputStream os = res.getOutputStream(); try { os.write(buf); } finally { diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackServlet.java index 27bee85d8..c84d52b69 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackServlet.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ReceivePackServlet.java @@ -52,6 +52,7 @@ import static org.eclipse.jgit.http.server.GitSmartHttpTools.RECEIVE_PACK_RESULT_TYPE; import static org.eclipse.jgit.http.server.GitSmartHttpTools.sendError; import static org.eclipse.jgit.http.server.ServletUtils.ATTRIBUTE_HANDLER; +import static org.eclipse.jgit.http.server.ServletUtils.consumeRequestBody; import static org.eclipse.jgit.http.server.ServletUtils.getInputStream; import static org.eclipse.jgit.http.server.ServletUtils.getRepository; @@ -177,6 +178,7 @@ public void flush() throws IOException { getServletContext().log( HttpServerText.get().internalErrorDuringReceivePack, e.getCause()); + consumeRequestBody(req); out.close(); } catch (Throwable e) { diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ServletUtils.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ServletUtils.java index 211465587..91fb8cce9 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ServletUtils.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ServletUtils.java @@ -118,6 +118,50 @@ else if (enc != null) return in; } + /** + * Consume the entire request body, if one was supplied. + * + * @param req + * the request whose body must be consumed. + */ + public static void consumeRequestBody(HttpServletRequest req) { + if (0 < req.getContentLength() || isChunked(req)) { + try { + consumeRequestBody(req.getInputStream()); + } catch (IOException e) { + // Ignore any errors obtaining the input stream. + } + } + } + + private static boolean isChunked(HttpServletRequest req) { + return "chunked".equals(req.getHeader("Transfer-Encoding")); + } + + /** + * Consume the rest of the input stream and discard it. + * + * @param in + * the stream to discard, closed if not null. + */ + public static void consumeRequestBody(InputStream in) { + if (in == null) + return; + try { + while (0 < in.skip(2048) || 0 <= in.read()) { + // Discard until EOF. + } + } catch (IOException err) { + // Discard IOException during read or skip. + } finally { + try { + in.close(); + } catch (IOException err) { + // Discard IOException during close of input stream. + } + } + } + /** * Send a plain text response to a {@code GET} or {@code HEAD} HTTP request. *

diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java index 33bfff6d4..15ef2c7ea 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/UploadPackServlet.java @@ -52,6 +52,7 @@ import static org.eclipse.jgit.http.server.GitSmartHttpTools.UPLOAD_PACK_RESULT_TYPE; import static org.eclipse.jgit.http.server.GitSmartHttpTools.sendError; import static org.eclipse.jgit.http.server.ServletUtils.ATTRIBUTE_HANDLER; +import static org.eclipse.jgit.http.server.ServletUtils.consumeRequestBody; import static org.eclipse.jgit.http.server.ServletUtils.getInputStream; import static org.eclipse.jgit.http.server.ServletUtils.getRepository; @@ -177,6 +178,7 @@ public void flush() throws IOException { } catch (UploadPackMayNotContinueException e) { if (e.isOutput()) { + consumeRequestBody(req); out.close(); } else if (!rsp.isCommitted()) { rsp.reset(); @@ -189,6 +191,7 @@ public void flush() throws IOException { getServletContext().log( HttpServerText.get().internalErrorDuringUploadPack, e.getCause()); + consumeRequestBody(req); out.close(); } catch (Throwable e) {