1
2
3
4
5
6
7 package net.sourceforge.mavenplugins.sourceforge;
8
9 import java.io.BufferedInputStream;
10 import java.io.File;
11 import java.io.FileOutputStream;
12 import java.io.IOException;
13 import java.io.InputStream;
14 import java.io.StringReader;
15 import java.net.InetAddress;
16 import java.net.UnknownHostException;
17
18 import org.apache.commons.httpclient.Header;
19 import org.apache.commons.httpclient.HttpClient;
20 import org.apache.commons.httpclient.HttpMethod;
21 import org.apache.commons.httpclient.HttpRecoverableException;
22 import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
23 import org.apache.commons.httpclient.NTCredentials;
24 import org.apache.commons.httpclient.URI;
25 import org.apache.commons.httpclient.URIException;
26 import org.apache.commons.httpclient.UsernamePasswordCredentials;
27 import org.apache.commons.httpclient.contrib.ssl.EasySSLProtocolSocketFactory;
28 import org.apache.commons.httpclient.cookie.CookiePolicy;
29 import org.apache.commons.httpclient.methods.GetMethod;
30 import org.apache.commons.httpclient.protocol.Protocol;
31 import org.apache.xerces.xni.parser.XMLInputSource;
32 import org.cyberneko.html.parsers.DOMParser;
33 import org.w3c.dom.Document;
34 import org.xml.sax.SAXNotRecognizedException;
35 import org.xml.sax.SAXNotSupportedException;
36
37 /***
38 * Emulates a web browser
39 *
40 * @author <a href="mailto:ludovicc@users.sourceforge.net">Ludovic Claude</a>
41 * @author Stephen Colebourne
42 * @version $Revision: 1.3 $ $Date: 2006/01/07 22:50:45 $
43 * @created on 11 oct. 2003
44 */
45 public class WebBrowser {
46
47 static {
48
49 System.setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog");
50 System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true");
51 System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.commons.httpclient", "error");
52 }
53
54 private static WebBrowser _instance = new WebBrowser();
55
56 private HttpClient _client;
57 private DOMParser _parser;
58
59 /***
60 * @return the singleton instance
61 */
62 public static WebBrowser getInstance() {
63 return _instance;
64 }
65
66 public static String forceFinalSlash(String s) {
67 if (!s.endsWith("/")) {
68 return s + "/";
69 }
70 return s;
71 }
72
73 public static String removeFinalSlash(String s) {
74 if (s.endsWith("/")) {
75 return s.substring(0, s.length()-1);
76 }
77 return s;
78 }
79
80 /***
81 * Constructor for WebBrowser
82 */
83 private WebBrowser() {
84 super();
85 CookiePolicy.setDefaultPolicy(CookiePolicy.COMPATIBILITY);
86 Protocol.registerProtocol("https",
87 new Protocol("https", new EasySSLProtocolSocketFactory(), 443));
88 _client = new HttpClient(new MultiThreadedHttpConnectionManager());
89 _parser = new DOMParser();
90 try {
91 _parser.setProperty("http://cyberneko.org/html/properties/names/elems", "lower");
92 } catch (SAXNotRecognizedException e) {
93 e.printStackTrace();
94 } catch (SAXNotSupportedException e) {
95 e.printStackTrace();
96 }
97 }
98
99 /***
100 * Gets the client.
101 * @return the client.
102 */
103 public HttpClient getClient() {
104 return _client;
105 }
106
107 /***
108 * Use a proxy to bypass the firewall
109 *
110 * @param proxyHost Host of the proxy
111 * @param proxyPort Port of the proxy
112 * @param proxyNTDomain NT domain for authentification on a MS proxy
113 * @param userName Username (if authentification is required), or null
114 * @param password Password (if authentification is required), or null
115 */
116 public void useProxy(String proxyHost, int proxyPort, final String ntDomain, final String userName, String password) {
117 System.out.println("Using proxy " + proxyHost + ":" + proxyPort);
118 _client.getHostConfiguration().setProxy(proxyHost, proxyPort);
119 if (userName != null) {
120 if (ntDomain == null) {
121 System.out.println("Login on the proxy with user name " + userName);
122 _client.getState().setProxyCredentials(null, proxyHost,
123 new UsernamePasswordCredentials(userName, password));
124 } else {
125 try {
126 String host = InetAddress.getLocalHost().getHostName();
127 System.out.println("Login on the NT proxy with user name " + userName
128 + ", host " + host + ", NT domain " + ntDomain);
129 _client.getState().setProxyCredentials(null, proxyHost,
130 new NTCredentials(userName, password, host, ntDomain));
131 } catch (UnknownHostException ex) {
132 ex.printStackTrace();
133 }
134 }
135 }
136 }
137
138 /***
139 * Execute a http method
140 *
141 * @param method The method
142 * @return the last http method executed (after following redirects)
143 */
144 public HttpMethod executeMethod(HttpMethod method) throws URIException {
145 int statusCode = -1;
146 int attempt = 0;
147
148 method.setRequestHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0b; Windows 98)");
149
150
151 while ((statusCode == -1) && (attempt < 3)) {
152 try {
153
154 statusCode = _client.executeMethod(method);
155 } catch (HttpRecoverableException e) {
156 System.out.println("A recoverable exception occurred, retrying. " + e.getMessage());
157 } catch (IOException e) {
158 System.out.println("Failed to download file.");
159 e.printStackTrace();
160 throw new RuntimeException("Failed to download file.");
161 }
162 }
163
164
165 if (statusCode == -1) {
166 System.out.println("Failed to recover from exception.");
167 throw new RuntimeException("Error when reading " + method.getPath());
168 }
169
170 if (statusCode >= 400) {
171 System.out.println("Page not found (error " + statusCode + ")");
172 throw new RuntimeException("Error when reading " + method.getPath());
173 }
174
175
176 if ((statusCode >= 300) && (statusCode < 400)) {
177 Header locationHeader = method.getResponseHeader("location");
178 if (locationHeader == null) {
179 locationHeader = method.getResponseHeader("Location");
180 }
181
182 if (locationHeader != null) {
183 String redirectLocation = locationHeader.getValue();
184
185 method.releaseConnection();
186
187 URI uri = new URI(redirectLocation);
188 if (!uri.isAbsoluteURI()) {
189 uri = method.getURI();
190 if (!redirectLocation.startsWith("/")) {
191 redirectLocation = uri.getCurrentHierPath() + "/" + redirectLocation;
192 }
193 uri.setPath(redirectLocation);
194 redirectLocation = uri.getURI();
195 }
196
197 HttpMethod redirectMethod = new GetMethod(redirectLocation);
198
199
200
201 redirectMethod.setFollowRedirects(false);
202
203 redirectMethod = executeMethod(redirectMethod);
204
205 return redirectMethod;
206 } else {
207
208
209
210 System.out.println("Page not found");
211 throw new RuntimeException("Error when reading " + method);
212 }
213 }
214
215 return method;
216 }
217
218 /***
219 * Gets the response from a method that has been executed
220 *
221 * @param method
222 * @return
223 */
224 public String getResponse(HttpMethod method) throws URIException {
225 HttpMethod lastMethod = executeMethod(method);
226 String response = new String(lastMethod.getResponseBody());
227 lastMethod.releaseConnection();
228 return response;
229 }
230
231 /***
232 * Execute the method and gets the response as a xml document.
233 *
234 * @param method
235 * @return
236 */
237 public Document getDocument(HttpMethod method) throws Exception {
238 String response = getResponse(method);
239
240 XMLInputSource source = new XMLInputSource(null, null, null, new StringReader(response), null);
241
242 _parser.parse(source);
243
244 Document doc = _parser.getDocument();
245 return doc;
246 }
247
248 public void loadFile(HttpMethod method, File destFile) throws Exception {
249 HttpMethod lastMethod = executeMethod(method);
250 InputStream in = null;
251 FileOutputStream out = null;
252 try {
253 in = new BufferedInputStream(lastMethod.getResponseBodyAsStream());
254 out = new FileOutputStream(destFile);
255
256 byte[] buffer = new byte[8 * 1024];
257 int count = 0;
258 do {
259 out.write(buffer, 0, count);
260 count = in.read(buffer, 0, buffer.length);
261 } while (count != -1);
262 } finally {
263 if (out != null) {
264 out.close();
265 }
266 if (in != null) {
267 in.close();
268 }
269 }
270 }
271
272 }