mirror of
https://github.com/matrix-org/matrix-hookshot.git
synced 2025-03-10 21:19:13 +00:00
Aidd a maximum speed size
This commit is contained in:
parent
6c6cd6ee92
commit
1ef0026509
@ -10,6 +10,7 @@ import { GetConnectionsResponseItem } from "../provisioning/api";
|
||||
import { readFeed, sanitizeHtml } from "../libRs";
|
||||
import UserAgent from "../UserAgent";
|
||||
import { retry, retryMatrixErrorFilter } from "../PromiseUtil";
|
||||
import { BridgeConfigFeeds } from "../config/Config";
|
||||
const log = new Logger("FeedConnection");
|
||||
const md = new markdown({
|
||||
html: true,
|
||||
@ -64,7 +65,7 @@ export class FeedConnection extends BaseConnection implements IConnection {
|
||||
return new FeedConnection(roomId, event.stateKey, event.content, intent);
|
||||
}
|
||||
|
||||
static async validateUrl(url: string): Promise<void> {
|
||||
static async validateUrl(url: string, config: BridgeConfigFeeds): Promise<void> {
|
||||
try {
|
||||
new URL(url);
|
||||
} catch (ex) {
|
||||
@ -75,6 +76,7 @@ export class FeedConnection extends BaseConnection implements IConnection {
|
||||
await readFeed(url, {
|
||||
userAgent: UserAgent,
|
||||
pollTimeoutSeconds: VALIDATION_FETCH_TIMEOUT_S,
|
||||
maximumFeedSizeMb: config.maximumFeedSizeMB,
|
||||
});
|
||||
} catch (ex) {
|
||||
throw new ApiError(`Could not read feed from URL: ${ex.message}`, ErrCode.BadValue);
|
||||
@ -113,7 +115,7 @@ export class FeedConnection extends BaseConnection implements IConnection {
|
||||
}
|
||||
|
||||
const state = this.validateState(data);
|
||||
await FeedConnection.validateUrl(state.url);
|
||||
await FeedConnection.validateUrl(state.url, config.feeds);
|
||||
const connection = new FeedConnection(roomId, state.url, state, intent);
|
||||
await intent.underlyingClient.sendStateEvent(roomId, FeedConnection.CanonicalEventType, state.url, state);
|
||||
|
||||
|
@ -312,7 +312,7 @@ export class SetupConnection extends CommandConnection {
|
||||
|
||||
// provisionConnection will check it again, but won't give us a nice CommandError on failure
|
||||
try {
|
||||
await FeedConnection.validateUrl(url);
|
||||
await FeedConnection.validateUrl(url, this.config.feeds);
|
||||
} catch (err: unknown) {
|
||||
log.debug(`Feed URL '${url}' failed validation: ${err}`);
|
||||
if (err instanceof ApiError) {
|
||||
|
@ -251,6 +251,7 @@ export interface BridgeConfigFeedsYAML {
|
||||
pollIntervalSeconds?: number;
|
||||
pollConcurrency?: number;
|
||||
pollTimeoutSeconds?: number;
|
||||
maximumFeedSizeMB?: number;
|
||||
}
|
||||
|
||||
export class BridgeConfigFeeds {
|
||||
@ -259,6 +260,9 @@ export class BridgeConfigFeeds {
|
||||
public pollTimeoutSeconds: number;
|
||||
public pollConcurrency: number;
|
||||
|
||||
@configKey("The maximum response size of a feed on first load. Oversized responses will prevent a connection from being created.", true)
|
||||
public maximumFeedSizeMB: number;
|
||||
|
||||
constructor(yaml: BridgeConfigFeedsYAML) {
|
||||
this.enabled = yaml.enabled;
|
||||
this.pollConcurrency = yaml.pollConcurrency ?? 4;
|
||||
@ -266,6 +270,11 @@ export class BridgeConfigFeeds {
|
||||
assert.strictEqual(typeof this.pollIntervalSeconds, "number");
|
||||
this.pollTimeoutSeconds = yaml.pollTimeoutSeconds ?? 30;
|
||||
assert.strictEqual(typeof this.pollTimeoutSeconds, "number");
|
||||
this.maximumFeedSizeMB = yaml.maximumFeedSizeMB ?? 25;
|
||||
assert.strictEqual(typeof this.maximumFeedSizeMB, "number");
|
||||
if (this.maximumFeedSizeMB < 1) {
|
||||
throw new ConfigError('feeds.maximumFeedSizeMB', 'Must be at least 1MB or greater');
|
||||
}
|
||||
}
|
||||
|
||||
@hideKey()
|
||||
|
@ -124,6 +124,7 @@ export const DefaultConfigRoot: BridgeConfigRoot = {
|
||||
pollIntervalSeconds: 600,
|
||||
pollTimeoutSeconds: 30,
|
||||
pollConcurrency: 4,
|
||||
maximumFeedSizeMB: 25,
|
||||
},
|
||||
provisioning: {
|
||||
secret: "!secretToken"
|
||||
|
@ -215,6 +215,7 @@ export class FeedReader {
|
||||
etag,
|
||||
lastModified,
|
||||
userAgent: UserAgent,
|
||||
maximumFeedSizeMb: this.config.maximumFeedSizeMB,
|
||||
});
|
||||
|
||||
// Store any entity tags/cache times.
|
||||
|
@ -37,6 +37,7 @@ pub struct ReadFeedOptions {
|
||||
pub etag: Option<String>,
|
||||
pub poll_timeout_seconds: i64,
|
||||
pub user_agent: String,
|
||||
pub maximum_feed_size_mb: i64,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug, Deserialize)]
|
||||
@ -202,6 +203,13 @@ pub async fn js_read_feed(url: String, options: ReadFeedOptions) -> Result<FeedR
|
||||
match req.headers(headers).send().await {
|
||||
Ok(res) => {
|
||||
let res_headers = res.headers().clone();
|
||||
if res.content_length().unwrap_or(0) > options.maximum_feed_size_mb as u64 {
|
||||
return Err(JsError::new(
|
||||
Status::Unknown,
|
||||
"Feed exceeded maximum size",
|
||||
));
|
||||
}
|
||||
|
||||
match res.status() {
|
||||
StatusCode::OK => match res.text().await {
|
||||
Ok(body) => match js_parse_feed(body) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user