summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.lfs.server/src
diff options
context:
space:
mode:
authorDavid Pursehouse <david.pursehouse@gmail.com>2016-07-29 12:37:48 +0900
committerDavid Pursehouse <david.pursehouse@gmail.com>2016-08-05 11:22:27 +0900
commit571c9f5fd6f7c25f0729088e4f23bb38ea743e7b (patch)
treed398a0a710322469fc51334192356ad24ad7643d /org.eclipse.jgit.lfs.server/src
parent1ce24d46a6db83f074b4eafc80be799727b988a4 (diff)
downloadjgit-571c9f5fd6f7c25f0729088e4f23bb38ea743e7b.tar.gz
jgit-571c9f5fd6f7c25f0729088e4f23bb38ea743e7b.zip
LfsProtocolServlet: Allow getLargeFileRepository to raise exceptions
According to the specification [1] the server may return the following HTTP error responses: - 403: The user has read, but not write access. - 404: The repository does not exist for the user. - 422: Validation error with one or more of the objects in the request. In the current implementation, however, getLargeFileRepository can only return null to indicate an error. This results in the error code: - 503: Service Unavailable being returned to the client regardless of what the actual reason was. Add exception classes to cover these cases, derived from a common base exception, and change the specification of getLargeFileRepository to throw the base exception. In LfsProtocolServlet#post, handle the new exceptions and send back the appropriate HTTP responses as mentioned above. The specification also mentions several other optional response codes (406, 429, 501, and 509) but these are not implemented in this commit. It should be trivial to implement them in follow-up commits. [1] https://github.com/github/git-lfs/blob/master/docs/api/v1/http-v1-batch.md#response-errors Change-Id: I91be6165bcaf856d0cefc533882330962e2fc9b2 Signed-off-by: David Pursehouse <david.pursehouse@gmail.com>
Diffstat (limited to 'org.eclipse.jgit.lfs.server/src')
-rw-r--r--org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java55
1 files changed, 49 insertions, 6 deletions
diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java
index 7b1a67007d..c38f567540 100644
--- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java
+++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/LfsProtocolServlet.java
@@ -43,14 +43,18 @@
package org.eclipse.jgit.lfs.server;
import static java.nio.charset.StandardCharsets.UTF_8;
-import static javax.servlet.http.HttpServletResponse.SC_OK;
-import static javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE;
+import static org.apache.http.HttpStatus.SC_FORBIDDEN;
+import static org.apache.http.HttpStatus.SC_NOT_FOUND;
+import static org.apache.http.HttpStatus.SC_OK;
+import static org.apache.http.HttpStatus.SC_SERVICE_UNAVAILABLE;
+import static org.apache.http.HttpStatus.SC_UNPROCESSABLE_ENTITY;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.List;
@@ -60,6 +64,11 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.eclipse.jgit.lfs.errors.LfsException;
+import org.eclipse.jgit.lfs.errors.LfsRepositoryNotFound;
+import org.eclipse.jgit.lfs.errors.LfsRepositoryReadOnly;
+import org.eclipse.jgit.lfs.errors.LfsValidationError;
+
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@@ -80,7 +89,7 @@ public abstract class LfsProtocolServlet extends HttpServlet {
private Gson gson = createGson();
/**
- * Get the large file repository
+ * Get the large file repository for the given request and path.
*
* @param request
* the request
@@ -89,9 +98,10 @@ public abstract class LfsProtocolServlet extends HttpServlet {
*
* @return the large file repository storing large files or null if the
* request is not supported.
+ * @throws LfsException
*/
protected abstract LargeFileRepository getLargeFileRepository(
- LfsRequest request, String path);
+ LfsRequest request, String path) throws LfsException;
/** LFS request. */
protected static class LfsRequest {
@@ -119,7 +129,22 @@ public abstract class LfsProtocolServlet extends HttpServlet {
LfsRequest request = gson.fromJson(r, LfsRequest.class);
String path = req.getPathInfo();
- LargeFileRepository repo = getLargeFileRepository(request, path);
+ LargeFileRepository repo = null;
+ try {
+ repo = getLargeFileRepository(request, path);
+ } catch (LfsValidationError e) {
+ sendError(res, SC_UNPROCESSABLE_ENTITY, e.getMessage());
+ return;
+ } catch (LfsRepositoryNotFound e) {
+ sendError(res, SC_NOT_FOUND, e.getMessage());
+ return;
+ } catch (LfsRepositoryReadOnly e) {
+ sendError(res, SC_FORBIDDEN, e.getMessage());
+ return;
+ } catch (LfsException e) {
+ sendError(res, SC_SERVICE_UNAVAILABLE, e.getMessage());
+ return;
+ }
if (repo == null) {
res.setStatus(SC_SERVICE_UNAVAILABLE);
return;
@@ -133,7 +158,25 @@ public abstract class LfsProtocolServlet extends HttpServlet {
w.flush();
}
- private static Gson createGson() {
+ static class Error {
+ String message;
+
+ Error(String m) {
+ this.message = m;
+ }
+ }
+
+ private void sendError(HttpServletResponse rsp, int status, String message)
+ throws IOException {
+ rsp.setStatus(status);
+ PrintWriter writer = rsp.getWriter();
+ gson.toJson(new Error(message), writer);
+ writer.flush();
+ writer.close();
+ rsp.flushBuffer();
+ }
+
+ private Gson createGson() {
GsonBuilder gb = new GsonBuilder()
.setFieldNamingPolicy(
FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)