mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Use HttpRequests to fix IDEA-131621
checkPluginsHost — don't load twice versions info (we still parse it twice) ensure that we download plugin under determinate progress
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
package com.intellij.ide.plugins;
|
||||
|
||||
import com.intellij.openapi.extensions.PluginId;
|
||||
import com.intellij.util.containers.Stack;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.xml.sax.Attributes;
|
||||
@@ -24,9 +25,8 @@ import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
class RepositoryContentHandler extends DefaultHandler {
|
||||
public class RepositoryContentHandler extends DefaultHandler {
|
||||
@NonNls public static final String CATEGORY = "category";
|
||||
@NonNls public static final String IDEA_PLUGIN = "idea-plugin";
|
||||
@NonNls public static final String NAME = "name";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -39,7 +39,6 @@ import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URLConnection;
|
||||
import java.util.List;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
/**
|
||||
* @author stathik
|
||||
@@ -52,24 +51,6 @@ public class RepositoryHelper {
|
||||
return loadPluginsFromRepository(indicator, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
|
||||
@NotNull
|
||||
public static InputStream getConnectionInputStream(@NotNull URLConnection connection) throws IOException {
|
||||
InputStream inputStream = connection.getInputStream();
|
||||
if ("gzip".equalsIgnoreCase(connection.getContentEncoding())) {
|
||||
try {
|
||||
return new GZIPInputStream(inputStream);
|
||||
}
|
||||
catch (IOException e) {
|
||||
inputStream.close();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return inputStream;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
|
||||
public static List<IdeaPluginDescriptor> loadPluginsFromRepository(@Nullable final ProgressIndicator indicator, @Nullable BuildNumber buildnumber) throws Exception {
|
||||
final ApplicationInfoEx appInfo = ApplicationInfoImpl.getShadowInstance();
|
||||
@@ -83,6 +64,7 @@ public class RepositoryHelper {
|
||||
final File pluginListFile = new File(PathManager.getPluginsPath(), PLUGIN_LIST_FILE);
|
||||
if (pluginListFile.length() > 0) {
|
||||
try {
|
||||
//noinspection SpellCheckingInspection
|
||||
url = url + "&crc32=" + Files.hash(pluginListFile, Hashing.crc32()).toString();
|
||||
}
|
||||
catch (NoSuchMethodError e) {
|
||||
@@ -91,15 +73,12 @@ public class RepositoryHelper {
|
||||
}
|
||||
}
|
||||
|
||||
return HttpRequests.request(url).supportGzip(true).get(new ThrowableConvertor<URLConnection, List<IdeaPluginDescriptor>, Exception>() {
|
||||
return HttpRequests.request(url).get(new ThrowableConvertor<URLConnection, List<IdeaPluginDescriptor>, Exception>() {
|
||||
@Override
|
||||
public List<IdeaPluginDescriptor> convert(URLConnection connection) throws Exception {
|
||||
if (indicator != null) {
|
||||
indicator.setText2(IdeBundle.message("progress.waiting.for.reply.from.plugin.manager", appInfo.getPluginManagerUrl()));
|
||||
}
|
||||
connection.connect();
|
||||
if (indicator != null) {
|
||||
indicator.checkCanceled();
|
||||
indicator.setText2(IdeBundle.message("progress.waiting.for.reply.from.plugin.manager", appInfo.getPluginManagerUrl()));
|
||||
}
|
||||
|
||||
if (connection instanceof HttpURLConnection && ((HttpURLConnection)connection).getResponseCode() == HttpURLConnection.HTTP_NOT_MODIFIED) {
|
||||
@@ -107,6 +86,7 @@ public class RepositoryHelper {
|
||||
}
|
||||
|
||||
if (indicator != null) {
|
||||
indicator.checkCanceled();
|
||||
indicator.setText2(IdeBundle.message("progress.downloading.list.of.plugins"));
|
||||
}
|
||||
return readPluginsStream(connection, indicator, PLUGIN_LIST_FILE);
|
||||
@@ -114,11 +94,11 @@ public class RepositoryHelper {
|
||||
});
|
||||
}
|
||||
|
||||
private synchronized static List<IdeaPluginDescriptor> readPluginsStream(@NotNull URLConnection connection,
|
||||
@Nullable ProgressIndicator indicator,
|
||||
@NotNull String file) throws Exception {
|
||||
public synchronized static List<IdeaPluginDescriptor> readPluginsStream(@NotNull URLConnection connection,
|
||||
@Nullable ProgressIndicator indicator,
|
||||
@NotNull String file) throws Exception {
|
||||
File localFile;
|
||||
InputStream input = getConnectionInputStream(connection);
|
||||
InputStream input = HttpRequests.getInputStream(connection);
|
||||
try {
|
||||
localFile = createLocalPluginsDescriptions(file);
|
||||
OutputStream output = new FileOutputStream(localFile);
|
||||
@@ -159,10 +139,6 @@ public class RepositoryHelper {
|
||||
return temp;
|
||||
}
|
||||
|
||||
public static List<IdeaPluginDescriptor> loadPluginsFromDescription(@NotNull URLConnection connection, @Nullable ProgressIndicator indicator) throws Exception {
|
||||
return readPluginsStream(connection, indicator, "host.xml");
|
||||
}
|
||||
|
||||
public static String getDownloadUrl() {
|
||||
return ApplicationInfoImpl.getShadowInstance().getPluginsDownloadUrl() + "?action=download&id=";
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.ide.reporter;
|
||||
|
||||
public class ConnectionException extends Exception {
|
||||
|
||||
public ConnectionException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ConnectionException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public ConnectionException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
+33
-45
@@ -25,15 +25,15 @@ import com.intellij.openapi.extensions.PluginId;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.BuildNumber;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.openapi.vfs.VirtualFileSystem;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.HttpRequests;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.io.UrlConnectionUtil;
|
||||
import com.intellij.util.ThrowableConvertor;
|
||||
import com.intellij.util.io.ZipUtil;
|
||||
import com.intellij.util.net.NetUtils;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -41,7 +41,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URLConnection;
|
||||
import java.util.List;
|
||||
|
||||
@@ -92,7 +91,7 @@ public class PluginDownloader {
|
||||
return prepareToInstall(progressIndicator, myBuildNumber);
|
||||
}
|
||||
|
||||
public boolean prepareToInstall(@Nullable ProgressIndicator progressIndicator, @Nullable BuildNumber forBuildNumber) throws IOException {
|
||||
public boolean prepareToInstall(@NotNull ProgressIndicator progressIndicator, @Nullable BuildNumber forBuildNumber) throws IOException {
|
||||
if (myFile != null) {
|
||||
return true;
|
||||
}
|
||||
@@ -226,65 +225,54 @@ public class PluginDownloader {
|
||||
}
|
||||
}
|
||||
|
||||
private File downloadPlugin(@Nullable final ProgressIndicator progressIndicator) throws IOException {
|
||||
final File pluginsTemp = new File(PathManager.getPluginTempPath());
|
||||
@NotNull
|
||||
private File downloadPlugin(@NotNull final ProgressIndicator progressIndicator) throws IOException {
|
||||
File pluginsTemp = new File(PathManager.getPluginTempPath());
|
||||
if (!pluginsTemp.exists() && !pluginsTemp.mkdirs()) {
|
||||
throw new IOException(IdeBundle.message("error.cannot.create.temp.dir", pluginsTemp));
|
||||
}
|
||||
final File file = FileUtil.createTempFile(pluginsTemp, "plugin_", "_download", true, false);
|
||||
|
||||
if (progressIndicator != null) {
|
||||
progressIndicator.setText(IdeBundle.message("progress.connecting"));
|
||||
}
|
||||
progressIndicator.checkCanceled();
|
||||
progressIndicator.setText(IdeBundle.message("progress.downloading.plugin", getPluginName()));
|
||||
|
||||
URLConnection connection = null;
|
||||
try {
|
||||
Pair<URLConnection, String> result = HttpRequests.openConnection(myPluginUrl, false);
|
||||
if (result.second != null) {
|
||||
myPluginUrl = result.second;
|
||||
return HttpRequests.request(myPluginUrl).supportGzip(false).effectiveUrlConsumer(new Consumer<String>() {
|
||||
@Override
|
||||
public void consume(String url) {
|
||||
myPluginUrl = url;
|
||||
}
|
||||
connection = result.first;
|
||||
}).get(new ThrowableConvertor<URLConnection, File, IOException>() {
|
||||
@Override
|
||||
public File convert(URLConnection connection) throws IOException {
|
||||
progressIndicator.checkCanceled();
|
||||
|
||||
final InputStream is = (ApplicationManager.getApplication() != null)
|
||||
? UrlConnectionUtil.getConnectionInputStream(connection, progressIndicator)
|
||||
: connection.getInputStream();
|
||||
if (is == null) {
|
||||
throw new IOException("Failed to open connection");
|
||||
}
|
||||
|
||||
if (progressIndicator != null && ApplicationManager.getApplication() != null) {
|
||||
progressIndicator.setText(IdeBundle.message("progress.downloading.plugin", getPluginName()));
|
||||
}
|
||||
try {
|
||||
final OutputStream fos = new BufferedOutputStream(new FileOutputStream(file, false));
|
||||
InputStream input = HttpRequests.getInputStream(connection);
|
||||
try {
|
||||
NetUtils.copyStreamContent(progressIndicator, is, fos, connection.getContentLength());
|
||||
OutputStream fileOut = new FileOutputStream(file);
|
||||
try {
|
||||
NetUtils.copyStreamContent(progressIndicator, input, fileOut, connection.getContentLength());
|
||||
}
|
||||
finally {
|
||||
fileOut.close();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
fos.close();
|
||||
input.close();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
is.close();
|
||||
}
|
||||
|
||||
if (myFileName == null) {
|
||||
myFileName = guessFileName(connection, file);
|
||||
}
|
||||
if (myFileName == null) {
|
||||
myFileName = guessFileName(connection, file);
|
||||
}
|
||||
|
||||
final File newFile = new File(file.getParentFile(), myFileName);
|
||||
FileUtil.rename(file, newFile);
|
||||
return newFile;
|
||||
}
|
||||
finally {
|
||||
if (connection instanceof HttpURLConnection) {
|
||||
((HttpURLConnection)connection).disconnect();
|
||||
File newFile = new File(file.getParentFile(), myFileName);
|
||||
FileUtil.rename(file, newFile);
|
||||
return newFile;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String guessFileName(final URLConnection connection, final File file) throws IOException {
|
||||
private String guessFileName(@NotNull URLConnection connection, @NotNull File file) throws IOException {
|
||||
String fileName = null;
|
||||
|
||||
final String contentDisposition = connection.getHeaderField("Content-Disposition");
|
||||
|
||||
+68
-87
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,7 +18,6 @@ package com.intellij.openapi.updateSettings.impl;
|
||||
import com.intellij.diagnostic.IdeErrorsDialog;
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.ide.plugins.*;
|
||||
import com.intellij.ide.reporter.ConnectionException;
|
||||
import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.notification.*;
|
||||
import com.intellij.openapi.application.ApplicationInfo;
|
||||
@@ -30,24 +29,20 @@ import com.intellij.openapi.application.impl.ApplicationInfoImpl;
|
||||
import com.intellij.openapi.diagnostic.IdeaLoggingEvent;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.PluginId;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.progress.*;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.StandardFileSystems;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.HttpRequests;
|
||||
import com.intellij.util.PlatformUtils;
|
||||
import com.intellij.util.ThrowableConvertor;
|
||||
import com.intellij.util.*;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.io.UrlConnectionUtil;
|
||||
import com.intellij.util.net.HttpConfigurable;
|
||||
import com.intellij.util.net.NetUtils;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
@@ -58,15 +53,14 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
/**
|
||||
* See XML file by {@link com.intellij.openapi.application.ex.ApplicationInfoEx#getUpdateUrls()} for reference.
|
||||
@@ -133,7 +127,6 @@ public final class UpdateChecker {
|
||||
ProgressManager.getInstance().run(new Task.Backgroundable(project, IdeBundle.message("updates.checking.progress"), true) {
|
||||
@Override
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
indicator.setIndeterminate(true);
|
||||
doUpdateAndShowResult(project, !fromSettings, true, settings, indicator, null);
|
||||
}
|
||||
|
||||
@@ -163,7 +156,9 @@ public final class UpdateChecker {
|
||||
settings.setKnownChannelIds(result.getAllChannelsIds());
|
||||
}
|
||||
else if (result.getState() == UpdateStrategy.State.CONNECTION_ERROR) {
|
||||
showErrorMessage(manualCheck, IdeBundle.message("updates.error.connection.failed"));
|
||||
//noinspection ThrowableResultOfMethodCallIgnored
|
||||
showErrorMessage(manualCheck,
|
||||
result.getError() instanceof InterruptedIOException ? IdeBundle.message("updates.timeout.error") : IdeBundle.message("updates.error.connection.failed"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -287,7 +282,7 @@ public final class UpdateChecker {
|
||||
if (isReadyToUpdate(pluginId, pluginVersion)) {
|
||||
descriptor = downloader.getDescriptor();
|
||||
if (descriptor == null) {
|
||||
if (downloader.prepareToInstall(indicator, buildNumber)) {
|
||||
if (downloader.prepareToInstall(indicator == null ? new EmptyProgressIndicator() : indicator, buildNumber)) {
|
||||
descriptor = downloader.getDescriptor();
|
||||
}
|
||||
ourUpdatedPlugins.put(pluginId, downloader);
|
||||
@@ -351,45 +346,74 @@ public final class UpdateChecker {
|
||||
return checkPluginsHost(host, downloaded, null, collectToUpdate, indicator, null);
|
||||
}
|
||||
|
||||
private static boolean checkPluginsHost(String host,
|
||||
private static boolean checkPluginsHost(@NotNull String host,
|
||||
final Map<PluginId, PluginDownloader> downloaded,
|
||||
final @Nullable Collection<IdeaPluginDescriptor> incompatiblePlugins,
|
||||
final boolean collectToUpdate,
|
||||
@Nullable ProgressIndicator indicator,
|
||||
boolean collectToUpdate,
|
||||
@Nullable final ProgressIndicator indicator,
|
||||
final BuildNumber buildNumber) throws Exception {
|
||||
String url;
|
||||
if (StandardFileSystems.FILE_PROTOCOL.equals(new URL(host).getProtocol())) {
|
||||
url = host;
|
||||
}
|
||||
else {
|
||||
url = host + (host.contains("?") ? '&' : '?') + "build=" + ApplicationInfo.getInstance().getBuild().asString();
|
||||
}
|
||||
|
||||
BufferExposingByteArrayOutputStream bytes = HttpRequests.request(url)
|
||||
.get(new ThrowableConvertor<URLConnection, BufferExposingByteArrayOutputStream, Exception>() {
|
||||
@Override
|
||||
public BufferExposingByteArrayOutputStream convert(URLConnection connection) throws Exception {
|
||||
InputStream input = HttpRequests.getInputStream(connection);
|
||||
try {
|
||||
BufferExposingByteArrayOutputStream output = new BufferExposingByteArrayOutputStream();
|
||||
try {
|
||||
NetUtils.copyStreamContent(indicator, input, output, connection.getContentLength());
|
||||
}
|
||||
finally {
|
||||
output.close();
|
||||
}
|
||||
return output;
|
||||
}
|
||||
finally {
|
||||
input.close();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes.getInternalBuffer(), 0, bytes.size());
|
||||
final Document document;
|
||||
try {
|
||||
document = JDOMUtil.loadDocument(RepositoryHelper.getConnectionInputStream(loadVersionInfo(host)));
|
||||
document = JDOMUtil.loadDocument(inputStream);
|
||||
}
|
||||
catch (JDOMException e) {
|
||||
return false;
|
||||
}
|
||||
finally {
|
||||
inputStream.reset();
|
||||
}
|
||||
|
||||
final List<IdeaPluginDescriptor> descriptors = RepositoryHelper.loadPluginsFromDescription(loadVersionInfo(host), indicator);
|
||||
for (IdeaPluginDescriptor descriptor : descriptors) {
|
||||
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
|
||||
RepositoryContentHandler handler = new RepositoryContentHandler();
|
||||
parser.parse(inputStream, handler);
|
||||
|
||||
for (IdeaPluginDescriptor descriptor : handler.getPluginsList()) {
|
||||
((PluginNode)descriptor).setRepositoryName(host);
|
||||
prepareToInstall(PluginDownloader.createDownloader(descriptor, buildNumber), buildNumber, downloaded, incompatiblePlugins, collectToUpdate,
|
||||
indicator);
|
||||
}
|
||||
|
||||
boolean success = true;
|
||||
for (Object plugin : document.getRootElement().getChildren("plugin")) {
|
||||
final Element pluginElement = (Element)plugin;
|
||||
for (Element pluginElement : document.getRootElement().getChildren("plugin")) {
|
||||
final String pluginId = pluginElement.getAttributeValue("id");
|
||||
final String pluginUrl = pluginElement.getAttributeValue("url");
|
||||
String pluginUrl = pluginElement.getAttributeValue("url");
|
||||
final String pluginVersion = pluginElement.getAttributeValue("version");
|
||||
final Element descriptionElement = pluginElement.getChild("description");
|
||||
final String description;
|
||||
if (descriptionElement != null) {
|
||||
description = descriptionElement.getText();
|
||||
} else {
|
||||
description = null;
|
||||
}
|
||||
Element descriptionElement = pluginElement.getChild("description");
|
||||
String description = descriptionElement != null ? descriptionElement.getText() : null;
|
||||
|
||||
final List<PluginId> dependsPlugins = new ArrayList<PluginId>();
|
||||
final List depends = pluginElement.getChildren("depends");
|
||||
for (Object depend : depends) {
|
||||
dependsPlugins.add(PluginId.getId(((Element)depend).getText()));
|
||||
List<PluginId> dependsPlugins = new SmartList<PluginId>();
|
||||
for (Element depend : pluginElement.getChildren("depends")) {
|
||||
dependsPlugins.add(PluginId.getId(depend.getText()));
|
||||
}
|
||||
|
||||
if (pluginId == null) {
|
||||
@@ -404,8 +428,10 @@ public final class UpdateChecker {
|
||||
continue;
|
||||
}
|
||||
|
||||
final VirtualFile pluginFile = PluginDownloader.findPluginFile(pluginUrl, host);
|
||||
if (pluginFile == null) continue;
|
||||
VirtualFile pluginFile = PluginDownloader.findPluginFile(pluginUrl, host);
|
||||
if (pluginFile == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (collectToUpdate) {
|
||||
final String finalPluginUrl = getPluginUrl(pluginFile);
|
||||
@@ -436,7 +462,8 @@ public final class UpdateChecker {
|
||||
String pluginVersion,
|
||||
BuildNumber buildNumber,
|
||||
Map<PluginId, PluginDownloader> downloaded,
|
||||
Collection<IdeaPluginDescriptor> incompatiblePlugins, boolean collectToUpdate, ProgressIndicator indicator) {
|
||||
Collection<IdeaPluginDescriptor> incompatiblePlugins, boolean collectToUpdate,
|
||||
ProgressIndicator indicator) {
|
||||
try {
|
||||
if (indicator != null) {
|
||||
indicator.setText2(finalPluginUrl);
|
||||
@@ -463,7 +490,7 @@ public final class UpdateChecker {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static UpdatesInfo loadUpdatesInfo(@Nullable final String updateUrl) throws Exception {
|
||||
private static UpdatesInfo loadUpdatesInfo(@Nullable String updateUrl) throws Exception {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("load update xml (UPDATE_URL='" + updateUrl + "' )");
|
||||
}
|
||||
@@ -477,7 +504,7 @@ public final class UpdateChecker {
|
||||
.get(new ThrowableConvertor<URLConnection, UpdatesInfo, Exception>() {
|
||||
@Override
|
||||
public UpdatesInfo convert(URLConnection connection) throws Exception {
|
||||
InputStream inputStream = connection.getInputStream();
|
||||
InputStream inputStream = HttpRequests.getInputStream(connection);
|
||||
try {
|
||||
return new UpdatesInfo(JDOMUtil.loadDocument(inputStream).getRootElement());
|
||||
}
|
||||
@@ -502,9 +529,6 @@ public final class UpdateChecker {
|
||||
return new CheckForUpdateResult(UpdateStrategy.State.NOTHING_LOADED);
|
||||
}
|
||||
}
|
||||
catch (InterruptedIOException e) {
|
||||
return new CheckForUpdateResult(UpdateStrategy.State.CONNECTION_ERROR, new ConnectionException(IdeBundle.message("updates.timeout.error")));
|
||||
}
|
||||
catch (Exception e) {
|
||||
return new CheckForUpdateResult(UpdateStrategy.State.CONNECTION_ERROR, e);
|
||||
}
|
||||
@@ -645,49 +669,6 @@ public final class UpdateChecker {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static URLConnection loadVersionInfo(@NotNull final String url) throws Exception {
|
||||
final Ref<URLConnection> connectionRef = Ref.create();
|
||||
final Ref<Exception> exception = Ref.create();
|
||||
Future<?> downloadThreadFuture = ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
String urlToCheck;
|
||||
if (!StandardFileSystems.FILE_PROTOCOL.equals(new URL(url).getProtocol())) {
|
||||
urlToCheck = url + (url.contains("?") ? "&" : "?") + "build=" + ApplicationInfo.getInstance().getBuild().asString();
|
||||
}
|
||||
else {
|
||||
urlToCheck = url;
|
||||
}
|
||||
|
||||
URLConnection connection = HttpRequests.openConnection(urlToCheck, true).first;
|
||||
connection.connect();
|
||||
connectionRef.set(connection);
|
||||
}
|
||||
catch (IOException e) {
|
||||
exception.set(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
downloadThreadFuture.get(5, TimeUnit.SECONDS);
|
||||
}
|
||||
catch (TimeoutException ignored) {
|
||||
}
|
||||
|
||||
if (!downloadThreadFuture.isDone()) {
|
||||
downloadThreadFuture.cancel(true);
|
||||
throw new ConnectionException(IdeBundle.message("updates.timeout.error"));
|
||||
}
|
||||
|
||||
if (!exception.isNull()) {
|
||||
throw exception.get();
|
||||
}
|
||||
return connectionRef.get();
|
||||
}
|
||||
|
||||
public static String getInstallationUID(final PropertiesComponent propertiesComponent) {
|
||||
if (SystemInfo.isWindows) {
|
||||
String uid = getInstallationUIDOnWindows(propertiesComponent);
|
||||
|
||||
@@ -17,25 +17,29 @@ package com.intellij.util;
|
||||
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.util.ClassLoaderUtil;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.ThrowableComputable;
|
||||
import com.intellij.util.net.HttpConfigurable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.net.URLConnection;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
/**
|
||||
* GZip supported by default, so, you must use {@link #getInputStream(java.net.URLConnection)} to get connection input stream.
|
||||
*/
|
||||
public final class HttpRequests {
|
||||
public static class HttpRequestBuilder {
|
||||
private final String url;
|
||||
private int connectTimeout = HttpConfigurable.CONNECTION_TIMEOUT;
|
||||
private int readTimeout = HttpConfigurable.CONNECTION_TIMEOUT;
|
||||
|
||||
private boolean supportGzip;
|
||||
private Consumer<String> effectiveUrlConsumer;
|
||||
|
||||
private boolean supportGzip = true;
|
||||
|
||||
private HttpRequestBuilder(@NotNull String url) {
|
||||
this.url = url;
|
||||
@@ -47,6 +51,7 @@ public final class HttpRequests {
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@NotNull
|
||||
public HttpRequestBuilder readTimeout(int value) {
|
||||
readTimeout = value;
|
||||
@@ -59,7 +64,13 @@ public final class HttpRequests {
|
||||
return this;
|
||||
}
|
||||
|
||||
public <T> T get(@NotNull final ThrowableConvertor<URLConnection, T, Exception> handler) throws Exception {
|
||||
@NotNull
|
||||
public HttpRequestBuilder effectiveUrlConsumer(Consumer<String> value) {
|
||||
effectiveUrlConsumer = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public <T, E extends Throwable> T get(@NotNull final ThrowableConvertor<URLConnection, T, E> handler) throws E, IOException {
|
||||
return loadData(this, handler);
|
||||
}
|
||||
}
|
||||
@@ -69,30 +80,46 @@ public final class HttpRequests {
|
||||
return new HttpRequestBuilder(url);
|
||||
}
|
||||
|
||||
private static <T> T loadData(@NotNull final HttpRequestBuilder requestBuilder, @NotNull final ThrowableConvertor<URLConnection, T, Exception> handler) throws Exception {
|
||||
return ClassLoaderUtil.runWithClassLoader(new URLClassLoader(new URL[0], Thread.currentThread().getContextClassLoader()), new ThrowableComputable<T, Exception>() {
|
||||
@Override
|
||||
public T compute() throws Exception {
|
||||
URLConnection connection = openConnection(requestBuilder.url, requestBuilder.supportGzip).first;
|
||||
try {
|
||||
return handler.convert(connection);
|
||||
}
|
||||
finally {
|
||||
if (connection instanceof HttpURLConnection) {
|
||||
((HttpURLConnection)connection).disconnect();
|
||||
}
|
||||
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
|
||||
@NotNull
|
||||
public static InputStream getInputStream(@NotNull URLConnection connection) throws IOException {
|
||||
InputStream inputStream = connection.getInputStream();
|
||||
if ("gzip".equalsIgnoreCase(connection.getContentEncoding())) {
|
||||
try {
|
||||
return new GZIPInputStream(inputStream);
|
||||
}
|
||||
catch (IOException e) {
|
||||
inputStream.close();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return inputStream;
|
||||
}
|
||||
}
|
||||
|
||||
private static <T, E extends Throwable> T loadData(@NotNull HttpRequestBuilder requestBuilder, @NotNull ThrowableConvertor<URLConnection, T, E> handler)
|
||||
throws E, IOException {
|
||||
ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(new URLClassLoader(new URL[0], oldClassLoader));
|
||||
try {
|
||||
URLConnection connection = openConnection(requestBuilder);
|
||||
try {
|
||||
return handler.convert(connection);
|
||||
}
|
||||
finally {
|
||||
if (connection instanceof HttpURLConnection) {
|
||||
((HttpURLConnection)connection).disconnect();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
finally {
|
||||
Thread.currentThread().setContextClassLoader(oldClassLoader);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Pair<URLConnection, String> openConnection(@NotNull String initialUrl, boolean supportGzip) throws IOException {
|
||||
return openConnection(request(initialUrl).supportGzip(supportGzip));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Pair<URLConnection, String> openConnection(@NotNull HttpRequestBuilder requestBuilder) throws IOException {
|
||||
private static URLConnection openConnection(@NotNull HttpRequestBuilder requestBuilder) throws IOException {
|
||||
int i = 0;
|
||||
String url = requestBuilder.url;
|
||||
while (i++ < 99) {
|
||||
@@ -132,7 +159,11 @@ public final class HttpRequests {
|
||||
}
|
||||
}
|
||||
}
|
||||
return Pair.create(connection, url == requestBuilder.url ? null : url);
|
||||
|
||||
if (url != requestBuilder.url && requestBuilder.effectiveUrlConsumer != null) {
|
||||
requestBuilder.effectiveUrlConsumer.consume(url);
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
throw new IOException("Infinite redirection");
|
||||
}
|
||||
|
||||
@@ -531,7 +531,6 @@ button.http.proxy.settings=&HTTP Proxy Settings...
|
||||
group.vendor=Vendor
|
||||
plugin.status.installed=Installed
|
||||
progress.waiting.for.reply.from.plugin.manager=Waiting for reply from {0}
|
||||
progress.connecting=Connecting...
|
||||
progress.downloading.plugin=Downloading plugin ''{0}''
|
||||
error.cannot.create.temp.dir=Unable to create temp directory ''{0}''
|
||||
error.connection.failed.with.http.code.N=Connection failed with HTTP code {0}
|
||||
|
||||
Reference in New Issue
Block a user