A simple defensive library to encode/decode URL components. https://github.com/ethauvin/urlencoder
Find a file
2023-08-07 12:00:23 +02:00
.github/workflows update Gradle Build workflow 2023-08-07 12:00:23 +02:00
.idea/copyright rm .idea files 2023-05-31 20:58:41 +02:00
buildSrc Updated dependencies for JDK 20 support 2023-08-04 10:05:52 -07:00
gradle update Gradle wrapper 2023-08-06 11:42:55 +02:00
urlencoder-app enable Kotlin/Native and Kotlin/JS targets. Update lock files. Disable Kotlin/Native warnings. 2023-08-06 11:15:43 +02:00
urlencoder-lib enable Kotlin/Native and Kotlin/JS targets. Update lock files. Disable Kotlin/Native warnings. 2023-08-06 11:15:43 +02:00
.gitattributes Initial commit. 2022-12-30 17:45:42 -08:00
.gitignore re-add gradle.properties 2023-07-13 14:17:58 +02:00
build.gradle.kts Fixed Kover missing dependency 2023-07-13 12:32:01 -07:00
CONTRIBUTING.md add Contributing guide with lockfile info 2023-08-06 11:43:21 +02:00
gradle.lockfile enable Kotlin/Native and Kotlin/JS targets. Update lock files. Disable Kotlin/Native warnings. 2023-08-06 11:15:43 +02:00
gradle.properties enable Kotlin/Native and Kotlin/JS targets. Update lock files. Disable Kotlin/Native warnings. 2023-08-06 11:15:43 +02:00
gradlew Updated git index with executable permissions for gradlew 2023-08-06 10:14:32 -07:00
gradlew.bat Initial commit. 2022-12-30 17:45:42 -08:00
LICENSE.txt Initial commit. 2022-12-30 17:45:42 -08:00
README.md Update README with Kotlin MP info 2023-08-06 11:43:09 +02:00
settings.gradle.kts enable Kotlin/Native and Kotlin/JS targets. Update lock files. Disable Kotlin/Native warnings. 2023-08-06 11:18:48 +02:00

License Kotlin Nexus Snapshot Release Maven Central

Quality Gate Status GitHub CI Tests

URL Encoder for Kotlin

UrlEncoder is a simple defensive Kotlin Multiplatform library to encode/decode URL components.

This library was adapted from the RIFE2 Web Application Framework.
A pure Java version can also be found at https://github.com/gbevin/urlencoder.

The rules are determined by combining the unreserved character set from RFC 3986 with the percent-encode set from application/x-www-form-urlencoded.

Both specs above support percent decoding of two hexadecimal digits to a binary octet, however their unreserved set of characters differs and application/x-www-form-urlencoded adds conversion of space to +, that has the potential to be misunderstood.

This class encodes with rules that will be decoded correctly in either case.

Additionally, this library allocates no memory when encoding isn't needed and does the work in a single pass without multiple loops. Both of these optimizations have a significantly beneficial impact on performance of encoding compared to other solutions like the standard URLEncoder in the JDK or UriUtils in Spring.

Examples (TL;DR)

UrlEncoder.encode("a test &") // -> a%20test%20%26
UrlEncoder.encode("%#okékÉȢ smile!😁") // -> %25%23ok%C3%A9k%C3%89%C8%A2%20smile%21%F0%9F%98%81
UrlEncoder.encode("?test=a test", allow = "?=") // -> ?test=a%20test
UrlEncoder.endode("foo bar", spaceToPlus = true) // -> foo+bar

UrlEncoder.decode("a%20test%20%26") // -> a test &
UrlEncoder.decode("%25%23ok%C3%A9k%C3%89%C8%A2%20smile%21%F0%9F%98%81") // -> %#okékÉȢ smile!😁
UrlEncoder.decode("foo+bar", plusToSpace = true) // -> foo bar

Gradle, Maven, etc.

To use with Gradle, include the following dependency in your build file:

repositories {
    mavenCentral()
    // only needed for SNAPSHOT
    maven("https://oss.sonatype.org/content/repositories/snapshots") { 
      name = "SonatypeSnapshots"
      mavenContent { snapshotsOnly() }
    }
}

dependencies {
    implementation("net.thauvin.erik:urlencoder-lib:1.3.0")
}

Adding a dependency in Maven requires specifying the JVM variant by adding a -jvm suffix to the artifact URL.

<dependency>
    <groupId>net.thauvin.erik</groupId>
    <artifactId>urlencoder-lib-jvm</artifactId>
    <version>1.3.0</version>
</dependency>

Instructions for using with Maven, Ivy, etc. can be found on Maven Central.

Standalone usage

UrlEncoder can be used on the command line also, both for encoding and decoding.

You have two options:

  • run it with Gradle
  • build the jar and launch it with Java

The usage is as follows:

Encode and decode URL components defensively.
  -e  encode (default)
  -d  decode

Running with Gradle

./gradlew run --quiet --args="-e 'a test &'"        # -> a%20test%20%26
./gradlew run --quiet --args="%#okékÉȢ"             # -> %25%23ok%C3%A9k%C3%89%C8%A2

./gradlew run --quiet --args="-d 'a%20test%20%26'"  # -> a test &

Running with Java

First build the jar file:

./gradlew fatJar

Then run it:

java -jar urlencoder-app/build/libs/urlencoder-*all.jar -e "a test &"       # -> a%20test%20%26
java -jar urlencoder-app/build/libs/urlencoder-*all.jar "%#okékÉȢ"          # -> %25%23ok%C3%A9k%C3%89%C8%A2

java -jar urlencoder-app/build/libs/urlencoder-*all.jar -d "a%20test%20%26" # -> a test &

Why not simply use java.net.URLEncoder?

Apart for being quite inefficient, some URL components encoded with URLEncoder.encode might not be able to be properly decoded.

For example, a simple search query such as:

val u = URLEncoder.encode("foo +bar", StandardCharsets.UTF_8)

would be encoded as:

foo+%2Bbar

Trying to decode it with Spring, for example:

UriUtils.decode(u, StandardCharsets.UTF_8)

would return:

foo++bar

Unfortunately, decoding with Uri.decode on Android, decodeURI in Javascript, etc. would yield the exact same result.

URLEncoder