1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.mortbay.jetty.client.webdav;
17
18 import java.io.IOException;
19
20 import javax.servlet.http.HttpServletResponse;
21
22 import org.mortbay.io.Buffer;
23 import org.mortbay.jetty.HttpMethods;
24 import org.mortbay.jetty.client.HttpDestination;
25 import org.mortbay.jetty.client.HttpEventListenerWrapper;
26 import org.mortbay.jetty.client.HttpExchange;
27 import org.mortbay.jetty.client.security.SecurityListener;
28 import org.mortbay.log.Log;
29 import org.mortbay.util.URIUtil;
30
31
32
33
34
35
36
37
38 public class WebdavListener extends HttpEventListenerWrapper
39 {
40 private HttpDestination _destination;
41 private HttpExchange _exchange;
42 private boolean _requestComplete;
43 private boolean _responseComplete;
44 private boolean _webdavEnabled;
45 private boolean _needIntercept;
46
47 public WebdavListener(HttpDestination destination, HttpExchange ex)
48 {
49
50
51 super(ex.getEventListener(),true);
52 _destination=destination;
53 _exchange=ex;
54
55
56 if ( HttpMethods.PUT.equalsIgnoreCase( _exchange.getMethod() ) )
57 {
58 _webdavEnabled = true;
59 }
60 }
61
62 public void onResponseStatus(Buffer version, int status, Buffer reason) throws IOException
63 {
64 if ( !_webdavEnabled )
65 {
66 _needIntercept = false;
67 super.onResponseStatus(version, status, reason);
68 return;
69 }
70
71 if (Log.isDebugEnabled())
72 Log.debug("WebdavListener:Response Status: " + status );
73
74
75
76 if ( status == HttpServletResponse.SC_CONFLICT || status == HttpServletResponse.SC_FORBIDDEN )
77 {
78 if ( _webdavEnabled )
79 {
80 if (Log.isDebugEnabled())
81 Log.debug("WebdavListener:Response Status: dav enabled, taking a stab at resolving put issue" );
82 setDelegatingResponses( false );
83 _needIntercept = true;
84 }
85 else
86 {
87 if (Log.isDebugEnabled())
88 Log.debug("WebdavListener:Response Status: Webdav Disabled" );
89 setDelegatingResponses( true );
90 setDelegatingRequests( true );
91 _needIntercept = false;
92 }
93 }
94 else
95 {
96 _needIntercept = false;
97 setDelegatingResponses( true );
98 setDelegatingRequests( true );
99 }
100
101 super.onResponseStatus(version, status, reason);
102 }
103
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 public void onRequestComplete () throws IOException
153 {
154 _requestComplete = true;
155 if (_needIntercept)
156 {
157 if ( _requestComplete && _responseComplete)
158 {
159 try
160 {
161
162 if ( resolveCollectionIssues() )
163 {
164 setDelegatingRequests( true );
165 setDelegatingResponses(true);
166 _requestComplete = false;
167 _responseComplete = false;
168 _destination.resend(_exchange);
169 }
170 else
171 {
172
173 setDelegatingRequests( true );
174 setDelegatingResponses(true);
175 super.onRequestComplete();
176 }
177 }
178 catch ( IOException ioe )
179 {
180 Log.debug("WebdavListener:Complete:IOException: might not be dealing with dav server, delegate");
181 super.onRequestComplete();
182 }
183 }
184 else
185 {
186 if (Log.isDebugEnabled())
187 Log.debug("WebdavListener:Not ready, calling super");
188 super.onRequestComplete();
189 }
190 }
191 else
192 {
193 super.onRequestComplete();
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 PropfindExchange propfindExchange = new PropfindExchange();
242 propfindExchange.setAddress( _exchange.getAddress() );
243 propfindExchange.setMethod( HttpMethods.GET );
244 propfindExchange.setScheme( _exchange.getScheme() );
245 propfindExchange.setEventListener( new SecurityListener( _destination, propfindExchange ) );
246 propfindExchange.setConfigureListeners( false );
247 propfindExchange.setURI( uri );
248
249 _destination.send( propfindExchange );
250
251 try
252 {
253 propfindExchange.waitForDone();
254
255 return propfindExchange.exists();
256 }
257 catch ( InterruptedException ie )
258 {
259 Log.ignore( ie );
260 return false;
261 }
262 }
263
264 private boolean makeCollection( String uri ) throws IOException
265 {
266 MkcolExchange mkcolExchange = new MkcolExchange();
267 mkcolExchange.setAddress( _exchange.getAddress() );
268 mkcolExchange.setMethod( "MKCOL " + uri + " HTTP/1.1" );
269 mkcolExchange.setScheme( _exchange.getScheme() );
270 mkcolExchange.setEventListener( new SecurityListener( _destination, mkcolExchange ) );
271 mkcolExchange.setConfigureListeners( false );
272 mkcolExchange.setURI( uri );
273
274 _destination.send( mkcolExchange );
275
276 try
277 {
278 mkcolExchange.waitForDone();
279
280 return mkcolExchange.exists();
281 }
282 catch ( InterruptedException ie )
283 {
284 Log.ignore( ie );
285 return false;
286 }
287 }
288
289
290 private boolean checkWebdavSupported() throws IOException
291 {
292 WebdavSupportedExchange supportedExchange = new WebdavSupportedExchange();
293 supportedExchange.setAddress( _exchange.getAddress() );
294 supportedExchange.setMethod( HttpMethods.OPTIONS );
295 supportedExchange.setScheme( _exchange.getScheme() );
296 supportedExchange.setEventListener( new SecurityListener( _destination, supportedExchange ) );
297 supportedExchange.setConfigureListeners( false );
298 supportedExchange.setURI( _exchange.getURI() );
299
300 _destination.send( supportedExchange );
301
302 try
303 {
304 supportedExchange.waitTilCompletion();
305 return supportedExchange.isWebdavSupported();
306 }
307 catch (InterruptedException ie )
308 {
309 Log.ignore( ie );
310 return false;
311 }
312
313 }
314
315 }