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 static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
47 import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;
48 import static org.eclipse.jgit.http.server.GitSmartHttpTools.infoRefsResultType;
49 import static org.eclipse.jgit.http.server.GitSmartHttpTools.sendError;
50 import static org.eclipse.jgit.http.server.ServletUtils.ATTRIBUTE_HANDLER;
51 import static org.eclipse.jgit.http.server.ServletUtils.getRepository;
52
53 import java.io.IOException;
54 import java.util.List;
55
56 import javax.servlet.Filter;
57 import javax.servlet.FilterChain;
58 import javax.servlet.FilterConfig;
59 import javax.servlet.ServletException;
60 import javax.servlet.ServletRequest;
61 import javax.servlet.ServletResponse;
62 import javax.servlet.http.HttpServletRequest;
63 import javax.servlet.http.HttpServletResponse;
64
65 import org.eclipse.jgit.lib.Repository;
66 import org.eclipse.jgit.transport.PacketLineOut;
67 import org.eclipse.jgit.transport.RefAdvertiser.PacketLineOutRefAdvertiser;
68 import org.eclipse.jgit.transport.ServiceMayNotContinueException;
69 import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
70 import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
71
72
73 abstract class SmartServiceInfoRefs implements Filter {
74 private final String svc;
75
76 private final Filter[] filters;
77
78 SmartServiceInfoRefs(String service, List<Filter> filters) {
79 this.svc = service;
80 this.filters = filters.toArray(new Filter[filters.size()]);
81 }
82
83
84 @Override
85 public void init(FilterConfig config) throws ServletException {
86
87 }
88
89
90 @Override
91 public void destroy() {
92
93 }
94
95
96 @Override
97 public void doFilter(ServletRequest request, ServletResponse response,
98 FilterChain chain) throws IOException, ServletException {
99 final HttpServletRequest req = (HttpServletRequest) request;
100 final HttpServletResponse res = (HttpServletResponse) response;
101
102 if (svc.equals(req.getParameter("service"))) {
103 final Repository db = getRepository(req);
104 try {
105 begin(req, db);
106 } catch (ServiceNotAuthorizedException e) {
107 res.sendError(SC_UNAUTHORIZED, e.getMessage());
108 return;
109 } catch (ServiceNotEnabledException e) {
110 sendError(req, res, SC_FORBIDDEN, e.getMessage());
111 return;
112 }
113
114 try {
115 if (filters.length == 0)
116 service(req, response);
117 else
118 new Chain().doFilter(request, response);
119 } finally {
120 req.removeAttribute(ATTRIBUTE_HANDLER);
121 }
122 } else {
123 chain.doFilter(request, response);
124 }
125 }
126
127 private void service(ServletRequest request, ServletResponse response)
128 throws IOException {
129 final HttpServletRequest req = (HttpServletRequest) request;
130 final HttpServletResponse res = (HttpServletResponse) response;
131 final SmartOutputStream buf = new SmartOutputStream(req, res, true);
132 try {
133 res.setContentType(infoRefsResultType(svc));
134
135 final PacketLineOut out = new PacketLineOut(buf);
136 respond(req, out, svc);
137 buf.close();
138 } catch (ServiceNotAuthorizedException e) {
139 res.sendError(SC_UNAUTHORIZED, e.getMessage());
140 } catch (ServiceNotEnabledException e) {
141 sendError(req, res, SC_FORBIDDEN, e.getMessage());
142 } catch (ServiceMayNotContinueException e) {
143 if (e.isOutput())
144 buf.close();
145 else
146 sendError(req, res, e.getStatusCode(), e.getMessage());
147 }
148 }
149
150
151
152
153
154
155
156
157
158
159
160
161 protected abstract void begin(HttpServletRequest req, Repository db)
162 throws IOException, ServiceNotEnabledException,
163 ServiceNotAuthorizedException;
164
165
166
167
168
169
170
171
172
173
174
175 protected abstract void advertise(HttpServletRequest req,
176 PacketLineOutRefAdvertiser pck) throws IOException,
177 ServiceNotEnabledException, ServiceNotAuthorizedException;
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201 protected void respond(HttpServletRequest req,
202 PacketLineOut pckOut, String serviceName)
203 throws IOException, ServiceNotEnabledException,
204 ServiceNotAuthorizedException {
205 pckOut.writeString("# service=" + svc + '\n');
206 pckOut.end();
207 advertise(req, new PacketLineOutRefAdvertiser(pckOut));
208 }
209
210 private class Chain implements FilterChain {
211 private int filterIdx;
212
213 @Override
214 public void doFilter(ServletRequest req, ServletResponse rsp)
215 throws IOException, ServletException {
216 if (filterIdx < filters.length)
217 filters[filterIdx++].doFilter(req, rsp, this);
218 else
219 service(req, rsp);
220 }
221 }
222 }