Skip to content

Instantly share code, notes, and snippets.

@jokester
Last active October 30, 2023 17:22
Show Gist options
  • Save jokester/937c43eb8918e141ef43dc320f38b8d8 to your computer and use it in GitHub Desktop.
Save jokester/937c43eb8918e141ef43dc320f38b8d8 to your computer and use it in GitHub Desktop.
Response.text() may twist underlying bytes
res Response {
[Symbol(realm)]: null,
[Symbol(state)]: {
aborted: false,
rangeRequested: false,
timingAllowPassed: true,
requestIncludesCredentials: true,
type: 'default',
status: 200,
timingInfo: {
startTime: 74.42806800082326,
redirectStartTime: 0,
redirectEndTime: 0,
postRedirectStartTime: 74.42806800082326,
finalServiceWorkerStartTime: 0,
finalNetworkResponseStartTime: 0,
finalNetworkRequestStartTime: 0,
endTime: 0,
encodedBodySize: 538,
decodedBodySize: 538,
finalConnectionTimingInfo: null
},
cacheState: '',
statusText: 'OK',
headersList: HeadersList {
cookies: null,
[Symbol(headers map)]: [Map],
[Symbol(headers map sorted)]: null
},
urlList: [ [URL] ],
body: { stream: undefined }
},
[Symbol(headers)]: HeadersList {
cookies: null,
[Symbol(headers map)]: Map(8) {
'date' => [Object],
'content-type' => [Object],
'content-length' => [Object],
'connection' => [Object],
'last-modified' => [Object],
'etag' => [Object],
'accept-ranges' => [Object],
'server' => [Object]
},
[Symbol(headers map sorted)]: null
}
}
textBytes [
'3c68746d6c3e0a3c686561643e0a3c6d',
'65746120687474702d65717569763d22',
'436f6e74656e742d547970652220636f',
'6e74656e743d22746578742f68746d6c',
'3b20636861727365743d53686966745f',
'4a4953223e0a3c6d657461206e616d65',
'3d2247454e455241544f522220636f6e',
'74656e743d224a75737453797374656d',
'7320486f6d6570616765204275696c64',
'65722056657273696f6e2032302e302e',
'362e3020666f722057696e646f777322',
'3e0a3c6d65746120687474702d657175',
'69763d22436f6e74656e742d5374796c',
'652d547970652220636f6e74656e743d',
'22746578742f637373223e0a3c746974',
'6c653eefbfbdefbfbdefbfbdefbfbdef',
^ "efbfbd" is U+FFFD "Replacement Character" in UTF8.
'bfbdefbfbdefbfbdcc837aefbfbd5bef',
'bfbdefbfbdefbfbd79efbfbd5befbfbd',
'573c2f7469746c653e0a3c2f68656164',
'3e0a3c6672616d6573657420636f6c73',
'3d31382c38323e0a20203c6672616d65',
'207372633d226d656e752e68746d2220',
'6d617267696e6865696768743d223022',
'206d617267696e77696474683d223022',
'207363726f6c6c696e673d226175746f',
'22206e616d653d226c656674223e0a20',
'203c6672616d65207372633d22746f70',
'2e68746d22206d617267696e68656967',
'68743d223022206d617267696e776964',
'74683d223022207363726f6c6c696e67',
'3d226175746f22206e616d653d227269',
'676874223e0a20203c6e6f6672616d65',
'733e0a20203c626f64793e3c2f626f64',
'793e0a20203c2f6e6f6672616d65733e',
'0a3c2f6672616d657365743e0a3c2f68',
'746d6c3e'
]
textBytes [
{ confidence: 100, name: 'UTF-8', lang: undefined },
{ confidence: 45, name: 'GB18030', lang: 'zh' },
{ confidence: 31, name: 'windows-1252', lang: 'fr' },
{ confidence: 18, name: 'windows-1250', lang: 'ro' },
{ confidence: 10, name: 'Shift_JIS', lang: 'ja' },
{ confidence: 10, name: 'Big5', lang: 'zh' },
{ confidence: 8, name: 'windows-1254', lang: 'tr' },
{ confidence: 0, name: 'ASCII', lang: undefined }
]
rawBytes [
'3c68746d6c3e0a3c686561643e0a3c6d',
'65746120687474702d65717569763d22',
'436f6e74656e742d547970652220636f',
'6e74656e743d22746578742f68746d6c',
'3b20636861727365743d53686966745f',
'4a4953223e0a3c6d657461206e616d65',
'3d2247454e455241544f522220636f6e',
'74656e743d224a75737453797374656d',
'7320486f6d6570616765204275696c64',
'65722056657273696f6e2032302e302e',
'362e3020666f722057696e646f777322',
'3e0a3c6d65746120687474702d657175',
'69763d22436f6e74656e742d5374796c',
'652d547970652220636f6e74656e743d',
'22746578742f637373223e0a3c746974',
'6c653e88a295948ab082cc837a815b83',
'808379815b83573c2f7469746c653e0a',
'3c2f686561643e0a3c6672616d657365',
'7420636f6c733d31382c38323e0a2020',
'3c6672616d65207372633d226d656e75',
'2e68746d22206d617267696e68656967',
'68743d223022206d617267696e776964',
'74683d223022207363726f6c6c696e67',
'3d226175746f22206e616d653d226c65',
'6674223e0a20203c6672616d65207372',
'633d22746f702e68746d22206d617267',
'696e6865696768743d223022206d6172',
'67696e77696474683d22302220736372',
'6f6c6c696e673d226175746f22206e61',
'6d653d227269676874223e0a20203c6e',
'6f6672616d65733e0a20203c626f6479',
'3e3c2f626f64793e0a20203c2f6e6f66',
'72616d65733e0a3c2f6672616d657365',
'743e0a3c2f68746d6c3e'
]
rawBytes [
{ confidence: 33, name: 'windows-1252', lang: 'fr' },
{ confidence: 20, name: 'windows-1250', lang: 'ro' },
{ confidence: 10, name: 'Shift_JIS', lang: 'ja' },
{ confidence: 10, name: 'Big5', lang: 'zh' },
{ confidence: 10, name: 'GB18030', lang: 'zh' },
{ confidence: 8, name: 'windows-1254', lang: 'tr' },
{ confidence: 0, name: 'ASCII', lang: undefined }
]
const { fetch } = require('undici');
const chardet = require('chardet');
/**
* @param {Buffer} buffer
*/
function dumpBuffer(buffer) {
const lines = []
const SPAN = 16;
for (let i = 0; ; i += SPAN) {
const slice = buffer.subarray(i, i + SPAN)
if (!slice.length) break
lines.push(slice.toString('hex'))
}
return lines
}
async function main() {
const res = await fetch('http://abehiroshi.la.coocan.jp/')
console.debug('res', res);
const text = await res.clone().text()
const textBytes = Buffer.from(text);
console.debug(`textBytes`, dumpBuffer(textBytes))
console.debug(`textBytes`, chardet.analyse(textBytes))
const rawBytes = Buffer.from(await res.clone().arrayBuffer())
console.debug(`rawBytes`, dumpBuffer(rawBytes))
console.debug(`rawBytes`, chardet.analyse(rawBytes))
}
main().finally(() => process.exit(0));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment