/* * SOME METHODS: * * The Apache Software License, Version 1.1 * * * Copyright (c) 1999 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Xerces" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation and was * originally based on software copyright (c) 1999, International * Business Machines, Inc., http://www.apache.org. For more * information on the Apache Software Foundation, please see * . * --------------------------------------------------------------------------- * * OTHER METHOD: * (C) Copyright 2001, CrossWire Bible Society, under the terms of the GNU * General Public License * */ package org.crosswire.utils; import org.apache.commons.codec.binary.Base64; import org.apache.http.HttpEntity; import org.apache.http.Header; import org.apache.http.HttpHost; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.HttpResponse; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.AuthCache; import org.apache.http.impl.client.BasicAuthCache; import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.auth.BasicScheme; import org.apache.http.protocol.HTTP; import org.apache.http.util.EntityUtils; import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.entity.StringEntity; import org.apache.http.entity.ContentType; import org.apache.http.conn.ssl.TrustSelfSignedStrategy; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.ssl.SSLContextBuilder; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import java.security.cert.X509Certificate; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLSession; import java.util.HashMap; import org.owasp.html.HtmlPolicyBuilder; import org.owasp.html.PolicyFactory; import java.net.URL; import java.net.URI; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.StringWriter; import java.io.PrintWriter; import org.apache.log4j.Logger; public class HTTPUtils { static Logger logger = Logger.getLogger(HTTPUtils.class); /** Normalizes the given string. */ public static String canonize(String s) { StringBuffer str = new StringBuffer(); int len = (s != null) ? s.length() : 0; for (int i = 0; i < len; i++) { char ch = s.charAt(i); /* if ( ch <= 31 ) { str.append("�"); } else { */ switch ( ch ) { case '<': { str.append("<"); break; } case '>': { str.append(">"); break; } case '&': { str.append("&"); break; } case '"': { str.append("""); break; } case 0x2028: case '\r': case '\n': { str.append("&#"); str.append(Integer.toString(ch)); str.append(';'); break; } default: { str.append(ch); } } // } } return (str.toString()); } static PolicyFactory sanitizer = new HtmlPolicyBuilder() .allowElements("a") .allowUrlProtocols("https") .allowAttributes("href").onElements("a") .requireRelNofollowOnLinks() .toFactory(); public static String sanitize(String val) { // assert we have something to do if (val == null) return null; val = sanitizer.sanitize(val); // whitelist val = val.replaceAll("@", "@"); return val; } public static final int POST = 1; public static final int GET = 2; public static final int PUT = 3; public static final int DELETE = 4; public static final int PARAMSTYPE_FORMPARAMS = 1; public static final int PARAMSTYPE_JSON = 2; public static final int PARAMSTYPE_XML = 3; public static class Response { public int resultCode; public HashMap headers = new HashMap(); } public static StringBuffer postURL(String urlText, String params, int method, Response callerResponse) { return postURL(urlText, params, null, null, null, method, false, callerResponse, PARAMSTYPE_FORMPARAMS); } public static StringBuffer postURL(String urlText, String params, int method, int paramsType) { return postURL(urlText, params, null, null, null, method, false, null, paramsType); } public static StringBuffer postURL(String urlText, String params, String headers[], int method, int paramsType) { return postURL(urlText, params, null, null, headers, method, false, null, paramsType); } public static StringBuffer postURL(String urlText, String params, int method) { return postURL(urlText, params, null, null, null, method, false, null, PARAMSTYPE_FORMPARAMS); } public static StringBuffer postURL(String urlText, String params) { return postURL(urlText, params, null, null, null, POST, false, null, PARAMSTYPE_FORMPARAMS); } public static StringBuffer postURL(String urlText, String params, final String user, final String passwd) { return postURL(urlText, params, user, passwd, null, POST, false, null, PARAMSTYPE_FORMPARAMS); } public static StringBuffer postURL(String urlText, String params, final String user, final String passwd, String headers[]) { return postURL(urlText, params, user, passwd, headers, POST, false, null, PARAMSTYPE_FORMPARAMS); } public static StringBuffer postURL(String urlText, String params, final String user, final String passwd, String headers[], int method) { return postURL(urlText, params, user, passwd, headers, method, false, null, PARAMSTYPE_FORMPARAMS); } public static StringBuffer postURL(String urlText, String params, final String user, final String passwd, String headers[], int method, boolean toBase64) { return postURL(urlText, params, user, passwd, headers, method, toBase64, null, PARAMSTYPE_FORMPARAMS); } public static StringBuffer postURL(String urlText, String params, final String user, final String passwd, String headers[], int method, boolean toBase64, Response callerResponse) { return postURL(urlText, params, user, passwd, headers, method, toBase64, callerResponse, PARAMSTYPE_FORMPARAMS); } public static StringBuffer postURL(String urlText, String params, final String user, final String passwd, String headers[], int method, boolean toBase64, Response callerResponse, int paramsType) { CloseableHttpClient httpClient = null; StringBuffer data = new StringBuffer(); byte[] sdata = null; try { SSLContextBuilder sslContextBuilder = new SSLContextBuilder(); sslContextBuilder.loadTrustMaterial(null, new TrustSelfSignedStrategy()); HttpClientBuilder httpClientBuilder = HttpClientBuilder.create() .setSSLContext(sslContextBuilder.build()) .setSSLHostnameVerifier(new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }); URL url = new URL(urlText); if (user != null && passwd != null) { CredentialsProvider cp = new BasicCredentialsProvider(); cp.setCredentials( new AuthScope(url.getHost(), url.getPort()), new UsernamePasswordCredentials(user, passwd) ); httpClientBuilder = httpClientBuilder.setDefaultCredentialsProvider(cp); } httpClient = httpClientBuilder.build(); // Create AuthCache instance HttpHost targetHost = new HttpHost(url.getHost(), url.getPort(), url.getProtocol()); AuthCache authCache = new BasicAuthCache(); BasicScheme basicAuth = new BasicScheme(); authCache.put(targetHost, basicAuth); BasicHttpContext ctx = new BasicHttpContext(); ctx.setAttribute(HttpClientContext.AUTH_CACHE, authCache); HttpEntity p = null; HttpRequestBase httpRequest = null; switch (method) { case POST: p = (paramsType == PARAMSTYPE_JSON) ? (HttpEntity)new StringEntity(params, ContentType.APPLICATION_JSON) : paramsType == PARAMSTYPE_XML ? (HttpEntity)new StringEntity(params, ContentType.APPLICATION_XML) : (HttpEntity)new UrlEncodedFormEntity(URLEncodedUtils.parse(new URI("http://x.com?"+params), "UTF-8"), "UTF-8"); httpRequest = new HttpPost(url.toString()); break; case PUT: p = (paramsType == PARAMSTYPE_JSON) ? (HttpEntity)new StringEntity(params, ContentType.APPLICATION_JSON) : paramsType == PARAMSTYPE_XML ? (HttpEntity)new StringEntity(params, ContentType.APPLICATION_XML) : (HttpEntity)new UrlEncodedFormEntity(URLEncodedUtils.parse(new URI("http://x.com?"+params), "UTF-8"), "UTF-8"); httpRequest = new HttpPut(url.toString()); break; case DELETE: httpRequest = new HttpDelete(url.toString()+(params != null && params.length() > 0 ? ("?"+params) : "")); break; case GET: default: httpRequest = new HttpGet(url.toString()+(params != null && params.length() > 0 ? ("?"+params) : "")); break; } if (headers != null) { for (int i = 0; i < headers.length-1; i+=2) { httpRequest.addHeader(headers[i], headers[i+1]); } } if (p != null) { ((HttpEntityEnclosingRequestBase)httpRequest).setEntity(p); } HttpResponse response = httpClient.execute(targetHost, httpRequest, ctx); if (callerResponse != null) { callerResponse.resultCode = response.getStatusLine().getStatusCode(); for (Header h : response.getAllHeaders()) { callerResponse.headers.put(h.getName(), h.getValue()); } } HttpEntity entity = response.getEntity(); if (entity != null) { InputStream is = entity.getContent(); ByteArrayOutputStream rawData = new ByteArrayOutputStream(); byte[] buffer = new byte[8192]; int len = 0; while ((len = is.read(buffer)) > -1) { rawData.write(buffer, 0, len); } EntityUtils.consume(entity); sdata = (byte[]) rawData.toByteArray(); } } catch (Exception e) { logger.error("Problem posting URL: " + urlText + "; error: " + e); e.printStackTrace(); if (callerResponse != null) callerResponse.resultCode = -1; StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); data.append(sw.toString()); } finally { // When HttpClient instance is no longer needed, // shut down the connection manager to ensure // immediate deallocation of all system resources try { if (httpClient != null) httpClient.close(); // getConnectionManager().shutdown(); } catch (Exception e) { logger.error("Project closing client connection: " + e); e.printStackTrace(); } } if (sdata != null) { if (toBase64) { data.append(Base64.encodeBase64String(sdata)); } else { data.append(new String(sdata, 0, sdata.length)); } } return data; } }