Author: veithen
Date: Tue Feb  3 13:44:07 2009
New Revision: 740303

URL: http://svn.apache.org/viewvc?rev=740303&view=rev
Log:
AXIS2-4229: Parse URL query strings more carefully when looking for wsdl, 
wsdl2, xsd and policy parameters. Also added a reusable query string parser 
that will be useful in other places.

Added:
    
webservices/commons/trunk/modules/transport/modules/base/src/main/java/org/apache/axis2/transport/base/QueryStringParser.java
   (with props)
    
webservices/commons/trunk/modules/transport/modules/base/src/test/java/org/apache/axis2/transport/
    
webservices/commons/trunk/modules/transport/modules/base/src/test/java/org/apache/axis2/transport/base/
    
webservices/commons/trunk/modules/transport/modules/base/src/test/java/org/apache/axis2/transport/base/QueryStringParserTest.java
   (with props)
Modified:
    
webservices/commons/trunk/modules/transport/modules/http/src/org/apache/axis2/transport/http/AxisServlet.java

Added: 
webservices/commons/trunk/modules/transport/modules/base/src/main/java/org/apache/axis2/transport/base/QueryStringParser.java
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/transport/modules/base/src/main/java/org/apache/axis2/transport/base/QueryStringParser.java?rev=740303&view=auto
==============================================================================
--- 
webservices/commons/trunk/modules/transport/modules/base/src/main/java/org/apache/axis2/transport/base/QueryStringParser.java
 (added)
+++ 
webservices/commons/trunk/modules/transport/modules/base/src/main/java/org/apache/axis2/transport/base/QueryStringParser.java
 Tue Feb  3 13:44:07 2009
