Fixup tests.

This commit is contained in:
Half-Shot 2024-04-16 22:31:13 +01:00
parent 6157fbccff
commit f2d97af122
2 changed files with 62 additions and 30 deletions

View File

@ -200,17 +200,23 @@ pub async fn js_read_feed(url: String, options: ReadFeedOptions) -> Result<FeedR
headers.append("If-None-Match", HeaderValue::from_str(&etag).unwrap()); headers.append("If-None-Match", HeaderValue::from_str(&etag).unwrap());
} }
let max_content_size = (options.maximum_feed_size_mb * 1024 * 1024) as u64;
match req.headers(headers).send().await { match req.headers(headers).send().await {
Ok(res) => { Ok(res) => {
// Pre-emptive check
let content_length = res.content_length().unwrap_or(0); let content_length = res.content_length().unwrap_or(0);
if content_length > (options.maximum_feed_size_mb * 1024 * 1024) as u64 { if content_length > max_content_size {
return Err(JsError::new(Status::Unknown, "Feed exceeded maximum size")); return Err(JsError::new(Status::Unknown, "Feed exceeded maximum size"));
} }
let res_headers = res.headers().clone(); let res_headers = res.headers().clone();
match res.status() { match res.status() {
StatusCode::OK => match res.text().await { StatusCode::OK => match res.text().await {
Ok(body) => match js_parse_feed(body) { Ok(body) => {
// Check if we only got the length after loading the response.
match body.len() as u64 <= max_content_size {
true => match js_parse_feed(body) {
Ok(feed) => Ok(FeedResult { Ok(feed) => Ok(FeedResult {
feed: Some(feed), feed: Some(feed),
etag: res_headers etag: res_headers
@ -223,6 +229,9 @@ pub async fn js_read_feed(url: String, options: ReadFeedOptions) -> Result<FeedR
.map(|v| v.to_string()), .map(|v| v.to_string()),
}), }),
Err(err) => Err(err), Err(err) => Err(err),
}
false => Err(JsError::new(Status::Unknown, "Feed exceeded maximum size"))
}
}, },
Err(err) => Err(JsError::new(Status::Unknown, err)), Err(err) => Err(JsError::new(Status::Unknown, err)),
}, },

View File

@ -39,12 +39,12 @@ class MockMessageQueue extends EventEmitter implements MessageQueue {
} }
} }
async function constructFeedReader(feedResponse: () => {headers: Record<string,string>, data: string}, extraConfig?: Partial<BridgeConfigFeedsYAML>) { async function constructFeedReader(feedResponse: () => {headers?: Record<string,string>, data: string}, extraConfig?: Partial<BridgeConfigFeedsYAML>) {
const httpServer = await new Promise<Server>(resolve => { const httpServer = await new Promise<Server>(resolve => {
const srv = createServer((_req, res) => { const srv = createServer((_req, res) => {
const { headers, data } = feedResponse(); const { headers, data } = feedResponse();
Object.entries(headers).forEach(([key,value]) => { Object.entries(headers ?? {}).forEach(([key,value]) => {
res.setHeader(key, value); res.setHeader(key, value);
}); });
res.writeHead(200); res.writeHead(200);
@ -300,21 +300,44 @@ describe("FeedReader", () => {
}); });
it("should fail to handle a feed which exceed the maximum size.", async () => { it("should fail to handle a feed which exceed the maximum size.", async () => {
const { feedReader, feedUrl } = await constructFeedReader(() => ({ // Create some data of the right length
headers: { const data = `
'Content-Length': Math.pow(1024, 2).toString(),
}, data: `
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0"> <rss version="2.0">
<channel> <channel>
<title>RSS Title</title> <title>RSS Title</title>
<description>This is an example of an RSS feed</description> <description>This is an example of an RSS feed</description>
<item> ${Array.from({length: 8000}).map((_, i) => `<item>
<title>Example entry</title> <title>Example entry</title>
<guid isPermaLink="true">http://www.example.com/blog/post/1</guid> <guid isPermaLink="true">http://www.example.com/blog/post/${i}</guid>
</item> </item>`).join('')}
</channel> </channel>
</rss>` </rss>`;
const { feedReader, feedUrl } = await constructFeedReader(() => ({
data, headers: { 'Content-Length': data.length.toString()}
}), {
maximumFeedSizeMB: 1
});
await feedReader.pollFeed(feedUrl);
expect(feedReader["feedsFailingParsing"]).to.contain(feedUrl);
});
it("should fail to handle a feed which exceed the maximum size which does NOT send a Content-Length.", async () => {
// Create some data of the right length
const data = `
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title>RSS Title</title>
<description>This is an example of an RSS feed</description>
${Array.from({length: 8000}).map((_, i) => `<item>
<title>Example entry</title>
<guid isPermaLink="true">http://www.example.com/blog/post/${i}</guid>
</item>`).join('')}
</channel>
</rss>`;
const { feedReader, feedUrl } = await constructFeedReader(() => ({
data
}), { }), {
maximumFeedSizeMB: 1 maximumFeedSizeMB: 1
}); });