Example usage for org.apache.commons.httpclient HttpMethod getResponseHeader

List of usage examples for org.apache.commons.httpclient HttpMethod getResponseHeader

Introduction

In this page you can find the example usage for org.apache.commons.httpclient HttpMethod getResponseHeader.

Prototype

public abstract Header getResponseHeader(String paramString);

Source Link

Usage

From source file:org.openqa.selenium.remote.HttpCommandExecutor.java

private Response createResponse(HttpMethod httpMethod) throws Exception {
    Response response;//from   w w  w .j a  v a 2 s  . c  o m

    Header header = httpMethod.getResponseHeader("Content-Type");

    if (header != null && header.getValue().startsWith("application/json")) {
        response = new JsonToBeanConverter().convert(Response.class, httpMethod.getResponseBodyAsString());
    } else {
        response = new Response();

        if (header != null && header.getValue().startsWith("image/png")) {
            response.setValue(httpMethod.getResponseBody());
        } else {
            response.setValue(httpMethod.getResponseBodyAsString());
        }

        String uri = httpMethod.getURI().toString();
        int sessionIndex = uri.indexOf("/session/");
        if (sessionIndex != -1) {
            sessionIndex += "/session/".length();
            int nextSlash = uri.indexOf("/", sessionIndex);
            if (nextSlash != -1) {
                response.setSessionId(uri.substring(sessionIndex, nextSlash));
                response.setContext("foo");
            }
        }
    }
    response.setError(!(httpMethod.getStatusCode() > 199 && httpMethod.getStatusCode() < 300));

    if (response.getValue() instanceof String) {
        //We normalise to \n because Java will translate this to \r\n
        //if this is suitable on our platform, and if we have \r\n, java will
        //turn this into \r\r\n, which would be Bad!
        response.setValue(((String) response.getValue()).replace("\r\n", "\n"));
    }

    return response;
}

From source file:org.openqa.selenium.remote.HttpCommandExecutor.java

private boolean isRedirect(HttpMethod httpMethod) {
    int code = httpMethod.getStatusCode();
    return (code == 301 || code == 302 || code == 303 || code == 307)
            && httpMethod.getResponseHeader("location") != null;
}

From source file:org.osaf.caldav4j.util.UrlUtils.java

public static String getHeaderPrettyValue(HttpMethod method, String headerName) {
    if (method != null && headerName != null) {
        Header header = method.getResponseHeader(headerName);
        if (header != null) {
            return header.getValue();
        }/*from w  w  w . ja  v  a  2 s. c om*/
    }

    return null;
}

From source file:org.paxle.crawler.http.impl.HttpCrawler.java