@@ -0,0 +1,131 @@
+/*
+ *  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.axis2.transport.base;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Collection;
+
+import org.apache.axis2.transport.http.util.URIEncoderDecoder;
+
+/**
+ * Parser for URL query strings.
+ */
+// TODO: maybe this class should go to Axis2 and be reused in 
XFormURLEncodedBuilder
+public class QueryStringParser {
+    private final String queryString;
+    
+    /**
+     * The position of the current parameter.
+     */
+    private int paramBegin;
+    private int paramEnd;
+    private int paramNameEnd;
+    private String paramName;
+    private String paramValue;
+
+    /**
+     * Construct a parser from the given URL query string.
+     * 
+     * @param queryString the query string, i.e. the part of the URL starting
+     *                    after the '?' character
+     */
+    public QueryStringParser(String queryString) {
+        this.queryString = queryString;
+    }
+    
+    /**
+     * Move to the next parameter in the query string.
+     * 
+     * @return <code>true</code> if a parameter has been found; 
+     * <code>false</code> if there are no more parameters
+     */
+    public boolean next() {
+        int len = queryString.length();
+        if (paramEnd == len) {
+            return false;
+        }
+        paramBegin = paramEnd == 0 ? 0 : paramEnd+1;
+        int idx = queryString.indexOf('&', paramBegin);
+        paramEnd = idx == -1 ? len : idx;
+        idx = queryString.indexOf('=', paramBegin);
+        paramNameEnd = idx == -1 || idx > paramEnd ? paramEnd : idx;
+        paramName = null;
+        paramValue = null;
+        return true;
+    }
+    
+    /**
+     * Search for a parameter with a name in a given collection.
+     * This method iterates over the parameters until a parameter with
+     * a matching name has been found. Note that the current parameter is not
+     * considered.
+     * 
+     * @param names
+     * @return
+     */
+    public boolean search(Collection<String> names) {
+        while (next()) {
+            if (names.contains(getName())) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    /**
+     * Get the name of the current parameter.
+     * Calling this method is only allowed if {...@link #next()} has been 
called
+     * previously and the result of this call was <code>true</code>. Otherwise 
the
+     * result of this method is undefined.
+     * 
+     * @return the name of the current parameter
+     */
+    public String getName() {
+        if (paramName == null) {
+            paramName = queryString.substring(paramBegin, paramNameEnd);
+        }
+        return paramName;
+    }
+    
+    /**
+     * Get the value of the current parameter.
+     * Calling this method is only allowed if {...@link #next()} has been 
called
+     * previously and the result of this call was <code>true</code>. Otherwise 
the
+     * result of this method is undefined.
+     * 
+     * @return the decoded value of the current parameter
+     */
+    public String getValue() {
+        if (paramValue == null) {
+            if (paramNameEnd == paramEnd) {
+                return null;
+            }
+            try {
+                paramValue = 
URIEncoderDecoder.decode(queryString.substring(paramNameEnd+1, paramEnd));
+            } catch (UnsupportedEncodingException ex) {
+                // TODO: URIEncoderDecoder.decode should be changed to not 
throw
+                // UnsupportedEncodingException since this actually never 
happens (the charset
+                // being looked up is UTF-8 which always exists).
+                throw new Error(ex);
+            }
+        }
+        return paramValue;
+    }
+}

Propchange: 
webservices/commons/trunk/modules/transport/modules/base/src/main/java/org/apache/axis2/transport/base/QueryStringParser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
webservices/commons/trunk/modules/transport/modules/base/src/test/java/org/apache/axis2/transport/base/QueryStringParserTest.java
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/transport/modules/base/src/test/java/org/apache/axis2/transport/base/QueryStringParserTest.java?rev=740303&view=auto
==============================================================================
--- 
webservices/commons/trunk/modules/transport/modules/base/src/test/java/org/apache/axis2/transport/base/QueryStringParserTest.java
 (added)
+++ 
webservices/commons/trunk/modules/transport/modules/base/src/test/java/org/apache/axis2/transport/base/QueryStringParserTest.java
 Tue Feb  3 13:44:07 2009
@@ -0,0 +1,81 @@
+/*
+ *  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.axis2.transport.base;
+
+import junit.framework.TestCase;
+
+public class QueryStringParserTest extends TestCase {
+    public void testSingleParameter() {
+        QueryStringParser p = new QueryStringParser("name=value");
+        assertTrue(p.next());
+        assertEquals("name", p.getName());
+        assertEquals("value", p.getValue());
+        assertFalse(p.next());
+    }
+    
+    public void testMultipleParameters() {
+        QueryStringParser p = new 
QueryStringParser("name1=value1&name2=value2");
+        assertTrue(p.next());
+        assertEquals("name1", p.getName());
+        assertEquals("value1", p.getValue());
+        assertTrue(p.next());
+        assertEquals("name2", p.getName());
+        assertEquals("value2", p.getValue());
+        assertFalse(p.next());
+    }
+    
+    public void testSingleParameterWithoutValue() {
+        QueryStringParser p = new QueryStringParser("name");
+        assertTrue(p.next());
+        assertEquals("name", p.getName());
+        assertNull(p.getValue());
+        assertFalse(p.next());
+    }
+    
+    public void testMultipleParametersWithoutValue1() {
+        QueryStringParser p = new QueryStringParser("name&name2");
+        assertTrue(p.next());
+        assertEquals("name", p.getName());
+        assertNull(p.getValue());
+        assertTrue(p.next());
+        assertEquals("name2", p.getName());
+        assertNull(p.getValue());
+        assertFalse(p.next());
+    }
+    
+    public void testMultipleParametersWithoutValue2() {
+        QueryStringParser p = new QueryStringParser("name=value&name2");
+        assertTrue(p.next());
+        assertEquals("name", p.getName());
+        assertEquals("value", p.getValue());
+        assertTrue(p.next());
+        assertEquals("name2", p.getName());
+        assertNull(p.getValue());
+        assertFalse(p.next());
+    }
+    
+    public void testEncodedValue() {
+        QueryStringParser p = new QueryStringParser("name=20%25%20down");
+        assertTrue(p.next());
+        assertEquals("name", p.getName());
+        assertEquals("20% down", p.getValue());
+        assertFalse(p.next());
+    }
+}

Propchange: 
webservices/commons/trunk/modules/transport/modules/base/src/test/java/org/apache/axis2/transport/base/QueryStringParserTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
webservices/commons/trunk/modules/transport/modules/http/src/org/apache/axis2/transport/http/AxisServlet.java
URL: 
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/transport/modules/http/src/org/apache/axis2/transport/http/AxisServlet.java?rev=740303&r1=740302&r2=740303&view=diff
==============================================================================
--- 
webservices/commons/trunk/modules/transport/modules/http/src/org/apache/axis2/transport/http/AxisServlet.java
 (original)
+++ 
webservices/commons/trunk/modules/transport/modules/http/src/org/apache/axis2/transport/http/AxisServlet.java
 Tue Feb  3 13:44:07 2009
@@ -47,6 +47,7 @@
 import org.apache.axis2.transport.RequestResponseTransport;
 import org.apache.axis2.transport.TransportListener;
 import org.apache.axis2.transport.TransportUtils;
+import org.apache.axis2.transport.base.QueryStringParser;
 import org.apache.axis2.transport.http.server.HttpUtils;
 import org.apache.axis2.transport.http.util.RESTUtil;
 import org.apache.axis2.util.JavaUtils;
@@ -68,7 +69,10 @@
 import java.io.OutputStream;
 import java.io.PrintWriter;
 import java.net.SocketException;
+import java.util.Arrays;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.CountDownLatch;
 
 /**
@@ -79,6 +83,10 @@
     private static final Log log = LogFactory.getLog(AxisServlet.class);
     public static final String CONFIGURATION_CONTEXT = "CONFIGURATION_CONTEXT";
     public static final String SESSION_ID = "SessionId";
+    
+    private static final Set<String> metadataQueryParamNames = new 
HashSet<String>(
+            Arrays.asList("wsdl2", "wsdl", "xsd", "policy"));
+    
     protected transient ConfigurationContext configContext;
     protected transient AxisConfiguration axisConfiguration;
 
@@ -235,9 +243,7 @@
         // 1. wsdl, wsdl2 and xsd requests
         // 2. list services requests
         // 3. REST requests.
-        if ((query != null) && (query.indexOf("wsdl2") >= 0 ||
-                query.indexOf("wsdl") >= 0 || query.indexOf("xsd") >= 0 ||
-                query.indexOf("policy") >= 0)) {
+        if ((query != null) && new 
QueryStringParser(query).search(metadataQueryParamNames)) {
             // handling meta data exchange stuff
             agent.initTransportListener(request);
             agent.processListService(request, response);


Reply via email to