| 1 | # fast-uri
|
|---|
| 2 |
|
|---|
| 3 | [](https://www.npmjs.com/package/fast-uri)
|
|---|
| 4 | [](https://github.com/fastify/fast-uri/actions/workflows/ci.yml)
|
|---|
| 5 | [](https://github.com/neostandard/neostandard)
|
|---|
| 6 |
|
|---|
| 7 | Dependency-free RFC 3986 URI toolbox.
|
|---|
| 8 |
|
|---|
| 9 | ## Usage
|
|---|
| 10 |
|
|---|
| 11 | ## Options
|
|---|
| 12 |
|
|---|
| 13 | All of the above functions can accept an additional options argument that is an object that can contain one or more of the following properties:
|
|---|
| 14 |
|
|---|
| 15 | Malformed authorities and out-of-range ports are reported through the parsed component's `error` field. `normalize()` leaves malformed string inputs unchanged, and `equal()` returns `false` when either string input is malformed.
|
|---|
| 16 |
|
|---|
| 17 | * `scheme` (string)
|
|---|
| 18 | Indicates the scheme that the URI should be treated as, overriding the URI's normal scheme parsing behavior.
|
|---|
| 19 |
|
|---|
| 20 | * `reference` (string)
|
|---|
| 21 | If set to `"suffix"`, it indicates that the URI is in the suffix format and the parser will use the option's `scheme` property to determine the URI's scheme.
|
|---|
| 22 |
|
|---|
| 23 | * `tolerant` (boolean, false)
|
|---|
| 24 | If set to `true`, the parser will relax URI resolving rules.
|
|---|
| 25 |
|
|---|
| 26 | * `absolutePath` (boolean, false)
|
|---|
| 27 | If set to `true`, the serializer will not resolve a relative `path` component.
|
|---|
| 28 |
|
|---|
| 29 | * `unicodeSupport` (boolean, false)
|
|---|
| 30 | If set to `true`, the parser will unescape non-ASCII characters in the parsed output as per [RFC 3987](http://www.ietf.org/rfc/rfc3987.txt).
|
|---|
| 31 |
|
|---|
| 32 | * `domainHost` (boolean, false)
|
|---|
| 33 | If set to `true`, the library will treat the `host` component as a domain name, and convert IDNs (International Domain Names) as per [RFC 5891](http://www.ietf.org/rfc/rfc5891.txt).
|
|---|
| 34 |
|
|---|
| 35 | ### Parse
|
|---|
| 36 |
|
|---|
| 37 | ```js
|
|---|
| 38 | const uri = require('fast-uri')
|
|---|
| 39 | uri.parse('uri://user:pass@example.com:123/one/two.three?q1=a1&q2=a2#body')
|
|---|
| 40 | // Output
|
|---|
| 41 | {
|
|---|
| 42 | scheme: "uri",
|
|---|
| 43 | userinfo: "user:pass",
|
|---|
| 44 | host: "example.com",
|
|---|
| 45 | port: 123,
|
|---|
| 46 | path: "/one/two.three",
|
|---|
| 47 | query: "q1=a1&q2=a2",
|
|---|
| 48 | fragment: "body"
|
|---|
| 49 | }
|
|---|
| 50 | ```
|
|---|
| 51 |
|
|---|
| 52 | ### Serialize
|
|---|
| 53 |
|
|---|
| 54 | ```js
|
|---|
| 55 | const uri = require('fast-uri')
|
|---|
| 56 | uri.serialize({scheme: "http", host: "example.com", fragment: "footer"})
|
|---|
| 57 | // Output
|
|---|
| 58 | "http://example.com/#footer"
|
|---|
| 59 |
|
|---|
| 60 | ```
|
|---|
| 61 |
|
|---|
| 62 | ### Resolve
|
|---|
| 63 |
|
|---|
| 64 | ```js
|
|---|
| 65 | const uri = require('fast-uri')
|
|---|
| 66 | uri.resolve("uri://a/b/c/d?q", "../../g")
|
|---|
| 67 | // Output
|
|---|
| 68 | "uri://a/g"
|
|---|
| 69 | ```
|
|---|
| 70 |
|
|---|
| 71 | ### Normalize
|
|---|
| 72 |
|
|---|
| 73 | ```js
|
|---|
| 74 | const uri = require('fast-uri')
|
|---|
| 75 | uri.normalize('http://example.com/a%2Fb')
|
|---|
| 76 | // Output
|
|---|
| 77 | "http://example.com/a%2Fb"
|
|---|
| 78 | ```
|
|---|
| 79 |
|
|---|
| 80 | Reserved path escapes such as `%2F` and `%2E` are preserved as path data during normalization and comparison.
|
|---|
| 81 |
|
|---|
| 82 | ### Equal
|
|---|
| 83 |
|
|---|
| 84 | ```js
|
|---|
| 85 | const uri = require('fast-uri')
|
|---|
| 86 | uri.equal("example://a/b/c/%7Bfoo%7D", "eXAMPLE://a/./b/../b/%63/%7bfoo%7d")
|
|---|
| 87 | // Output
|
|---|
| 88 | true
|
|---|
| 89 | ```
|
|---|
| 90 |
|
|---|
| 91 | ## Scheme supports
|
|---|
| 92 |
|
|---|
| 93 | fast-uri supports inserting custom [scheme](http://en.wikipedia.org/wiki/URI_scheme)-dependent processing rules. Currently, fast-uri has built-in support for the following schemes:
|
|---|
| 94 |
|
|---|
| 95 | * http \[[RFC 2616](http://www.ietf.org/rfc/rfc2616.txt)\]
|
|---|
| 96 | * https \[[RFC 2818](http://www.ietf.org/rfc/rfc2818.txt)\]
|
|---|
| 97 | * ws \[[RFC 6455](http://www.ietf.org/rfc/rfc6455.txt)\]
|
|---|
| 98 | * wss \[[RFC 6455](http://www.ietf.org/rfc/rfc6455.txt)\]
|
|---|
| 99 | * urn \[[RFC 2141](http://www.ietf.org/rfc/rfc2141.txt)\]
|
|---|
| 100 | * urn:uuid \[[RFC 4122](http://www.ietf.org/rfc/rfc4122.txt)\]
|
|---|
| 101 |
|
|---|
| 102 |
|
|---|
| 103 | ## Benchmarks
|
|---|
| 104 |
|
|---|
| 105 | ```
|
|---|
| 106 | fast-uri benchmark
|
|---|
| 107 | ┌─────────┬──────────────────────────────────────────┬──────────────────┬──────────────────┬────────────────────────┬────────────────────────┬─────────┐
|
|---|
| 108 | │ (index) │ Task name │ Latency avg (ns) │ Latency med (ns) │ Throughput avg (ops/s) │ Throughput med (ops/s) │ Samples │
|
|---|
| 109 | ├─────────┼──────────────────────────────────────────┼──────────────────┼──────────────────┼────────────────────────┼────────────────────────┼─────────┤
|
|---|
| 110 | │ 0 │ 'fast-uri: parse domain' │ '951.31 ± 0.75%' │ '875.00 ± 11.00' │ '1122538 ± 0.01%' │ '1142857 ± 14550' │ 1051187 │
|
|---|
| 111 | │ 1 │ 'fast-uri: parse IPv4' │ '443.44 ± 0.22%' │ '406.00 ± 3.00' │ '2422762 ± 0.01%' │ '2463054 ± 18335' │ 2255105 │
|
|---|
| 112 | │ 2 │ 'fast-uri: parse IPv6' │ '1241.6 ± 1.74%' │ '1131.0 ± 30.00' │ '875177 ± 0.02%' │ '884173 ± 24092' │ 805399 │
|
|---|
| 113 | │ 3 │ 'fast-uri: parse URN' │ '689.19 ± 4.29%' │ '618.00 ± 9.00' │ '1598373 ± 0.01%' │ '1618123 ± 23913' │ 1450972 │
|
|---|
| 114 | │ 4 │ 'fast-uri: parse URN uuid' │ '1025.4 ± 2.02%' │ '921.00 ± 19.00' │ '1072419 ± 0.02%' │ '1085776 ± 22871' │ 975236 │
|
|---|
| 115 | │ 5 │ 'fast-uri: serialize uri' │ '1028.5 ± 0.53%' │ '933.00 ± 43.00' │ '1063310 ± 0.02%' │ '1071811 ± 50523' │ 972249 │
|
|---|
| 116 | │ 6 │ 'fast-uri: serialize long uri with dots' │ '1805.1 ± 0.52%' │ '1627.0 ± 17.00' │ '602620 ± 0.02%' │ '614628 ± 6490' │ 553997 │
|
|---|
| 117 | │ 7 │ 'fast-uri: serialize IPv6' │ '2569.4 ± 2.69%' │ '2302.0 ± 21.00' │ '426080 ± 0.03%' │ '434405 ± 3999' │ 389194 │
|
|---|
| 118 | │ 8 │ 'fast-uri: serialize ws' │ '979.39 ± 0.43%' │ '882.00 ± 8.00' │ '1111665 ± 0.02%' │ '1133787 ± 10378' │ 1021045 │
|
|---|
| 119 | │ 9 │ 'fast-uri: resolve' │ '2208.2 ± 1.08%' │ '1980.0 ± 24.00' │ '495001 ± 0.03%' │ '505051 ± 6049' │ 452848 │
|
|---|
| 120 | └─────────┴──────────────────────────────────────────┴──────────────────┴──────────────────┴────────────────────────┴────────────────────────┴─────────┘
|
|---|
| 121 | uri-js benchmark
|
|---|
| 122 | ┌─────────┬───────────────────────────────────────┬──────────────────┬──────────────────┬────────────────────────┬────────────────────────┬─────────┐
|
|---|
| 123 | │ (index) │ Task name │ Latency avg (ns) │ Latency med (ns) │ Throughput avg (ops/s) │ Throughput med (ops/s) │ Samples │
|
|---|
| 124 | ├─────────┼───────────────────────────────────────┼──────────────────┼──────────────────┼────────────────────────┼────────────────────────┼─────────┤
|
|---|
| 125 | │ 0 │ 'urijs: parse domain' │ '3618.3 ± 0.43%' │ '3314.0 ± 33.00' │ '294875 ± 0.04%' │ '301750 ± 2975' │ 276375 │
|
|---|
| 126 | │ 1 │ 'urijs: parse IPv4' │ '4024.1 ± 0.41%' │ '3751.0 ± 25.00' │ '261981 ± 0.04%' │ '266596 ± 1789' │ 248506 │
|
|---|
| 127 | │ 2 │ 'urijs: parse IPv6' │ '5417.2 ± 0.46%' │ '4968.0 ± 43.00' │ '196023 ± 0.05%' │ '201288 ± 1727' │ 184598 │
|
|---|
| 128 | │ 3 │ 'urijs: parse URN' │ '1324.2 ± 0.23%' │ '1229.0 ± 17.00' │ '801535 ± 0.02%' │ '813670 ± 11413' │ 755185 │
|
|---|
| 129 | │ 4 │ 'urijs: parse URN uuid' │ '1822.0 ± 3.08%' │ '1655.0 ± 15.00' │ '594433 ± 0.02%' │ '604230 ± 5427' │ 548843 │
|
|---|
| 130 | │ 5 │ 'urijs: serialize uri' │ '4196.8 ± 0.36%' │ '3908.0 ± 27.00' │ '251146 ± 0.04%' │ '255885 ± 1756' │ 238276 │
|
|---|
| 131 | │ 6 │ 'urijs: serialize long uri with dots' │ '8331.0 ± 1.30%' │ '7658.0 ± 72.00' │ '126440 ± 0.07%' │ '130582 ± 1239' │ 120034 │
|
|---|
| 132 | │ 7 │ 'urijs: serialize IPv6' │ '5685.5 ± 0.30%' │ '5366.0 ± 33.00' │ '182632 ± 0.05%' │ '186359 ± 1153' │ 175886 │
|
|---|
| 133 | │ 8 │ 'urijs: serialize ws' │ '4159.3 ± 0.20%' │ '3899.0 ± 28.00' │ '250459 ± 0.04%' │ '256476 ± 1855' │ 240423 │
|
|---|
| 134 | │ 9 │ 'urijs: resolve' │ '6729.9 ± 0.39%' │ '6261.0 ± 37.00' │ '156361 ± 0.06%' │ '159719 ± 949' │ 148591 │
|
|---|
| 135 | └─────────┴───────────────────────────────────────┴──────────────────┴──────────────────┴────────────────────────┴────────────────────────┴─────────┘
|
|---|
| 136 | WHATWG URL benchmark
|
|---|
| 137 | ┌─────────┬────────────────────────────┬──────────────────┬──────────────────┬────────────────────────┬────────────────────────┬─────────┐
|
|---|
| 138 | │ (index) │ Task name │ Latency avg (ns) │ Latency med (ns) │ Throughput avg (ops/s) │ Throughput med (ops/s) │ Samples │
|
|---|
| 139 | ├─────────┼────────────────────────────┼──────────────────┼──────────────────┼────────────────────────┼────────────────────────┼─────────┤
|
|---|
| 140 | │ 0 │ 'WHATWG URL: parse domain' │ '475.22 ± 0.20%' │ '444.00 ± 5.00' │ '2217599 ± 0.01%' │ '2252252 ± 25652' │ 2104289 │
|
|---|
| 141 | │ 1 │ 'WHATWG URL: parse URN' │ '384.78 ± 0.85%' │ '350.00 ± 5.00' │ '2809071 ± 0.01%' │ '2857143 ± 41408' │ 2598885 │
|
|---|
| 142 | └─────────┴────────────────────────────┴──────────────────┴──────────────────┴────────────────────────┴────────────────────────┴─────────┘
|
|---|
| 143 | ```
|
|---|
| 144 |
|
|---|
| 145 | ## TODO
|
|---|
| 146 |
|
|---|
| 147 | - [ ] Support MailTo
|
|---|
| 148 | - [ ] Be 100% iso compatible with uri-js
|
|---|
| 149 |
|
|---|
| 150 | ## License
|
|---|
| 151 |
|
|---|
| 152 | Licensed under [BSD-3-Clause](./LICENSE).
|
|---|