/******************************************************************************* * Copyright (c) 2016 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: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.eclipse.wst.json.core.internal.download; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.util.Date; import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.config.RequestConfig.Builder; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpHead; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.eclipse.core.net.proxy.IProxyData; import org.eclipse.core.net.proxy.IProxyService; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.json.internal.JSONPlugin; import org.eclipse.wst.json.core.JSONCorePlugin; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; public class HttpClientProvider { private static final String JSON_DOWNLOAD_FOLDER = ".jsonDownloadFolder"; //$NON-NLS-1$ public static final String PROTOCOL_FILE = "file"; //$NON-NLS-1$ public static final String PROTOCOL_PLATFORM = "platform"; //$NON-NLS-1$ public static File getFile(URL url) throws IOException { if (url == null) { return null; } if (PROTOCOL_FILE.equals(url.getProtocol()) || PROTOCOL_PLATFORM.equalsIgnoreCase(url.getProtocol())) { File file; try { file = new File(new URI(url.toExternalForm())); } catch (Exception e) { file = new File(url.getFile()); } if (!file.exists()) { return null; } return file; } File file = getCachedFile(url); long urlLastModified = getLastModified(url); if (file.exists()) { long lastModified = file.lastModified(); if (urlLastModified > lastModified) { file = download(file, url); if (file != null) { file.setLastModified(urlLastModified); } } } else { file = download(file, url); if (file != null && urlLastModified > -1) { file.setLastModified(urlLastModified); } } return file; } private static File download(File file, URL url) { CloseableHttpClient httpclient = HttpClients.createDefault(); CloseableHttpResponse response = null; OutputStream out = null; file.getParentFile().mkdirs(); try { HttpHost target = new HttpHost(url.getHost(), url.getPort(), url.getProtocol()); Builder builder = RequestConfig.custom(); HttpHost proxy = getProxy(target); if (proxy != null) { builder = builder.setProxy(proxy); } RequestConfig config = builder.build(); HttpGet request = new HttpGet(url.toURI()); request.setConfig(config); response = httpclient.execute(target, request); InputStream in = response.getEntity().getContent(); out = new BufferedOutputStream(new FileOutputStream(file)); copy(in, out); return file; } catch (Exception e) { logWarning(e); ; } finally { if (out != null) { try { out.close(); } catch (IOException e) { } } if (response != null) { try { response.close(); } catch (IOException e) { } } try { httpclient.close(); } catch (IOException e) { } } return null; } private static void copy(InputStream in, OutputStream out) throws IOException { byte[] buffer = new byte[8192]; int n = 0; while ((n = in.read(buffer)) != -1) { out.write(buffer, 0, n); } } private static long getLastModified(URL url) { CloseableHttpClient httpclient = HttpClients.createDefault(); CloseableHttpResponse response = null; try { HttpHost target = new HttpHost(url.getHost(), url.getPort(), url.getProtocol()); Builder builder = RequestConfig.custom(); HttpHost proxy = getProxy(target); if (proxy != null) { builder = builder.setProxy(proxy); } RequestConfig config = builder.build(); HttpHead request = new HttpHead(url.toURI()); request.setConfig(config); response = httpclient.execute(target, request); Header[] s = response.getHeaders("last-modified"); if (s != null && s.length > 0) { String lastModified = s[0].getValue(); return new Date(lastModified).getTime(); } } catch (Exception e) { logWarning(e); return -1; } finally { if (response != null) { try { response.close(); } catch (IOException e) { } } try { httpclient.close(); } catch (IOException e) { } } return -1; } private static HttpHost getProxy(HttpHost target) { final IProxyService proxyService = getProxyService(); IProxyData[] select = null; try { select = proxyService.select(new URI(target.toURI())); } catch (URISyntaxException e) { logWarning(e); return null; } String type = target.getSchemeName(); for (IProxyData proxyData : select) { if (proxyData.getType().equals(type)) { return new HttpHost(proxyData.getHost(), proxyData.getPort()); } } return null; } private static void logWarning(Exception e) { IStatus status = new Status(IStatus.WARNING, JSONCorePlugin.PLUGIN_ID, e.getMessage(), e); JSONCorePlugin.getDefault().getLog().log(status); } public static IProxyService getProxyService() { BundleContext bc = JSONPlugin.getDefault().getBundle().getBundleContext(); ServiceReference<?> serviceReference = bc.getServiceReference(IProxyService.class.getName()); IProxyService service = (IProxyService) bc.getService(serviceReference); return service; } private static File getCachedFile(URL url) { IPath stateLocation = JSONCorePlugin.getDefault().getStateLocation(); IPath downloadFolder = stateLocation.append(JSON_DOWNLOAD_FOLDER); String urlPath = url.getPath(); IPath filePath = downloadFolder.append(urlPath); File file = filePath.toFile(); return file; } }