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