| [9af201e] | 1 | "use strict";
|
|---|
| 2 | const MIMEType = require("whatwg-mimetype");
|
|---|
| 3 | const { parseURL, serializeURL } = require("whatwg-url");
|
|---|
| 4 | const {
|
|---|
| 5 | stripLeadingAndTrailingASCIIWhitespace,
|
|---|
| 6 | stringPercentDecode,
|
|---|
| 7 | isomorphicDecode,
|
|---|
| 8 | forgivingBase64Decode
|
|---|
| 9 | } = require("./utils.js");
|
|---|
| 10 |
|
|---|
| 11 | module.exports = stringInput => {
|
|---|
| 12 | const urlRecord = parseURL(stringInput);
|
|---|
| 13 |
|
|---|
| 14 | if (urlRecord === null) {
|
|---|
| 15 | return null;
|
|---|
| 16 | }
|
|---|
| 17 |
|
|---|
| 18 | return module.exports.fromURLRecord(urlRecord);
|
|---|
| 19 | };
|
|---|
| 20 |
|
|---|
| 21 | module.exports.fromURLRecord = urlRecord => {
|
|---|
| 22 | if (urlRecord.scheme !== "data") {
|
|---|
| 23 | return null;
|
|---|
| 24 | }
|
|---|
| 25 |
|
|---|
| 26 | const input = serializeURL(urlRecord, true).substring("data:".length);
|
|---|
| 27 |
|
|---|
| 28 | let position = 0;
|
|---|
| 29 |
|
|---|
| 30 | let mimeType = "";
|
|---|
| 31 | while (position < input.length && input[position] !== ",") {
|
|---|
| 32 | mimeType += input[position];
|
|---|
| 33 | ++position;
|
|---|
| 34 | }
|
|---|
| 35 | mimeType = stripLeadingAndTrailingASCIIWhitespace(mimeType);
|
|---|
| 36 |
|
|---|
| 37 | if (position === input.length) {
|
|---|
| 38 | return null;
|
|---|
| 39 | }
|
|---|
| 40 |
|
|---|
| 41 | ++position;
|
|---|
| 42 |
|
|---|
| 43 | const encodedBody = input.substring(position);
|
|---|
| 44 |
|
|---|
| 45 | let body = stringPercentDecode(encodedBody);
|
|---|
| 46 |
|
|---|
| 47 | // Can't use /i regexp flag because it isn't restricted to ASCII.
|
|---|
| 48 | const mimeTypeBase64MatchResult = /(.*); *[Bb][Aa][Ss][Ee]64$/.exec(mimeType);
|
|---|
| 49 | if (mimeTypeBase64MatchResult) {
|
|---|
| 50 | const stringBody = isomorphicDecode(body);
|
|---|
| 51 | body = forgivingBase64Decode(stringBody);
|
|---|
| 52 |
|
|---|
| 53 | if (body === null) {
|
|---|
| 54 | return null;
|
|---|
| 55 | }
|
|---|
| 56 | mimeType = mimeTypeBase64MatchResult[1];
|
|---|
| 57 | }
|
|---|
| 58 |
|
|---|
| 59 | if (mimeType.startsWith(";")) {
|
|---|
| 60 | mimeType = "text/plain" + mimeType;
|
|---|
| 61 | }
|
|---|
| 62 |
|
|---|
| 63 | let mimeTypeRecord;
|
|---|
| 64 | try {
|
|---|
| 65 | mimeTypeRecord = new MIMEType(mimeType);
|
|---|
| 66 | } catch (e) {
|
|---|
| 67 | mimeTypeRecord = new MIMEType("text/plain;charset=US-ASCII");
|
|---|
| 68 | }
|
|---|
| 69 |
|
|---|
| 70 | return {
|
|---|
| 71 | mimeType: mimeTypeRecord,
|
|---|
| 72 | body
|
|---|
| 73 | };
|
|---|
| 74 | };
|
|---|