public ICrawlerDocument request(URI requestUri) {
    if (requestUri == null)
        throw new NullPointerException("URL was null");
    this.logger.debug(String.format("Crawling URL '%s' ...", requestUri));

    ICrawlerDocument doc = null;/*  w  w w.ja  v  a2 s.  c o  m*/
    HttpMethod method = null;
    try {
        final ICrawlerContext ctx = this.contextLocal.getCurrentContext();

        // creating an empty crawler-document
        doc = ctx.createDocument();
        doc.setLocation(requestUri);

        final String uriAsciiString = requestUri.toASCIIString();

        /* ==============================================================================
         * HTTP HEAD request
         * 
         * first use the HEAD method to determine whether the MIME-type is supported
         * and to compare the content-length with the maximum allowed download size
         * (both only if the server provides this information, if not, the file is
         * fetched)
         * ============================================================================== */
        method = new HeadMethod(uriAsciiString); // automatically follows redirects
        this.initRequestMethod(method);
        int statusCode = this.getHttpClient().executeMethod(method);

        final boolean headUnsupported = (statusCode == HttpStatus.SC_METHOD_FAILURE
                || statusCode == HttpStatus.SC_METHOD_NOT_ALLOWED);
        if (!headUnsupported) {
            if (statusCode != HttpStatus.SC_OK) {
                // RFC 2616 states that the GET and HEAD methods _must_ be supported by any
                // general purpose servers (which are in fact the ones we are connecting to here)

                if (statusCode == HttpStatus.SC_NOT_FOUND) {
                    doc.setStatus(ICrawlerDocument.Status.NOT_FOUND);
                } else {
                    doc.setStatus(ICrawlerDocument.Status.UNKNOWN_FAILURE,
                            String.format("Server returned: %s", method.getStatusLine()));
                }

                this.logger.warn(String.format("Crawling of URL '%s' failed. Server returned: %s", requestUri,
                        method.getStatusLine()));
                return doc;
            }

            // getting the mimetype and charset
            Header contentTypeHeader = method.getResponseHeader(HTTPHEADER_CONTENT_TYPE);
            if (!handleContentTypeHeader(contentTypeHeader, doc))
                return doc;

            // reject the document if content-length is above our limit
            Header contentLengthHeader = method.getResponseHeader(HTTPHEADER_CONTENT_LENGTH);
            if (!handleContentLengthHeader(contentLengthHeader, doc))
                return doc;

            // FIXME: we've been redirected, re-enqueue the new URL and abort processing
            //if (!requestUri.equals(method.getURI())) ;            
        }

        /* ==============================================================================
         * HTTP GET request
         * 
         * secondly - if everything is alright up to now - proceed with getting the 
         * actual document
         * ============================================================================== */
        HttpMethod getMethod = new GetMethod(uriAsciiString); // automatically follows redirects
        method.releaseConnection();

        method = getMethod;
        this.initRequestMethod(method);

        // send the request to the server
        statusCode = this.getHttpClient().executeMethod(method);

        // check the response status code
        if (statusCode != HttpStatus.SC_OK) {
            if (statusCode == HttpStatus.SC_NOT_FOUND) {
                doc.setStatus(ICrawlerDocument.Status.NOT_FOUND);
            } else {
                doc.setStatus(ICrawlerDocument.Status.UNKNOWN_FAILURE,
                        String.format("Server returned: %s", method.getStatusLine()));
            }

            this.logger.warn(String.format("Crawling of URL '%s' failed. Server returned: %s", requestUri,
                    method.getStatusLine()));
            return doc;
        }

        // FIXME: we've been redirected, re-enqueue the new URL and abort processing
        // if (!requestUri.equals(method.getURI())) ; 

        /*
         * HTTP Content-Type
         * - getting the mimetype and charset
         */
        Header contentTypeHeader = method.getResponseHeader(HTTPHEADER_CONTENT_TYPE);
        if (!handleContentTypeHeader(contentTypeHeader, doc))
            return doc;

        /* 
         * HTTP Content-Length
         * - Reject the document if content-length is above our limit
         * 
         *   We do this a second time here because some servers may have set the content-length
         *   of the head response to <code>0</code>
         */
        Header contentLengthHeader = method.getResponseHeader(HTTPHEADER_CONTENT_LENGTH);
        if (!handleContentLengthHeader(contentLengthHeader, doc))
            return doc;

        extractHttpHeaders(method, doc); // externalised into this method to cleanup here a bit

        // getting the response body
        InputStream respBody = method.getResponseBodyAsStream();

        // handle the content-encoding, i.e. decompress the server's response
        Header contentEncodingHeader = method.getResponseHeader(HTTPHEADER_CONTENT_ENCODING);
        try {
            respBody = handleContentEncoding(contentEncodingHeader, respBody);

            /* Limit the max allowed length of the content to copy. -1 is used for no limit.
             * 
             * We need to set a limit if:
             * a) the user has configured a max-download-size AND
             * b) the server returned no content-length header
             */
            int copyLimit = (this.maxDownloadSize <= 0 || contentLengthHeader != null) ? -1
                    : this.maxDownloadSize;

            // copy the content to file
            final ICrawlerTools crawlerTools = ctx.getCrawlerTools();
            crawlerTools.saveInto(doc, respBody, lrc, copyLimit);

            doc.setStatus(ICrawlerDocument.Status.OK);
            this.logger.debug(String.format("Crawling of URL '%s' finished.", requestUri));
        } catch (IOException e) {
            String msg = e.getMessage();
            if (msg == null || !msg.equals("Corrupt GZIP trailer"))
                throw e;

            setHostSetting(method.getURI().getHost(), PREF_NO_ENCODING);
            msg = String.format("server sent a corrupt gzip trailer at URL '%s'", requestUri);
            logger.warn(msg);

            // FIXME re-enqueue command
            doc.setStatus(ICrawlerDocument.Status.UNKNOWN_FAILURE, msg);
        } finally {
            respBody.close();
        }
    } catch (NoRouteToHostException e) {
        this.logger.warn(String.format("Error crawling %s: %s", requestUri, e.getMessage()));
        doc.setStatus(ICrawlerDocument.Status.NOT_FOUND, e.getMessage());
    } catch (UnknownHostException e) {
        this.logger.warn(String.format("Error crawling %s: Unknown host.", requestUri));
        doc.setStatus(ICrawlerDocument.Status.NOT_FOUND, e.getMessage());
    } catch (ConnectException e) {
        this.logger.warn(String.format("Error crawling %s: Unable to connect to host.", requestUri));
        doc.setStatus(ICrawlerDocument.Status.NOT_FOUND, e.getMessage());
    } catch (ConnectTimeoutException e) {
        this.logger.warn(String.format("Error crawling %s: %s.", requestUri, e.getMessage()));
        doc.setStatus(ICrawlerDocument.Status.NOT_FOUND, e.getMessage());
    } catch (SocketTimeoutException e) {
        this.logger.warn(String.format("Error crawling %s: Connection timeout.", requestUri));
        doc.setStatus(ICrawlerDocument.Status.NOT_FOUND, e.getMessage());
    } catch (CircularRedirectException e) {
        this.logger.warn(String.format("Error crawling %s: %s", requestUri, e.getMessage()));
        doc.setStatus(ICrawlerDocument.Status.NOT_FOUND, e.getMessage());
    } catch (NoHttpResponseException e) {
        this.logger.warn(String.format("Error crawling %s: %s", requestUri, e.getMessage()));
        doc.setStatus(ICrawlerDocument.Status.NOT_FOUND, e.getMessage());
    } catch (ContentLengthLimitExceededException e) {
        this.logger.warn(String.format("Error crawling %s: %s", requestUri, e.getMessage()));
        doc.setStatus(ICrawlerDocument.Status.UNKNOWN_FAILURE, e.getMessage());
    } catch (Throwable e) {
        String errorMsg;
        if (e instanceof HttpException) {
            errorMsg = "Unrecovered protocol exception: [%s] %s";
        } else if (e instanceof IOException) {
            errorMsg = "Transport exceptions: [%s] %s";
        } else {
            errorMsg = "Unexpected exception: [%s] %s";
        }
        errorMsg = String.format(errorMsg, e.getClass().getName(), e.getMessage());

        this.logger.error(String.format("Error crawling %s: %s", requestUri, errorMsg));
        doc.setStatus(ICrawlerDocument.Status.UNKNOWN_FAILURE, errorMsg);
        e.printStackTrace();
    } finally {
        if (method != null)
            method.releaseConnection();
    }

    return doc;
}

