You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ode.apache.org by mi...@apache.org on 2008/07/14 20:41:14 UTC

svn commit: r676678 - in /ode/branches/APACHE_ODE_1.X/axis2/src/main/java/org/apache/ode/axis2/httpbinding: HttpExternalService.java HttpHelper.java HttpMethodConverter.java

Author: midon
Date: Mon Jul 14 11:41:14 2008
New Revision: 676678

URL: http://svn.apache.org/viewvc?rev=676678&view=rev
Log:
rename HttpClientHelper into HttpHelper

Added:
    ode/branches/APACHE_ODE_1.X/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpHelper.java
Modified:
    ode/branches/APACHE_ODE_1.X/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpExternalService.java
    ode/branches/APACHE_ODE_1.X/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpMethodConverter.java

Modified: ode/branches/APACHE_ODE_1.X/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpExternalService.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpExternalService.java?rev=676678&r1=676677&r2=676678&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpExternalService.java (original)
+++ ode/branches/APACHE_ODE_1.X/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpExternalService.java Mon Jul 14 11:41:14 2008
@@ -154,7 +154,7 @@
             client.getParams().setDefaults(params);
 
             // configure the client (proxy, security, etc)
-            HttpClientHelper.configure(client.getHostConfiguration(), client.getState(), method.getURI(), params);
+            HttpHelper.configure(client.getHostConfiguration(), client.getState(), method.getURI(), params);
 
             // this callable encapsulates the http method execution and the process of the response
             final Callable executionCallable;
@@ -298,7 +298,7 @@
             PartnerRoleMessageExchange odeMex = (PartnerRoleMessageExchange) server.getEngine().getMessageExchange(mexId);
             String errmsg = "Unmanaged Status Code! Status-Line: " + method.getStatusLine()+ " for "+ method.getURI();
             log.error(errmsg);
