Skip to content

Commit 487fdbb

Browse files
shwstpprrohityadavcloud
authored andcommitted
engine-storage: control download redirection
Add a global setting to control whether redirection is allowed while downloading templates and volumes Signed-off-by: Abhishek Kumar <[email protected]> (cherry picked from commit 52dc0da) Signed-off-by: Rohit Yadav <[email protected]>
1 parent 2b4d8bb commit 487fdbb

File tree

45 files changed

+457
-137
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+457
-137
lines changed

core/src/main/java/com/cloud/storage/template/HttpTemplateDownloader.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.net.URI;
2727
import java.net.URISyntaxException;
2828
import java.util.Date;
29+
import java.util.List;
2930

3031
import com.cloud.utils.exception.CloudRuntimeException;
3132
import org.apache.cloudstack.utils.imagestore.ImageStoreUtil;
@@ -81,6 +82,7 @@ public class HttpTemplateDownloader extends ManagedContextRunnable implements Te
8182
private long maxTemplateSizeInBytes;
8283
private ResourceType resourceType = ResourceType.TEMPLATE;
8384
private final HttpMethodRetryHandler myretryhandler;
85+
private boolean followRedirects = false;
8486

8587
public HttpTemplateDownloader(StorageLayer storageLayer, String downloadUrl, String toDir, DownloadCompleteCallback callback, long maxTemplateSizeInBytes,
8688
String user, String password, Proxy proxy, ResourceType resourceType) {
@@ -112,7 +114,7 @@ public HttpTemplateDownloader(StorageLayer storageLayer, String downloadUrl, Str
112114
private GetMethod createRequest(String downloadUrl) {
113115
GetMethod request = new GetMethod(downloadUrl);
114116
request.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, myretryhandler);
115-
request.setFollowRedirects(true);
117+
request.setFollowRedirects(followRedirects);
116118
return request;
117119
}
118120

@@ -336,6 +338,12 @@ private boolean checkServerResponse(long localFileSize) throws IOException {
336338
} else if ((responseCode = client.executeMethod(request)) != HttpStatus.SC_OK) {
337339
status = Status.UNRECOVERABLE_ERROR;
338340
errorString = " HTTP Server returned " + responseCode + " (expected 200 OK) ";
341+
if (List.of(HttpStatus.SC_MOVED_PERMANENTLY, HttpStatus.SC_MOVED_TEMPORARILY).contains(responseCode)
342+
&& !followRedirects) {
343+
errorString = String.format("Failed to download %s due to redirection, response code: %d",
344+
downloadUrl, responseCode);
345+
s_logger.error(errorString);
346+
}
339347
return true; //FIXME: retry?
340348
}
341349
return false;
@@ -537,4 +545,12 @@ public VerifyFormat invoke() {
537545
return this;
538546
}
539547
}
548+
549+
@Override
550+
public void setFollowRedirects(boolean followRedirects) {
551+
this.followRedirects = followRedirects;
552+
if (this.request != null) {
553+
this.request.setFollowRedirects(followRedirects);
554+
}
555+
}
540556
}

