Skip to content

Commit 237abb0

Browse files
authored
feat: support http-path in multiaddrs (#53)
Since the `http-path` tuple is now [well specified](https://github.com/multiformats/multiaddr/blob/master/protocols/http-path.md) we can support parsing paths out of URIs. Fixes #47
1 parent 73bde1d commit 237abb0

File tree

2 files changed

+33
-5
lines changed

2 files changed

+33
-5
lines changed

src/index.ts

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,17 @@ export interface MultiaddrFromUriOpts {
6969
export function uriToMultiaddr (uriStr: string, opts?: MultiaddrFromUriOpts): Multiaddr {
7070
opts = opts ?? {}
7171
const defaultDnsType = opts.defaultDnsType ?? 'dns4'
72-
const { scheme, hostname, port } = parseUri(uriStr)
72+
const { scheme, hostname, port, path } = parseUri(uriStr)
7373
const parts = [
7474
tupleForHostname(hostname, defaultDnsType),
7575
tupleForPort(port, scheme),
7676
tupleForScheme(scheme)
7777
]
7878

79+
if (path != null) {
80+
parts.push(tupleForPath(path))
81+
}
82+
7983
const multiaddrStr = '/' + parts
8084
.filter(x => Boolean(x))
8185
// @ts-expect-error ts cannot see we filter falsy values
@@ -85,7 +89,7 @@ export function uriToMultiaddr (uriStr: string, opts?: MultiaddrFromUriOpts): Mu
8589
return multiaddr(multiaddrStr)
8690
}
8791

88-
function parseUri (uriStr: string): { scheme: string, hostname: string, port: string } {
92+
function parseUri (uriStr: string): { scheme: string, hostname: string, port: string, path?: string } {
8993
const [scheme] = uriStr.split(':')
9094

9195
// browsers will only parse URLs with schemes they understand
@@ -94,7 +98,7 @@ function parseUri (uriStr: string): { scheme: string, hostname: string, port: st
9498
}
9599

96100
// Use the WHATWG URL global, in node >= 10 and the browser
97-
let { protocol, hostname, port } = new URL(uriStr)
101+
let { protocol, hostname, port, pathname, search } = new URL(uriStr)
98102

99103
if (port == null || port === '') {
100104
const protocolPort = portForProtocol(scheme)
@@ -110,7 +114,22 @@ function parseUri (uriStr: string): { scheme: string, hostname: string, port: st
110114
}
111115
}
112116

113-
return { scheme, hostname, port }
117+
let path: string | undefined
118+
119+
if (pathname != null && pathname !== '' && pathname !== '/') {
120+
if (pathname.startsWith('/')) {
121+
pathname = pathname.substring(1)
122+
}
123+
124+
path = pathname
125+
}
126+
127+
if (search != null && search !== '') {
128+
path = path ?? ''
129+
path += search
130+
}
131+
132+
return { scheme, hostname, port, path }
114133
}
115134

116135
function tupleForHostname (hostname: string, defaultDnsType: string): [string, string] | undefined {
@@ -158,6 +177,14 @@ function tupleForScheme (scheme: string): [string] | undefined {
158177
return [scheme]
159178
}
160179

180+
function tupleForPath (path: string): [string, string] | undefined {
181+
if (path == null || path === '') {
182+
return undefined
183+
}
184+
185+
return ['http-path', encodeURIComponent(path)]
186+
}
187+
161188
function portForProtocol (protocol: string): string | undefined {
162189
if (protocol == null || protocol === '' || portFor[protocol] == null) {
163190
return undefined

test/test.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ describe('uri-to-multiaddr', () => {
2727
['/ip4/1.2.3.4/tcp/3456/wss', 'wss://1.2.3.4:3456'],
2828
['/ip6/::/tcp/0/ws', 'ws://[::]:0'],
2929
['/ip4/1.2.3.4/tcp/3456/wss', 'wss://1.2.3.4:3456'],
30-
['/ip6/::/tcp/0/wss', 'wss://[::]:0']
30+
['/ip6/::/tcp/0/wss', 'wss://[::]:0'],
31+
['/dns4/example.com/tcp/443/wss/http-path/foo', 'wss://example.com:443/foo']
3132
]
3233

3334
data.forEach(d => {

0 commit comments

Comments
 (0)