Skip to content

Commit

Permalink
Initial implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
nwoltman committed Jul 5, 2019
1 parent 4de7c93 commit 7bb3da8
Show file tree
Hide file tree
Showing 9 changed files with 386 additions and 3 deletions.
20 changes: 20 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"root": true,
"extends": "@nwoltman/eslint-config",
"overrides": [
{
"files": ["test/test.js"],
"env": {
"mocha": true
},
"rules": {
"consistent-return": "off",
"max-len": "off",
"max-nested-callbacks": "off",
"no-sync": "off",
"padded-blocks": "off",
"prefer-arrow-callback": "off"
}
}
]
}
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text=auto
75 changes: 75 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env

# next.js build output
.next

# Mac files
.DS_Store

# Sublime Text
*.sublime-*

# VS Code
.vscode
*code-workspace

# Lock files
yarn.lock
package-lock.json
22 changes: 22 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
language: node_js
node_js:
- '12'
- '10'
after_success: npm run coveralls
stages:
- test
- name: npm release
if: tag IS present
jobs:
include:
- stage: npm release
install: skip
script: skip
after_success: true
deploy:
provider: npm
email: [email protected]
on:
tags: true
api_key:
secure: Cjg1hcBxKT8j203uVIhvvXjl+L5qHloM+1UdjFw3WnZqxglrMLaGimIbkcMXPcNWL4fI550qOs9z4/OMeNHsWj/e5u0khxTNSAR5uJyQIFt6giul0udUJNOcI9sCBDJwF15twzM2AaHoVenLR6+jA/25aOedaeBrT0EX70dosRiJ8+FExVSLezPhbXQUFHhHZ+XutcTGY1KVHM81wluL0O7s9KliVmmzG9VkFQUbQ6qGTcUmKEEV+raryspf6TGT4HSEy5XM+BzU4LQEmgvWcyC55hiuR6nhrl5qRhHxg92cKsnNmmc2Q5Uh43aIx1Uhog3Q8hXyU9fLEDBbqR5Ud+5zZJKqwGHgpUXUdzZRZnXjB4RBobmlVU479rwo73kUVuOJAjL9H2w7ryXl6G3ZZFeEJbu+AbAOOqUsRTGZ4HLLJNSqcLtY25G9Ymy9ezPZe0LE2f357iF0y4ahg+t9+SEXxACytAwWlIjJY4OlOSTn3sDlgJusz9iJoyjDLSCGrUy+PbYbOxVft0YmwgQNagAa0z/XhL7W+dNGAJ9brtZTf5f7Q1uPRpNgXiYMRxOUV8mVDrGCMaGovicvDhMDDc4zWHWpEllONAn28QfOHQvYQMcXd5Wo7XpRfep/fQZ+DPAwod6Xdd9s7qif8yiOFEBJMb2zrKrEWYQM+77v9m0=
2 changes: 1 addition & 1 deletion LICENSE → LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2019 Medley
Copyright (c) 2019-present The Medley Team (https://github.com/orgs/medleyjs/people)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
35 changes: 33 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,33 @@
# etag
Medley plugin for automatic ETag generation + conditional GET responses
# @medley/etag

[![npm Version](https://img.shields.io/npm/v/@medley/etag.svg)](https://www.npmjs.com/package/@medley/etag)
[![Build Status](https://travis-ci.org/medleyjs/etag.svg?branch=master)](https://travis-ci.org/medleyjs/etag)
[![Coverage Status](https://coveralls.io/repos/github/medleyjs/etag/badge.svg?branch=master)](https://coveralls.io/github/medleyjs/etag?branch=master)
[![dependencies Status](https://img.shields.io/david/medleyjs/etag.svg)](https://david-dm.org/medleyjs/etag)

[Medley](https://www.npmjs.com/package/@medley/medley) plugin for automatic ETag generation & conditional GET responses.

Generates an `ETag` header for `string` and `Buffer` response bodies and sends a `304 Not Modified` response if the ETag matches the incoming `If-None-Match` header.

## Installation

```sh
npm install @medley/etag
# or
yarn add @medley/etag
```

## Usage

```js
const medley = require('@medley/medley');
const app = medley();

app.register(require('@medley/etag'));

app.get('/', (req, res) => {
res.send('Hello World');
});

app.listen(3000);
```
45 changes: 45 additions & 0 deletions etag.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
'use strict';

const {createHash} = require('crypto');

const rgxNoCache = /(?:^|,)\s*?no-cache\s*?(?:,|$)/;

function onSend(req, res, body, next) {
if (
res.statusCode !== 200 ||
req.headers['cache-control'] !== undefined && rgxNoCache.test(req.headers['cache-control'])
) {
next();
return;
}

let {etag} = res.headers;

if (etag === undefined) {
if (typeof body !== 'string' && body instanceof Buffer === false) {
next();
return;
}

const hash = createHash('sha1')
.update(body, 'utf8')
.digest('base64')
.slice(0, 27);

etag = '"' + body.length.toString(36) + '-' + hash + '"';
res.headers.etag = etag;
}

if (req.headers['if-none-match'] === etag) {
res.statusCode = 304;
next(null, null);
} else {
next();
}
}

function etagPlugin(app) {
app.addHook('onSend', onSend);
}

module.exports = etagPlugin;
37 changes: 37 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"name": "@medley/etag",
"version": "0.0.0",
"description": "Medley plugin for automatic ETag generation & conditional GET responses",
"author": "Nathan Woltman <[email protected]>",
"license": "MIT",
"main": "etag.js",
"files": [
"etag.js"
],
"engines": {
"node": ">=8"
},
"repository": "github:medleyjs/etag",
"homepage": "https://github.com/medleyjs/etag",
"bugs": "https://github.com/medleyjs/etag/issues",
"keywords": [
"medley",
"plugin",
"etag",
"conditional-get"
],
"devDependencies": {
"@medley/medley": "~0.12.1",
"@medley/self-request": "~0.3.0",
"@nwoltman/eslint-config": "~0.2.1",
"coveralls": "^3.0.4",
"eslint": "^5.16.0",
"mocha": "^6.1.4",
"nyc": "^14.1.1"
},
"scripts": {
"lint": "eslint .",
"test": "eslint . && nyc --reporter=html --reporter=text-summary mocha",
"coveralls": "nyc report --reporter=text-lcov | coveralls"
}
}
Loading

0 comments on commit 7bb3da8

Please sign in to comment.