[DynamicXml] parse doc as html if served with text/html content type (#10607)
This commit is contained in:
@@ -70,7 +70,7 @@ export default class DynamicXml extends BaseService {
|
||||
|
||||
static defaultBadgeData = { label: 'custom badge' }
|
||||
|
||||
transform({ pathExpression, buffer }) {
|
||||
transform({ pathExpression, buffer, contentType = 'text/xml' }) {
|
||||
// e.g. //book[2]/@id
|
||||
const pathIsAttr = (
|
||||
pathExpression.split('/').slice(-1)[0] || ''
|
||||
@@ -78,14 +78,20 @@ export default class DynamicXml extends BaseService {
|
||||
|
||||
let parsed
|
||||
try {
|
||||
parsed = new DOMParser().parseFromString(buffer, 'text/xml')
|
||||
parsed = new DOMParser().parseFromString(buffer, contentType)
|
||||
} catch (e) {
|
||||
throw new InvalidResponse({ prettyMessage: e.message })
|
||||
}
|
||||
|
||||
let values
|
||||
try {
|
||||
values = xpath.select(pathExpression, parsed)
|
||||
if (contentType === 'text/html') {
|
||||
values = xpath
|
||||
.parse(pathExpression)
|
||||
.select({ node: parsed, isHtml: true })
|
||||
} else {
|
||||
values = xpath.select(pathExpression, parsed)
|
||||
}
|
||||
} catch (e) {
|
||||
throw new InvalidParameter({ prettyMessage: e.message })
|
||||
}
|
||||
@@ -122,16 +128,25 @@ export default class DynamicXml extends BaseService {
|
||||
}
|
||||
|
||||
async handle(_namedParams, { url, query: pathExpression, prefix, suffix }) {
|
||||
const { buffer } = await this._request({
|
||||
const { buffer, res } = await this._request({
|
||||
url,
|
||||
options: { headers: { Accept: 'application/xml, text/xml' } },
|
||||
httpErrors,
|
||||
logErrors: [],
|
||||
})
|
||||
|
||||
let contentType = 'text/xml'
|
||||
if (
|
||||
res.headers['content-type'] &&
|
||||
res.headers['content-type'].includes('text/html')
|
||||
) {
|
||||
contentType = 'text/html'
|
||||
}
|
||||
|
||||
const { values: value } = this.transform({
|
||||
pathExpression,
|
||||
buffer,
|
||||
contentType,
|
||||
})
|
||||
|
||||
return renderDynamicBadge({ value, prefix, suffix })
|
||||
|
||||
@@ -20,6 +20,29 @@ const exampleXml = `<?xml version="1.0"?>
|
||||
</catalog>
|
||||
`
|
||||
|
||||
const exampleHtml = `<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Herman Melville - Moby-Dick</h1>
|
||||
<div>
|
||||
<p>
|
||||
Availing himself of the mild, summer-cool weather that now reigned in these
|
||||
latitudes, and in preparation for the peculiarly active pursuits shortly to
|
||||
be anticipated, Perth, the begrimed, blistered old blacksmith, had not
|
||||
removed his portable forge to the hold again, after concluding his
|
||||
contributory work for Ahab's leg, but still retained it on deck, fast lashed
|
||||
to ringbolts by the foremast; being now almost incessantly invoked by the
|
||||
headsmen, and harpooneers, and bowsmen to do some little job for them;
|
||||
altering, or repairing, or new shaping their various weapons and boat
|
||||
furniture.
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
|
||||
describe('DynamicXml', function () {
|
||||
describe('transform()', function () {
|
||||
beforeEach(function () {
|
||||
@@ -126,5 +149,12 @@ describe('DynamicXml', function () {
|
||||
}).expect({
|
||||
values: ["XML Developer's Guide", '44.95'],
|
||||
})
|
||||
given({
|
||||
pathExpression: '//h1[1]',
|
||||
buffer: exampleHtml,
|
||||
contentType: 'text/html',
|
||||
}).expect({
|
||||
values: ['Herman Melville - Moby-Dick'],
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -215,3 +215,16 @@ t.create('query with type conversion to number')
|
||||
message: '44.95',
|
||||
color: 'blue',
|
||||
})
|
||||
|
||||
t.create('query HTML document')
|
||||
.get(
|
||||
`.json?${queryString.stringify({
|
||||
url: 'https://httpbin.org/html',
|
||||
query: '//h1[1]',
|
||||
})}`,
|
||||
)
|
||||
.expectBadge({
|
||||
label: 'custom badge',
|
||||
message: 'Herman Melville - Moby-Dick',
|
||||
color: 'blue',
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user