w3c.css.util.HTTPURL Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cssvalidator Show documentation
Show all versions of cssvalidator Show documentation
Backend for the W3C CSS Validation Service
/*
* (c) COPYRIGHT 1995-1999 MIT, INRIA and Keio University. All Rights reserved.
* W3C Intellectual Property Notice and Legal Disclaimers:
* http://www.w3.org/Consortium/Legal/
*
* HTTPURL.java
* $Id$
*/
package org.w3c.css.util;
import org.w3c.css.servlet.CssValidator;
import org.w3c.www.mime.MimeType;
import org.w3c.www.mime.MimeTypeFormatException;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLConnection;
import java.util.zip.GZIPInputStream;
/**
* @author Philippe Le Hegaret
* @version $Revision$
*/
public class HTTPURL {
/**
* Don't create this class
*/
private HTTPURL() {
}
public static String getHTTPStatusCode(int status) {
switch (status) {
case 100:
return "Continue";
case 101:
return "Switching Protocols";
case 200:
return "OK";
case 201:
return "Created";
case 202:
return "Accepted";
case 203:
return "Non-Authoritative Information";
case 204:
return "No Content";
case 205:
return "Reset Content";
case 206:
return "Partial Content";
case 300:
return "Multiple Choices";
case 301:
return "Moved Permanently";
case 302:
return "Found";
case 303:
return "See Other";
case 304:
return "Not Modified";
case 305:
return "Use Proxy";
case 306:
return "(Unused)";
case 307:
return "Temporary Redirect";
case 308:
return "Permanent Redirect";
case 400:
return "Bad Request";
case 401:
return "Unauthorized";
case 402:
return "Payment Required";
case 403:
return "Forbidden";
case 404:
return "Not Found";
case 405:
return "Method Not Allowed";
case 406:
return "Not Acceptable";
case 407:
return "Proxy Authentication Required";
case 408:
return "Request Timeout";
case 409:
return "Conflict";
case 410:
return "Gone";
case 411:
return "Length Required";
case 412:
return "Precondition Failed";
case 413:
return "Request Entity Too Large";
case 414:
return "Request-URI Too Long";
case 415:
return "Unsupported Media Type";
case 416:
return "Requested Range Not Satisfiable";
case 417:
return "Expectation Failed";
case 500:
return "Internal Server Error";
case 501:
return "Not Implemented";
case 502:
return "Bad Gateway";
case 503:
return "Service Unavailable";
case 504:
return "Gateway Timeout";
case 505:
return "HTTP Version Not Supported";
default:
return Integer.toString(status, 10);
}
}
public static URL getURL(String url) throws IOException {
// url = URLEncoder.encode(url);
try {
return new URL(url);
} catch (MalformedURLException e) {
//if (!url.startsWith("http:")) { // ook!? dkfj://wwww.3.org -> http://dkfj://www.w3.org
if (url.indexOf("://") == -1) { // the protocol is missing
return new URL("http://" + url);
} else {
throw (IOException) e.fillInStackTrace();
}
}
}
public static URL getURL(URL base, String url)
throws MalformedURLException {
// url = URLEncoder.encode(url);
return new URL(base, url);
}
private static URLConnection getConnection(URL url, int count)
throws IOException {
return getConnection(url, null, count, null);
}
private static void setSSLVerifier(HttpsURLConnection uConn) {
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
uConn.setSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
}
// Step 2: hostname verifier
HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
return true;
}
};
uConn.setHostnameVerifier(hv);
}
private static URLConnection getConnection(URL url, URL referrer, int count,
ApplContext ac)
throws IOException {
if (count > 5) {
throw new ProtocolException("Server redirected too many " +
"times (5)");
}
// add the referrer, if not the same as the target URL
URL ref = (url.equals(referrer) ? null : referrer);
if (Util.servlet) {
String protocol = url.getProtocol();
if (!(("https".equalsIgnoreCase(protocol)) || ("http".equalsIgnoreCase(protocol)))) {
System.err.println("[WARNING] : someone is trying to get the file: "
+ url);
throw new FileNotFoundException("import " + url +
": Operation not permitted");
}
if (url.getPort() >= 0 && url.getPort() != 80 && url.getPort() != 443 && url.getPort() <= 1024) {
System.err.println("[WARNING] : someone is trying to access a forbidden port: "
+ url);
throw new FileNotFoundException("import " + url +
": Operation not permitted");
}
}
URLConnection urlC = url.openConnection();
if (Util.onDebug) {
System.err.println("Accessing " + url);
if (ac.getCredential() != null) {
System.err.println("with [" + ac.getCredential() + ']');
}
}
// avoid all kind of caches
urlC.setRequestProperty("Pragma", "no-cache");
urlC.setRequestProperty("Cache-Control", "no-cache, no-store");
// for the fun
urlC.setRequestProperty("User-Agent", CssValidator.server_name);
// referrer
setReferrer(urlC, ref);
// relay authorization information
if (ac.getCredential() != null) {
urlC.setRequestProperty("Authorization", ac.getCredential());
}
// relay languages
if (ac.getLang() != null) {
if (ac.getLang().indexOf('*') == -1) {
urlC.setRequestProperty("Accept-Language", ac.getLang() + ",*");
} else {
urlC.setRequestProperty("Accept-Language", ac.getLang());
}
}
// should I put an Accept header?
urlC.setRequestProperty("Accept",
"text/css,text/html,text/xml,"
+ "application/xhtml+xml,application/xml,"
+ "image/svg+xml,*/*;q=0.1");
if (urlC instanceof HttpURLConnection) {
HttpURLConnection httpURL = (HttpURLConnection) urlC;
int status;
httpURL.setInstanceFollowRedirects(false);
if (urlC instanceof HttpsURLConnection) {
try {
urlC.connect();
} catch (IOException ioex) {
setSSLVerifier((HttpsURLConnection) urlC);
urlC.connect();
}
} else {
urlC.connect();
}
try {
status = httpURL.getResponseCode();
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new FileNotFoundException(url + ": " +
getHTTPStatusCode(404));
}
switch (status) {
case HttpURLConnection.HTTP_OK:
// nothing to do
break;
case HttpURLConnection.HTTP_MOVED_PERM:
case HttpURLConnection.HTTP_MOVED_TEMP:
case 307:
case 308:
try {
URL u = getURL(url, httpURL.getHeaderField("Location"));
return getConnection(u, ref, count + 1, ac);
} catch (Exception ex) {
// usually a NPE when Location is absent on a redirect.
// in any case, we will count this as non existent result.
throw new FileNotFoundException(url + ":" + " Error in "+status);
} finally {
httpURL.disconnect();
}
case HttpURLConnection.HTTP_UNAUTHORIZED:
String realm = httpURL.getHeaderField("WWW-Authenticate");
httpURL.disconnect();
if (realm != null) {
throw new ProtocolException(realm);
}
default:
try {
if (httpURL.getResponseMessage() != null) {
throw new FileNotFoundException(url + ": " +
httpURL.getResponseMessage());
} else {
throw new FileNotFoundException(url + ": " +
getHTTPStatusCode(status));
}
} finally {
httpURL.disconnect();
}
}
} else {
urlC.connect();
}
return urlC;
}
public static URLConnection getConnection(URL url)
throws IOException {
return getConnection(url, 0);
}
public static URLConnection getConnection(URL url, ApplContext ac)
throws IOException {
return getConnection(url, ac.getReferrer(), 0, ac);
}
/* more madness */
public static InputStream getInputStream(ApplContext ac, URLConnection uco)
throws IOException {
InputStream orig_stream = uco.getInputStream();
String charset;
String encoding;
if (orig_stream == null) {
return orig_stream; // let it fail elsewhere
}
encoding = uco.getContentEncoding();
// not set -> return
if (encoding != null) {
if (encoding.equalsIgnoreCase("gzip")) {
orig_stream = new GZIPInputStream(orig_stream);
}
}
charset = getCharacterEncoding(ac, uco);
if ((charset == null) || (charset.regionMatches(true, 0, "utf", 0, 3))) {
UnicodeInputStream is = new UnicodeInputStream(orig_stream);
charset = is.getEncodingFromStream();
if (charset != null) {
ac.setCharsetForURL(uco.getURL(), charset);
}
return is;
}
return orig_stream;
}
public static String getCharacterEncoding(ApplContext ac,
URLConnection uco) {
String charset = ac.getCharsetForURL(uco.getURL());
if (charset != null) {
return charset;
}
String mtypestr = uco.getContentType();
if (mtypestr == null) {
return mtypestr;
}
MimeType mt;
try {
mt = new MimeType(mtypestr);
} catch (MimeTypeFormatException mex) {
return null;
}
charset = mt.getParameterValue("charset");
if (charset != null) {
ac.setCharsetForURL(uco.getURL(), charset);
}
return charset;
}
// used to set referrer
private static void setReferrer(URLConnection connection, URL referrer) {
if (referrer == null) {
return;
}
URL current = connection.getURL();
String curProtocol = current.getProtocol();
String refProtocol = referrer.getProtocol();
if ("https".equalsIgnoreCase(refProtocol)) {
if (!"https".equalsIgnoreCase(curProtocol)) {
// exit, we won't disclose information on non-https
// connections (ref using https, req using http)
return;
}
// ok so we have https for both, avoid leaking information
// so check that hosts are the same
if (!current.getHost().equalsIgnoreCase(referrer.getHost())) {
return;
}
}
// ok good, let's do it
connection.setRequestProperty("Referer", referrer.toExternalForm());
}
/**
*
*/
public static void main(String[] args)
throws Exception {
int c;
InputStream in = HTTPURL.getConnection(
getURL(args[0])).getInputStream();
while ((c = in.read()) != -1) {
System.err.print((char) c);
}
System.exit(0);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy