Skip to content

Commit

Permalink
perf(fetch): simplify url serializer
Browse files Browse the repository at this point in the history
  • Loading branch information
anonrig committed Nov 24, 2022
1 parent 93f150f commit ac11cc6
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 89 deletions.
69 changes: 2 additions & 67 deletions lib/fetch/dataURL.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const assert = require('assert')
const { atob } = require('buffer')
const { format } = require('url')
const { isValidHTTPToken, isomorphicDecode } = require('./util')

const encoder = new TextEncoder()
Expand Down Expand Up @@ -111,73 +112,7 @@ function dataURLProcessor (dataURL) {
* @param {boolean} excludeFragment
*/
function URLSerializer (url, excludeFragment = false) {
// 1. Let output be url’s scheme and U+003A (:) concatenated.
let output = url.protocol

// 2. If url’s host is non-null:
if (url.host.length > 0) {
// 1. Append "//" to output.
output += '//'

// 2. If url includes credentials, then:
if (url.username.length > 0 || url.password.length > 0) {
// 1. Append url’s username to output.
output += url.username

// 2. If url’s password is not the empty string, then append U+003A (:),
// followed by url’s password, to output.
if (url.password.length > 0) {
output += ':' + url.password
}

// 3. Append U+0040 (@) to output.
output += '@'
}

// 3. Append url’s host, serialized, to output.
output += decodeURIComponent(url.hostname)

// 4. If url’s port is non-null, append U+003A (:) followed by url’s port,
// serialized, to output.
if (url.port.length > 0) {
output += ':' + url.port
}
}

// 3. If url’s host is null, url does not have an opaque path,
// url’s path’s size is greater than 1, and url’s path[0]
// is the empty string, then append U+002F (/) followed by
// U+002E (.) to output.
// Note: This prevents web+demo:/.//not-a-host/ or web+demo:/path/..//not-a-host/,
// when parsed and then serialized, from ending up as web+demo://not-a-host/
// (they end up as web+demo:/.//not-a-host/).
// Undici implementation note: url's path[0] can never be an
// empty string, so we have to slightly alter what the spec says.
if (
url.host.length === 0 &&
url.pathname.length > 1 &&
url.href.slice(url.protocol.length + 1)[0] === '.'
) {
output += '/.'
}

// 4. Append the result of URL path serializing url to output.
output += url.pathname

// 5. If url’s query is non-null, append U+003F (?),
// followed by url’s query, to output.
if (url.search.length > 0) {
output += url.search
}

// 6. If exclude fragment is false and url’s fragment is non-null,
// then append U+0023 (#), followed by url’s fragment, to output.
if (excludeFragment === false && url.hash.length > 0) {
output += url.hash
}

// 7. Return output.
return output
return format(url, { fragment: excludeFragment !== false })
}

// https://infra.spec.whatwg.org/#collect-a-sequence-of-code-points
Expand Down
11 changes: 11 additions & 0 deletions test/fetch/data-uri.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,14 @@ test('too long base64 url', async (t) => {
t.fail(`failed to fetch ${dataURL}`)
}
})

test('https://domain.com#', (t) => {
const domain = 'https://domain.com#'
const serialized = URLSerializer(new URL(domain))
t.same(serialized, domain)
})

test('https://domain.com?', (t) => {
const domain = 'https://domain.com?'
t.same(URLSerializer(new URL(domain)), domain)
})
22 changes: 0 additions & 22 deletions test/node-fetch/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -1532,17 +1532,6 @@ describe('node-fetch', () => {
})
})

it('should NOT keep `?` sign in URL when no params are given', () => {
const url = `${base}question?`
const urlObject = new URL(url)
const request = new Request(urlObject)
return fetch(request).then(res => {
expect(res.url).to.equal(url.slice(0, -1))
expect(res.ok).to.be.true
expect(res.status).to.equal(200)
})
})

it('if params are given, do not modify anything', () => {
const url = `${base}question?a=1`
const urlObject = new URL(url)
Expand All @@ -1554,17 +1543,6 @@ describe('node-fetch', () => {
})
})

it('should NOT preserve the hash (#) symbol', () => {
const url = `${base}question?#`
const urlObject = new URL(url)
const request = new Request(urlObject)
return fetch(request).then(res => {
expect(res.url).to.equal(url.slice(0, -2))
expect(res.ok).to.be.true
expect(res.status).to.equal(200)
})
})

it('should support reading blob as text', () => {
return new Response('hello')
.blob()
Expand Down

0 comments on commit ac11cc6

Please sign in to comment.