1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 package org.eclipse.jgit.http.server;
45
46 import java.io.File;
47 import java.text.MessageFormat;
48 import java.util.LinkedList;
49 import java.util.List;
50
51 import javax.servlet.Filter;
52 import javax.servlet.FilterConfig;
53 import javax.servlet.ServletException;
54 import javax.servlet.http.HttpServletRequest;
55 import javax.servlet.http.HttpServletResponse;
56
57 import org.eclipse.jgit.http.server.glue.ErrorServlet;
58 import org.eclipse.jgit.http.server.glue.MetaFilter;
59 import org.eclipse.jgit.http.server.glue.RegexGroupFilter;
60 import org.eclipse.jgit.http.server.glue.ServletBinder;
61 import org.eclipse.jgit.http.server.resolver.AsIsFileService;
62 import org.eclipse.jgit.http.server.resolver.DefaultReceivePackFactory;
63 import org.eclipse.jgit.http.server.resolver.DefaultUploadPackFactory;
64 import org.eclipse.jgit.lib.Constants;
65 import org.eclipse.jgit.transport.ReceivePack;
66 import org.eclipse.jgit.transport.UploadPack;
67 import org.eclipse.jgit.transport.resolver.FileResolver;
68 import org.eclipse.jgit.transport.resolver.ReceivePackFactory;
69 import org.eclipse.jgit.transport.resolver.RepositoryResolver;
70 import org.eclipse.jgit.transport.resolver.UploadPackFactory;
71 import org.eclipse.jgit.util.StringUtils;
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87 public class GitFilter extends MetaFilter {
88 private volatile boolean initialized;
89
90 private RepositoryResolver<HttpServletRequest> resolver;
91
92 private AsIsFileService asIs = new AsIsFileService();
93
94 private UploadPackFactory<HttpServletRequest> uploadPackFactory = new DefaultUploadPackFactory();
95
96 private ReceivePackFactory<HttpServletRequest> receivePackFactory = new DefaultReceivePackFactory();
97
98 private final List<Filter> uploadPackFilters = new LinkedList<Filter>();
99
100 private final List<Filter> receivePackFilters = new LinkedList<Filter>();
101
102
103
104
105
106
107
108 public GitFilter() {
109
110 }
111
112
113
114
115
116
117
118
119
120
121 public void setRepositoryResolver(RepositoryResolver<HttpServletRequest> resolver) {
122 assertNotInitialized();
123 this.resolver = resolver;
124 }
125
126
127
128
129
130
131
132 public void setAsIsFileService(AsIsFileService f) {
133 assertNotInitialized();
134 this.asIs = f != null ? f : AsIsFileService.DISABLED;
135 }
136
137
138
139
140
141
142 @SuppressWarnings("unchecked")
143 public void setUploadPackFactory(UploadPackFactory<HttpServletRequest> f) {
144 assertNotInitialized();
145 this.uploadPackFactory = f != null ? f : (UploadPackFactory<HttpServletRequest>)UploadPackFactory.DISABLED;
146 }
147
148
149
150
151
152
153
154 public void addUploadPackFilter(Filter filter) {
155 assertNotInitialized();
156 uploadPackFilters.add(filter);
157 }
158
159
160
161
162
163
164 @SuppressWarnings("unchecked")
165 public void setReceivePackFactory(ReceivePackFactory<HttpServletRequest> f) {
166 assertNotInitialized();
167 this.receivePackFactory = f != null ? f : (ReceivePackFactory<HttpServletRequest>)ReceivePackFactory.DISABLED;
168 }
169
170
171
172
173
174
175
176 public void addReceivePackFilter(Filter filter) {
177 assertNotInitialized();
178 receivePackFilters.add(filter);
179 }
180
181 private void assertNotInitialized() {
182 if (initialized)
183 throw new IllegalStateException(HttpServerText.get().alreadyInitializedByContainer);
184 }
185
186 @Override
187 public void init(FilterConfig filterConfig) throws ServletException {
188 super.init(filterConfig);
189
190 if (resolver == null) {
191 File root = getFile(filterConfig, "base-path");
192 boolean exportAll = getBoolean(filterConfig, "export-all");
193 setRepositoryResolver(new FileResolver<HttpServletRequest>(root, exportAll));
194 }
195
196 initialized = true;
197
198 if (uploadPackFactory != UploadPackFactory.DISABLED) {
199 ServletBinder b = serve("*/" + GitSmartHttpTools.UPLOAD_PACK);
200 b = b.through(new UploadPackServlet.Factory(uploadPackFactory));
201 for (Filter f : uploadPackFilters)
202 b = b.through(f);
203 b.with(new UploadPackServlet());
204 }
205
206 if (receivePackFactory != ReceivePackFactory.DISABLED) {
207 ServletBinder b = serve("*/" + GitSmartHttpTools.RECEIVE_PACK);
208 b = b.through(new ReceivePackServlet.Factory(receivePackFactory));
209 for (Filter f : receivePackFilters)
210 b = b.through(f);
211 b.with(new ReceivePackServlet());
212 }
213
214 ServletBinder refs = serve("*/" + Constants.INFO_REFS);
215 if (uploadPackFactory != UploadPackFactory.DISABLED) {
216 refs = refs.through(new UploadPackServlet.InfoRefs(
217 uploadPackFactory, uploadPackFilters));
218 }
219 if (receivePackFactory != ReceivePackFactory.DISABLED) {
220 refs = refs.through(new ReceivePackServlet.InfoRefs(
221 receivePackFactory, receivePackFilters));
222 }
223 if (asIs != AsIsFileService.DISABLED) {
224 refs = refs.through(new IsLocalFilter());
225 refs = refs.through(new AsIsFileFilter(asIs));
226 refs.with(new InfoRefsServlet());
227 } else
228 refs.with(new ErrorServlet(HttpServletResponse.SC_NOT_ACCEPTABLE));
229
230 if (asIs != AsIsFileService.DISABLED) {
231 final IsLocalFilter mustBeLocal = new IsLocalFilter();
232 final AsIsFileFilter enabled = new AsIsFileFilter(asIs);
233
234 serve("*/" + Constants.HEAD)
235 .through(mustBeLocal)
236 .through(enabled)
237 .with(new TextFileServlet(Constants.HEAD));
238
239 final String info_alternates = "objects/info/alternates";
240 serve("*/" + info_alternates)
241 .through(mustBeLocal)
242 .through(enabled)
243 .with(new TextFileServlet(info_alternates));
244
245 final String http_alternates = "objects/info/http-alternates";
246 serve("*/" + http_alternates)
247 .through(mustBeLocal)
248 .through(enabled)
249 .with(new TextFileServlet(http_alternates));
250
251 serve("*/objects/info/packs")
252 .through(mustBeLocal)
253 .through(enabled)
254 .with(new InfoPacksServlet());
255
256 serveRegex("^/(.*)/objects/([0-9a-f]{2}/[0-9a-f]{38})$")
257 .through(mustBeLocal)
258 .through(enabled)
259 .through(new RegexGroupFilter(2))
260 .with(new ObjectFileServlet.Loose());
261
262 serveRegex("^/(.*)/objects/(pack/pack-[0-9a-f]{40}\\.pack)$")
263 .through(mustBeLocal)
264 .through(enabled)
265 .through(new RegexGroupFilter(2))
266 .with(new ObjectFileServlet.Pack());
267
268 serveRegex("^/(.*)/objects/(pack/pack-[0-9a-f]{40}\\.idx)$")
269 .through(mustBeLocal)
270 .through(enabled)
271 .through(new RegexGroupFilter(2))
272 .with(new ObjectFileServlet.PackIdx());
273 }
274 }
275
276 private static File getFile(FilterConfig cfg, String param)
277 throws ServletException {
278 String n = cfg.getInitParameter(param);
279 if (n == null || "".equals(n))
280 throw new ServletException(MessageFormat.format(HttpServerText.get().parameterNotSet, param));
281
282 File path = new File(n);
283 if (!path.exists())
284 throw new ServletException(MessageFormat.format(HttpServerText.get().pathForParamNotFound, path, param));
285 return path;
286 }
287
288 private static boolean getBoolean(FilterConfig cfg, String param)
289 throws ServletException {
290 String n = cfg.getInitParameter(param);
291 if (n == null)
292 return false;
293 try {
294 return StringUtils.toBoolean(n);
295 } catch (IllegalArgumentException err) {
296 throw new ServletException(MessageFormat.format(HttpServerText.get().invalidBoolean, param, n));
297 }
298 }
299
300 @Override
301 protected ServletBinder register(ServletBinder binder) {
302 if (resolver == null)
303 throw new IllegalStateException(HttpServerText.get().noResolverAvailable);
304 binder = binder.through(new NoCacheFilter());
305 binder = binder.through(new RepositoryFilter(resolver));
306 return binder;
307 }
308 }