-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
328 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -1,2 +1,38 @@ | |||
connect-strictenjs | connect-strictenjs | ||
================== | ================== | ||
|
|||
overview | |||
-------- | |||
|
|||
This is a connect middelware that adds ECMAScript 5 (ES5) strict mode by prepending "use strict" to all javascript blocks. | |||
As developers do not need to modify the html or JS code that the server is serving, one could quickly test if their | |||
code are compatible with the ES5 strict mode. | |||
|
|||
The package also comes with a code beautifier (based on UglifyJS2), which allows easier troubleshooting when syntax errors | |||
are reported on minified code. | |||
|
|||
recommended usage | |||
----------------- | |||
|
|||
Use it with the javascript testing framework that use connect. To enable the middleware, one should simply patch the | |||
code with | |||
|
|||
```javascript | |||
var strict = require('connect-strictenjs'); | |||
|
|||
app = express(); | |||
|
|||
app.use(strict.stricten() ); | |||
app.use(strict.beautifier()); | |||
|
|||
// ... other logics that render the pages | |||
``` | |||
|
|||
Then install the package via | |||
|
|||
```shell | |||
npm link | |||
``` | |||
|
|||
Sample code could be found in the example directory. | |||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1 @@ | |||
<script src=helloworld.js></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,4 @@ | |||
(function(){ console.log('hello world!'); document.write('hello world'); /* this is a quick and dirty... */ })(); | |||
var b = 2; | |||
(function(){ b = 3; console.log("b ="+ b);})(); | |||
(function(){ a = 1; console.log("a ="+ a);})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,9 @@ | |||
|
|||
|
|||
|
|||
<script> | |||
(function(){var k=13,d=4,j=0,a=document.documentElement,b=[a.className],f,c=navigator.plugins,g=k;if(c&&c.length){f=c["Shockwave Flash"];if(f&&f.description){j=parseInt(f.description.match(/\b(\d+)\.\d+\b/)[1],10)||0}}else{while(g--){try{new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+g);j=g;break}catch(h){}}}b.push("flash-"+j);while(j-->d){b.push("flash-gt"+j)}a.className=b.join(" ")})(); | |||
</script> | |||
|
|||
<script type="text/javascript"> | |||
rtTop = Number(new Date()); document.documentElement.className += ' jsenabled'; </script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,29 @@ | |||
var express = require('express'); | |||
var connect = require('connect'); | |||
|
|||
var httpProxy = require('http-proxy') | |||
var url = require('url'); | |||
|
|||
// for development, use npm link to create symlink based installation. | |||
var strict = require('connect-strictenjs'); | |||
|
|||
var proxy = new httpProxy.RoutingProxy(); | |||
|
|||
app = express(); | |||
|
|||
var proxyware = function( req, res ) { | |||
var uri = url.parse(req.url); | |||
req.headers["Accept-Encoding"] = ''; | |||
proxy.proxyRequest(req, res, { | |||
host: uri.hostname, | |||
port: uri.port || 80 | |||
}); | |||
}; | |||
|
|||
// app.use(express.logger()); | |||
app.use(connect.responseTime()); | |||
app.use(strict.stricten() ); | |||
app.use(strict.beautifier()); | |||
app.all('/*',proxyware); | |||
|
|||
app.listen(8080); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,18 @@ | |||
var express = require('express'); | |||
var connect = require('connect'); | |||
|
|||
var url = require('url'); | |||
|
|||
// for development, use npm link to create symlink based installation. | |||
var strict = require('connect-strictenjs'); | |||
|
|||
app = express(); | |||
|
|||
// app.use(express.logger()); | |||
app.use(connect.responseTime()); | |||
app.use(strict.stricten() ); | |||
app.use(strict.beautifier()); | |||
|
|||
app.use(express.static(__dirname + '/html')); | |||
|
|||
app.listen(8080); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,206 @@ | |||
exports.filterJS = function( req, res ) { | |||
|
|||
// TODO don't test url. | |||
return ( | |||
/\.js/.test(req.url) | |||
&& req.accepts('json') == 'json' | |||
&& res.statusCode == 200 | |||
) ; | |||
} | |||
|
|||
exports.filterHTML = function( req, res ) { | |||
return ( | |||
req.accepts('html') == 'html' | |||
&& res.statusCode == 200 | |||
) ; | |||
} | |||
|
|||
exports.beautify = function( body, p1, p2, p3 ) { | |||
if( p3 ) body = p2; | |||
try { | |||
var U = require("uglify-js2"); | |||
var ostream = U.OutputStream({beautify: true, source_map: null} ); | |||
var toplevel = U.parse(body); | |||
toplevel.print(ostream); | |||
if( p3 ) | |||
return p1 + "\n" + ostream.toString() + "\n" + p3 ; | |||
else | |||
return ostream.toString(); | |||
} catch (e) { | |||
console.log(body); | |||
console.log(e) | |||
} | |||
return body; | |||
} | |||
|
|||
exports.strictening = function( body, p1, p2, p3 ) { | |||
if( p3 ) | |||
return p1 + "\n" + '"use strict";' + "\n" + p2 + "\n" + p3 ; | |||
else | |||
return '"use strict";' + "\n" + body; | |||
} | |||
|
|||
exports.beautifier = function(options) { | |||
|
|||
var options = options || {} ; | |||
|
|||
return function (req, res, next) { | |||
|
|||
var | |||
write = res.write | |||
, writeHead = res.writeHead | |||
, end = res.end | |||
, url = req.originalUrl | |||
, body = '' | |||
, isJS = exports.filterJS(req,res) | |||
, isHTML = exports.filterHTML(req,res) | |||
; | |||
|
|||
|
|||
|
|||
res.on('header', function( ) { | |||
if( isJS || isHTML ) { | |||
console.log('Url is ' + req.url ); | |||
console.log('Content Length is ' + res.get('Content-Length')); | |||
console.log('Content Type is ' + res.get('Content-Type')); | |||
|
|||
res.removeHeader('Content-Length'); | |||
res.removeHeader('last-modified'); | |||
} | |||
if( res.get('Content-Type') ) { | |||
isJS = isJS && /javascript|json/.test(res.get('Content-Type')); | |||
} | |||
}); | |||
|
|||
// From https://github.com/nateps/connect/blob/4025c2fbd2f53d4a8fe5608055514eee0d696ca1/lib/patch.js | |||
// Until connect has taken the patch, we could only patch it here. | |||
res.writeHead = function(statusCode){ | |||
var reasonPhrase, headers, headerIndex; | |||
if (typeof arguments[1] == 'string') { | |||
reasonPhrase = arguments[1]; | |||
headerIndex = 2; | |||
} else { | |||
headerIndex = 1; | |||
} | |||
headers = arguments[headerIndex]; | |||
if (headers) { | |||
for (var name in headers) { | |||
this.setHeader(name, headers[name]); | |||
} | |||
} | |||
if (!this._emittedHeader) this.emit('header'); | |||
this._emittedHeader = true; | |||
return writeHead.call(this, statusCode, reasonPhrase); | |||
}; | |||
|
|||
res.write = function( chunk, encoding ) { | |||
if( isJS || isHTML ) { | |||
body += chunk; } | |||
else { | |||
write.apply(res,arguments); | |||
} | |||
} | |||
|
|||
res.end = function(chunk,encoding) { | |||
if( isJS ) { | |||
if (chunk) body += chunk; | |||
console.log('beautifying ' + url); | |||
var ubody = exports.beautify( body ) ; | |||
write.call(res,ubody,encoding); | |||
end.call(res); | |||
} else if ( isHTML ) { | |||
if (chunk) body += chunk; | |||
console.log('beautifying ' + url); | |||
body = body.replace(/(<script[^>]*>)((?:.|\s)*?)(<\/script>)/mig, exports.beautify ) ; | |||
write.call(res,body,encoding); | |||
end.call(res); | |||
|
|||
} else { | |||
end.apply(res,arguments) | |||
} | |||
} | |||
|
|||
next(); | |||
|
|||
}; | |||
} | |||
|
|||
exports.stricten = function(options) { | |||
|
|||
var options = options || {} ; | |||
|
|||
return function (req, res, next) { | |||
|
|||
var | |||
called = false | |||
, write = res.write | |||
, writeHead = res.writeHead | |||
, body = '' | |||
, end = res.end | |||
, url = req.originalUrl | |||
, isJS = exports.filterJS( req, res) | |||
, isHTML = exports.filterHTML( req, res) | |||
; | |||
|
|||
// Normal case | |||
res.on('header', function( ) { | |||
if( isJS ) { | |||
res.removeHeader('Content-Length'); | |||
res.removeHeader('last-modified'); // do not cache modification on-the-fly | |||
} | |||
if( res.get('Content-Type') ) { | |||
isJS = isJS && /javascript|json/.test(res.get('Content-Type')); | |||
} | |||
}); | |||
|
|||
// From https://github.com/nateps/connect/blob/4025c2fbd2f53d4a8fe5608055514eee0d696ca1/lib/patch.js | |||
// Until connect has taken the patch, we could only patch it here. | |||
res.writeHead = function(statusCode){ | |||
var reasonPhrase, headers, headerIndex; | |||
if (typeof arguments[1] == 'string') { | |||
reasonPhrase = arguments[1]; | |||
headerIndex = 2; | |||
} else { | |||
headerIndex = 1; | |||
} | |||
headers = arguments[headerIndex]; | |||
if (headers) { | |||
for (var name in headers) { | |||
this.setHeader(name, headers[name]); | |||
} | |||
} | |||
if (!this._emittedHeader) this.emit('header'); | |||
this._emittedHeader = true; | |||
return writeHead.call(this, statusCode, reasonPhrase); | |||
}; | |||
|
|||
res.write = function( chunk, encoding ) { | |||
|
|||
if( isJS ) { | |||
called = true; | |||
console.log('strictening ' + url); | |||
write.call(res, exports.strictening(chunk), encoding); | |||
} else if ( isHTML ) { | |||
if (chunk) body += chunk; | |||
} else { | |||
write.apply(res,arguments); | |||
} | |||
} | |||
|
|||
|
|||
res.end = function(chunk,encoding) { | |||
if ( isHTML ) { | |||
if (chunk) body += chunk; | |||
console.log('strictening ' + url); | |||
body = body.replace(/(<script[^>]*>)((?:.|\s)*?)(<\/script>)/mig, exports.strictening ) ; | |||
write.call(res,body,encoding); | |||
end.call(res); | |||
} else { | |||
end.apply(res,arguments) | |||
} | |||
} | |||
|
|||
next(); | |||
|
|||
}; | |||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,24 @@ | |||
{ | |||
"name": "connect-strictenjs", | |||
"version": "0.0.1", | |||
"description": "a Strict mode (ES5) enforcer via connect middleware", | |||
"main": "lib/connect-stricten.js", | |||
"directories": { | |||
"example": "examples", | |||
"test": "test" | |||
}, | |||
"scripts": { | |||
"test": "echo \"Error: no test specified\" && exit 1" | |||
}, | |||
"repository": { | |||
"type": "git", | |||
"url": "git@github.com:yukinying/connect-strictenjs.git" | |||
}, | |||
"keywords": [ | |||
"ES5", | |||
"connect", | |||
"strict" | |||
], | |||
"author": "Albert Yu", | |||
"license": "BSD" | |||
} |