extensions/proxy/src/main/java/uk/co/tfd/sm/proxy/ProxyClientServiceImpl.java
public ProxyResponse executeCall(Map<String, Object> config,
			Map<String, Object> headers, Map<String, Object> input,
			InputStream requestInputStream, long requestContentLength,
			String requestContentType) throws ProxyClientException {
		try {
			LOGGER.info(
					"Calling Execute Call with Config:[{}] Headers:[{}] Input:[{}] "
							+ "RequestInputStream:[{}] InputStreamContentLength:[{}] RequestContentType:[{}] ",
					new Object[] { config, headers, input, requestInputStream,
							requestContentLength, requestContentType });
			bindConfig(config);

			if (config != null
					&& config.containsKey(CONFIG_REQUEST_PROXY_ENDPOINT)) {
				// setup the post request
				String endpointURL = (String) config
						.get(CONFIG_REQUEST_PROXY_ENDPOINT);
				if (isUnsafeProxyDefinition(config)) {
					try {
						URL u = new URL(endpointURL);
						String host = u.getHost();
						if (host.indexOf('$') >= 0) {
							throw new ProxyClientException(
									"Invalid Endpoint template, relies on request to resolve valid URL "
											+ u);
						}
					} catch (MalformedURLException e) {
						throw new ProxyClientException(
								"Invalid Endpoint template, relies on request to resolve valid URL",
								e);
					}
				}
				
				LOGGER.info("Valied Endpoint Def");

				Map<String, Object> context = Maps.newHashMap(input);

				// add in the config properties from the bundle overwriting
				// everything else.
				context.put("config", configProperties);

				endpointURL = processUrlTemplate(endpointURL, context);
				
				LOGGER.info("Calling URL {} ",endpointURL);

				ProxyMethod proxyMethod = ProxyMethod.GET;
				if (config.containsKey(CONFIG_REQUEST_PROXY_METHOD)) {
					try {
						proxyMethod = ProxyMethod.valueOf((String) config
								.get(CONFIG_REQUEST_PROXY_METHOD));
					} catch (Exception e) {

					}
				}

				HttpClient client = getHttpClient();

				HttpUriRequest method = null;
				switch (proxyMethod) {
				case GET:
					if (config.containsKey(CONFIG_LIMIT_GET_SIZE)) {
						long maxSize = (Long) config.get(CONFIG_LIMIT_GET_SIZE);
						HttpHead h = new HttpHead(endpointURL);

						HttpParams params = h.getParams();
						// make certain we reject the body of a head
						params.setBooleanParameter(
								"http.protocol.reject-head-body", true);
						h.setParams(params);
						populateMessage(method, config, headers);
						HttpResponse response = client.execute(h);
						if (response.getStatusLine().getStatusCode() == 200) {
							// Check if the content-length is smaller than the
							// maximum (if any).
							Header contentLengthHeader = response
									.getLastHeader("Content-Length");
							if (contentLengthHeader != null) {
								long length = Long
										.parseLong(contentLengthHeader
												.getValue());
								if (length > maxSize) {
									return new ProxyResponseImpl(
											HttpServletResponse.SC_PRECONDITION_FAILED,
											"Response too large", response);
								}
							}
						} else {
							return new ProxyResponseImpl(response);
						}
					}
					method = new HttpGet(endpointURL);
					break;
				case HEAD:
					method = new HttpHead(endpointURL);
					break;
				case OPTIONS:
					method = new HttpOptions(endpointURL);
					break;
				case POST:
					method = new HttpPost(endpointURL);
					break;
				case PUT:
					method = new HttpPut(endpointURL);
					break;
				default:
					method = new HttpGet(endpointURL);
				}

				populateMessage(method, config, headers);

				if (requestInputStream == null
						&& !config.containsKey(CONFIG_PROXY_REQUEST_TEMPLATE)) {
					if (method instanceof HttpPost) {
						HttpPost postMethod = (HttpPost) method;
						MultipartEntity multipart = new MultipartEntity();
						for (Entry<String, Object> param : input.entrySet()) {
							String key = param.getKey();
							Object value = param.getValue();
							if (value instanceof Object[]) {
								for (Object val : (Object[]) value) {
									addPart(multipart, key, val);
								}
							} else {
								addPart(multipart, key, value);
							}
							postMethod.setEntity(multipart);
						}
					}
				} else {

					if (method instanceof HttpEntityEnclosingRequestBase) {
						String contentType = requestContentType;
						if (contentType == null
								&& config
										.containsKey(CONFIG_REQUEST_CONTENT_TYPE)) {
							contentType = (String) config
									.get(CONFIG_REQUEST_CONTENT_TYPE);

						}
						if (contentType == null) {
							contentType = APPLICATION_OCTET_STREAM;
						}
						HttpEntityEnclosingRequestBase eemethod = (HttpEntityEnclosingRequestBase) method;
						if (requestInputStream != null) {
							eemethod.setHeader(HttpHeaders.CONTENT_TYPE,
									contentType);
							eemethod.setEntity(new InputStreamEntity(
									requestInputStream, requestContentLength));
						} else {
							// build the request
							StringWriter body = new StringWriter();
							templateService.evaluate(context, body, (String) config
											.get("path"), (String) config
											.get(CONFIG_PROXY_REQUEST_TEMPLATE));
							byte[] soapBodyContent = body.toString().getBytes(
									"UTF-8");
							eemethod.setHeader(HttpHeaders.CONTENT_TYPE,
									contentType);
							eemethod.setEntity(new InputStreamEntity(
									new ByteArrayInputStream(soapBodyContent),
									soapBodyContent.length));

						}
					}
				}

				HttpResponse response = client.execute(method);
				if (response.getStatusLine().getStatusCode() == 302
						&& method instanceof HttpEntityEnclosingRequestBase) {
					// handle redirects on post and put
					String url = response.getFirstHeader("Location").getValue();
					method = new HttpGet(url);
					response = client.execute(method);
				}

				return new ProxyResponseImpl(response);
			}

		} catch (ProxyClientException e) {
			throw e;
		} catch (Exception e) {
			LOGGER.error(e.getMessage(),e);
			throw new ProxyClientException("The Proxy request specified by  "
					+ config + " failed, cause follows:", e);
		} finally {
			unbindConfig();
		}
		throw new ProxyClientException("The Proxy request specified by "
				+ config + " does not contain a valid endpoint specification ");
	}
