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