From source file:org.paxle.crawler.http.impl.HttpCrawler.java

private static void extractHttpHeaders(final HttpMethod method, final ICrawlerDocument doc) throws IOException {
    // getting the document languages
    Header contentLanguageHeader = method.getResponseHeader(HTTPHEADER_CONTENT_LANGUAGE);
    if (contentLanguageHeader != null) {
        String contentLanguage = contentLanguageHeader.getValue();
        String[] languages = contentLanguage.split(",");
        doc.setLanguages(languages);/*from   w w  w  .jav a2 s .co  m*/
    }

    // crawling Date
    Date crawlingDate = null;
    Header crawlingDateHeader = method.getResponseHeader(HTTPHEADER_DATE);
    if (crawlingDateHeader == null) {
        crawlingDate = new Date();
    } else
        try {
            String dateStr = crawlingDateHeader.getValue();
            crawlingDate = DateUtil.parseDate(dateStr);
        } catch (DateParseException e) {
            crawlingDate = new Date();
        }
    doc.setCrawlerDate(crawlingDate);

    // last mod date
    Date lastModDate = null;
    Header lastModDateHeader = method.getResponseHeader(HTTPHEADER_LAST_MODIFIED);
    if (lastModDateHeader != null)
        try {
            String dateStr = lastModDateHeader.getValue();
            lastModDate = DateUtil.parseDate(dateStr);
        } catch (DateParseException e) {
            lastModDate = crawlingDate;
        }
    doc.setLastModDate(lastModDate);

    // ETAG
    // XXX: this is protocol specific. How to store this in a generic crawler-document?
    //      Header etageHeader = method.getResponseHeader(HTTPHEADER_ETAG);
    //      if (etageHeader != null) {
    //         String etag = etageHeader.getValue();
    //         doc.setEtag(etag);
    //      }
}

