/******************************************************************************* * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Exadel, Inc. and Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.common.util; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PostMethod; import org.eclipse.core.net.proxy.IProxyData; import org.eclipse.core.net.proxy.IProxyService; import org.jboss.tools.common.core.CommonCorePlugin; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; /** * HTTP Utilities * @author Alexey Kazakov */ public class HttpUtil { private static IProxyService proxyService; /** * @param url * @return InputStream of the response body of the http GET request. Proxy settings from preferences is used. * @throws Exception * @deprecated Use getInputStreamReader(HttpURLConnection connection) */ @Deprecated public static InputStream getInputStreamFromUrlByGetMethod(String url) throws IOException { return getInputStreamFromUrlByGetMethod(url, false); } /** * Returns the response body of the Get HTTP method. If checkStatusCode==true then return null if the status code is not OK (200) * Uses proxy settings from preferences. * @param url * @return * @throws IOException * @deprecated Use getInputStreamReader(HttpURLConnection connection) */ @Deprecated public static InputStream getInputStreamFromUrlByGetMethod(String url, boolean checkStatusCode) throws IOException { InputStream is = null; GetMethod method = executeGetMethod(url); if(!checkStatusCode || method.getStatusCode()==HttpStatus.SC_OK) { is = method.getResponseBodyAsStream(); } return is; } /** * Create and open an HTTP connection (GET). If the response code is 200 (OK) then returns an input stream reader that reads from this open connection. * Otherwise returns null. * @param httpUrl * @param timeout * @return * @throws IOException */ public static InputStreamReader getInputStreamReader(String httpUrl, int timeout) throws IOException { HttpURLConnection connection = createHttpURLConnection(httpUrl, timeout); if(connection!=null) { return getInputStreamReader(connection); } return null; } /** * Open the HTTP connection. If the response code is 200 (OK) then returns an input stream reader that reads from this connection. * Otherwise returns null. * @param httpUrl * @param timeout * @return * @throws IOException */ public static InputStreamReader getInputStreamReader(HttpURLConnection connection) throws IOException { return getInputStreamReader(connection, 0); } /** * Create an HTTP connection (GET). Returns null if the URL does not use HTTP(S) protocol. * @param urlString * @param timeout * @return * @throws IOException */ public static HttpURLConnection createHttpURLConnection(String urlString, int timeout) throws IOException { URL url = new URL(urlString); URLConnection connetion = url.openConnection(); HttpURLConnection httpConnection = null; if(connetion instanceof HttpURLConnection) { httpConnection = (HttpURLConnection) url.openConnection(); httpConnection.setInstanceFollowRedirects(true); httpConnection.setRequestMethod("GET"); httpConnection.setConnectTimeout(timeout); } return httpConnection; } private static InputStreamReader getInputStreamReader(HttpURLConnection connection, int redirectAttemptCount) throws IOException { InputStreamReader responseReader = null; connection.connect(); int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { // OK String contentTypeCharset = null; String contentType = connection.getContentType(); if(contentType!=null) { Matcher matcher = Pattern.compile("charset=(.+)").matcher(contentType); if (matcher.find()) { contentTypeCharset = matcher.group(1); } } InputStream inputStream = connection.getInputStream(); if (contentTypeCharset != null && contentTypeCharset.length() > 0) { responseReader = new InputStreamReader(new BufferedInputStream(inputStream), contentTypeCharset); } else { responseReader = new InputStreamReader(new BufferedInputStream(inputStream)); } } else if(responseCode >= 300 && responseCode < 400) { // Redirect // URLConnection does not redirect automatically if the protocol is different. HTTP -> HTTPS for example. // So we have to do it manually. String redirectLocation = connection.getHeaderField("location"); if(redirectLocation!=null && !connection.getURL().toString().equalsIgnoreCase(redirectLocation.trim())) { // Ignore responses with empty redirect locations or with the same redirect URL redirectAttemptCount++; if(redirectAttemptCount>1) { // Only one redirect is allowed. HttpURLConnection redirectConnection = createHttpURLConnection(redirectLocation, connection.getConnectTimeout()); redirectConnection.setIfModifiedSince(connection.getIfModifiedSince()); return getInputStreamReader(redirectConnection, redirectAttemptCount); } } } return responseReader; } /** * @param url * @return InputStream of response to http GET request. Use proxy settings from preferences. * @throws Exception */ public static InputStream getInputStreamFromUrlByGetMethod(String url, IProxyService proxyService) throws IOException { InputStream is = executeGetMethod(url, proxyService).getResponseBodyAsStream(); return is; } /** * @param url * @param proxyService * @return Status code of response to http GET request. Use given proxy settings. * @throws Exception */ public static int getStatusCodeFromUrlByGetMethod(String url, IProxyService proxyService) throws IOException { int code = executeGetMethod(url, proxyService).getStatusCode(); return code; } /** * @param url * @return Status code of response to http GET request. Use proxy settings from preferences. * @throws Exception */ public static int getStatusCodeFromUrlByGetMethod(String url) throws IOException { int code = executeGetMethod(url).getStatusCode(); return code; } /** * @param url * @return InputStream of response to http POST request. Use proxy settings from preferences. * @throws Exception */ public static InputStream getInputStreamFromUrlByPostMethod(String url) throws IOException { InputStream is = executePostMethod(url).getResponseBodyAsStream(); return is; } /** * @param url * @param proxyService * @return Status code of response to http POST request. Use given proxy settings. * @throws Exception */ public static int getStatusCodeFromUrlByPostMethod(String url, IProxyService proxyService) throws IOException { int code = executePostMethod(url, proxyService).getStatusCode(); return code; } /** * @param url * @return Status code of response to http POST request. Use proxy settings from preferences. * @throws Exception */ public static int getStatusCodeFromUrlByPostMethod(String url) throws IOException { int code = executePostMethod(url).getStatusCode(); return code; } private static GetMethod executeGetMethod(String url) throws IOException { IProxyService proxyService = getProxyService(); return executeGetMethod(url, proxyService); } private static PostMethod executePostMethod(String url) throws IOException { IProxyService proxyService = getProxyService(); return executePostMethod(url, proxyService); } /** * @param url * @param proxyService * @return * @throws Exception */ public static GetMethod executeGetMethod(String url, IProxyService proxyService) throws IOException { GetMethod httpGet = new GetMethod(url); HttpClient httpClient = createHttpClient(url, proxyService); httpClient.executeMethod(httpGet); return httpGet; } private static PostMethod executePostMethod(String url, IProxyService proxyService) throws IOException { PostMethod httpPost = new PostMethod(url); HttpClient httpClient = createHttpClient(url, proxyService); httpClient.executeMethod(httpPost); return httpPost; } /** * @param url * @return HttpClient with internet proxy settings; * @throws Exception */ public static HttpClient createHttpClient(String url) throws IOException { return createHttpClient(url, getProxyService()); } public static HttpClient createHttpClient(String url, int connectionTimeout) throws IOException { return createHttpClient(url, getProxyService(), connectionTimeout); } private static HttpClient createHttpClient(String url, IProxyService proxyService) throws IOException { return createHttpClient(url, proxyService, 30000); } private static HttpClient createHttpClient(String url, IProxyService proxyService, int connectionTimeout) throws IOException { HttpClient httpClient = new HttpClient(); if(proxyService.isProxiesEnabled()) { IProxyData[] proxyData = proxyService.getProxyData(); URL netUrl = new URL(url); String hostName = netUrl.getHost(); String[] nonProxiedHosts = proxyService.getNonProxiedHosts(); boolean nonProxiedHost = false; for (int i = 0; i < nonProxiedHosts.length; i++) { String nonProxiedHostName = nonProxiedHosts[i]; if(nonProxiedHostName.equalsIgnoreCase(hostName)) { nonProxiedHost = true; break; } } if(!nonProxiedHost) { for (int i = 0; i < proxyData.length; i++) { IProxyData proxy = proxyData[i]; if(IProxyData.HTTP_PROXY_TYPE.equals(proxy.getType())) { String proxyHostName = proxy.getHost(); if(proxyHostName==null) { break; } int portNumber = proxy.getPort(); if(portNumber==-1) { portNumber = 80; } httpClient.getHostConfiguration().setProxy(proxyHostName, portNumber); if(proxy.isRequiresAuthentication()) { String userName = proxy.getUserId(); if(userName!=null) { String password = proxy.getPassword(); httpClient.getState().setProxyCredentials(new AuthScope(null, AuthScope.ANY_PORT, null, AuthScope.ANY_SCHEME), new UsernamePasswordCredentials(userName, password)); } } break; // Use HTTP proxy only. } } } } httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(connectionTimeout); return httpClient; } private static IProxyService getProxyService() { if(proxyService==null) { BundleContext bundleContext = CommonCorePlugin.getInstance().getBundle().getBundleContext(); ServiceReference serviceReference = bundleContext.getServiceReference(IProxyService.class.getName()); proxyService = (IProxyService)bundleContext.getService(serviceReference); } return proxyService; } }