c611e13f0dac9d7196a032954908f1d391d69e98
[so/libs.git] /
1 /*-\r
2  * ============LICENSE_START=======================================================\r
3  * Licensed under the Apache License, Version 2.0 (the "License");\r
4  * you may not use this file except in compliance with the License.\r
5  * You may obtain a copy of the License at\r
6  *\r
7  *      http://www.apache.org/licenses/LICENSE-2.0\r
8  *\r
9  * Unless required by applicable law or agreed to in writing, software\r
10  * distributed under the License is distributed on an "AS IS" BASIS,\r
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
12  * See the License for the specific language governing permissions and\r
13  * limitations under the License.\r
14  * ============LICENSE_END=========================================================\r
15  */\r
16 \r
17 \r
18 package com.woorea.openstack.connector;\r
19 \r
20 import java.net.URI;\r
21 \r
22 import org.apache.http.HttpRequest;\r
23 import org.apache.http.HttpResponse;\r
24 import org.apache.http.HttpStatus;\r
25 import org.apache.http.ProtocolException;\r
26 import org.apache.http.annotation.Immutable;\r
27 import org.apache.http.client.methods.HttpGet;\r
28 import org.apache.http.client.methods.HttpHead;\r
29 import org.apache.http.client.methods.HttpDelete;\r
30 import org.apache.http.client.methods.HttpUriRequest;\r
31 import org.apache.http.client.methods.RequestBuilder;\r
32 import org.apache.http.impl.client.DefaultRedirectStrategy;\r
33 import org.apache.http.protocol.HttpContext;\r
34 \r
35 /**\r
36  * Custom {@link org.apache.http.client.RedirectStrategy} implementation\r
37  * that automatically redirects all HEAD, GET and DELETE requests.\r
38  * The {@link org.apache.http.client.DefaultRedirectStrategy} only\r
39  * redirects GET and HEAD automatically, per the HTTP specification\r
40  * (POST and PUT typically have bodies and thus cannot be redirected).\r
41  *\r
42  * A custom strategy is needed for the Openstack API, which can also send\r
43  * 302 on a DELETE (by name) request, expecting the client to follow the\r
44  * redirect to perform the actual deletion.\r
45  */\r
46 @Immutable\r
47 public class HttpClientRedirectStrategy extends DefaultRedirectStrategy {\r
48 \r
49     /**\r
50      * Redirectable methods.\r
51      */\r
52     private static final String[] REDIRECT_METHODS = new String[] {\r
53             HttpGet.METHOD_NAME,\r
54             HttpDelete.METHOD_NAME,\r
55             HttpHead.METHOD_NAME\r
56     };\r
57 \r
58     /**\r
59      * Determine if the request should be redirected.\r
60      * This may not actually be needed, since the REDIRECT_METHODS\r
61      * array has been updated with the DELETE.\r
62      */\r
63     @Override\r
64     protected boolean isRedirectable(final String method) {\r
65         for (final String m: REDIRECT_METHODS) {\r
66             if (m.equalsIgnoreCase(method)) {\r
67                 return true;\r
68             }\r
69         }\r
70         return false;\r
71     }\r
72 \r
73     /**\r
74      * Override the default redirect handling method.  As implemented\r
75      * in HttpClient, it does not preserve the method on 301 or 302\r
76      * responses, always redirecting to a GET.\r
77      */\r
78     @Override\r
79     public HttpUriRequest getRedirect(\r
80             final HttpRequest request,\r
81             final HttpResponse response,\r
82             final HttpContext context) throws ProtocolException {\r
83 \r
84         final URI uri = getLocationURI(request, response, context);\r
85         final String method = request.getRequestLine().getMethod();\r
86         if (method.equalsIgnoreCase(HttpHead.METHOD_NAME)) {\r
87             return new HttpHead(uri);\r
88         } else if (method.equalsIgnoreCase(HttpGet.METHOD_NAME)) {\r
89             return new HttpGet(uri);\r
90         } else {\r
91 \r
92             final int status = response.getStatusLine().getStatusCode();\r
93 \r
94             HttpUriRequest newRequest;\r
95             if (status == HttpStatus.SC_TEMPORARY_REDIRECT || status == HttpStatus.SC_MOVED_TEMPORARILY) {\r
96                 newRequest = RequestBuilder.copy(request).setUri(uri).build();\r
97             } else {\r
98                 newRequest =  new HttpGet(uri);\r
99             }\r
100             return newRequest;\r
101         }\r
102     }\r
103 }