From source file:org.paxle.filter.robots.impl.RobotsTxtManager.java

/**
 * Downloads a <i>robots.txt</i> file from the given url and parses it
 * @param robotsUrlStr the URL to the robots.txt. This must be a http(s) resource
 * @return the parsed robots.txt file as a {@link RobotsTxt}-object
 * @throws IOException/*from  ww w.  j a  va2s  . co  m*/
 * @throws URISyntaxException 
 */
RobotsTxt getFromWeb(URI robotsURL) throws IOException, URISyntaxException {
    String hostPort = this.getHostPort(robotsURL);

    String statusLine = null;
    if (!robotsURL.getScheme().startsWith("http")) {
        throw new IOException(String.format("Unsupported protocol: %s", robotsURL.getScheme()));
    }

    InputStream inputStream = null;
    HttpMethod getMethod = null;
    try {
        getMethod = new GetMethod(robotsURL.toASCIIString());
        int code = this.httpClient.executeMethod(getMethod);
        statusLine = getMethod.getStatusLine().toString();

        if (code == HttpStatus.SC_UNAUTHORIZED || code == HttpStatus.SC_FORBIDDEN) {
            // access to the whole website is restricted
            return new RobotsTxt(hostPort, RobotsTxt.RELOAD_INTERVAL_DEFAULT, statusLine, true);
        } else if (code == HttpStatus.SC_NOT_FOUND) {
            // no robots.txt provided
            return new RobotsTxt(hostPort, RobotsTxt.RELOAD_INTERVAL_DEFAULT, statusLine);
        } else if (code != HttpStatus.SC_OK) {
            // the robots.txt seems not to be deliverable
            return new RobotsTxt(hostPort, RobotsTxt.RELOAD_INTERVAL_DEFAULT, statusLine);
        }

        Header contentTypeHeader = getMethod.getResponseHeader("Content-Type");
        if (contentTypeHeader != null && !contentTypeHeader.getValue().startsWith("text/plain")) {
            // the robots.txt seems not to be available
            return new RobotsTxt(hostPort, RobotsTxt.RELOAD_INTERVAL_ERROR,
                    "Wrong mimeType " + contentTypeHeader.getValue());
        }

        inputStream = getMethod.getResponseBodyAsStream();
        RobotsTxt robotsTxt = new RobotsTxt(hostPort, RobotsTxt.RELOAD_INTERVAL_DEFAULT, statusLine);
        return this.parseRobotsTxt(robotsTxt, inputStream);
    } catch (IOException e) {
        long reloadInterval = RobotsTxt.RELOAD_INTERVAL_TEMP_ERROR;
        String status = e.getMessage();

        if (e instanceof UnknownHostException) {
            reloadInterval = RobotsTxt.RELOAD_INTERVAL_ERROR;
            status = "Unknown host";
            logger.info(String.format("Unknown host '%s'.", robotsURL.getHost()));
        } else if (e instanceof CircularRedirectException || e instanceof RedirectException
                || e instanceof InvalidRedirectLocationException) {
            reloadInterval = RobotsTxt.RELOAD_INTERVAL_ERROR;
            logger.info(String.format("Invalid redirection on host '%s'.", hostPort));
        } else if (e instanceof SocketTimeoutException || e instanceof ConnectTimeoutException
                || e instanceof NoHttpResponseException) {
            logger.debug(String.format("TimeOut while loading robots.txt from host '%s'.", hostPort));
        } else if (!(e instanceof ConnectException || e instanceof SocketException)) {
            logger.error("Exception while loading robots.txt from " + hostPort, e);
        }

        return new RobotsTxt(hostPort, reloadInterval, status);
    } catch (IllegalArgumentException e) {
        // occurs if redirected to an invalid URI, see https://bugs.pxl.li/view.php?id=172
        // we treat it like a 404, see above
        logger.info(String.format("Invalid redirection URI on host '%s'.", hostPort));
        return new RobotsTxt(hostPort, RobotsTxt.RELOAD_INTERVAL_DEFAULT, "Redirected to illegal URI");
    } catch (IllegalStateException e) {
        // occurs if redirected to an URI with an invalid protocol, see https://bugs.pxl.li/view.php?id=169
        // we treat it like a 404, see above
        logger.info(String.format("Invalid redirection URI on host '%s'.", hostPort));
        return new RobotsTxt(hostPort, RobotsTxt.RELOAD_INTERVAL_DEFAULT, "Redirected to illegal URI");

    } finally {
        if (inputStream != null)
            try {
                inputStream.close();
            } catch (Exception e) {
                this.logger.error(e);
            }
        if (getMethod != null)
            getMethod.releaseConnection();
    }
}

