Java tutorial
/** * WS-Attacker - A Modular Web Services Penetration Testing Framework Copyright * (C) 2014 Christian Mainka * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package wsattacker.http.transport; import com.eviware.soapui.impl.wsdl.WsdlRequest; import com.eviware.soapui.impl.wsdl.submit.transports.http.WsdlResponse; import com.eviware.soapui.impl.wsdl.support.http.HttpClientSupport; import com.eviware.soapui.support.types.StringToStringsMap; import java.io.*; import java.util.*; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.params.ConnRoutePNames; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; import org.apache.log4j.Logger; /** * @author Juraj Somorovsky - juraj.somorovsky@rub.de * @version 0.1 */ public class SoapHttpClient { /** * if the connection is closed, the client tries to send the soap message again, max MAX_RETRY_NUMBER times */ private static int MAX_RETRY_NUMBER = 3; /** * holds the current instance of the object */ private static SoapHttpClient currentInstance = null; /** * http client */ private HttpClient client; /** * http post */ private HttpPost post; private static Logger LOG = Logger.getLogger(SoapHttpClient.class); SoapHttpClient(WsdlRequest request) { this(request.getEndpoint()); setSoapUiHeaders(request); } SoapHttpClient(String destinationUrl) { this.client = TlsWrapperClient.wrapClient(new DefaultHttpClient()); this.post = new HttpPost(destinationUrl); setConfigProxy(); } private void setConfigProxy() { final String[] protocols = { "http", "https" }; for (String protocol : protocols) { final String httpProxyHost = System.getProperty(protocol + ".proxyHost"); final String proxyPortAsString = System.getProperty(protocol + ".proxyPort"); if (httpProxyHost != null && !httpProxyHost.isEmpty() && proxyPortAsString != null && !proxyPortAsString.isEmpty()) { try { final int httpProxyPort = Integer.parseInt(proxyPortAsString); if (httpProxyHost != null && !httpProxyHost.isEmpty()) { final HttpHost proxy = new HttpHost(httpProxyHost, httpProxyPort, protocol); client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy); } } catch (NumberFormatException e) { Logger.getLogger(SoapHttpClient.class) .warn(String.format("Could not set Proxy for %s with value with value '%s'", protocol, proxyPortAsString), e); } } } } public static boolean isContentLengthHeader(String name) { return "Content-Length".equals(name); } private void setSoapUiHeaders(WsdlRequest request) { final WsdlResponse response = request.getResponse(); if (response != null) { final StringToStringsMap requestBasicHeaders = response.getRequestHeaders(); setHeaders(requestBasicHeaders); } final StringToStringsMap additionalHeaders = request.getRequestHeaders(); setHeaders(additionalHeaders); } private void setHeaders(final StringToStringsMap headers) { for (Map.Entry<String, List<String>> header : headers.entrySet()) { String name = header.getKey(); if (isContentLengthHeader(name)) { LOG.debug("HTTP-Header 'Content-Length' will be recalculated."); continue; } for (String value : header.getValue()) { post.setHeader(name, value); } } } /** * Get the current soap http client initialized with the URL and wsdl request * * @return */ public static SoapHttpClient getSoapHttpClient() { return currentInstance; } /** * Sends the SOAP message to the initialized endpoint destination * * @param soap * @return * @throws IOException */ public SoapResponse sendSoap(String soap) throws IOException { final StringEntity httpBody = new StringEntity(soap); post.setEntity(httpBody); int maxTries = MAX_RETRY_NUMBER; HttpResponse httpResponse = null; while (httpResponse == null) { try { httpResponse = client.execute(post); } catch (IOException ex) { if (maxTries == 0) { throw ex; } else { maxTries--; LOG.warn(ex.getLocalizedMessage()); LOG.warn("Trying to send the message once more"); LOG.debug(ex); } } } SoapResponse soapResponse = new SoapResponse(); if (LOG.isDebugEnabled()) { LOG.debug(httpResponse.getStatusLine()); } soapResponse.setStatusLine(httpResponse.getStatusLine().toString()); for (Header h : httpResponse.getAllHeaders()) { final String name = h.getName(); final String value = h.getValue(); if (LOG.isDebugEnabled()) { final String headerDebug = name + ": " + value; LOG.debug(headerDebug); } HttpHeader newHeader = new HttpHeader(name, value); soapResponse.getHeaders().add(newHeader); } LOG.debug("waiting for response: "); final HttpEntity entity = httpResponse.getEntity(); final String charset = EntityUtils.getContentCharSet(entity); final String responseString = EntityUtils.toString(entity, charset); soapResponse.setBody(responseString); return soapResponse; } /** * Shuts down the connection manager and releases all the allocated resources */ public void shutDownConnectionManager() { client.getConnectionManager().shutdown(); } }