-            odeMex.replyWithFailure(MessageExchange.FailureType.OTHER, errmsg, HttpClientHelper.prepareDetailsElement(method));
+            odeMex.replyWithFailure(MessageExchange.FailureType.OTHER, errmsg, HttpHelper.prepareDetailsElement(method));
         }
 
         /**
@@ -316,15 +316,15 @@
             if (opDef.getFaults().isEmpty()) {
                 errmsg = "Operation [" + opDef.getName() + "] has no fault. This 500 error will be considered as a failure.";
                 log.error(errmsg);
-                odeMex.replyWithFailure(MessageExchange.FailureType.OTHER, errmsg, HttpClientHelper.prepareDetailsElement(method));
+                odeMex.replyWithFailure(MessageExchange.FailureType.OTHER, errmsg, HttpHelper.prepareDetailsElement(method));
             } else if (opBinding.getBindingFaults().isEmpty()) {
                 errmsg = "No fault binding. This 500 error will be considered as a failure.";
                 log.error(errmsg);
-                odeMex.replyWithFailure(MessageExchange.FailureType.OTHER, errmsg, HttpClientHelper.prepareDetailsElement(method));
+                odeMex.replyWithFailure(MessageExchange.FailureType.OTHER, errmsg, HttpHelper.prepareDetailsElement(method));
             } else if (StringUtils.isEmpty(body)) {
                 errmsg = "No body in the response. This 500 error will be considered as a failure.";
                 log.error(errmsg);
-                odeMex.replyWithFailure(MessageExchange.FailureType.OTHER, errmsg, HttpClientHelper.prepareDetailsElement(method));
+                odeMex.replyWithFailure(MessageExchange.FailureType.OTHER, errmsg, HttpHelper.prepareDetailsElement(method));
             } else {
                 try {
                     Element bodyEl = DOMUtils.stringToDOM(body);
@@ -334,12 +334,12 @@
                     if (faultDef == null) {
                         errmsg = "Unknown Fault Type [" + bodyName + "] This 500 error will be considered as a failure.";
                         log.error(errmsg);
-                        odeMex.replyWithFailure(MessageExchange.FailureType.OTHER, errmsg, HttpClientHelper.prepareDetailsElement(method));
+                        odeMex.replyWithFailure(MessageExchange.FailureType.OTHER, errmsg, HttpHelper.prepareDetailsElement(method));
                     } else if (!WsdlUtils.isOdeFault(opBinding.getBindingFault(faultDef.getName()))) {
                         // is this fault bound with ODE extension?
                         errmsg = "Fault [" + bodyName + "] is not bound with " + new QName(Namespaces.ODE_HTTP_EXTENSION_NS, "fault") + ". This 500 error will be considered as a failure.";
                         log.error(errmsg);
-                        odeMex.replyWithFailure(MessageExchange.FailureType.OTHER, errmsg, HttpClientHelper.prepareDetailsElement(method));
+                        odeMex.replyWithFailure(MessageExchange.FailureType.OTHER, errmsg, HttpHelper.prepareDetailsElement(method));
                     } else {
                         // a fault must have only one part
                         Part partDef = (Part) faultDef.getMessage().getParts().values().iterator().next();
@@ -368,7 +368,7 @@
                 } catch (Exception e) {
                     errmsg = "Unable to parse the response body as xml. This 500 error will be considered as a failure.";
                     log.error(errmsg, e);
-                    odeMex.replyWithFailure(MessageExchange.FailureType.OTHER, errmsg, HttpClientHelper.prepareDetailsElement(method, false));
+                    odeMex.replyWithFailure(MessageExchange.FailureType.OTHER, errmsg, HttpHelper.prepareDetailsElement(method, false));
                 }
             }
 
@@ -438,7 +438,7 @@
                     } catch (Exception ex) {
                         String errmsg = "Unable to process response: " + ex.getMessage();
                         log.error(errmsg, ex);
-                        odeMex.replyWithFailure(MessageExchange.FailureType.OTHER, errmsg, HttpClientHelper.prepareDetailsElement(method));
+                        odeMex.replyWithFailure(MessageExchange.FailureType.OTHER, errmsg, HttpHelper.prepareDetailsElement(method));
                     }
                 }
             } catch (IOException e) {

Added: ode/branches/APACHE_ODE_1.X/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpHelper.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpHelper.java?rev=676678&view=auto
==============================================================================
--- ode/branches/APACHE_ODE_1.X/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpHelper.java (added)
+++ ode/branches/APACHE_ODE_1.X/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpHelper.java Mon Jul 14 11:41:14 2008
@@ -0,0 +1,198 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ode.axis2.httpbinding;
+
+import org.apache.axis2.transport.http.HttpTransportProperties;
+import org.apache.commons.httpclient.HostConfiguration;
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.HttpState;
+import org.apache.commons.httpclient.URI;
+import org.apache.commons.httpclient.URIException;
+import org.apache.commons.httpclient.StatusLine;
+import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.params.HttpParams;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.lang.StringUtils;
+import org.apache.ode.axis2.Properties;
+import org.apache.ode.utils.DOMUtils;
+import org.w3c.dom.Element;
+import org.w3c.dom.Document;
+
+import java.io.IOException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class HttpHelper {
+
+    private static final Log log = LogFactory.getLog(HttpHelper.class);
+
+    public static void configure(HostConfiguration hostConfig, HttpState state, URI targetURI, HttpParams params) throws URIException {
+        if (log.isDebugEnabled()) log.debug("Configuring http client...");
+        // proxy configuration
+        if (ProxyConf.isProxyEnabled(params, targetURI.getHost())) {
+            if (log.isDebugEnabled()) log.debug("ProxyConf");
+            ProxyConf.configure(hostConfig, state, (HttpTransportProperties.ProxyProperties) params.getParameter(Properties.PROP_HTTP_PROXY_PREFIX));
+        }
+
+        // security
+        // ...
+
+    }
+
+    /**
+     * Parse and convert a HTTP status line into an aml element.
+     *
+     * @param statusLine
+     * @return
+     * @throws HttpException
+     * @see #statusLineToElement(org.w3c.dom.Document, org.apache.commons.httpclient.StatusLine)
+     */
+    public static Element statusLineToElement(String statusLine) throws HttpException {
+        return statusLineToElement(new StatusLine(statusLine));
+    }
+
+    public static Element statusLineToElement(StatusLine statusLine) {
+        return statusLineToElement(DOMUtils.newDocument(), statusLine);
+    }
+
+    /**
+     * Convert a <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1">HTTP status line</a> into an xml element like this:
+     * <p/>
+     * < Status-line>
+     * < HTTP-Version>HTTP/1.1< /HTTP-Version>
+     * < Status-Code>200< /Status-Code>
+     * < Reason-Phrase>Success - The action was successfully received, understood, and accepted< /Reason-Phrase>
+     * < /Status-line></br>
+     *
+     * @param statusLine - the {@link org.apache.commons.httpclient.StatusLine} instance to be converted
+     * @param doc        - the document to use to create new nodes
+     * @return an Element
+     */
+    public static Element statusLineToElement(Document doc, StatusLine statusLine) {
+        Element statusLineEl = doc.createElementNS(null, "Status-Line");
+        Element versionEl = doc.createElementNS(null, "HTTP-Version");
+        Element codeEl = doc.createElementNS(null, "Status-Code");
+        Element reasonEl = doc.createElementNS(null, "Reason-Phrase");
+        Element originalEl = doc.createElementNS(null, "original");
+
+        // wiring
+        doc.appendChild(statusLineEl);
+        statusLineEl.appendChild(versionEl);
+        statusLineEl.appendChild(codeEl);
+        statusLineEl.appendChild(reasonEl);
+        statusLineEl.appendChild(originalEl);
+
+        // values
+        versionEl.setTextContent(statusLine.getHttpVersion());
+        codeEl.setTextContent(String.valueOf(statusLine.getStatusCode()));
+        reasonEl.setTextContent(statusLine.getReasonPhrase());
+        // the line as received, not parsed
+        originalEl.setTextContent(statusLine.toString());
+
+        return statusLineEl;
+    }
+
+    /**
+     * Build a "details" element that looks like this:
+     *
+     * @param method
+     * @return
+     * @throws IOException
+     */
+    public static Element prepareDetailsElement(HttpMethod method) throws IOException {
+        return prepareDetailsElement(method, true);
+    }
+
+    /**
+     * @param method
+     * @param bodyIsXml if true the body will be parsed as xml else the body will be inserted as string
+     * @return
+     * @throws IOException
+     */
+    public static Element prepareDetailsElement(HttpMethod method, boolean bodyIsXml) throws IOException {
+        Document doc = DOMUtils.newDocument();
+        Element detailsEl = doc.createElementNS(null, "details");
+        Element statusLineEl = statusLineToElement(doc, method.getStatusLine());
+        detailsEl.appendChild(statusLineEl);
+
+        // set the body if any
+        final String body = method.getResponseBodyAsString();
+        if (StringUtils.isNotEmpty(body)) {
+            Element bodyEl = doc.createElementNS(null, "responseBody");
+            detailsEl.appendChild(bodyEl);
+            // first, try to parse the body as xml
+            // if it fails, put it as string in the body element
+            boolean exceptionDuringParsing = false;
+            if (bodyIsXml) {
+                try {
+                    Element parsedBodyEl = DOMUtils.stringToDOM(body);
+                    bodyEl.appendChild(doc.importNode(parsedBodyEl, true));
+                } catch (Exception e) {
+                    String errmsg = "Unable to parse the response body as xml. Body will be inserted as string.";
+                    if (log.isDebugEnabled()) log.debug(errmsg, e);
+                    exceptionDuringParsing = true;
+                }
+            }
+            if (!bodyIsXml || exceptionDuringParsing) {
+                bodyEl.setTextContent(method.getResponseBodyAsString());
+            }
+        }
+        return detailsEl;
+    }
+
+    private static final Pattern NON_LWS_PATTERN = Pattern.compile("\r\n([^\\s])");
+
+    /**
+     *
+     * This method ensures that a header value containing CRLF does not mess up the HTTP request.
+     * Actually CRLF is the end-of-line marker for headers.
+     * <p/>
+     * To do so, all CRLF followed by a non-whitespace character are replaced by CRLF HT.
+     * <p/>
+     * This is possible because the
+     *  <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2">Section 2.2</a> of HTTP standard (RFC2626) states that:
+     * <p/>
+     * <quote>
+     * HTTP/1.1 header field values can be folded onto multiple lines if the
+     * continuation line begins with a space or horizontal tab. All linear
+     * white space, including folding, has the same semantics as SP. A
+     * recipient MAY replace any linear white space with a single SP before
+     * interpreting the field value or forwarding the message downstream.
+     * <p/>
+     * LWS            = [CRLF] 1*( SP | HT )
+     * <p/>
+     * </quote>
+     *<p/>
+     * FYI, HttpClient 3.x.x does not check this.
+     * @param header
+     * @return the string properly ready to be used as an HTTP header field-content
+     */
+    public static String replaceCRLFwithLWS(String header) {
+        Matcher m = NON_LWS_PATTERN.matcher(header);
+        StringBuffer sb = new StringBuffer(header.length());
+        while (m.find()) {
+            m.appendReplacement(sb, "\r\n\t");
+            sb.append(m.group(1));
+        }
+        m.appendTail(sb);
+        return sb.toString();
+    }
+}

