Skip to content

Commit

Permalink
CODENVY-538:Fix checking of recipe location: now will match only host… (
Browse files Browse the repository at this point in the history
#1301)

* CODENVY-538:Fix checking of recipe location: now will match only host without scheme.
Add method for download file in case server send redirect(in some reason setInstanceFollowRedirects(true) don't work so need to do one more request)

Signed-off-by: Vitaly Parfonov <vparfonov@codenvy.com>
  • Loading branch information
Vitalii Parfonov committed May 20, 2016
1 parent 055e996 commit 88eb928
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,25 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import javax.ws.rs.HttpMethod;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.FileChannel;
import java.nio.file.*;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.security.DigestInputStream;
import java.security.MessageDigest;
Expand All @@ -28,8 +41,6 @@
import java.util.List;
import java.util.Locale;

import javax.ws.rs.HttpMethod;

import static java.nio.file.FileVisitResult.CONTINUE;
import static java.nio.file.FileVisitResult.TERMINATE;

Expand Down Expand Up @@ -231,6 +242,62 @@ public static File downloadFile(File parent, String prefix, String suffix, URL u
return file;
}



/**
* Download file with redirection if got status 301, 302, 303.
* Will useful in case redirection http -> https
*
* @param parent
* parent directory, may be <code>null</code> then use 'java.io.tmpdir'
* @param prefix
* prefix of temporary file name, may not be <code>null</code> and must be at least three characters long
* @param suffix
* suffix of temporary file name, may be <code>null</code>
* @param url
* URL for download
* @return downloaded file
* @throws java.io.IOException
* if any i/o error occurs
*/
public static File downloadFileWithRedirect(File parent, String prefix, String suffix, URL url) throws IOException {
File file = File.createTempFile(prefix, suffix, parent);
URLConnection conn = null;
final String protocol = url.getProtocol().toLowerCase(Locale.ENGLISH);
try {
conn = url.openConnection();
boolean redirect = false;
if ("http".equals(protocol) || "https".equals(protocol)) {
HttpURLConnection http = (HttpURLConnection)conn;
http.setRequestMethod(HttpMethod.GET);
int status = http.getResponseCode();
if (status == HttpURLConnection.HTTP_MOVED_TEMP || status == HttpURLConnection.HTTP_MOVED_PERM ||
status == HttpURLConnection.HTTP_SEE_OTHER) {
redirect = true;
}
if (redirect) {
String newUrl = conn.getHeaderField("Location");
// open the new connection again
http = (HttpURLConnection)new URL(newUrl).openConnection();
http.setRequestMethod(HttpMethod.GET);
}
}
try (InputStream input = conn.getInputStream();
FileOutputStream fOutput = new FileOutputStream(file)) {
byte[] b = new byte[8192];
int r;
while ((r = input.read(b)) != -1) {
fOutput.write(b, 0, r);
}
}
} finally {
if (conn != null && ("http".equals(protocol) || "https".equals(protocol))) {
((HttpURLConnection)conn).disconnect();
}
}
return file;
}

/**
* Copy file or directory to the specified destination. Existed files in destination directory will be overwritten.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URL;

import static java.lang.String.format;
Expand All @@ -39,10 +40,10 @@
public class RecipeDownloader {
private static final Logger LOG = getLogger(RecipeDownloader.class);

private final String apiEndpoint;
private final URI apiEndpoint;

@Inject
public RecipeDownloader(@Named("api.endpoint") String apiEndpoint) {
public RecipeDownloader(@Named("api.endpoint") URI apiEndpoint) {
this.apiEndpoint = apiEndpoint;
}

Expand All @@ -58,24 +59,27 @@ public RecipeDownloader(@Named("api.endpoint") String apiEndpoint) {
public RecipeImpl getRecipe(MachineConfig machineConfig) throws MachineException {
URL recipeUrl;
File file = null;
final String location = machineConfig.getSource().getLocation();
try {
UriBuilder targetUriBuilder = UriBuilder.fromUri(machineConfig.getSource().getLocation());
UriBuilder targetUriBuilder = UriBuilder.fromUri(location);
// add user token to be able to download user's private recipe
if (machineConfig.getSource().getLocation().startsWith(apiEndpoint)) {
final String apiEndPointHost = apiEndpoint.getHost();
final String host = targetUriBuilder.build().getHost();
if (apiEndPointHost.equals(host)) {
if (EnvironmentContext.getCurrent().getSubject() != null
&& EnvironmentContext.getCurrent().getSubject().getToken() != null) {
targetUriBuilder.queryParam("token", EnvironmentContext.getCurrent().getSubject().getToken());
}
}
recipeUrl = targetUriBuilder.build().toURL();
file = IoUtil.downloadFile(null, "recipe", null, recipeUrl);
file = IoUtil.downloadFileWithRedirect(null, "recipe", null, recipeUrl);

return new RecipeImpl().withType(machineConfig.getSource().getType())
.withScript(IoUtil.readAndCloseQuietly(new FileInputStream(file)));
} catch (IOException | IllegalArgumentException e) {
throw new MachineException(format("Can't start machine %s because machine recipe downloading failed. Recipe url %s. Error: %s",
machineConfig.getName(),
machineConfig.getSource().getLocation(),
location,
e.getLocalizedMessage()));
} finally {
if (file != null && !file.delete()) {
Expand Down

0 comments on commit 88eb928

Please sign in to comment.