1
2
3
4
5
6
7
8
9
10 package org.eclipse.jgit.lfs.server.fs;
11
12 import java.io.IOException;
13 import java.io.PrintWriter;
14 import java.text.MessageFormat;
15
16 import javax.servlet.AsyncContext;
17 import javax.servlet.ServletException;
18 import javax.servlet.annotation.WebServlet;
19 import javax.servlet.http.HttpServlet;
20 import javax.servlet.http.HttpServletRequest;
21 import javax.servlet.http.HttpServletResponse;
22
23 import org.apache.http.HttpStatus;
24 import org.eclipse.jgit.lfs.errors.InvalidLongObjectIdException;
25 import org.eclipse.jgit.lfs.lib.AnyLongObjectId;
26 import org.eclipse.jgit.lfs.lib.Constants;
27 import org.eclipse.jgit.lfs.lib.LongObjectId;
28 import org.eclipse.jgit.lfs.server.internal.LfsGson;
29 import org.eclipse.jgit.lfs.server.internal.LfsServerText;
30
31
32
33
34
35
36
37
38
39 @WebServlet(asyncSupported = true)
40 public class FileLfsServlet extends HttpServlet {
41
42 private static final long serialVersionUID = 1L;
43
44 private final FileLfsRepository repository;
45
46 private final long timeout;
47
48
49
50
51
52
53
54
55
56 public FileLfsServlet(FileLfsRepository repository, long timeout) {
57 this.repository = repository;
58 this.timeout = timeout;
59 }
60
61
62
63
64
65
66 @Override
67 protected void doGet(HttpServletRequest req,
68 HttpServletResponse rsp) throws ServletException, IOException {
69 AnyLongObjectId obj = getObjectToTransfer(req, rsp);
70 if (obj != null) {
71 if (repository.getSize(obj) == -1) {
72 sendError(rsp, HttpStatus.SC_NOT_FOUND, MessageFormat
73 .format(LfsServerText.get().objectNotFound,
74 obj.getName()));
75 return;
76 }
77 AsyncContext context = req.startAsync();
78 context.setTimeout(timeout);
79 rsp.getOutputStream()
80 .setWriteListener(new ObjectDownloadListener(repository,
81 context, rsp, obj));
82 }
83 }
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98 protected AnyLongObjectId getObjectToTransfer(HttpServletRequest req,
99 HttpServletResponse rsp) throws IOException {
100 String info = req.getPathInfo();
101 int length = 1 + Constants.LONG_OBJECT_ID_STRING_LENGTH;
102 if (info.length() != length) {
103 sendError(rsp, HttpStatus.SC_UNPROCESSABLE_ENTITY, MessageFormat
104 .format(LfsServerText.get().invalidPathInfo, info));
105 return null;
106 }
107 try {
108 return LongObjectId.fromString(info.substring(1, length));
109 } catch (InvalidLongObjectIdException e) {
110 sendError(rsp, HttpStatus.SC_UNPROCESSABLE_ENTITY, e.getMessage());
111 return null;
112 }
113 }
114
115
116
117
118
119
120 @Override
121 protected void doPut(HttpServletRequest req,
122 HttpServletResponse rsp) throws ServletException, IOException {
123 AnyLongObjectId id = getObjectToTransfer(req, rsp);
124 if (id != null) {
125 AsyncContext context = req.startAsync();
126 context.setTimeout(timeout);
127 req.getInputStream().setReadListener(new ObjectUploadListener(
128 repository, context, req, rsp, id));
129 }
130 }
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145 protected static void sendError(HttpServletResponse rsp, int status, String message)
146 throws IOException {
147 if (rsp.isCommitted()) {
148 rsp.getOutputStream().close();
149 return;
150 }
151 rsp.reset();
152 rsp.setStatus(status);
153 try (PrintWriter writer = rsp.getWriter()) {
154 LfsGson.toJson(message, writer);
155 writer.flush();
156 }
157 rsp.flushBuffer();
158 }
159 }