public ProxyResponse executeCall(Map<String, Object> config,
			Map<String, Object> headers, Map<String, Object> input,
			InputStream requestInputStream, long requestContentLength,
			String requestContentType) throws ProxyClientException {
		try {
			LOGGER.info(
					"Calling Execute Call with Config:[{}] Headers:[{}] Input:[{}] "
							+ "RequestInputStream:[{}] InputStreamContentLength:[{}] RequestContentType:[{}] ",
					new Object[] { config, headers, input, requestInputStream,
							requestContentLength, requestContentType });
			bindConfig(config);

			if (config != null
					&& config.containsKey(CONFIG_REQUEST_PROXY_ENDPOINT)) {
				// setup the post request
				String endpointURL = (String) config
						.get(CONFIG_REQUEST_PROXY_ENDPOINT);
				if (isUnsafeProxyDefinition(config)) {
					try {
						URL u = new URL(endpointURL);
						String host = u.getHost();
						if (host.indexOf('$') >= 0) {
							throw new ProxyClientException(
									"Invalid Endpoint template, relies on request to resolve valid URL "
											+ u);
						}
					} catch (MalformedURLException e) {
						throw new ProxyClientException(
								"Invalid Endpoint template, relies on request to resolve valid URL",
								e);
					}
				}
				
				LOGGER.info("Valied Endpoint Def");

				Map<String, Object> context = Maps.newHashMap(input);

				// add in the config properties from the bundle overwriting
				// everything else.
				context.put("config", configProperties);

				endpointURL = processUrlTemplate(endpointURL, context);
				
				LOGGER.info("Calling URL {} ",endpointURL);

				ProxyMethod proxyMethod = ProxyMethod.GET;
				if (config.containsKey(CONFIG_REQUEST_PROXY_METHOD)) {
					try {
						proxyMethod = ProxyMethod.valueOf((String) config
								.get(CONFIG_REQUEST_PROXY_METHOD));
					} catch (Exception e) {

					}
				}

				HttpClient client = getHttpClient();

				HttpUriRequest method = null;
				switch (proxyMethod) {
				case GET:
					if (config.containsKey(CONFIG_LIMIT_GET_SIZE)) {
						long maxSize = (Long) config.get(CONFIG_LIMIT_GET_SIZE);
						HttpHead h = new HttpHead(endpointURL);

						HttpParams params = h.getParams();
						// make certain we reject the body of a head
						params.setBooleanParameter(
								"http.protocol.reject-head-body", true);
						h.setParams(params);
						populateMessage(method, config, headers);
						HttpResponse response = client.execute(h);
						if (response.getStatusLine().getStatusCode() == 200) {
							// Check if the content-length is smaller than the
							// maximum (if any).
							Header contentLengthHeader = response
									.getLastHeader("Content-Length");
							if (contentLengthHeader != null) {
								long length = Long
										.parseLong(contentLengthHeader
												.getValue());
								if (length > maxSize) {
									return new ProxyResponseImpl(
											HttpServletResponse.SC_PRECONDITION_FAILED,
											"Response too large", response);
								}
							}
						} else {
							return new ProxyResponseImpl(response);
						}
					}
					method = new HttpGet(endpointURL);
					break;
				case HEAD:
					method = new HttpHead(endpointURL);
					break;
				case OPTIONS:
					method = new HttpOptions(endpointURL);
					break;
				case POST:
					method = new HttpPost(endpointURL);
					break;
				case PUT:
					method = new HttpPut(endpointURL);
					break;
				default:
					method = new HttpGet(endpointURL);
				}

				populateMessage(method, config, headers);

				if (requestInputStream == null
						&& !config.containsKey(CONFIG_PROXY_REQUEST_TEMPLATE)) {
					if (method instanceof HttpPost) {
						HttpPost postMethod = (HttpPost) method;
						MultipartEntity multipart = new MultipartEntity();
						for (Entry<String, Object> param : input.entrySet()) {
							String key = param.getKey();
							Object value = param.getValue();
							if (value instanceof Object[]) {
								for (Object val : (Object[]) value) {
									addPart(multipart, key, val);
								}
							} else {
								addPart(multipart, key, value);
							}
							postMethod.setEntity(multipart);
						}
					}
				} else {

					if (method instanceof HttpEntityEnclosingRequestBase) {
						String contentType = requestContentType;
						if (contentType == null
								&& config
										.containsKey(CONFIG_REQUEST_CONTENT_TYPE)) {
							contentType = (String) config
									.get(CONFIG_REQUEST_CONTENT_TYPE);

						}
						if (contentType == null) {
							contentType = APPLICATION_OCTET_STREAM;
						}
						HttpEntityEnclosingRequestBase eemethod = (HttpEntityEnclosingRequestBase) method;
						if (requestInputStream != null) {
							eemethod.setHeader(HttpHeaders.CONTENT_TYPE,
									contentType);
							eemethod.setEntity(new InputStreamEntity(
									requestInputStream, requestContentLength));
						} else {
							// build the request
							StringWriter body = new StringWriter();
							templateService.evaluate(context, body, (String) config
											.get("path"), (String) config
											.get(CONFIG_PROXY_REQUEST_TEMPLATE));
							byte[] soapBodyContent = body.toString().getBytes(
									"UTF-8");
							eemethod.setHeader(HttpHeaders.CONTENT_TYPE,
									contentType);
							eemethod.setEntity(new InputStreamEntity(
									new ByteArrayInputStream(soapBodyContent),
									soapBodyContent.length));

						}
					}
				}

				HttpResponse response = client.execute(method);
				if (response.getStatusLine().getStatusCode() == 302
						&& method instanceof HttpEntityEnclosingRequestBase) {
					// handle redirects on post and put
					String url = response.getFirstHeader("Location").getValue();
					method = new HttpGet(url);
					response = client.execute(method);
				}

				return new ProxyResponseImpl(response);
			}

		} catch (ProxyClientException e) {
			throw e;
		} catch (Exception e) {
			LOGGER.error(e.getMessage(),e);
			throw new ProxyClientException("The Proxy request specified by  "
					+ config + " failed, cause follows:", e);
		} finally {
			unbindConfig();
		}
		throw new ProxyClientException("The Proxy request specified by "
				+ config + " does not contain a valid endpoint specification ");
	}
