1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.eclipse.jetty.client.webdav;
21
22 import java.io.IOException;
23
24 import org.eclipse.jetty.client.HttpDestination;
25 import org.eclipse.jetty.client.HttpEventListenerWrapper;
26 import org.eclipse.jetty.client.HttpExchange;
27 import org.eclipse.jetty.client.security.SecurityListener;
28 import org.eclipse.jetty.http.HttpMethods;
29 import org.eclipse.jetty.http.HttpStatus;
30 import org.eclipse.jetty.io.Buffer;
31 import org.eclipse.jetty.util.URIUtil;
32 import org.eclipse.jetty.util.log.Log;
33 import org.eclipse.jetty.util.log.Logger;
34
35
36
37
38
39
40
41
42 public class WebdavListener extends HttpEventListenerWrapper
43 {
44 private static final Logger LOG = Log.getLogger(WebdavListener.class);
45
46 private HttpDestination _destination;
47 private HttpExchange _exchange;
48 private boolean _requestComplete;
49 private boolean _responseComplete;
50 private boolean _webdavEnabled;
51 private boolean _needIntercept;
52
53 public WebdavListener(HttpDestination destination, HttpExchange ex)
54 {
55
56
57 super(ex.getEventListener(),true);
58 _destination=destination;
59 _exchange=ex;
60
61
62 if ( HttpMethods.PUT.equalsIgnoreCase( _exchange.getMethod() ) )
63 {
64 _webdavEnabled = true;
65 }
66 }
67
68 @Override
69 public void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
70 {
71 if ( !_webdavEnabled )
72 {
73 _needIntercept = false;
74 super.onResponseStatus(version, status, reason);
75 return;
76 }
77
78 if (LOG.isDebugEnabled())
79 LOG.debug("WebdavListener:Response Status: " + status );
80
81
82
83 if ( status == HttpStatus.FORBIDDEN_403 || status == HttpStatus.CONFLICT_409 )
84 {
85 if ( _webdavEnabled )
86 {
87 if (LOG.isDebugEnabled())
88 LOG.debug("WebdavListener:Response Status: dav enabled, taking a stab at resolving put issue" );
89 setDelegatingResponses( false );
90 _needIntercept = true;
91 }
92 else
93 {
94 if (LOG.isDebugEnabled())
95 LOG.debug("WebdavListener:Response Status: Webdav Disabled" );
96 setDelegatingResponses( true );
97 setDelegatingRequests( true );
98 _needIntercept = false;
99 }
100 }
101 else
102 {
103 _needIntercept = false;
104 setDelegatingResponses( true );
105 setDelegatingRequests( true );
106 }
107
108 super.onResponseStatus(version, status, reason);
109 }
110
111 @Override
112 public void onResponseComplete() throws IOException
113 {
114 _responseComplete = true;
115 if (_needIntercept)
116 {
117 if ( _requestComplete && _responseComplete)
118 {
119 try
120 {
121
122 if ( resolveCollectionIssues() )
123 {
124 setDelegatingRequests( true );
125 setDelegatingResponses(true);
126 _requestComplete = false;
127 _responseComplete = false;
128 _destination.resend(_exchange);
129 }
130 else
131 {
132
133 setDelegationResult(false);
134 setDelegatingRequests( true );
135 setDelegatingResponses(true);
136 super.onResponseComplete();
137 }
138 }
139 catch ( IOException ioe )
140 {
141 LOG.debug("WebdavListener:Complete:IOException: might not be dealing with dav server, delegate");
142 super.onResponseComplete();
143 }
144 }
145 else
146 {
147 if (LOG.isDebugEnabled())
148 LOG.debug("WebdavListener:Not ready, calling super");
149 super.onResponseComplete();
150 }
151 }
152 else
153 {
154 super.onResponseComplete();
155 }
156 }
157
158
159
160 @Override
161 public void onRequestComplete () throws IOException
162 {
163 _requestComplete = true;
164 if (_needIntercept)
165 {
166 if ( _requestComplete && _responseComplete)
167 {
168 try
169 {
170
171 if ( resolveCollectionIssues() )
172 {
173 setDelegatingRequests( true );
174 setDelegatingResponses(true);
175 _requestComplete = false;
176 _responseComplete = false;
177 _destination.resend(_exchange);
178 }
179 else
180 {
181
182 setDelegatingRequests( true );
183 setDelegatingResponses(true);
184 super.onRequestComplete();
185 }
186 }
187 catch ( IOException ioe )
188 {
189 LOG.debug("WebdavListener:Complete:IOException: might not be dealing with dav server, delegate");
190 super.onRequestComplete();
191 }
192 }
193 else
194 {
195 if (LOG.isDebugEnabled())
196 LOG.debug("WebdavListener:Not ready, calling super");
197 super.onRequestComplete();
198 }
199 }
200 else
201 {
202 super.onRequestComplete();
203 }
204 }
205
206
207
208
209
210
211
212
213
214
215
216
217 private boolean resolveCollectionIssues() throws IOException
218 {
219
220 String uri = _exchange.getURI();
221 String[] uriCollection = _exchange.getURI().split("/");
222 int checkNum = uriCollection.length;
223 int rewind = 0;
224
225 String parentUri = URIUtil.parentPath( uri );
226 while ( parentUri != null && !checkExists(parentUri) )
227 {
228 ++rewind;
229 parentUri = URIUtil.parentPath( parentUri );
230 }
231
232
233 if ( checkWebdavSupported() )
234 {
235 for (int i = 0; i < rewind;)
236 {
237 makeCollection(parentUri + "/" + uriCollection[checkNum - rewind - 1]);
238 parentUri = parentUri + "/" + uriCollection[checkNum - rewind - 1];
239 --rewind;
240 }
241 }
242 else
243 {
244 return false;
245 }
246
247 return true;
248 }
249
250 private boolean checkExists( String uri ) throws IOException
251 {
252 if (uri == null)
253 {
254 System.out.println("have failed miserably");
255 return false;
256 }
257
258 PropfindExchange propfindExchange = new PropfindExchange();
259 propfindExchange.setAddress( _exchange.getAddress() );
260 propfindExchange.setMethod( HttpMethods.GET );
261 propfindExchange.setScheme( _exchange.getScheme() );
262 propfindExchange.setEventListener( new SecurityListener( _destination, propfindExchange ) );
263 propfindExchange.setConfigureListeners( false );
264 propfindExchange.setRequestURI( uri );
265
266 _destination.send( propfindExchange );
267
268 try
269 {
270 propfindExchange.waitForDone();
271
272 return propfindExchange.exists();
273 }
274 catch ( InterruptedException ie )
275 {
276 LOG.ignore( ie );
277 return false;
278 }
279 }
280
281 private boolean makeCollection( String uri ) throws IOException
282 {
283 MkcolExchange mkcolExchange = new MkcolExchange();
284 mkcolExchange.setAddress( _exchange.getAddress() );
285 mkcolExchange.setMethod( "MKCOL " + uri + " HTTP/1.1" );
286 mkcolExchange.setScheme( _exchange.getScheme() );
287 mkcolExchange.setEventListener( new SecurityListener( _destination, mkcolExchange ) );
288 mkcolExchange.setConfigureListeners( false );
289 mkcolExchange.setRequestURI( uri );
290
291 _destination.send( mkcolExchange );
292
293 try
294 {
295 mkcolExchange.waitForDone();
296
297 return mkcolExchange.exists();
298 }
299 catch ( InterruptedException ie )
300 {
301 LOG.ignore( ie );
302 return false;
303 }
304 }
305
306
307 private boolean checkWebdavSupported() throws IOException
308 {
309 WebdavSupportedExchange supportedExchange = new WebdavSupportedExchange();
310 supportedExchange.setAddress( _exchange.getAddress() );
311 supportedExchange.setMethod( HttpMethods.OPTIONS );
312 supportedExchange.setScheme( _exchange.getScheme() );
313 supportedExchange.setEventListener( new SecurityListener( _destination, supportedExchange ) );
314 supportedExchange.setConfigureListeners( false );
315 supportedExchange.setRequestURI( _exchange.getURI() );
316
317 _destination.send( supportedExchange );
318
319 try
320 {
321 supportedExchange.waitTilCompletion();
322 return supportedExchange.isWebdavSupported();
323 }
324 catch (InterruptedException ie )
325 {
326 LOG.ignore( ie );
327 return false;
328 }
329
330 }
331
332 }