From source file:org.pentaho.di.baserver.utils.web.HttpConnectionHelper.java

public Response callHttp(String url, Map<String, String> queryParameters, String httpMethod, String user,
        String password) throws IOException, KettleStepException {

    // used for calculating the responseTime
    long startTime = System.currentTimeMillis();

    HttpClient httpclient = getHttpClient();
    HttpMethod method = getHttpMethod(url, queryParameters, httpMethod);
    httpclient.getParams().setAuthenticationPreemptive(true);
    Credentials credentials = getCredentials(user, password);
    httpclient.getState().setCredentials(AuthScope.ANY, credentials);
    HostConfiguration hostConfiguration = new HostConfiguration();

    int status;/*from w w w . j a  v  a2 s  .c om*/
    try {
        status = httpclient.executeMethod(hostConfiguration, method);
    } catch (IllegalArgumentException ex) {
        status = -1;
    }

    Response response = new Response();
    if (status != -1) {
        String body;
        String encoding = "";
        Header contentTypeHeader = method.getResponseHeader("Content-Type");
        if (contentTypeHeader != null) {
            String contentType = contentTypeHeader.getValue();
            if (contentType != null && contentType.contains("charset")) {
                encoding = contentType.replaceFirst("^.*;\\s*charset\\s*=\\s*", "").replace("\"", "").trim();
            }
        }

        // get the response
        body = getContent(method, encoding);
        // Get response time
        long responseTime = System.currentTimeMillis() - startTime;

        response.setStatusCode(status);
        response.setResult(body);
        response.setResponseTime(responseTime);
    }
    return response;
}

From source file:org.pentaho.di.trans.steps.http.HTTP.java