public ProxyResponse executeCall ( Map < String , Object > config , Map < String , Object > headers , Map < String , Object > input , InputStream requestInputStream , long requestContentLength , String requestContentType ) throws ProxyClientException { try { LOGGER . info ( "Calling Execute Call with Config:[{}] Headers:[{}] Input:[{}] " + "RequestInputStream:[{}] InputStreamContentLength:[{}] RequestContentType:[{}] " , new Object [ ] { config , headers , input , requestInputStream , requestContentLength , requestContentType } ) ; bindConfig ( config ) ; if ( config != null && config . containsKey ( CONFIG_REQUEST_PROXY_ENDPOINT ) ) { // setup the post request String endpointURL = ( String ) config . get ( CONFIG_REQUEST_PROXY_ENDPOINT ) ; if ( isUnsafeProxyDefinition ( config ) ) { try { URL u = new URL ( endpointURL ) ; String host = u . getHost ( ) ; if ( host . indexOf ( ' ' ) >= 0 ) { throw new ProxyClientException ( "Invalid Endpoint template, relies on request to resolve valid URL " + u ) ; } } catch ( MalformedURLException e ) { throw new ProxyClientException ( "Invalid Endpoint template, relies on request to resolve valid URL" , e ) ; } } LOGGER . info ( "Valied Endpoint Def" ) ; Map < String , Object > context = Maps . newHashMap ( input ) ; // add in the config properties from the bundle overwriting // everything else. context . put ( "config" , configProperties ) ; endpointURL = processUrlTemplate ( endpointURL , context ) ; LOGGER . info ( "Calling URL {} " , endpointURL ) ; ProxyMethod proxyMethod = ProxyMethod . GET ; if ( config . containsKey ( CONFIG_REQUEST_PROXY_METHOD ) ) { try { proxyMethod = ProxyMethod . valueOf ( ( String ) config . get ( CONFIG_REQUEST_PROXY_METHOD ) ) ; } catch ( Exception e ) { } } HttpClient client = getHttpClient ( ) ; HttpUriRequest method = null ; switch ( proxyMethod ) { case GET : if ( config . containsKey ( CONFIG_LIMIT_GET_SIZE ) ) { long maxSize = ( Long ) config . get ( CONFIG_LIMIT_GET_SIZE ) ; HttpHead h = new HttpHead ( endpointURL ) ; HttpParams params = h . getParams ( ) ; // make certain we reject the body of a head params . setBooleanParameter ( "http.protocol.reject-head-body" , true ) ; h . setParams ( params ) ; populateMessage ( method , config , headers ) ; HttpResponse response = client . execute ( h ) ; if ( response . getStatusLine ( ) . getStatusCode ( ) == 200 ) { // Check if the content-length is smaller than the // maximum (if any). Header contentLengthHeader = response . getLastHeader ( "Content-Length" ) ; if ( contentLengthHeader != null ) { long length = Long . parseLong ( contentLengthHeader . getValue ( ) ) ; if ( length > maxSize ) { return new ProxyResponseImpl ( HttpServletResponse . SC_PRECONDITION_FAILED , "Response too large" , response ) ; } } } else { return new ProxyResponseImpl ( response ) ; } } method = new HttpGet ( endpointURL ) ; break ; case HEAD : method = new HttpHead ( endpointURL ) ; break ; case OPTIONS : method = new HttpOptions ( endpointURL ) ; break ; case POST : method = new HttpPost ( endpointURL ) ; break ; case PUT : method = new HttpPut ( endpointURL ) ; break ; default : method = new HttpGet ( endpointURL ) ; } populateMessage ( method , config , headers ) ; if ( requestInputStream == null && ! config . containsKey ( CONFIG_PROXY_REQUEST_TEMPLATE ) ) { if ( method instanceof HttpPost ) { HttpPost postMethod = ( HttpPost ) method ; MultipartEntity multipart = new MultipartEntity ( ) ; for ( Entry < String , Object > param : input . entrySet ( ) ) { String key = param . getKey ( ) ; Object value = param . getValue ( ) ; if ( value instanceof Object [ ] ) { for ( Object val : ( Object [ ] ) value ) { addPart ( multipart , key , val ) ; } } else { addPart ( multipart , key , value ) ; } postMethod . setEntity ( multipart ) ; } } } else { if ( method instanceof HttpEntityEnclosingRequestBase ) { String contentType = requestContentType ; if ( contentType == null && config . containsKey ( CONFIG_REQUEST_CONTENT_TYPE ) ) { contentType = ( String ) config . get ( CONFIG_REQUEST_CONTENT_TYPE ) ; } if ( contentType == null ) { contentType = APPLICATION_OCTET_STREAM ; } HttpEntityEnclosingRequestBase eemethod = ( HttpEntityEnclosingRequestBase ) method ; if ( requestInputStream != null ) { eemethod . setHeader ( HttpHeaders . CONTENT_TYPE , contentType ) ; eemethod . setEntity ( new InputStreamEntity ( requestInputStream , requestContentLength ) ) ; } else { // build the request StringWriter body = new StringWriter ( ) ; templateService . evaluate ( context , body , ( String ) config . get ( "path" ) , ( String ) config . get ( CONFIG_PROXY_REQUEST_TEMPLATE ) ) ; byte [ ] soapBodyContent = body . toString ( ) . getBytes ( "UTF-8" ) ; eemethod . setHeader ( HttpHeaders . CONTENT_TYPE , contentType ) ; eemethod . setEntity ( new InputStreamEntity ( new ByteArrayInputStream ( soapBodyContent ) , soapBodyContent . length ) ) ; } } } HttpResponse response = client . execute ( method ) ; if ( response . getStatusLine ( ) . getStatusCode ( ) == 302 && method instanceof HttpEntityEnclosingRequestBase ) { // handle redirects on post and put String url = response . getFirstHeader ( "Location" ) . getValue ( ) ; method = new HttpGet ( url ) ; response = client . execute ( method ) ; } return new ProxyResponseImpl ( response ) ; } } catch ( ProxyClientException e ) { throw e ; } catch ( Exception e ) { LOGGER . error ( e . getMessage ( ) , e ) ; throw new ProxyClientException ( "The Proxy request specified by  " + config + " failed, cause follows:" , e ) ; } finally { unbindConfig ( ) ; } throw new ProxyClientException ( "The Proxy request specified by " + config + " does not contain a valid endpoint specification " ) ; }
Executes a HTTP call using a path in the JCR to point to a template and a
map of properties to populate that template with. An example might be a
SOAP call.

<pre>
{http://www.w3.org/2001/12/soap-envelope}Envelope:{
{http://www.w3.org/2001/12/soap-envelope}Body:{
{http://www.example.org/stock}GetStockPriceResponse:{
&gt;body:[       ]
{http://www.example.org/stock}Price:{
&gt;body:[34.5]
}
}
&gt;body:[  ]
}
&gt;body:[   ]
{http://www.w3.org/2001/12/soap-envelope}encodingStyle:[http://www.w3.org/2001/12/soap-encoding]
}

</pre>

@param resource
the resource containing the proxy end point specification.
@param headers
a map of headers to set int the request.
@param input
a map of parameters for all templates (both url and body)
@param requestInputStream
containing the request body (can be null if the call requires
no body or the template will be used to generate the body)
@param requestContentLength
if the requestImputStream is specified, the length specifies
the lenght of the body.
@param requerstContentType
the content type of the request, if null the node property
sakai:proxy-request-content-type will be used.
@throws ProxyClientException
Executes a HTTP call using a path in the JCR to point to a template and a map of properties to populate that template with . An example might be a SOAP call .