Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CODENVY-538:Fix checking of recipe location: now will match only host… #1301

Merged
merged 2 commits into from
May 20, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tried to allow redirects in the connection instead of maling this custom logic?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, we tried but it does not work, that is why @vparfonov added custom method with redirect.
As @vparfonov mentioned above "setInstanceFollowRedirects(true) don't work"

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