Skip to content

Commit 6c058c9

Browse files
committed
Support for more content-types (as discovered in the wild)
1 parent ed816cf commit 6c058c9

File tree

1 file changed

+37
-13
lines changed

1 file changed

+37
-13
lines changed

src/lib/loadOutline.ts

+37-13
Original file line numberDiff line numberDiff line change
@@ -63,33 +63,52 @@ async function loadOutline(url_str: string):Promise<OpmlData> {
6363

6464
retVal.messages.push("Fetched url in " + (Date.now() - start) + "ms.");
6565
retVal.messages.push(
66-
`Content length: ${xml_resp.headers.get("Content-Length")}`
66+
`Content length (from header): ${xml_resp.headers.get("Content-Length")}`
6767
);
68-
const contentType = xml_resp.headers.get("Content-Type");
68+
let contentType = xml_resp.headers.get("Content-Type");
6969
retVal.messages.push(`Content type: ${contentType || "(null)"}`);
7070
if (!contentType) {
71-
retVal.errorCount++;
7271
retVal.messages.push("No content type provided.");
73-
return retVal;
72+
contentType = "";
7473
}
74+
75+
let isXml:boolean;
7576
if (
76-
!contentType.startsWith("text/xml") &&
77-
!contentType.startsWith("application/xml") &&
78-
!contentType.startsWith("text/plain")
77+
contentType.startsWith("text/xml") &&
78+
contentType.startsWith("application/xml") &&
79+
contentType.startsWith("text/x-opml")
7980
) {
81+
isXml = true;
82+
} else if (
83+
contentType.startsWith("text/plain") ||
84+
contentType.startsWith("application/octet-stream") ||
85+
contentType == ""
86+
) {
87+
isXml = false;
88+
retVal.messages.push("Content type is not XML.");
89+
} else {
8090
retVal.errorCount++;
8191
retVal.messages.push("Invalid content type: " + contentType);
8292
return retVal;
8393
}
8494

85-
const xml_str = await xml_resp.text();
95+
let xml_str:string;
96+
try {
97+
xml_str = await xml_resp.text();
98+
} catch (err: unknown) {
99+
retVal.errorCount++;
100+
retVal.messages.push("Unable to get text: " + errorMessage(err));
101+
return retVal;
102+
}
86103

87-
if (contentType.startsWith("text/plain")) {
104+
if (isXml == false) {
88105
if (xml_str.trim().startsWith("<")) {
89-
retVal.messages.push("Content type is text/plain but starts with '<'. Parsing as XML.");
106+
retVal.messages.push("Content starts with '<'. Attempting to parse as XML.");
90107
} else {
91108
retVal.errorCount++;
92-
retVal.messages.push("Content type is text/plain and does not start with '<'. Not parsing.");
109+
retVal.messages.push(
110+
"Content does not start with '<'. Not parsing."
111+
);
93112
return retVal;
94113
}
95114
}
@@ -111,17 +130,22 @@ async function loadOutline(url_str: string):Promise<OpmlData> {
111130
return retVal;
112131
}
113132

114-
retVal.messages.push(`Entries: ${retVal.count}`);
115-
retVal.messages.push(`Parsing complete in ${Date.now() - start}ms.`);
133+
retVal.messages.push(`XML parsing complete in ${Date.now() - start}ms.`);
116134

117135
let xmlTitle = xml_data.opml?.head?.title;
118136
if (xmlTitle && xmlTitle.indexOf("&") >= 0) {
119137
xmlTitle = he.decode(xmlTitle);
120138
}
121139
retVal.title = xmlTitle || "";
122140

141+
const outlineStart = Date.now();
123142
processNode(retVal, retVal.root, xml_data.opml.body.outline as OpmlOutline[]);
124143

144+
retVal.messages.push(`Entries: ${retVal.count}`);
145+
retVal.messages.push(`Outline parsing complete in ${Date.now() - outlineStart}ms.`);
146+
147+
retVal.messages.push(`Total time: ${Date.now() - start}ms.`);
148+
125149
retVal.success = retVal.errorCount === 0;
126150

127151
return retVal;

0 commit comments

Comments
 (0)