import React from "react"
import PropTypes from "prop-types"
import formatXml from "xml-but-prettier"
import lowerCase from "lodash/lowerCase"
export default class ResponseBody extends React.Component {
static propTypes = {
content: PropTypes.any.isRequired,
contentType: PropTypes.string,
getComponent: PropTypes.func.isRequired,
headers: PropTypes.object,
url: PropTypes.string
}
render() {
let { content, contentType, url, headers={}, getComponent } = this.props
const HighlightCode = getComponent("highlightCode")
let body, bodyEl
url = url || ""
// JSON
if (/json/i.test(contentType)) {
try {
body = JSON.stringify(JSON.parse(content), null, " ")
} catch (error) {
body = "can't parse JSON. Raw result:\n\n" + content
}
bodyEl =
// XML
} else if (/xml/i.test(contentType)) {
body = formatXml(content, {
textNodesOnSameLine: true
})
bodyEl =
// HTML or Plain Text
} else if (lowerCase(contentType) === "text/html" || /text\/plain/.test(contentType)) {
bodyEl =
// Image
} else if (/^image\//i.test(contentType)) {
bodyEl =
// Audio
} else if (/^audio\//i.test(contentType)) {
bodyEl =
// Download
} else if (
/^application\/octet-stream/i.test(contentType) ||
(headers["Content-Disposition"] && (/attachment/i).test(headers["Content-Disposition"])) ||
(headers["content-disposition"] && (/attachment/i).test(headers["content-disposition"])) ||
(headers["Content-Description"] && (/File Transfer/i).test(headers["Content-Description"])) ||
(headers["content-description"] && (/File Transfer/i).test(headers["content-description"]))) {
let contentLength = headers["content-length"] || headers["Content-Length"]
if ( !(+contentLength) ) return null
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)
if (!isSafari && "Blob" in window) {
let type = contentType || "text/html"
let blob = (content instanceof Blob) ? content : new Blob([content], {type: type})
let href = window.URL.createObjectURL(blob)
let fileName = url.substr(url.lastIndexOf("/") + 1)
let download = [type, fileName, href].join(":")
// Use filename from response header
let disposition = headers["content-disposition"] || headers["Content-Disposition"]
if (typeof disposition !== "undefined") {
let responseFilename = /filename=([^;]*);?/i.exec(disposition)
if (responseFilename !== null && responseFilename.length > 1) {
download = responseFilename[1]
}
}
bodyEl =
} else {
bodyEl = Download headers detected but your browser does not support downloading binary via XHR (Blob).
}
// Anything else (CORS)
} else if (typeof content === "string") {
bodyEl =
} else if ( content.size > 0 ) {
// We don't know the contentType, but there was some content returned
bodyEl = Unknown response type
} else {
// We don't know the contentType and there was no content returned
bodyEl = null
}
return ( !bodyEl ? null :
Response body
{ bodyEl }
)
}
}