Skip to content

Commit

Permalink
feat: add timeout config option (#168)
Browse files Browse the repository at this point in the history
  • Loading branch information
JustinBeckwith authored May 4, 2020
1 parent 2bb0246 commit 2f3a6d3
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 1 deletion.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ $ linkinator LOCATION [ --arguments ]
--silent
Only output broken links.

--timeout
Request timeout in ms. Defaults to 0 (no timeout).

--help
Show this command.
```
Expand Down Expand Up @@ -109,6 +112,7 @@ All options are optional. It should look like this:
"recurse": true,
"silent": true,
"concurrency": 100,
"timeout": 0,
"skip": "www.googleapis.com"
}
```
Expand All @@ -127,6 +131,7 @@ Asynchronous method that runs a site wide scan. Options come in the form of an o
- `concurrency` (number) - The number of connections to make simultaneously. Defaults to 100.
- `port` (number) - When the `path` is provided as a local path on disk, the `port` on which to start the temporary web server. Defaults to a random high range order port.
- `recurse` (boolean) - By default, all scans are shallow. Only the top level links on the requested page will be scanned. By setting `recurse` to `true`, the crawler will follow all links on the page, and continue scanning links **on the same domain** for as long as it can go. Results are cached, so no worries about loops.
- `timeout` (number) - By default, requests made by linkinator do not time out (or follow the settings of the OS). This option (in milliseconds) will fail requests after the configured amount of time.
- `linksToSkip` (array | function) - An array of regular expression strings that should be skipped, OR an async function that's called for each link with the link URL as its only argument. Return a Promise that resolves to `true` to skip the link or `false` to check it.

#### linkinator.LinkChecker()
Expand Down
5 changes: 5 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ const cli = meow(
--silent
Only output broken links
--timeout
Request timeout in ms. Defaults to 0 (no timeout).
--help
Show this command.
Expand All @@ -61,6 +64,7 @@ const cli = meow(
skip: {type: 'string', alias: 's'},
format: {type: 'string', alias: 'f'},
silent: {type: 'boolean'},
timeout: {type: 'number'},
},
booleanDefault: undefined,
}
Expand Down Expand Up @@ -110,6 +114,7 @@ async function main() {
const opts: CheckOptions = {
path: cli.input[0],
recurse: flags.recurse,
timeout: Number(flags.timeout),
concurrency: Number(flags.concurrency),
};
if (flags.skip) {
Expand Down
1 change: 1 addition & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export interface Flags {
skip?: string;
format?: string;
silent?: boolean;
timeout?: number;
}

export async function getConfig(flags: Flags) {
Expand Down
6 changes: 5 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface CheckOptions {
port?: number;
path: string;
recurse?: boolean;
timeout?: number;
linksToSkip?: string[] | ((link: string) => Promise<boolean>);
}

Expand Down Expand Up @@ -184,6 +185,7 @@ export class LinkChecker extends EventEmitter {
url: opts.url.href,
responseType: opts.crawl ? 'text' : 'stream',
validateStatus: () => true,
timeout: opts.checkOptions.timeout,
});

// If we got an HTTP 405, the server may not like HEAD. GET instead!
Expand All @@ -193,6 +195,7 @@ export class LinkChecker extends EventEmitter {
url: opts.url.href,
responseType: 'stream',
validateStatus: () => true,
timeout: opts.checkOptions.timeout,
});
}
} catch (err) {
Expand All @@ -212,10 +215,11 @@ export class LinkChecker extends EventEmitter {
url: opts.url.href,
responseType: 'text',
validateStatus: () => true,
timeout: opts.checkOptions.timeout,
});
}
} catch (ex) {
//catch the next failure
// catch the next failure
}

if (res !== undefined) {
Expand Down
1 change: 1 addition & 0 deletions test/test.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ describe('config', () => {
silent: true,
skip: '🌳',
concurrency: 22,
timeout: 1,
};
const config = await getConfig(cfg);
assert.deepStrictEqual(config, cfg);
Expand Down
9 changes: 9 additions & 0 deletions test/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,4 +271,13 @@ describe('linkinator', () => {
assert.ok(results.passed);
scopes.forEach(x => x.done());
});

it('should support a configurable timeout', async () => {
nock('http://fake.local').head('/').delay(200).reply(200);
const results = await check({
path: 'test/fixtures/basic',
timeout: 1,
});
assert.ok(!results.passed);
});
});

0 comments on commit 2f3a6d3

Please sign in to comment.