httpserver.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. // https://github.com/andrewpthorp/simple-http-server
  2. /*
  3. // Command Line Parameters
  4. var argv, options;
  5. argv = require('optimist').argv;
  6. options = {};
  7. if (argv.p) options.port = argv.p;
  8. if (argv.port) options.port = argv.port;
  9. if (argv.d) options.directory = argv.d;
  10. if (argv.directory) options.directory = argv.directory;
  11. if (argv.nocolors) options.colors = false;
  12. if (argv.nologs) options.nologs = true;
  13. if (argv.help) options.help = true;
  14. // Run the Server!
  15. var url = require('../lib/server').run(options);
  16. */
  17. /**
  18. * simple-http-server
  19. *
  20. * This will serve up static html, css, and javascript
  21. * from the current directory, or a specified directory/port
  22. *
  23. * @author Andrew Thorp
  24. */
  25. (function(){
  26. var SWITCHES, BANNER, colors, libs, config, printLine, server;
  27. // colors = require('colors');
  28. libs = exports.libs = {
  29. http: require('http'),
  30. url: require('url'),
  31. fs: require('fs'),
  32. path: require('path')
  33. };
  34. config = exports.config = {
  35. port: 8000,
  36. directory: process.cwd(),
  37. colors: false,
  38. nologs: false
  39. };
  40. printLine = exports.printLine = function(line) {
  41. // Strip All Colors
  42. if (!config.colors){
  43. return process.stdout.write(line.stripColors + '\n');
  44. } else {
  45. return process.stdout.write(line + '\n');
  46. }
  47. };
  48. /**
  49. * getMimeType
  50. *
  51. * Utility function that returns the mimeType of a given file
  52. *
  53. * @author Andrew Thorp
  54. */
  55. getMimeType = exports.getMimeType = function(file){
  56. var i = file.lastIndexOf("."),
  57. ext = (i === -1) ? "default" : file.substr(i),
  58. mimeTypes = {
  59. ".bmp": "image/bmp",
  60. ".css": "text/css",
  61. ".gif": "image/gif",
  62. ".htm": "text/html",
  63. ".html": "text/html",
  64. ".jpg": "image/jpeg",
  65. ".jpeg": "image/jpeg",
  66. ".js": "application/javascript",
  67. ".json": "application/json",
  68. ".otf": "font/opentype",
  69. ".png": "image/png",
  70. ".text": "text/plain",
  71. "default": "application/octet-stream"
  72. };
  73. return mimeTypes[ext.toLowerCase()];
  74. }
  75. BANNER = 'Usage: nserver [options]\n\nIf called without options, `nserver` will listen to the current directory on port ' + config.port + '.';
  76. SWITCHES = [
  77. ['-d', '--directory', 'root directory to listen to'],
  78. ['-p', '--port', 'port to listen on'],
  79. ['', '--launch', 'launch the server in your default browser after starting'],
  80. ['', '--nocolors', 'disable colors, default: false'],
  81. ['', '--nologs', 'disable request logs, default: false'],
  82. ['', '--help', 'show this help screen']
  83. ];
  84. /**
  85. * run
  86. *
  87. * This function is what fires off the server
  88. * if --help is passed as a flag, it will print the
  89. * help screen. If not, the server will start.
  90. *
  91. * @author Andrew Thorp
  92. */
  93. exports.run = function(options){
  94. // Options
  95. if (options !== undefined){
  96. if (options.help !== undefined) return usage();
  97. if (options.port !== undefined) exports.config.port = config.port = options.port;
  98. if (options.directory !== undefined) exports.config.directory = config.directory = options.directory;
  99. if (options.colors !== undefined) exports.config.colors = config.colors = options.colors;
  100. if (options.nologs !== undefined) exports.config.nologs = config.nologs = options.nologs;
  101. }
  102. // Fire off the server!
  103. server = libs.http.createServer(function(request, response) {
  104. var url = libs.url.parse(request.url, true),
  105. path = decodeURIComponent(url.pathname),
  106. result = request.method + " " + path.bold,
  107. fileCount = 0;
  108. // Default file to index.html
  109. if (path === "/") path += "index.html";
  110. var fullPath = libs.path.join(config.directory, path);
  111. libs.fs.exists(fullPath, function(exists){
  112. if (exists) {
  113. libs.fs.readFile(fullPath, function(error, data) {
  114. if (!error){
  115. response.writeHead(200, {
  116. 'content-type': getMimeType(fullPath)
  117. });
  118. response.write(data);
  119. response.end();
  120. result += " - 200 OK".green;
  121. logString(result);
  122. } else {
  123. result += " - 500 Internal Server Error".red;
  124. logString(result);
  125. }
  126. });
  127. } else {
  128. response.writeHead(404, {});
  129. response.write("<h1>404 - Not Found</h1>");
  130. response.end();
  131. result += " - 404 Not Found".red;
  132. logString(result);
  133. }
  134. });
  135. }).listen(config.port);
  136. logString();
  137. // Return the URL
  138. return "http://localhost:" + config.port + "/";
  139. };
  140. /**
  141. * stop
  142. *
  143. * Stop the current server (if it is running)
  144. *
  145. * @author Andrew Thorp
  146. */
  147. exports.stop = function(){
  148. if (server){
  149. server.close();
  150. }
  151. }
  152. /**
  153. * usage
  154. *
  155. * print the help screen
  156. *
  157. * @author Andrew Thorp
  158. */
  159. var usage = function(){
  160. var lines, spaces, i, len, switchLength, currSwitch, spaces, shortFlag, longFlag;
  161. lines = [];
  162. lines.unshift("" + BANNER + "\n");
  163. for (i = 0, len = SWITCHES.length; i < len; i++){
  164. currSwitch = SWITCHES[i];
  165. spaces = Array(16 - currSwitch[1].length).join(' ');
  166. if (currSwitch[0] === ""){
  167. shortFlag = " ";
  168. } else {
  169. shortFlag = currSwitch[0] + ", ";
  170. }
  171. longFlag = currSwitch[1];
  172. lines.push(' ' + shortFlag + longFlag + spaces + currSwitch[2]);
  173. }
  174. return printLine("\n" + (lines.join('\n')) + "\n");
  175. };
  176. /**
  177. * logString
  178. *
  179. * log a string (used for requests)
  180. *
  181. * @variable string (if not passed, connection string is printed)
  182. * @author Andrew Thorp
  183. */
  184. var logString = exports.logString = function(string){
  185. if (config.nologs) return;
  186. if (string !== undefined){
  187. printLine(string);
  188. return;
  189. }
  190. var consoleStrings, currDir;
  191. consoleStrings = {
  192. server: "simple-http-server".bold,
  193. directory: config.directory.green,
  194. shortDir: "./".green,
  195. url: "http://localhost:".green + config.port.toString().green + "/".green
  196. }
  197. if (__dirname.indexOf(consoleStrings.directory.stripColors) !== -1){
  198. currDir = consoleStrings.shortDir;
  199. } else {
  200. currDir = consoleStrings.directory;
  201. }
  202. printLine("\n" + consoleStrings.server + " Now Serving: " + currDir + " at " + consoleStrings.url + "\n");
  203. };
  204. }());