private Object[] callHttpService(RowMetaInterface rowMeta, Object[] rowData) throws KettleException {
    String url = determineUrl(rowMeta, rowData);
    try {//from   w  w  w.  j  a  va 2  s.c  o  m
        if (isDetailed()) {
            logDetailed(BaseMessages.getString(PKG, "HTTP.Log.Connecting", url));
        }

        // Prepare HTTP get
        //
        HttpClient httpclient = SlaveConnectionManager.getInstance().createHttpClient();
        HttpMethod method = new GetMethod(url);

        // Set timeout
        if (data.realConnectionTimeout > -1) {
            httpclient.getHttpConnectionManager().getParams().setConnectionTimeout(data.realConnectionTimeout);
        }
        if (data.realSocketTimeout > -1) {
            httpclient.getHttpConnectionManager().getParams().setSoTimeout(data.realSocketTimeout);
        }

        if (!Const.isEmpty(data.realHttpLogin)) {
            httpclient.getParams().setAuthenticationPreemptive(true);
            Credentials defaultcreds = new UsernamePasswordCredentials(data.realHttpLogin,
                    data.realHttpPassword);
            httpclient.getState().setCredentials(AuthScope.ANY, defaultcreds);
        }

        HostConfiguration hostConfiguration = new HostConfiguration();
        if (!Const.isEmpty(data.realProxyHost)) {
            hostConfiguration.setProxy(data.realProxyHost, data.realProxyPort);
        }

        // Add Custom HTTP headers
        if (data.useHeaderParameters) {
            for (int i = 0; i < data.header_parameters_nrs.length; i++) {
                method.addRequestHeader(data.headerParameters[i].getName(),
                        data.inputRowMeta.getString(rowData, data.header_parameters_nrs[i]));
                if (isDebug()) {
                    log.logDebug(BaseMessages.getString(PKG, "HTTPDialog.Log.HeaderValue",
                            data.headerParameters[i].getName(),
                            data.inputRowMeta.getString(rowData, data.header_parameters_nrs[i])));
                }
            }
        }

        InputStreamReader inputStreamReader = null;
        Object[] newRow = null;
        if (rowData != null) {
            newRow = rowData.clone();
        }
        // Execute request
        //
        try {
            // used for calculating the responseTime
            long startTime = System.currentTimeMillis();

            int statusCode = httpclient.executeMethod(hostConfiguration, method);

            // calculate the responseTime
            long responseTime = System.currentTimeMillis() - startTime;
            if (log.isDetailed()) {
                log.logDetailed(BaseMessages.getString(PKG, "HTTP.Log.ResponseTime", responseTime, url));
            }

            String body = null;
            // The status code
            if (isDebug()) {
                logDebug(BaseMessages.getString(PKG, "HTTP.Log.ResponseStatusCode", "" + statusCode));
            }

            if (statusCode != -1) {
                if (statusCode == 204) {
                    body = "";
                } else {
                    // if the response is not 401: HTTP Authentication required
                    if (statusCode != 401) {
                        // guess encoding
                        //
                        String encoding = meta.getEncoding();

                        // Try to determine the encoding from the Content-Type value
                        //
                        if (Const.isEmpty(encoding)) {
                            String contentType = method.getResponseHeader("Content-Type").getValue();
                            if (contentType != null && contentType.contains("charset")) {
                                encoding = contentType.replaceFirst("^.*;\\s*charset\\s*=\\s*", "")
                                        .replace("\"", "").trim();
                            }
                        }

                        if (isDebug()) {
                            log.logDebug(toString(),
                                    BaseMessages.getString(PKG, "HTTP.Log.ResponseHeaderEncoding", encoding));
                        }

                        // the response
                        if (!Const.isEmpty(encoding)) {
                            inputStreamReader = new InputStreamReader(method.getResponseBodyAsStream(),
                                    encoding);
                        } else {
                            inputStreamReader = new InputStreamReader(method.getResponseBodyAsStream());
                        }
                        StringBuffer bodyBuffer = new StringBuffer();

                        int c;
                        while ((c = inputStreamReader.read()) != -1) {
                            bodyBuffer.append((char) c);
                        }

                        inputStreamReader.close();

                        body = bodyBuffer.toString();
                        if (isDebug()) {
                            logDebug("Response body: " + body);
                        }

                    } else { // the status is a 401
                        throw new KettleStepException(
                                BaseMessages.getString(PKG, "HTTP.Exception.Authentication", data.realUrl));

                    }
                }
            }

            int returnFieldsOffset = rowMeta.size();
            if (!Const.isEmpty(meta.getFieldName())) {
                newRow = RowDataUtil.addValueData(newRow, returnFieldsOffset, body);
                returnFieldsOffset++;
            }

            if (!Const.isEmpty(meta.getResultCodeFieldName())) {
                newRow = RowDataUtil.addValueData(newRow, returnFieldsOffset, new Long(statusCode));
                returnFieldsOffset++;
            }
            if (!Const.isEmpty(meta.getResponseTimeFieldName())) {
                newRow = RowDataUtil.addValueData(newRow, returnFieldsOffset, new Long(responseTime));
            }

        } finally {
            if (inputStreamReader != null) {
                inputStreamReader.close();
            }
            // Release current connection to the connection pool once you are done
            method.releaseConnection();
            if (data.realcloseIdleConnectionsTime > -1) {
                httpclient.getHttpConnectionManager().closeIdleConnections(data.realcloseIdleConnectionsTime);
            }
        }
        return newRow;
    } catch (UnknownHostException uhe) {
        throw new KettleException(
                BaseMessages.getString(PKG, "HTTP.Error.UnknownHostException", uhe.getMessage()));
    } catch (Exception e) {
        throw new KettleException(BaseMessages.getString(PKG, "HTTP.Log.UnableGetResult", url), e);
    }
}

From source file:org.pentaho.platform.web.servlet.ProxyServlet.java

void setHeader(final String headerStr, final HttpMethod method, final HttpServletResponse response) {
    Header header = method.getResponseHeader(headerStr);
    if (header != null) {
        response.setHeader(headerStr, header.getValue());
    }/*from ww  w . j  a  v a2  s  .co m*/
}

From source file:org.sakaiproject.kernel.proxy.ProxyClientServiceImpl.java

/**
 * 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.
 * /*from  w w w. java 2  s .  c om*/
 * <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
 */
