make UrlResolver reuse commons Http redirectory strategy
[teamcity/dotNetPackagesSupport.git] / nuget-server / src / jetbrains / buildServer / nuget / server / feed / reader / impl / UrlResolverImpl.java
1 /*\r
2  * Copyright 2000-2011 JetBrains s.r.o.\r
3  *\r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  * http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 package jetbrains.buildServer.nuget.server.feed.reader.impl;\r
18 \r
19 import com.intellij.openapi.diagnostic.Logger;\r
20 import com.intellij.openapi.util.Pair;\r
21 import org.apache.http.HttpResponse;\r
22 import org.apache.http.HttpStatus;\r
23 import org.apache.http.ProtocolException;\r
24 import org.apache.http.client.RedirectStrategy;\r
25 import org.apache.http.client.methods.HttpGet;\r
26 import org.apache.http.client.methods.HttpUriRequest;\r
27 import org.apache.http.client.params.ClientPNames;\r
28 import org.apache.http.impl.client.DefaultRedirectStrategy;\r
29 import org.apache.http.protocol.BasicHttpContext;\r
30 import org.apache.http.protocol.HttpContext;\r
31 import org.jetbrains.annotations.NotNull;\r
32 import org.jetbrains.annotations.Nullable;\r
33 \r
34 import java.io.IOException;\r
35 \r
36 /**\r
37  * Created by Eugene Petrenko (eugene.petrenko@gmail.com)\r
38  * Date: 12.08.11 10:24\r
39  */\r
40 public class UrlResolverImpl implements UrlResolver {\r
41   private static final Logger LOG = Logger.getInstance(UrlResolverImpl.class.getName());\r
42 \r
43   private final FeedClient myClient;\r
44   private final FeedGetMethodFactory myMethods;\r
45 \r
46   public UrlResolverImpl(@NotNull final FeedClient client,\r
47                          @NotNull final FeedGetMethodFactory methods) {\r
48     myClient = client;\r
49     myMethods = methods;\r
50   }\r
51 \r
52   /**\r
53    * Generates GET request to a given URL.\r
54    * If HTTP Status 3xx is returned, Location header is\r
55    * used to generate next request unless non 3xx status\r
56    * is returned\r
57    * @param feedUrl url to ping and resolve\r
58    * @return resolved URL and HttpResponse\r
59    * @throws IOException if failed to communicate or non 3xx or 200 status returned\r
60    */\r
61   @NotNull\r
62   public Pair<String, HttpResponse> resolvePath(@NotNull String feedUrl) throws IOException {\r
63     for(int _ = 100; _-->0;) {\r
64       HttpGet ping = myMethods.createGet(feedUrl);\r
65       ping.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, false);\r
66 \r
67       final HttpResponse execute = myClient.execute(ping);\r
68 \r
69       String redirected = getRedirectedUrl(ping, execute);\r
70       if (redirected != null) {\r
71         LOG.debug("Redirected to " + redirected);\r
72         feedUrl = redirected;\r
73         continue;\r
74       }\r
75 \r
76       final int statusCode = execute.getStatusLine().getStatusCode();\r
77       if (statusCode != HttpStatus.SC_OK) {\r
78         throw new IOException("Failed to connect to " + feedUrl);\r
79       }\r
80       return Pair.create(feedUrl, execute);\r
81     }\r
82     throw new IOException("Failed to resolve redirects");\r
83   }\r
84 \r
85   private HttpContext createContext() {\r
86     return new BasicHttpContext();\r
87   }\r
88 \r
89   @NotNull\r
90   public RedirectStrategy getRedirectStrategy() {\r
91     //TODO: could use http client for that\r
92     return new DefaultRedirectStrategy();\r
93   }\r
94 \r
95   @Nullable\r
96   public String getRedirectedUrl(@NotNull HttpUriRequest request, @NotNull HttpResponse response) throws IOException {\r
97     try {\r
98       final RedirectStrategy redirectStrategy = getRedirectStrategy();\r
99       if (!redirectStrategy.isRedirected(request,response, createContext())) {\r
100         return null;\r
101       }\r
102 \r
103       return redirectStrategy.getRedirect(request, response, createContext()).getURI().toString();\r
104     } catch (ProtocolException e) {\r
105       return null;\r
106     }\r
107   }\r
108 }\r