core/src/main/java/com/cloud/storage/template/MetalinkTemplateDownloader.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public MetalinkTemplateDownloader(StorageLayer storageLayer, String downloadUrl,
6060
protected GetMethod createRequest(String downloadUrl) {
6161
GetMethod request = new GetMethod(downloadUrl);
6262
request.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, myretryhandler);
63-
request.setFollowRedirects(true);
63+
request.setFollowRedirects(followRedirects);
6464
if (!toFileSet) {
6565
String[] parts = downloadUrl.split("/");
6666
String filename = parts[parts.length - 1];
@@ -173,4 +173,12 @@ public Status getStatus() {
173173
public void setStatus(Status status) {
174174
this.status = status;
175175
}
176+
177+
@Override
178+
public void setFollowRedirects(boolean followRedirects) {
179+
super.setFollowRedirects(followRedirects);
180+
if (this.request != null) {
181+
this.request.setFollowRedirects(followRedirects);
182+
}
183+
}
176184
}

core/src/main/java/com/cloud/storage/template/S3TemplateDownloader.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType;
3535
import org.apache.commons.httpclient.Header;
3636
import org.apache.commons.httpclient.HttpClient;
37+
import org.apache.commons.httpclient.HttpStatus;
3738
import org.apache.commons.httpclient.URIException;
3839
import org.apache.commons.httpclient.methods.GetMethod;
3940
import org.apache.commons.httpclient.params.HttpMethodParams;
@@ -44,6 +45,7 @@
4445
import java.io.IOException;
4546
import java.io.InputStream;
4647
import java.util.Date;
48+
import java.util.List;
4749

4850
import static com.cloud.utils.NumbersUtil.toHumanReadableSize;
4951
import static java.util.Arrays.asList;
@@ -72,8 +74,8 @@ public class S3TemplateDownloader extends ManagedContextRunnable implements Temp
7274
private long downloadTime;
7375
private long totalBytes;
7476
private long maxTemplateSizeInByte;
75-
7677
private boolean resume = false;
78+
private boolean followRedirects = false;
7779

7880
public S3TemplateDownloader(S3TO s3TO, String downloadUrl, String installPath, DownloadCompleteCallback downloadCompleteCallback,
7981
long maxTemplateSizeInBytes, String username, String password, Proxy proxy, ResourceType resourceType) {
@@ -91,7 +93,7 @@ public S3TemplateDownloader(S3TO s3TO, String downloadUrl, String installPath, D
9193
this.getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, HTTPUtils.getHttpMethodRetryHandler(5));
9294

9395
// Follow redirects
94-
this.getMethod.setFollowRedirects(true);
96+
this.getMethod.setFollowRedirects(followRedirects);
9597

9698
// Set file extension.
9799
this.fileExtension = StringUtils.substringAfterLast(StringUtils.substringAfterLast(downloadUrl, "/"), ".");
@@ -124,10 +126,11 @@ public long download(boolean resume, DownloadCompleteCallback callback) {
124126
return 0;
125127
}
126128

127-
if (!HTTPUtils.verifyResponseCode(responseCode)) {
129+
boolean failedDueToRedirection = List.of(HttpStatus.SC_MOVED_PERMANENTLY,
130+
HttpStatus.SC_MOVED_TEMPORARILY).contains(responseCode) && !followRedirects;
131+
if (!HTTPUtils.verifyResponseCode(responseCode) || failedDueToRedirection) {
128132
errorString = "Response code for GetMethod of " + downloadUrl + " is incorrect, responseCode: " + responseCode;
129133
LOGGER.warn(errorString);
130-
131134
status = Status.UNRECOVERABLE_ERROR;
132135
return 0;
133136
}
@@ -373,4 +376,12 @@ public long getTotalBytes() {
373376
public String getFileExtension() {
374377
return fileExtension;
375378
}
379+
380+
@Override
381+
public void setFollowRedirects(boolean followRedirects) {
382+
this.followRedirects = followRedirects;
383+
if (this.getMethod != null) {
384+
this.getMethod.setFollowRedirects(followRedirects);
385+
}
386+
}
376387
}

core/src/main/java/com/cloud/storage/template/TemplateDownloader.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,6 @@ enum Status {
9292
boolean isInited();
9393

9494
long getMaxTemplateSizeInBytes();
95+
96+
void setFollowRedirects(boolean followRedirects);
9597
}

core/src/main/java/com/cloud/storage/template/TemplateDownloaderBase.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public abstract class TemplateDownloaderBase extends ManagedContextRunnable impl
4343
protected long _start;
4444
protected StorageLayer _storage;
4545
protected boolean _inited = false;
46+
protected boolean followRedirects = false;
4647
private long maxTemplateSizeInBytes;
4748

4849
public TemplateDownloaderBase(StorageLayer storage, String downloadUrl, String toDir, long maxTemplateSizeInBytes, DownloadCompleteCallback callback) {
@@ -149,4 +150,9 @@ public void setResume(boolean resume) {
149150
public boolean isInited() {
150151
return _inited;
151152
}
153+
154+
@Override
155+
public void setFollowRedirects(boolean followRedirects) {
156+
this.followRedirects = followRedirects;
157+
}
152158
}

core/src/main/java/org/apache/cloudstack/agent/directdownload/CheckUrlCommand.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public class CheckUrlCommand extends Command {
2525

2626
private String format;
2727
private String url;
28+
private boolean followRedirects;
2829

2930
public String getFormat() {
3031
return format;
@@ -34,10 +35,15 @@ public String getUrl() {
3435
return url;
3536
}
3637

37-
public CheckUrlCommand(final String format,final String url) {
38+
public boolean isFollowRedirects() {
39+
return followRedirects;
40+
}
41+
42+
public CheckUrlCommand(final String format, final String url, final boolean followRedirects) {
3843
super();
3944
this.format = format;
4045
this.url = url;
46+
this.followRedirects = followRedirects;
4147
}
4248

4349
@Override

core/src/main/java/org/apache/cloudstack/agent/directdownload/DirectDownloadCommand.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,11 @@ public enum DownloadProtocol {
4545
private Long templateSize;
4646
private Storage.ImageFormat format;
4747

48-
protected DirectDownloadCommand (final String url, final Long templateId, final PrimaryDataStoreTO destPool, final String checksum, final Map<String, String> headers, final Integer connectTimeout, final Integer soTimeout, final Integer connectionRequestTimeout) {
48+
private boolean followRedirects;
49+
50+
protected DirectDownloadCommand (final String url, final Long templateId, final PrimaryDataStoreTO destPool,
51+
final String checksum, final Map<String, String> headers, final Integer connectTimeout,
52+
final Integer soTimeout, final Integer connectionRequestTimeout, final boolean followRedirects) {
4953
this.url = url;
5054
this.templateId = templateId;
5155
this.destData = destData;
@@ -55,6 +59,7 @@ protected DirectDownloadCommand (final String url, final Long templateId, final
5559
this.connectTimeout = connectTimeout;
5660
this.soTimeout = soTimeout;
5761
this.connectionRequestTimeout = connectionRequestTimeout;
62+
this.followRedirects = followRedirects;
5863
}
5964

6065
public String getUrl() {
@@ -137,4 +142,12 @@ public boolean executeInSequence() {
137142
public int getWaitInMillSeconds() {
138143
return getWait() * 1000;
139144
}
145+
146+
public boolean isFollowRedirects() {
147+
return followRedirects;
148+
}
149+
150+
public void setFollowRedirects(boolean followRedirects) {
151+
this.followRedirects = followRedirects;
152+
}
140153
}

core/src/main/java/org/apache/cloudstack/agent/directdownload/HttpDirectDownloadCommand.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@
2424

2525
public class HttpDirectDownloadCommand extends DirectDownloadCommand {
2626

27-
public HttpDirectDownloadCommand(String url, Long templateId, PrimaryDataStoreTO destPool, String checksum, Map<String, String> headers, int connectTimeout, int soTimeout) {
28-
super(url, templateId, destPool, checksum, headers, connectTimeout, soTimeout, null);
27+
public HttpDirectDownloadCommand(String url, Long templateId, PrimaryDataStoreTO destPool, String checksum,
28+
Map<String, String> headers, int connectTimeout, int soTimeout, boolean followRedirects) {
29+
super(url, templateId, destPool, checksum, headers, connectTimeout, soTimeout,
30+
null, followRedirects);
2931
}
3032

3133
}

core/src/main/java/org/apache/cloudstack/agent/directdownload/HttpsDirectDownloadCommand.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@
2525

2626
public class HttpsDirectDownloadCommand extends DirectDownloadCommand {
2727

28-
public HttpsDirectDownloadCommand(String url, Long templateId, PrimaryDataStoreTO destPool, String checksum, Map<String, String> headers, int connectTimeout, int soTimeout, int connectionRequestTimeout) {
29-
super(url, templateId, destPool, checksum, headers, connectTimeout, soTimeout, connectionRequestTimeout);
28+
public HttpsDirectDownloadCommand(String url, Long templateId, PrimaryDataStoreTO destPool, String checksum,
29+
Map<String, String> headers, int connectTimeout, int soTimeout, int connectionRequestTimeout,
30+
boolean followRedirects) {
31+
super(url, templateId, destPool, checksum, headers, connectTimeout, soTimeout,
32+
connectionRequestTimeout, followRedirects);
3033
}
3134
}

core/src/main/java/org/apache/cloudstack/agent/directdownload/MetalinkDirectDownloadCommand.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@
2424

2525
public class MetalinkDirectDownloadCommand extends DirectDownloadCommand {
2626

27-
public MetalinkDirectDownloadCommand(String url, Long templateId, PrimaryDataStoreTO destPool, String checksum, Map<String, String> headers, int connectTimeout, int soTimeout) {
28-
super(url, templateId, destPool, checksum, headers, connectTimeout, soTimeout, null);
27+
public MetalinkDirectDownloadCommand(String url, Long templateId, PrimaryDataStoreTO destPool, String checksum,
28+
Map<String, String> headers, int connectTimeout, int soTimeout, boolean followRedirects) {
29+
super(url, templateId, destPool, checksum, headers, connectTimeout, soTimeout, null, followRedirects);
2930
}
3031

3132
}

0 commit comments

Comments
 (0)