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