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