Ticket #13118: 13118.patch

File 13118.patch, 23.1 KB (added by simon04, 8 years ago)
  • src/org/openstreetmap/josm/actions/AddImageryLayerAction.java

    commit 609bb4918526fa89ac5ddc86e5a2f205cbd5a488
    Author: Simon Legner <Simon.Legner@gmail.com>
    Date:   Tue Sep 27 15:39:14 2016 +0200
    
        see #13118 - WMSImagery: retain specified version for URL generation
    
    diff --git a/src/org/openstreetmap/josm/actions/AddImageryLayerAction.java b/src/org/openstreetmap/josm/actions/AddImageryLayerAction.java
    index 32eb835..5a46619 100644
    a b  
    1010import java.awt.event.ActionEvent;
    1111import java.io.IOException;
    1212import java.net.MalformedURLException;
     13import java.net.URISyntaxException;
    1314import java.util.HashSet;
    1415import java.util.List;
    1516import java.util.Set;
    protected ImageryInfo getWMSLayerInfo() {  
    131132            }
    132133            ret.setServerProjections(supportedCrs);
    133134            return ret;
    134         } catch (MalformedURLException ex) {
     135        } catch (MalformedURLException | URISyntaxException ex) {
    135136            if (!GraphicsEnvironment.isHeadless()) {
    136137                JOptionPane.showMessageDialog(Main.parent, tr("Invalid service URL."),
    137138                        tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
  • src/org/openstreetmap/josm/gui/preferences/imagery/AddWMSLayerPanel.java

    diff --git a/src/org/openstreetmap/josm/gui/preferences/imagery/AddWMSLayerPanel.java b/src/org/openstreetmap/josm/gui/preferences/imagery/AddWMSLayerPanel.java
    index 049b36e..63b39a8 100644
    a b  
    55
    66import java.io.IOException;
    77import java.net.MalformedURLException;
     8import java.net.URISyntaxException;
    89import java.net.URL;
    910import java.util.List;
    1011
    public AddWMSLayerPanel() {  
    7677                List<String> wmsFormats = wms.getFormats();
    7778                formats.setModel(new DefaultComboBoxModel<>(wmsFormats.toArray(new String[wmsFormats.size()])));
    7879                formats.setSelectedItem(wms.getPreferredFormats());
    79             } catch (MalformedURLException ex1) {
     80            } catch (MalformedURLException | URISyntaxException ex1) {
    8081                Main.error(ex1, false);
    8182                JOptionPane.showMessageDialog(getParent(), tr("Invalid service URL."),
    8283                        tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
  • src/org/openstreetmap/josm/io/imagery/WMSImagery.java

    diff --git a/src/org/openstreetmap/josm/io/imagery/WMSImagery.java b/src/org/openstreetmap/josm/io/imagery/WMSImagery.java
    index b21afa3..f9fca14 100644
    a b  
    55import java.io.IOException;
    66import java.io.StringReader;
    77import java.net.MalformedURLException;
     8import java.net.URI;
     9import java.net.URISyntaxException;
    810import java.net.URL;
    911import java.util.ArrayList;
    1012import java.util.Collection;
     
    1315import java.util.Iterator;
    1416import java.util.List;
    1517import java.util.Locale;
     18import java.util.Map;
    1619import java.util.NoSuchElementException;
    1720import java.util.Set;
    18 import java.util.regex.Pattern;
    1921import java.util.stream.Collectors;
    2022import java.util.stream.Stream;
    2123import java.util.stream.StreamSupport;
     
    2931import org.openstreetmap.josm.data.imagery.ImageryInfo;
    3032import org.openstreetmap.josm.data.projection.Projections;
    3133import org.openstreetmap.josm.tools.HttpClient;
     34import org.openstreetmap.josm.tools.HttpUrl;
    3235import org.openstreetmap.josm.tools.Utils;
    3336import org.w3c.dom.Document;
    3437import org.w3c.dom.Element;
    public String getIncomingData() {  
    110113    }
    111114
    112115    private List<LayerDetails> layers;
    113     private URL serviceUrl;
     116    private HttpUrl serviceUrl;
    114117    private List<String> formats;
    115118
    116119    /**
    public String getIncomingData() {  
    126129     * @return the service URL
    127130     */
    128131    public URL getServiceUrl() {
    129         return serviceUrl;
     132        try {
     133            return serviceUrl == null ? null : serviceUrl.toURL();
     134        } catch (MalformedURLException e) {
     135            Main.warn(e);
     136            return null;
     137        }
    130138    }
    131139
    132140    /**
    public URL getServiceUrl() {  
    138146    }
    139147
    140148    /**
    141      * Gets the preffered format for this imagery layer.
    142      * @return The preffered format as mime type.
     149     * Gets the preferred format for this imagery layer.
     150     * @return The preferred format as mime type.
    143151     */
    144152    public String getPreferredFormats() {
    145153        if (formats.contains("image/jpeg")) {
    public String getPreferredFormats() {  
    153161        }
    154162    }
    155163
    156     String buildRootUrl() {
    157         if (serviceUrl == null) {
    158             return null;
    159         }
    160         StringBuilder a = new StringBuilder(serviceUrl.getProtocol());
    161         a.append("://").append(serviceUrl.getHost());
    162         if (serviceUrl.getPort() != -1) {
    163             a.append(':').append(serviceUrl.getPort());
    164         }
    165         a.append(serviceUrl.getPath()).append('?');
    166         if (serviceUrl.getQuery() != null) {
    167             a.append(serviceUrl.getQuery());
    168             if (!serviceUrl.getQuery().isEmpty() && !serviceUrl.getQuery().endsWith("&")) {
    169                 a.append('&');
    170             }
    171         }
    172         return a.toString();
    173     }
    174 
    175164    public String buildGetMapUrl(Collection<LayerDetails> selectedLayers) {
    176165        return buildGetMapUrl(selectedLayers, "image/jpeg");
    177166    }
    178167
    179168    public String buildGetMapUrl(Collection<LayerDetails> selectedLayers, String format) {
    180         return buildRootUrl() + "FORMAT=" + format + (imageFormatHasTransparency(format) ? "&TRANSPARENT=TRUE" : "")
    181                 + "&VERSION=1.1.1&SERVICE=WMS&REQUEST=GetMap&LAYERS="
    182                 + selectedLayers.stream().map(x -> x.ident).collect(Collectors.joining(","))
     169        serviceUrl.putQueryParameter("REQUEST", "GetMap");
     170        serviceUrl.putQueryParameter("FORMAT", format);
     171        serviceUrl.putQueryParameter("TRANSPARENT", imageFormatHasTransparency(format) ? "TRUE" : "");
     172        serviceUrl.putQueryParameter("LAYERS", selectedLayers.stream().map(x -> x.ident).collect(Collectors.joining(",")));
     173        return serviceUrl.toString()
    183174                + "&STYLES=&SRS={proj}&WIDTH={width}&HEIGHT={height}&BBOX={bbox}";
    184175    }
    185176
    186     public void attemptGetCapabilities(String serviceUrlStr) throws IOException, WMSGetCapabilitiesException {
    187         URL getCapabilitiesUrl = null;
     177    public void attemptGetCapabilities(final String serviceUrlStr) throws IOException, WMSGetCapabilitiesException, URISyntaxException {
    188178        try {
    189             if (!Pattern.compile(".*GetCapabilities.*", Pattern.CASE_INSENSITIVE).matcher(serviceUrlStr).matches()) {
     179            final URL url = new URL(serviceUrlStr); // causing MalformedURLException on invalid input
     180            final HttpUrl getCapabilitiesUrl = new HttpUrl(url.toURI(), false);
     181            if (!"GetCapabilities".equals(getCapabilitiesUrl.getQueryParameter("REQUEST"))) {
    190182                // If the url doesn't already have GetCapabilities, add it in
    191                 getCapabilitiesUrl = new URL(serviceUrlStr);
    192                 final String getCapabilitiesQuery = "VERSION=1.1.1&SERVICE=WMS&REQUEST=GetCapabilities";
    193                 if (getCapabilitiesUrl.getQuery() == null) {
    194                     getCapabilitiesUrl = new URL(serviceUrlStr + '?' + getCapabilitiesQuery);
    195                 } else if (!getCapabilitiesUrl.getQuery().isEmpty() && !getCapabilitiesUrl.getQuery().endsWith("&")) {
    196                     getCapabilitiesUrl = new URL(serviceUrlStr + '&' + getCapabilitiesQuery);
    197                 } else {
    198                     getCapabilitiesUrl = new URL(serviceUrlStr + getCapabilitiesQuery);
     183                getCapabilitiesUrl.putQueryParameter("REQUEST", "GetCapabilities");
     184                if (!getCapabilitiesUrl.containsQueryParameter("SERVICE")) {
     185                    getCapabilitiesUrl.putQueryParameter("SERVICE", "WMS");
     186                }
     187                if (!getCapabilitiesUrl.containsQueryParameter("VERSION")) {
     188                    getCapabilitiesUrl.putQueryParameter("VERSION", "1.1.1");
    199189                }
    200190            } else {
    201191                // Otherwise assume it's a good URL and let the subsequent error
    202192                // handling systems deal with problems
    203                 getCapabilitiesUrl = new URL(serviceUrlStr);
    204193            }
    205             serviceUrl = new URL(serviceUrlStr);
     194            serviceUrl = getCapabilitiesUrl;
    206195        } catch (HeadlessException e) {
    207196            Main.warn(e);
    208197            return;
    209198        }
    210199
    211         final String incomingData = HttpClient.create(getCapabilitiesUrl).connect().fetchContent();
     200        final String incomingData = HttpClient.create(serviceUrl.toURL()).connect().fetchContent();
    212201        Main.debug("Server response to Capabilities request:");
    213202        Main.debug(incomingData);
    214203
    public void attemptGetCapabilities(String serviceUrlStr) throws IOException, WMS  
    244233                String baseURL = child.getAttribute("xlink:href");
    245234                if (baseURL != null && !baseURL.equals(serviceUrlStr)) {
    246235                    Main.info("GetCapabilities specifies a different service URL: " + baseURL);
    247                     serviceUrl = new URL(baseURL);
     236                    final Map<String, String> parameters = serviceUrl.getQueryParameters();
     237                    serviceUrl = new HttpUrl(URI.create(baseURL), false);
     238                    serviceUrl.putQueryParameters(parameters);
    248239                }
    249240            }
    250241
  • src/org/openstreetmap/josm/io/remotecontrol/handler/RequestHandler.java

    diff --git a/src/org/openstreetmap/josm/io/remotecontrol/handler/RequestHandler.java b/src/org/openstreetmap/josm/io/remotecontrol/handler/RequestHandler.java
    index cd83e6d..afd8f17 100644
    a b  
    1919
    2020import org.openstreetmap.josm.Main;
    2121import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
     22import org.openstreetmap.josm.tools.HttpUrl;
    2223import org.openstreetmap.josm.tools.Utils;
    2324
    2425/**
    public void setUrl(String url) throws RequestHandlerBadRequestException {  
    195196     * @throws URISyntaxException if request URL is invalid
    196197     */
    197198    protected void parseArgs() throws URISyntaxException {
    198         this.args = getRequestParameter(new URI(this.request));
    199     }
    200 
    201     /**
    202      * Returns the request parameters.
    203      * @param uri URI as string
    204      * @return map of request parameters
    205      * @see <a href="http://blog.lunatech.com/2009/02/03/what-every-web-developer-must-know-about-url-encoding">
    206      *      What every web developer must know about URL encoding</a>
    207      */
    208     static Map<String, String> getRequestParameter(URI uri) {
    209         Map<String, String> r = new HashMap<>();
    210         if (uri.getRawQuery() == null) {
    211             return r;
    212         }
    213         for (String kv : uri.getRawQuery().split("&")) {
    214             final String[] kvs = Utils.decodeUrl(kv).split("=", 2);
    215             r.put(kvs[0], kvs.length > 1 ? kvs[1] : null);
    216         }
    217         return r;
     199        this.args = HttpUrl.getQueryParameter(new URI(this.request), true);
    218200    }
    219201
    220202    void checkMandatoryParams() throws RequestHandlerBadRequestException {
  • new file src/org/openstreetmap/josm/tools/HttpUrl.java

    diff --git a/src/org/openstreetmap/josm/tools/HttpUrl.java b/src/org/openstreetmap/josm/tools/HttpUrl.java
    new file mode 100644
    index 0000000..ec11531
    - +  
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.tools;
     3
     4import java.net.MalformedURLException;
     5import java.net.URI;
     6import java.net.URISyntaxException;
     7import java.net.URL;
     8import java.util.Collections;
     9import java.util.Comparator;
     10import java.util.Map;
     11import java.util.TreeMap;
     12import java.util.stream.Collectors;
     13
     14/**
     15 * This class allows building HTTP URLs with query parameters.
     16 * @since 11059
     17 */
     18public class HttpUrl {
     19
     20    private final URI uri;
     21    private final Map<String, String> query;
     22
     23    /**
     24     * Creates a new instance from the specified URI
     25     * @param uri the URI
     26     * @param caseSensitive whether query parameters are considered case sensitive
     27     */
     28    public HttpUrl(URI uri, boolean caseSensitive) {
     29        this.uri = uri;
     30        this.query = getQueryParameter(uri, caseSensitive);
     31    }
     32
     33    /**
     34     * Returns the request query parameter.
     35     * @param uri the URI
     36     * @return map of request parameters
     37     * @see <a href="https://www.talisman.org/~erlkonig/misc/lunatech%5ewhat-every-webdev-must-know-about-url-encoding/">
     38     *      What every web developer must know about URL encoding</a>
     39     */
     40    public static Map<String, String> getQueryParameter(URI uri, boolean caseSensitive) {
     41        Map<String, String> r = new TreeMap<>(caseSensitive ? Comparator.<String>naturalOrder() : String.CASE_INSENSITIVE_ORDER);
     42        if (uri.getRawQuery() == null) {
     43            return r;
     44        }
     45        for (String kv : uri.getRawQuery().split("&")) {
     46            if (kv.isEmpty()) {
     47                continue;
     48            }
     49            final String[] kvs = Utils.decodeUrl(kv).split("=", 2);
     50            r.put(kvs[0], kvs.length > 1 ? kvs[1] : null);
     51        }
     52        return r;
     53    }
     54
     55    /**
     56     * Tests whether the query parameter {@code key} is present
     57     * @param key the query parameter
     58     * @return true if the query parameter {@code key} is present
     59     */
     60    public boolean containsQueryParameter(String key) {
     61        return query.containsKey(key);
     62    }
     63
     64    /**
     65     * Returns the value for the query parameter {@code key}
     66     * @param key the query parameter
     67     * @return the value for the query parameter
     68     */
     69    public String getQueryParameter(String key) {
     70        return query.get(key);
     71    }
     72
     73    /**
     74     * Returns a map of all query parameters
     75     * @return a map of all query parameters
     76     */
     77    public Map<String, String> getQueryParameters() {
     78        return Collections.unmodifiableMap(query);
     79    }
     80
     81    /**
     82     * Sets the the value for the query parameter {@code key}
     83     * @param key the query parameter
     84     * @param value the value for the query parameter
     85     * @return the old value for the query parameter, or {@code null}
     86     */
     87    public String putQueryParameter(String key, String value) {
     88        return query.put(key, value);
     89    }
     90
     91    /**
     92     * Sets all query parameters
     93     * @param parameters the query parameters
     94     */
     95    public void putQueryParameters(Map<? extends String, ? extends String> parameters) {
     96        query.putAll(parameters);
     97    }
     98
     99    /**
     100     * Constructs a URI from this.
     101     * @return a URI
     102     */
     103    public URI toURI() {
     104        final String query = this.query.entrySet().stream()
     105                .map(entry -> entry.getKey() + "=" + entry.getValue())
     106                .collect(Collectors.joining("&"));
     107        try {
     108            return new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(), uri.getPath(), query, uri.getFragment());
     109        } catch (URISyntaxException ex) {
     110            throw new RuntimeException(ex);
     111        }
     112    }
     113
     114    /**
     115     * Constructs a URL from this.
     116     * @return a URL
     117     * @throws MalformedURLException If a protocol handler for the URL could not be found, or if some other error occurred while constructing the URL
     118     */
     119    public URL toURL() throws MalformedURLException {
     120        return toURI().toURL();
     121    }
     122
     123    @Override
     124    public String toString() {
     125        return toURI().toString();
     126    }
     127}
  • .java

    diff --git a/test/unit/org/openstreetmap/josm/io/remotecontrol/handler/RequestHandlerTest.java b/test/unit/org/openstreetmap/josm/tools/HttpUrlTest.java
    similarity index 55%
    rename from test/unit/org/openstreetmap/josm/io/remotecontrol/handler/RequestHandlerTest.java
    rename to test/unit/org/openstreetmap/josm/tools/HttpUrlTest.java
    index eb342d6..f121a09 100644
    old new  
    11// License: GPL. For details, see LICENSE file.
    2 package org.openstreetmap.josm.io.remotecontrol.handler;
     2package org.openstreetmap.josm.tools;
    33
    44import static org.junit.Assert.assertEquals;
     5import static org.junit.Assert.assertTrue;
    56
     7import java.net.URI;
     8import java.net.URL;
    69import java.util.Collections;
    710import java.util.HashMap;
    811import java.util.Map;
    912
    1013import org.junit.Test;
    11 import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
    12 import org.openstreetmap.josm.io.remotecontrol.handler.RequestHandler.RequestHandlerBadRequestException;
    1314
    1415/**
    15  * Unit tests of {@link RequestHandler} class.
     16 * Unit tests of {@link HttpUrl} class.
    1617 */
    17 public class RequestHandlerTest {
     18public class HttpUrlTest {
    1819
    19     Map<String, String> getRequestParameter(String url) throws RequestHandlerBadRequestException {
    20         final RequestHandler req = new RequestHandler() {
    21             @Override
    22             protected void validateRequest() throws RequestHandlerBadRequestException {
    23             }
    24 
    25             @Override
    26             protected void handleRequest() throws RequestHandlerErrorException, RequestHandlerBadRequestException {
    27             }
    28 
    29             @Override
    30             public String getPermissionMessage() {
    31                 return null;
    32             }
    33 
    34             @Override
    35             public PermissionPrefWithDefault getPermissionPref() {
    36                 return null;
    37             }
     20    private static Map<String, String> getRequestParameter(String url) {
     21        return HttpUrl.getQueryParameter(URI.create(url), true);
     22    }
    3823
    39             @Override
    40             public String[] getMandatoryParams() {
    41                 return new String[0];
    42             }
    43         };
    44         req.setUrl(url);
    45         return req.args;
     24    /**
     25     * Test request parameter - case 1
     26     */
     27    @Test
     28    public void testRequestParameter0() {
     29        final Map<String, String> expected = new HashMap<>();
     30        assertEquals(expected, getRequestParameter("http://example.com/"));
     31        assertEquals(expected, getRequestParameter("http://example.com/?"));
     32        assertEquals(expected, getRequestParameter("http://example.com/#foobar"));
    4633    }
    4734
    4835    /**
    4936     * Test request parameter - case 1
    50      * @throws RequestHandlerBadRequestException never
    5137     */
    5238    @Test
    53     public void testRequestParameter1() throws RequestHandlerBadRequestException {
     39    public void testRequestParameter1() {
    5440        final Map<String, String> expected = new HashMap<>();
    5541        expected.put("query", "a");
    5642        expected.put("b", "=c");
    public void testRequestParameter1() throws RequestHandlerBadRequestException {  
    5945
    6046    /**
    6147     * Test request parameter - case 2
    62      * @throws RequestHandlerBadRequestException never
    6348     */
    6449    @Test
    65     public void testRequestParameter2() throws RequestHandlerBadRequestException {
     50    public void testRequestParameter2() {
    6651        assertEquals(Collections.singletonMap("query", "a&b==c"),
    6752                getRequestParameter("http://example.com/?query=a%26b==c"));
    6853    }
    6954
    7055    /**
    7156     * Test request parameter - case 3
    72      * @throws RequestHandlerBadRequestException never
    7357     */
    7458    @Test
    75     public void testRequestParameter3() throws RequestHandlerBadRequestException {
     59    public void testRequestParameter3() {
    7660        assertEquals(Collections.singleton("blue+light blue"),
    7761                getRequestParameter("http://example.com/blue+light%20blue?blue%2Blight+blue").keySet());
    7862    }
    7963
    8064    /**
    8165     * Test request parameter - case 4
    82      * @see <a href="http://blog.lunatech.com/2009/02/03/what-every-web-developer-must-know-about-url-encoding">
     66     * @see <a href="https://www.talisman.org/~erlkonig/misc/lunatech%5ewhat-every-webdev-must-know-about-url-encoding/">
    8367     *      What every web developer must know about URL encoding</a>
    84      * @throws RequestHandlerBadRequestException never
    8568     */
    8669    @Test
    87     public void testRequestParameter4() throws RequestHandlerBadRequestException {
     70    public void testRequestParameter4() {
    8871        assertEquals(Collections.singletonMap("/?:@-._~!$'()* ,;", "/?:@-._~!$'()* ,;=="), getRequestParameter(
    8972                // CHECKSTYLE.OFF: LineLength
    9073                "http://example.com/:@-._~!$&'()*+,=;:@-._~!$&'()*+,=:@-._~!$&'()*+,==?/?:@-._~!$'()*+,;=/?:@-._~!$'()*+,;==#/?:@-._~!$&'()*+,;="));
    public void testRequestParameter4() throws RequestHandlerBadRequestException {  
    9376
    9477    /**
    9578     * Test request parameter - case 5
    96      * @throws RequestHandlerBadRequestException never
    9779     */
    9880    @Test
    99     public void testRequestParameter5() throws RequestHandlerBadRequestException {
     81    public void testRequestParameter5() {
    10082        final Map<String, String> expected = new HashMap<>();
    10183        expected.put("space", " ");
    10284        expected.put("tab", "\t");
    public void testRequestParameter5() throws RequestHandlerBadRequestException {  
    10587
    10688    /**
    10789     * Test request parameter - case 6
    108      * @throws RequestHandlerBadRequestException never
    10990     */
    11091    @Test
    111     public void testRequestParameter6() throws RequestHandlerBadRequestException {
     92    public void testRequestParameter6() {
    11293        final Map<String, String> expected = new HashMap<>();
    11394        expected.put("addtags", "wikipedia:de=Weiße_Gasse|maxspeed=5");
    11495        expected.put("select", "way23071688,way23076176,way23076177,");
    public void testRequestParameter6() throws RequestHandlerBadRequestException {  
    124105
    125106    /**
    126107     * Test request parameter - invalid case
    127      * @throws RequestHandlerBadRequestException always
    128108     */
    129     @Test(expected = RequestHandlerBadRequestException.class)
    130     public void testRequestParameterInvalid() throws RequestHandlerBadRequestException {
     109    @Test(expected = IllegalArgumentException.class)
     110    public void testRequestParameterInvalid() {
    131111        getRequestParameter("http://localhost:8111/load_and_zoom"+
    132112                "?addtags=wikipedia:de=Wei%C3%9Fe_Gasse|maxspeed=5"+
    133113                "&select=way23071688,way23076176,way23076177,"+
    134114                "&left=13.739727546842&right=13.740890970188&top=51.049987191025&bottom=51.048466954325");
    135115    }
     116
     117    /**
     118     * Test request parameter changing
     119     */
     120    @Test
     121    public void testSettingQueryParameter() throws Exception {
     122        final HttpUrl url = new HttpUrl(URI.create("https://www.wms.com/guest?VERSION=1.3&SERVICE=WMS&REQUEST=GetCapabilities"), true);
     123        assertEquals("https://www.wms.com/guest?REQUEST=GetCapabilities&SERVICE=WMS&VERSION=1.3", url.toString());
     124        assertTrue(url.containsQueryParameter("REQUEST"));
     125        assertEquals("GetCapabilities", url.getQueryParameter("REQUEST"));
     126        url.putQueryParameter("REQUEST", "GetMap");
     127        assertEquals("https://www.wms.com/guest?REQUEST=GetMap&SERVICE=WMS&VERSION=1.3", url.toString());
     128        assertEquals("{REQUEST=GetMap, SERVICE=WMS, VERSION=1.3}", url.getQueryParameters().toString());
     129    }
     130
     131    @Test
     132    public void testUrlUnchanged() throws Exception {
     133        final URL url1 = new URL("http://example.com/:@-._~!$&'()*+,=;:@-._~!$&'()*+,=:@-._~!$&'()*+,==?/?" +
     134                ":@-._~!$'()*%20,;=/?:@-._~!$'()*%20,;==#/?:@-._~!$&'()*+,;=");
     135        final URL uri2 = new HttpUrl(url1.toURI(), true).toURL();
     136        assertEquals(url1, uri2);
     137    }
    136138}