Index: modules/resin/src/com/caucho/server/http/Form.java =================================================================== --- modules/resin/src/com/caucho/server/http/Form.java (revision 8009) +++ modules/resin/src/com/caucho/server/http/Form.java (working copy) @@ -67,9 +67,82 @@ { _freeList.free(form); } - + /** - * Parses the values from a query string. + * Writes to a table given a key/value pair. + */ + private static interface FormEntryWriter + { + public void write(HashMapImpl table, + boolean isTop, + String key, + String value); + } + + /** + * Adds key/value pairs to a table. + */ + private static FormEntryWriter valueAdder = new FormEntryWriter() { + + public void write(HashMapImpl table, + boolean isTop, + String key, + String value) + { + String []oldValue = table.get(key); + + if (key == null || key.equals("")) { + } + else if (oldValue == null) + table.put(key, new String[] { value }); + else if (isTop) { + String []newValue = new String[oldValue.length + 1]; + System.arraycopy(oldValue, 0, newValue, 0, oldValue.length); + newValue[oldValue.length] = value; + table.put(key, newValue); + } else { + String []newValue = new String[oldValue.length + 1]; + System.arraycopy(oldValue, 0, newValue, 1, oldValue.length); + newValue[0] = value; + table.put(key, newValue); + } + } + + }; + + /** + * Removes key/value pairs from a table. + */ + private static FormEntryWriter valueRemover = new FormEntryWriter() { + + public void write(HashMapImpl table, + boolean isTop, + String key, + String value) + { + String []oldValue = table.get(key); + + if (oldValue != null) { + for (int i = 0; i < oldValue.length; i++) { + if (value.equals(oldValue[i])) { + if (oldValue.length == 1) { + table.remove(key); + } else { + String []newValue = new String[oldValue.length - 1]; + System.arraycopy(oldValue, 0, newValue, 0, i); + System.arraycopy(oldValue, i + 1, newValue, i, oldValue.length - i - 1); + table.put(key, newValue); + } + break; + } + } + } + } + + }; + + /** + * Parses the values from a query string, adding them to the given table. * * @param table the hashtable which will contain the results * @param query the query string to evaluate @@ -81,6 +154,42 @@ boolean isTop) throws IOException { + iterateQueryString(table, query, javaEncoding, isTop, valueAdder); + } + + /** + * Parses the values from a query string, removing them from the given table. + * + * @param table the hashtable which will contain the results + * @param query the query string to evaluate + * @param javaEncoding the Java name for the charset + */ + public void unparseQueryString(HashMapImpl table, + String query, + String javaEncoding, + boolean isTop) + throws IOException + { + iterateQueryString(table, query, javaEncoding, isTop, valueRemover); + } + + /** + * Parses the values from a query string. For each key/value pair, the + * given entryWriter is invoked. + * + * @param table the hashtable which will contain the results + * @param query the query string to evaluate + * @param javaEncoding the Java name for the charset + * @param entryWriter the object responsible for writing key/value pairs to + * the table + */ + private void iterateQueryString(HashMapImpl table, + String query, + String javaEncoding, + boolean isTop, + FormEntryWriter entryWriter) + throws IOException + { CharCursor is = new StringCharCursor(query); ByteToChar converter = _converter; @@ -111,24 +220,8 @@ if (log.isLoggable(Level.FINE)) log.fine("query: " + key + "=" + value); - - String []oldValue = table.get(key); - - if (key == null || key.equals("")) { - } - else if (oldValue == null) - table.put(key, new String[] { value }); - else if (isTop) { - String []newValue = new String[oldValue.length + 1]; - System.arraycopy(oldValue, 0, newValue, 0, oldValue.length); - newValue[oldValue.length] = value; - table.put(key, newValue); - } else { - String []newValue = new String[oldValue.length + 1]; - System.arraycopy(oldValue, 0, newValue, 1, oldValue.length); - newValue[0] = value; - table.put(key, newValue); - } + + entryWriter.write(table, isTop, key, value); } } Index: modules/resin/src/com/caucho/server/webapp/ForwardRequest.java =================================================================== --- modules/resin/src/com/caucho/server/webapp/ForwardRequest.java (revision 8009) +++ modules/resin/src/com/caucho/server/webapp/ForwardRequest.java (working copy) @@ -348,7 +348,15 @@ String oldQueryString = getRequest().getQueryString(); if (queryString != null && ! queryString.equals(oldQueryString)) { - formParser.parseQueryString(form, queryString, javaEncoding, false); + + if (oldQueryString != null) { + // queryString contains all the values from oldQueryString, and + // possibly more. To avoid duplicating the parameters in + // oldQueryString, we need to remove them from the form. + formParser.unparseQueryString(form, oldQueryString, javaEncoding, true); + } + + formParser.parseQueryString(form, queryString, javaEncoding, true); } } catch (Exception e) { throw new RuntimeException(e);