Skip to content

Commit 9242858

Browse files
authored
Merge pull request #216 from andersonf/bugfix/ref-follow-redirects
Fix remote ref to follow redirects
2 parents 6eaf23b + 24aad4f commit 9242858

File tree

1 file changed

+58
-12
lines changed

1 file changed

+58
-12
lines changed

src/main/java/com/networknt/schema/uri/URLFetcher.java

Lines changed: 58 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,71 @@
1818

1919
import java.io.IOException;
2020
import java.io.InputStream;
21+
import java.net.HttpURLConnection;
2122
import java.net.URI;
2223
import java.net.URL;
24+
import java.net.URLConnection;
2325
import java.util.Collections;
2426
import java.util.Set;
2527

2628
/**
27-
* A URIfetcher that uses {@link URL#openStream()} for fetching and assumes given {@link URI}s
28-
* are actualy {@link URL}s.
29+
* A URIfetcher that uses {@link URL#openStream()} for fetching and assumes given {@link URI}s are actualy {@link URL}s.
2930
*/
3031
public final class URLFetcher implements URIFetcher {
31-
// These supported schemes are defined in {@link #URL(String, String, int, String)}.
32-
// This fetcher also supports the {@link URL}s created with the {@link ClasspathURIFactory}.
33-
public static final Set<String> SUPPORTED_SCHEMES = Collections.unmodifiableSet(URLFactory.SUPPORTED_SCHEMES);
3432

35-
/**
36-
* {@inheritDoc}
37-
*/
38-
@Override
39-
public InputStream fetch(final URI uri) throws IOException {
40-
return uri.toURL().openStream();
41-
}
33+
// These supported schemes are defined in {@link #URL(String, String, int, String)}.
34+
// This fetcher also supports the {@link URL}s created with the {@link ClasspathURIFactory}.
35+
public static final Set<String> SUPPORTED_SCHEMES = Collections.unmodifiableSet(URLFactory.SUPPORTED_SCHEMES);
36+
37+
/**
38+
* {@inheritDoc}
39+
*/
40+
@Override
41+
public InputStream fetch(final URI uri) throws IOException {
42+
URLConnection conn = uri.toURL().openConnection();
43+
return this.openConnectionCheckRedirects(conn);
44+
}
45+
46+
// https://www.cs.mun.ca/java-api-1.5/guide/deployment/deployment-guide/upgrade-guide/article-17.html
47+
private InputStream openConnectionCheckRedirects(URLConnection c) throws IOException {
48+
boolean redir;
49+
int redirects = 0;
50+
InputStream in = null;
51+
do {
52+
if (c instanceof HttpURLConnection) {
53+
((HttpURLConnection) c).setInstanceFollowRedirects(false);
54+
}
55+
// We want to open the input stream before getting headers
56+
// because getHeaderField() et al swallow IOExceptions.
57+
in = c.getInputStream();
58+
redir = false;
59+
if (c instanceof HttpURLConnection) {
60+
HttpURLConnection http = (HttpURLConnection) c;
61+
int stat = http.getResponseCode();
62+
if (stat >= 300 && stat <= 307 && stat != 306
63+
&& stat != HttpURLConnection.HTTP_NOT_MODIFIED) {
64+
URL base = http.getURL();
65+
String loc = http.getHeaderField("Location");
66+
URL target = null;
67+
if (loc != null) {
68+
target = new URL(base, loc);
69+
}
70+
http.disconnect();
71+
// Redirection should be allowed only for HTTP and HTTPS
72+
// and should be limited to 5 redirections at most.
73+
if (target == null
74+
|| !(target.getProtocol().equals("http")
75+
|| target.getProtocol().equals("https"))
76+
|| redirects >= 5) {
77+
throw new SecurityException("illegal URL redirect");
78+
}
79+
redir = true;
80+
c = target.openConnection();
81+
redirects++;
82+
}
83+
}
84+
}
85+
while (redir);
86+
return in;
87+
}
4288
}

0 commit comments

Comments
 (0)