public ProxyResponse executeCall(Node node, Map<String, String> headers, Map<String, String> input,
        InputStream requestInputStream, long requestContentLength, String requestContentType)
        throws ProxyClientException {
    try {
        bindNode(node);

        if (node != null && node.hasProperty(SAKAI_REQUEST_PROXY_ENDPOINT)) {

            VelocityContext context = new VelocityContext(input);

            // setup the post request
            String endpointURL = JcrUtils.getMultiValueString(node.getProperty(SAKAI_REQUEST_PROXY_ENDPOINT));
            Reader urlTemplateReader = new StringReader(endpointURL);
            StringWriter urlWriter = new StringWriter();
            velocityEngine.evaluate(context, urlWriter, "urlprocessing", urlTemplateReader);
            endpointURL = urlWriter.toString();

            ProxyMethod proxyMethod = ProxyMethod.GET;
            if (node.hasProperty(SAKAI_REQUEST_PROXY_METHOD)) {
                try {
                    proxyMethod = ProxyMethod.valueOf(node.getProperty(SAKAI_REQUEST_PROXY_METHOD).getString());
                } catch (Exception e) {

                }
            }
            HttpMethod method = null;
            switch (proxyMethod) {
            case GET:
                method = new GetMethod(endpointURL);
                // redirects work automatically for get, options and head, but not for put and
                // post
                method.setFollowRedirects(true);
                break;
            case HEAD:
                method = new HeadMethod(endpointURL);
                // redirects work automatically for get, options and head, but not for put and
                // post
                method.setFollowRedirects(true);
                break;
            case OPTIONS:
                method = new OptionsMethod(endpointURL);
                // redirects work automatically for get, options and head, but not for put and
                // post
                method.setFollowRedirects(true);
                break;
            case POST:
                method = new PostMethod(endpointURL);
                break;
            case PUT:
                method = new PutMethod(endpointURL);
                break;
            default:
                method = new GetMethod(endpointURL);
                // redirects work automatically for get, options and head, but not for put and
                // post
                method.setFollowRedirects(true);

            }
            // follow redirects, but dont auto process 401's and the like.
            // credentials should be provided
            method.setDoAuthentication(false);

            for (Entry<String, String> header : headers.entrySet()) {
                method.addRequestHeader(header.getKey(), header.getValue());
            }

            Value[] additionalHeaders = JcrUtils.getValues(node, SAKAI_PROXY_HEADER);
            for (Value v : additionalHeaders) {
                String header = v.getString();
                String[] keyVal = StringUtils.split(header, ':', 2);
                method.addRequestHeader(keyVal[0].trim(), keyVal[1].trim());
            }

            if (method instanceof EntityEnclosingMethod) {
                String contentType = requestContentType;
                if (contentType == null && node.hasProperty(SAKAI_REQUEST_CONTENT_TYPE)) {
                    contentType = node.getProperty(SAKAI_REQUEST_CONTENT_TYPE).getString();

                }
                if (contentType == null) {
                    contentType = APPLICATION_OCTET_STREAM;
                }
                EntityEnclosingMethod eemethod = (EntityEnclosingMethod) method;
                if (requestInputStream != null) {
                    eemethod.setRequestEntity(new InputStreamRequestEntity(requestInputStream,
                            requestContentLength, contentType));
                } else {
                    // build the request
                    Template template = velocityEngine.getTemplate(node.getPath());
                    StringWriter body = new StringWriter();
                    template.merge(context, body);
                    byte[] soapBodyContent = body.toString().getBytes("UTF-8");
                    eemethod.setRequestEntity(new ByteArrayRequestEntity(soapBodyContent, contentType));

                }
            }

            int result = httpClient.executeMethod(method);
            if (result == 302 && method instanceof EntityEnclosingMethod) {
                // handle redirects on post and put
                String url = method.getResponseHeader("Location").getValue();
                method = new GetMethod(url);
                method.setFollowRedirects(true);
                method.setDoAuthentication(false);
                result = httpClient.executeMethod(method);
            }

            return new ProxyResponseImpl(result, method);
        }

    } catch (Exception e) {
        throw new ProxyClientException("The Proxy request specified by  " + node + " failed, cause follows:",
                e);
    } finally {
        unbindNode();
    }
    throw new ProxyClientException(
            "The Proxy request specified by " + node + " does not contain a valid endpoint specification ");
}