~ubuntu-branches/ubuntu/utopic/jetty/utopic-proposed

« back to all changes in this revision

Viewing changes to extras/client/src/main/java/org/mortbay/jetty/client/webdav/WebdavListener.java

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Werner
  • Date: 2009-08-09 08:48:10 UTC
  • Revision ID: james.westby@ubuntu.com-20090809084810-k522b97ind2robyd
ImportĀ upstreamĀ versionĀ 6.1.19

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//========================================================================
 
2
//Copyright 2008 Mort Bay Consulting Pty. Ltd.
 
3
//------------------------------------------------------------------------
 
4
//Licensed under the Apache License, Version 2.0 (the "License");
 
5
//you may not use this file except in compliance with the License.
 
6
//You may obtain a copy of the License at
 
7
//http://www.apache.org/licenses/LICENSE-2.0
 
8
//Unless required by applicable law or agreed to in writing, software
 
9
//distributed under the License is distributed on an "AS IS" BASIS,
 
10
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
11
//See the License for the specific language governing permissions and
 
12
//limitations under the License.
 
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
 * WebdavListener
 
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
        // Start of sending events through to the wrapped listener
 
50
        // Next decision point is the onResponseStatus
 
51
        super(ex.getEventListener(),true);
 
52
        _destination=destination;
 
53
        _exchange=ex;
 
54
 
 
55
        // We'll only enable webdav if this is a PUT request
 
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
        // The dav spec says that CONFLICT should be returned when the parent collection doesn't exist but I am seeing
 
75
        // FORBIDDEN returned instead so running with that.
 
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 ); // stop delegating, we can try and fix this request
 
83
                _needIntercept = true;
 
84
            }
 
85
            else
 
86
            {
 
87
                if (Log.isDebugEnabled())
 
88
                    Log.debug("WebdavListener:Response Status: Webdav Disabled" );
 
89
                setDelegatingResponses( true ); // just make sure we delegate
 
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
                    // we have some work to do before retrying this
 
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
                        // admit defeat but retry because someone else might have 
 
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
                    // we have some work to do before retrying this
 
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
                        // admit defeat but retry because someone else might have 
 
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
     * walk through the steps to try and resolve missing parent collection issues via webdav
 
201
     *
 
202
     * @return
 
203
     * @throws IOException
 
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
        // confirm webdav is supported for this collection
 
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 ); // PROPFIND acts wonky, just use 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
}