URL encodes the provided path using the given character set. @param path The path to encode @param charset The character set to use to convert the path to bytes @return The encoded path
(String path, Charset charset)
| 168 | * @return The encoded path |
| 169 | */ |
| 170 | public String encode(String path, Charset charset) { |
| 171 | |
| 172 | int maxBytesPerChar = 10; |
| 173 | StringBuilder rewrittenPath = new StringBuilder(path.length()); |
| 174 | ByteArrayOutputStream buf = new ByteArrayOutputStream(maxBytesPerChar); |
| 175 | /* |
| 176 | * Most calls to this method use UTF-8 where malformed input and unmappable character issues are not expected to |
| 177 | * happen. The only Tomcat code that currently (January 2026) might call this method with something other than |
| 178 | * UTF-8 is the rewrite valve. In that case, the rewrite rules should be consistent with the configured URI |
| 179 | * encoding on the Connector. Given all of this, the IAE is only expected to be thrown as a result of |
| 180 | * configuration errors. |
| 181 | */ |
| 182 | OutputStreamWriter writer = new OutputStreamWriter(buf, charset.newEncoder() |
| 183 | .onMalformedInput(CodingErrorAction.REPORT).onUnmappableCharacter(CodingErrorAction.REPORT)); |
| 184 | |
| 185 | for (int i = 0; i < path.length(); i++) { |
| 186 | int c = path.charAt(i); |
| 187 | if (safeCharacters.get(c)) { |
| 188 | rewrittenPath.append((char) c); |
| 189 | } else if (encodeSpaceAsPlus && c == ' ') { |
| 190 | rewrittenPath.append('+'); |
| 191 | } else { |
| 192 | // convert to external encoding before hex conversion |
| 193 | try { |
| 194 | writer.write((char) c); |
| 195 | writer.flush(); |
| 196 | } catch (IOException ioe) { |
| 197 | throw new IllegalArgumentException(ioe); |
| 198 | } |
| 199 | byte[] ba = buf.toByteArray(); |
| 200 | for (byte toEncode : ba) { |
| 201 | // Converting each byte in the buffer |
| 202 | rewrittenPath.append('%'); |
| 203 | int low = toEncode & 0x0f; |
| 204 | int high = (toEncode & 0xf0) >> 4; |
| 205 | rewrittenPath.append(hexadecimal[high]); |
| 206 | rewrittenPath.append(hexadecimal[low]); |
| 207 | } |
| 208 | buf.reset(); |
| 209 | } |
| 210 | } |
| 211 | return rewrittenPath.toString(); |
| 212 | } |
| 213 | |
| 214 | |
| 215 | @Override |