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 setDelegatingRequests( true );
124 setDelegatingResponses(true);
125 super.onResponseComplete();
126 }
127 }
128 catch ( IOException ioe )
129 {
130 Log.debug("WebdavListener:Complete:IOException: might not be dealing with dav server, delegate");
131 super.onResponseComplete();
132 }
133 }
134 else
135 {
136 if (Log.isDebugEnabled())
137 Log.debug("WebdavListener:Not ready, calling super");
138 super.onResponseComplete();
139 }
140 }
141 else
142 {
143 super.onResponseComplete();
144 }
145 }
146
147
148
149 public void onRequestComplete () throws IOException
150 {
151 _requestComplete = true;
152 if (_needIntercept)
153 {
154 if ( _requestComplete && _responseComplete)
155 {
156 try
157 {
158
159 if ( resolveCollectionIssues() )
160 {
161 setDelegatingRequests( true );
162 setDelegatingResponses(true);
163 _requestComplete = false;
164 _responseComplete = false;
165 _destination.resend(_exchange);
166 }
167 else
168 {
169
170 setDelegatingRequests( true );
171 setDelegatingResponses(true);
172 super.onRequestComplete();
173 }
174 }
175 catch ( IOException ioe )
176 {
177 Log.debug("WebdavListener:Complete:IOException: might not be dealing with dav server, delegate");
178 super.onRequestComplete();
179 }
180 }
181 else
182 {
183 if (Log.isDebugEnabled())
184 Log.debug("WebdavListener:Not ready, calling super");
185 super.onRequestComplete();
186 }
187 }
188 else
189 {
190 super.onRequestComplete();
191 }
192 }
193
194
195
196
197
198
199
200
201
202
203 private boolean resolveCollectionIssues() throws IOException
204 {
205
206 String uri = _exchange.getURI();
207 String[] uriCollection = _exchange.getURI().split("/");
208 int checkNum = uriCollection.length;
209 int rewind = 0;
210
211 String parentUri = URIUtil.parentPath( uri );
212 while ( !checkExists( parentUri ) )
213 {
214 ++rewind;
215 parentUri = URIUtil.parentPath( parentUri );
216 }
217
218
219 if ( checkWebdavSupported() )
220 {
221 for (int i = 0; i < rewind;)
222 {
223 makeCollection(parentUri + "/" + uriCollection[checkNum - rewind - 1]);
224 parentUri = parentUri + "/" + uriCollection[checkNum - rewind - 1];
225 --rewind;
226 }
227 }
228 else
229 {
230 return false;
231 }
232
233 return true;
234 }
235
236 private boolean checkExists( String uri ) throws IOException
237 {
238 PropfindExchange propfindExchange = new PropfindExchange();
239 propfindExchange.setAddress( _exchange.getAddress() );
240 propfindExchange.setMethod( HttpMethods.GET );
241 propfindExchange.setScheme( _exchange.getScheme() );
242 propfindExchange.setEventListener( new SecurityListener( _destination, propfindExchange ) );
243 propfindExchange.setConfigureListeners( false );
244 propfindExchange.setURI( uri );
245
246 _destination.send( propfindExchange );
247
248 try
249 {
250 propfindExchange.waitForDone();
251
252 return propfindExchange.exists();
253 }
254 catch ( InterruptedException ie )
255 {
256 Log.ignore( ie );
257 return false;
258 }
259 }
260
261 private boolean makeCollection( String uri ) throws IOException
262 {
263 MkcolExchange mkcolExchange = new MkcolExchange();
264 mkcolExchange.setAddress( _exchange.getAddress() );
265 mkcolExchange.setMethod( "MKCOL " + uri + " HTTP/1.1" );
266 mkcolExchange.setScheme( _exchange.getScheme() );
267 mkcolExchange.setEventListener( new SecurityListener( _destination, mkcolExchange ) );
268 mkcolExchange.setConfigureListeners( false );
269 mkcolExchange.setURI( uri );
270
271 _destination.send( mkcolExchange );
272
273 try
274 {
275 mkcolExchange.waitForDone();
276
277 return mkcolExchange.exists();
278 }
279 catch ( InterruptedException ie )
280 {
281 Log.ignore( ie );
282 return false;
283 }
284 }
285
286
287 private boolean checkWebdavSupported() throws IOException
288 {
289 WebdavSupportedExchange supportedExchange = new WebdavSupportedExchange();
290 supportedExchange.setAddress( _exchange.getAddress() );
291 supportedExchange.setMethod( HttpMethods.OPTIONS );
292 supportedExchange.setScheme( _exchange.getScheme() );
293 supportedExchange.setEventListener( new SecurityListener( _destination, supportedExchange ) );
294 supportedExchange.setConfigureListeners( false );
295 supportedExchange.setURI( _exchange.getURI() );
296
297 _destination.send( supportedExchange );
298
299 try
300 {
301 supportedExchange.waitTilCompletion();
302 return supportedExchange.isWebdavSupported();
303 }
304 catch (InterruptedException ie )
305 {
306 Log.ignore( ie );
307 return false;
308 }
309
310 }
311
312 }