cdn-detector
Version:
203 lines (138 loc) • 5.7 kB
Markdown
# cdn-detector.js
v0.1.6
[http://nicj.net](http://nicj.net)
Licensed under the MIT license
## Introduction
`cdn-detector.js` detects whether or not a HTTP response is being served from a Content Delivery Network (CDN),
by inspecting the request's hostname and HTTP response headers.
This project is based on data from:
* [WebpageTest](https://github.com/WPO-Foundation/webpagetest/blob/master/agent/wpthook/cdn.h)
* [cdnfinder.js](https://github.com/sajal/cdnfinder.js/blob/master/lib/guesscnamecdn.js)
## Download
Releases are available for download from [GitHub](https://github.com/nicjansma/cdn-detector.js).
### Web
The main source file is `src/cdn-detector.js`. There are additional JSON data files in `data/*.json`. These
files automatically get converted to `.js` files and are merged into the single-file
distribution `dist/cdn-detector.[min].js` via `gulp`. If you want to use this project in a browser, use one of the `dist/*.js` files:
__Development:__ [cdn-detector.js](https://github.com/nicjansma/cdn-detector.js/raw/master/dist/cdn-detector.js) - 13.8kb
__Production:__ [cdn-detector.min.js](https://github.com/nicjansma/cdn-detector.js/raw/master/dist/cdn-detector.min.js) - 7.0kb minified, 2.3kb gzipped
### NPM
cdn-detector.js is also available as the [npm cdn-detector module](https://npmjs.org/package/cdn-detector). You can install
using Node Package Manager (npm):
npm install cdn-detector
### Bower
cdn-detector.js is also available via [bower](http://bower.io/). You can install using:
bower install cdn-detector
## Usage
To include `cdn-detector.js` in the browser, include it via a script tag:
```html
<script type="text/javascript" src="cdn-detector.min.js"></script>
```
Once included in the page, a top-level `CdnDetector` object is available on `window`. If AMD or CommonJS environments are detected, it will expose itself via those methods.
From the NPM module:
```js
var cdnDetector = require("cdn-detector");
```
Once loaded, `cdn-detector` can be used by calling `CdnDetector.detect(hostname, headers)`:
```js
var cdnDetector = require("cdn-detector");
var result = cdnDetector.detect(
"foo.googleusercontent.com", {
"gws": "1",
});
```
If `result` is non-null, the response was served from a CDN:
```json
{
"cdn": "Google",
"evidence": {
"hostname": "\\.googleusercontent\\.com$",
"headers": [
"gws: *"
]
}
}
```
### API
#### `CdnDetector.detect(hostname, headers)`
Determines whether the `hostname` and HTTP response `headers` indicate that the resource was served via a known CDN.
**Arguments**:
* `hostname`: The requested resource's hostname, such as `foo.googleusercontent.com`.
* `headers`: The HTTP response headers in map form, such as `{ "Server": "Foo", "Via": "Bar" }`
**Returns**: If no CDN was matched, `null`. If a CDN was matched, an object with the CDN name and evidence why:
```json
{
"cdn": "Google",
"evidence": {
"hostname": "\\.googleusercontent\\.com$",
"headers": [
"gws: *"
]
}
}
```
#### `CdnDetector.detectFromHostname(hostname)`
Determines whether the `hostname` indicates that the resource was served via a known CDN.
**Arguments**:
* `hostname`: The requested resource's hostname, such as `foo.googleusercontent.com`.
**Returns**: If no CDN was matched, `null`. If a CDN was matched, an object with the CDN name and evidence why. The
evidence is the regex string that matched the hostname.
```json
{
"cdn": "Google",
"evidence": "\\.googleusercontent\\.com$"
}
```
#### `CdnDetector.detectFromHeaders(hostname, headers)`
Determines whether the HTTP response `headers` indicate that the resource was served via a known CDN.
**Arguments**:
* `headers`: The HTTP response headers in map form, such as `{ "Server": "Foo", "Via": "Bar" }`
**Returns**: If no CDN was matched, `null`. If a CDN was matched, an object with the CDN name and evidence why. The evidence is an array of HTTP response headers that matched:
```json
{
"cdn": "Google",
"evidence": [
"server: foo"
]
}
```
## Data
The data files for hostnames and headers are in the following files:
* `data/headers.json`
* `data/hostnames.json`
* `data/multi-headers.json`
Via `gulp`, these are built as `data/*.js` and are included in the `dist/*.js` files for use on the web.
In NodeJS, these files are used as-is.
## Forcing Headers
Some CDNs may require a HTTP Request Header to be present before they expose a HTTP
Response Header that can be used for fingerprinting.
Known examples:
* [Akamai](https://community.akamai.com/community/web-performance/blog/2015/03/31/using-akamai-pragma-headers-to-investigate-or-troubleshoot-akamai-content-delivery):
`Pragma: akamai-x-get-request-id` will return a `X-Akamai-Request-ID`
If you're using [`request`](https://github.com/request/request) to fetch the
headers, you would add the HTTP Request Header to the `request()` options:
```js
request({
url: url,
gzip: true,
time: true,
headers: {
'pragma': 'akamai-x-get-request-id'
}
}, function(err, response, body) {
...
});
```
## Tests
Tests are provided in the `test/` directory, and can be run via `mocha`:
mocha test/*
Or via ``gulp``:
gulp test
## Version History
* v0.1.0 - 2016-08-17: Initial version
* v0.1.1 - 2016-08-17: Changed what `index.js` points to
* v0.1.2 - 2016-08-17: Fixed `module.exports`
* v0.1.3 - 2016-10-31: jQuery CDN added
* v0.1.4 - 2017-07-02: CDN list updated
* v0.1.5 - 2018-05-12: Added a rule for Akamai and a note about forcing headers
* v0.1.6 - 2018-05-12: Moved one dependency to dev