Browse Source

make http condition follow redirects from http to https

Bugzilla Report 65105
master
Stefan Bodewig 4 years ago
parent
commit
6dee370878
4 changed files with 125 additions and 12 deletions
  1. +3
    -0
      WHATSNEW
  2. +12
    -7
      src/main/org/apache/tools/ant/taskdefs/Get.java
  3. +39
    -5
      src/main/org/apache/tools/ant/taskdefs/condition/Http.java
  4. +71
    -0
      src/tests/antunit/taskdefs/condition/http-test.xml

+ 3
- 0
WHATSNEW View File

@@ -27,6 +27,9 @@ Fixed bugs:
central repository didn't contain any source files.
Bugzilla Report 65110

* The <http> condition didn't follow redirects from http to https.
Bugzilla Report 65105

Other changes:
--------------



+ 12
- 7
src/main/org/apache/tools/ant/taskdefs/Get.java View File

@@ -533,6 +533,18 @@ public class Get extends Task {
extends org.apache.tools.ant.util.Base64Converter {
}

/**
* Does the response code represent a redirection?
*
* @since 1.10.10
*/
public static boolean isMoved(final int responseCode) {
return responseCode == HttpURLConnection.HTTP_MOVED_PERM
|| responseCode == HttpURLConnection.HTTP_MOVED_TEMP
|| responseCode == HttpURLConnection.HTTP_SEE_OTHER
|| responseCode == HTTP_MOVED_TEMP;
}

/**
* Interface implemented for reporting
* progress of downloading.
@@ -815,13 +827,6 @@ public class Get extends Task {
return connection;
}

private boolean isMoved(final int responseCode) {
return responseCode == HttpURLConnection.HTTP_MOVED_PERM
|| responseCode == HttpURLConnection.HTTP_MOVED_TEMP
|| responseCode == HttpURLConnection.HTTP_SEE_OTHER
|| responseCode == HTTP_MOVED_TEMP;
}

private boolean downloadFile() throws IOException {
for (int i = 0; i < numberRetries; i++) {
// this three attempt trick is to get round quirks in different


+ 39
- 5
src/main/org/apache/tools/ant/taskdefs/condition/Http.java View File

@@ -30,6 +30,7 @@ import java.util.Locale;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.ProjectComponent;
import org.apache.tools.ant.taskdefs.Get;

/**
* Condition to wait for a HTTP request to succeed. Its attribute(s) are:
@@ -42,6 +43,8 @@ import org.apache.tools.ant.ProjectComponent;
public class Http extends ProjectComponent implements Condition {
private static final int ERROR_BEGINS = 400;
private static final String DEFAULT_REQUEST_METHOD = "GET";
private static final String HTTP = "http";
private static final String HTTPS = "https";

private String spec = null;
private String requestMethod = DEFAULT_REQUEST_METHOD;
@@ -124,11 +127,7 @@ public class Http extends ProjectComponent implements Condition {
try {
URLConnection conn = url.openConnection();
if (conn instanceof HttpURLConnection) {
HttpURLConnection http = (HttpURLConnection) conn;
http.setRequestMethod(requestMethod);
http.setInstanceFollowRedirects(followRedirects);
http.setReadTimeout(readTimeout);
int code = http.getResponseCode();
int code = request((HttpURLConnection) conn, url);
log("Result code for " + spec + " was " + code,
Project.MSG_VERBOSE);
return code > 0 && code < errorsBeginAt;
@@ -144,4 +143,39 @@ public class Http extends ProjectComponent implements Condition {
}
return true;
}

private int request(final HttpURLConnection http, final URL url) throws IOException {
http.setRequestMethod(requestMethod);
http.setInstanceFollowRedirects(followRedirects);
http.setReadTimeout(readTimeout);
final int firstStatusCode = http.getResponseCode();
if (Get.isMoved(firstStatusCode)) {
final String newLocation = http.getHeaderField("Location");
final URL newURL = new URL(newLocation);
if (redirectionAllowed(url, newURL)) {
final URLConnection newConn = newURL.openConnection();
if (newConn instanceof HttpURLConnection) {
log("Following redirect from " + url + " to " + newURL);
return request((HttpURLConnection) newConn, newURL);
}
}
}
return firstStatusCode;
}

private boolean redirectionAllowed(final URL from, final URL to) {
if (from.equals(to)) {
// most simple case of an infinite redirect loop
return false;
}
if (!(from.getProtocol().equals(to.getProtocol())
|| (HTTP.equals(from.getProtocol())
&& HTTPS.equals(to.getProtocol())))) {
log("Redirection detected from "
+ from.getProtocol() + " to " + to.getProtocol()
+ ". Protocol switch unsafe, not allowed.");
return false;
}
return true;
}
}

+ 71
- 0
src/tests/antunit/taskdefs/condition/http-test.xml View File

@@ -0,0 +1,71 @@
<?xml version="1.0"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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

https://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.
-->

<project name="http-test" default="antunit" xmlns:au="antlib:org.apache.ant.antunit">
<import file="../../antunit-base.xml" />

<property name="location" value="https://ant.apache.org/webtest/gettest" />
<property name="unsecurelocation" value="http://ant.apache.org/webtest/gettest/http-to-https.txt" />

<target name="testSeeOtherRedirect">
<sleep milliseconds="250"/>
<au:assertTrue>
<http url="${location}/other.txt"/>
</au:assertTrue>
<au:assertLogContains level="verbose"
text="Result code for ${location}/other.txt was 200" />
</target>

<target name="testPermanentRedirect">
<sleep milliseconds="250"/>
<au:assertTrue>
<http url="${location}/permanent.txt"/>
</au:assertTrue>
<au:assertLogContains level="verbose"
text="Result code for ${location}/permanent.txt was 200" />
</target>

<target name="testTemporaryRedirect">
<sleep milliseconds="250"/>
<au:assertTrue>
<http url="${location}/temp.txt"/>
</au:assertTrue>
<au:assertLogContains level="verbose"
text="Result code for ${location}/temp.txt was 200" />
</target>

<target name="testStatusCode307Redirect">
<sleep milliseconds="250"/>
<au:assertTrue>
<http url="${location}/307.txt"/>
</au:assertTrue>
<au:assertLogContains level="verbose"
text="Result code for ${location}/307.txt was 200" />
</target>

<target name="testHttpToHttpsRedirect" description="Tests that a resource that's redirected
from HTTP to HTTPS works without an error. See bugzilla-65105 for details">
<sleep milliseconds="250"/>
<au:assertTrue>
<http url="${unsecurelocation}"/>
</au:assertTrue>
<au:assertLogContains level="verbose"
text="Result code for ${unsecurelocation} was 200" />
</target>

</project>

Loading…
Cancel
Save