/******************************************************************************* * Copyright (c) 2016 ARM Ltd. and others * All rights reserved. This program and the accompanying materials * are 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: * ARM Ltd and ARM Germany GmbH - Initial API and implementation *******************************************************************************/ package com.arm.cmsis.pack.installer; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.InetSocketAddress; import java.net.Proxy; import java.net.SocketAddress; import java.net.URL; import java.net.URLConnection; import java.util.List; import javax.xml.bind.DatatypeConverter; import javax.xml.parsers.ParserConfigurationException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.osgi.util.NLS; import org.xml.sax.SAXException; import com.arm.cmsis.pack.CpPlugIn; import com.arm.cmsis.pack.ICpRepoServiceProvider; import com.arm.cmsis.pack.common.CmsisConstants; import com.arm.cmsis.pack.installer.utils.RepositoryRefreshingUtils; import com.arm.cmsis.pack.preferences.CpPreferenceInitializer; import com.arm.cmsis.pack.utils.Utils; /** * Default implementation of providing repository service like get pdsc files and pack files * from the Internet */ public class CpRepoServiceProvider implements ICpRepoServiceProvider { private final static int TIME_OUT = 10000; public CpRepoServiceProvider() { } @Override public int readIndexFile(String indexUrl, List<String[]> pdscList) throws ParserConfigurationException, SAXException, IOException { URL url = new URL(indexUrl); URLConnection connection = getConnection(url); return RepositoryRefreshingUtils.readIndex(connection.getInputStream(), pdscList); } @Override public File getPdscFile(String pdscUrl, String pdscName, String destFileName, IProgressMonitor monitor) throws IOException { File destFile = null; URL sourceUrl = new URL(pdscUrl + pdscName); File destFileTmp = File.createTempFile("temp-pdsc", ".tmp"); //$NON-NLS-1$ //$NON-NLS-2$ URLConnection connection = null; while (true) { connection = getConnection(sourceUrl); if (connection == null) { break; } connection.setConnectTimeout(TIME_OUT); connection.setReadTimeout(TIME_OUT); if (connection instanceof HttpURLConnection) { int responseCode = ((HttpURLConnection) connection).getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { break; } else if (responseCode == HttpURLConnection.HTTP_MOVED_TEMP || responseCode == HttpURLConnection.HTTP_MOVED_PERM || responseCode == HttpURLConnection.HTTP_SEE_OTHER) { String newUrl = connection.getHeaderField(CmsisConstants.REPO_LOCATION); sourceUrl = new URL(newUrl); } else { break; } } } if (connection != null) { InputStream input = connection.getInputStream(); OutputStream output = new FileOutputStream(destFileTmp); boolean finished = true; byte[] buf = new byte[1024]; int bytesRead; while ((bytesRead = input.read(buf)) > 0) { output.write(buf, 0, bytesRead); // Check if the cancel button is pressed if (monitor.isCanceled()) { finished = false; break; } } output.close(); if (input != null) { input.close(); } if (finished) { destFile = new File(destFileName); Utils.copy(destFileTmp, destFile); destFile.setReadOnly(); } if (destFileTmp.exists()) { destFileTmp.delete(); } if (connection instanceof HttpURLConnection) { ((HttpURLConnection) connection).disconnect(); } } return destFile; } @Override public File getPackFile(String packUrl, String destFileName, IProgressMonitor monitor) throws IOException { SubMonitor progress = SubMonitor.convert(monitor, 100); /***************** Establish connection *****************/ URLConnection connection = null; progress.subTask(Messages.CpPackInstallJob_ConnectingTo + packUrl); URL url = new URL(packUrl); while (true) { progress.worked(10); if (progress.isCanceled()) { throw new InterruptedIOException(Messages.CpPackJob_CancelledByUser); } connection = getConnection(url); connection.setConnectTimeout(TIME_OUT); connection.setReadTimeout(TIME_OUT); if (connection instanceof HttpURLConnection) { int responseCode = ((HttpURLConnection) connection).getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { break; } else if (responseCode == HttpURLConnection.HTTP_MOVED_TEMP || responseCode == HttpURLConnection.HTTP_MOVED_PERM || responseCode == HttpURLConnection.HTTP_SEE_OTHER) { String newUrl = connection.getHeaderField(CmsisConstants.REPO_LOCATION); url = new URL(newUrl); } else { break; } } } if(connection == null) { return null; // should not happen } /***************** Start downloading *****************/ int totalWork = connection.getContentLength(); if (totalWork == -1) { totalWork = IProgressMonitor.UNKNOWN; } progress = SubMonitor.convert(progress.newChild(90), totalWork); progress.subTask(NLS.bind(Messages.CpPackInstallJob_DownloadingFrom, destFileName, packUrl)); IPath downloadDir = new Path(CpPlugIn.getPackManager().getCmsisPackDownloadDir()); if (!downloadDir.toFile().exists()) { downloadDir.toFile().mkdir(); } File downloadFile = downloadDir.append(destFileName).toFile(); File downloadFileTmp = File.createTempFile("temp-pack", ".tmp"); //$NON-NLS-1$ //$NON-NLS-2$ InputStream input = null; OutputStream output = null; try { input = connection.getInputStream(); output = new FileOutputStream(downloadFileTmp); byte[] buf = new byte[1024]; int bytesRead; while ((bytesRead = input.read(buf)) > 0) { output.write(buf, 0, bytesRead); progress.worked(bytesRead); // Check if the cancel button is pressed if (progress.isCanceled()) { throw new InterruptedIOException(Messages.CpPackJob_CancelledByUser); } } Utils.copy(downloadFileTmp, downloadFile); return downloadFile; } finally { if (input != null) { input.close(); } if (output != null) { output.close(); } if (downloadFileTmp.exists()) { downloadFileTmp.delete(); } if (connection instanceof HttpURLConnection) { ((HttpURLConnection) connection).disconnect(); } } } private URLConnection getConnection(URL url) throws IOException { URLConnection connection = null; int proxyMode = CpPreferenceInitializer.getProxyMode(); if (proxyMode == 0) { // No Proxy connection = url.openConnection(); } else { String addr = CpPreferenceInitializer.getProxyAddress(); int port = CpPreferenceInitializer.getProxyPort(); SocketAddress socket = new InetSocketAddress(addr, port); Proxy proxy; if (proxyMode == 1) { // HTTP Proxy proxy = new Proxy(Proxy.Type.HTTP, socket); } else if (proxyMode == 2) { // Socket Proxy proxy = new Proxy(Proxy.Type.SOCKS, socket); } else { proxy = Proxy.NO_PROXY; } connection = url.openConnection(proxy); String username = CpPreferenceInitializer.getProxyUsername(); String password = CpPreferenceInitializer.getProxyPassword(); String userpass = username + ':' + password; String basicAuth = "Basic " + DatatypeConverter.printBase64Binary(userpass.getBytes()); //$NON-NLS-1$ connection.setRequestProperty("Authorization", basicAuth); //$NON-NLS-1$ } return connection; } }