Modified: ode/branches/APACHE_ODE_1.X/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpMethodConverter.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpMethodConverter.java?rev=676678&r1=676677&r2=676678&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpMethodConverter.java (original)
+++ ode/branches/APACHE_ODE_1.X/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpMethodConverter.java Mon Jul 14 11:41:14 2008
@@ -251,7 +251,7 @@
                 if (log.isErrorEnabled()) log.error(errMsg);
                 throw new RuntimeException(errMsg);
             }
-            method.setRequestHeader(headerName, HttpClientHelper.replaceCRLFwithLWS(headerValue));
+            method.setRequestHeader(headerName, HttpHelper.replaceCRLFwithLWS(headerValue));
         }
 
         // process message headers
@@ -262,7 +262,7 @@
             // set the request header but do not override any part value
             if (method.getRequestHeader(headerName) == null) {
                 String headerValue = DOMUtils.domToString(headerNode);
-                method.setRequestHeader(headerName, HttpClientHelper.replaceCRLFwithLWS(headerValue));
+                method.setRequestHeader(headerName, HttpHelper.replaceCRLFwithLWS(headerValue));
             }
         }
 
@@ -379,7 +379,7 @@
         }
 
         // make the status line information available as a single element
-        odeMessage.setHeaderPart("Status-Line", HttpClientHelper.statusLineToElement(method.getStatusLine()));
+        odeMessage.setHeaderPart("Status-Line", HttpHelper.statusLineToElement(method.getStatusLine()));
     }