You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

124 lines
3.8 KiB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
12 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
  1. #!/usr/bin/env node
  2. "use strict";
  3. var dope = require("console-dope"),
  4. connect = require("connect"),
  5. http = require("http"),
  6. cliArgs = require("command-line-args"),
  7. o = require("object-tools"),
  8. s = require("string-tools"),
  9. path = require("path"),
  10. loadConfig = require("config-master"),
  11. morgan = require("morgan"),
  12. serveStatic = require("serve-static"),
  13. directory = require("serve-index"),
  14. compress = require("compression"),
  15. homePath = require("home-path"),
  16. byteSize = require("byte-size"),
  17. clf = require("common-log-format"),
  18. logStats = require("stream-log-stats");
  19. var usage =
  20. "usage: \n\
  21. $ ws [--directory|-d <dir>] [--port|-p <port>] [--log-format|-f dev|default|short|tiny|logstalgia] [--compress|-c]\n\
  22. $ ws --config\n\
  23. $ ws --help|-h";
  24. function halt(message){
  25. dope.red.log("Error: %s", message);
  26. dope.log(usage);
  27. process.exit(1);
  28. }
  29. /* Merge together options from
  30. - ~/.local-web-server.json
  31. - {cwd}/.local-web-server.json
  32. - {cwd}/package.json
  33. */
  34. var storedConfig = loadConfig(
  35. path.join(homePath(), ".local-web-server.json"),
  36. path.join(process.cwd(), ".local-web-server.json"),
  37. { jsonPath: path.join(process.cwd(), "package.json"), configProperty: "local-web-server" }
  38. );
  39. /* override stored config with values parsed from command line */
  40. try {
  41. var argv = cliArgs([
  42. { name: "port", alias: "p", type: Number, defaultOption: true, value: 8000 },
  43. { name: "log-format", alias: "f", type: String },
  44. { name: "help", alias: "h", type: Boolean },
  45. { name: "directory", alias: "d", type: String, value: process.cwd() },
  46. { name: "config", type: Boolean },
  47. { name: "compress", alias: "c", type: Boolean }
  48. ]).parse();
  49. } catch(err){
  50. halt(err.message);
  51. }
  52. argv = o.extend(storedConfig, argv);
  53. if (argv.config){
  54. dope.log("Stored config: ");
  55. dope.log(storedConfig);
  56. process.exit(0);
  57. } else if (argv.help){
  58. dope.log(usage);
  59. } else {
  60. var total = {
  61. req: 0,
  62. bytes: 0,
  63. connections: 0
  64. };
  65. process.on("SIGINT", function(){
  66. dope.showCursor();
  67. dope.log();
  68. process.exit(0);
  69. });
  70. var app = connect();
  71. /* log using --log-format (if supplied) */
  72. if(argv["log-format"]) {
  73. if (argv["log-format"] === "logstalgia"){
  74. /* customised logger :date token, purely to satisfy Logstalgia. */
  75. morgan.token("date", function(){
  76. var a = new Date();
  77. return (a.getDate() + "/" + a.getUTCMonth() + "/" + a.getFullYear() + ":" + a.toTimeString())
  78. .replace("GMT", "").replace(" (BST)", "");
  79. });
  80. argv["log-format"] = "default";
  81. }
  82. app.use(morgan(argv["log-format"]));
  83. } else {
  84. var statStream = clf();
  85. statStream.pipe(logStats());
  86. app.use(morgan({ stream: statStream }));
  87. }
  88. /* --compress enables compression */
  89. if (argv.compress) app.use(compress());
  90. /* static file server including directory browsing support */
  91. app.use(serveStatic(path.resolve(argv.directory)))
  92. .use(directory(path.resolve(argv.directory), { icons: true }));
  93. /* launch server */
  94. var server = http.createServer(app)
  95. .on("error", function(err){
  96. if (err.code === "EADDRINUSE"){
  97. halt("port " + argv.port + " is already is use");
  98. } else {
  99. halt(err.message);
  100. }
  101. })
  102. .listen(argv.port);
  103. /* write status to stderr so stdout can be piped to disk ($ ws > log.txt) */
  104. if (path.resolve(argv.directory) === process.cwd()){
  105. dope.error("serving at %underline{%s}", "http://localhost:" + argv.port);
  106. } else {
  107. dope.error("serving %underline{%s} at %underline{%s}", argv.directory, "http://localhost:" + argv.port);
  108. }
  109. }