Advertisement
stuppid_bot

Простой сервер на Node.js

Aug 20th, 2013
172
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. http = require('http');
  2. https = require('https');
  3. // url = require('url');
  4. qs = require('querystring');
  5. fs = require('fs');
  6. serverCfg = require('./server.cfg');
  7. appCfg = require('./app.cfg');
  8. mime = require('./lib/mime');
  9. mimeMap = mime.loads('./mime.types');
  10.  
  11. routeMap = {
  12.     'POST': [
  13.         {
  14.             rule: '/test',
  15.  
  16.             fn: function(req, res) {            
  17.                 res.end(JSON.stringify(req.body));
  18.             }
  19.         }
  20.     ]
  21. };
  22.  
  23. function sendFile(path, req, res) {
  24.     if (!/^(HEAD|GET)$/.test(req.method)) {
  25.         res.statusCode = 405;
  26.         return res.end('Method not allowed');
  27.     }
  28.  
  29.     try {
  30.         var stats = fs.statSync(path);
  31.     }
  32.     catch (err) {
  33.         if (err.code == 'ENOENT') {
  34.             res.statusCode = 404;
  35.             return res.end('Resource not found');
  36.         }
  37.  
  38.         res.statusCode = 500;
  39.         return res.end('Internal server error');
  40.     }
  41.  
  42.     if (stats.isFile() || (stats.isDirectory() && fs.existsSync(path += '/index.htm'))) {
  43.         res.setHeader('Content-Type', mimeMap.getContentType(path) || 'application/octet-stream');
  44.         // Sending a 'Content-length' header will disable the default chunked encoding.
  45.         // res.setHeader('Content-Length', stats.size);
  46.         res.setHeader('Last-Modified', stats.mtime);
  47.  
  48.         if (req.method == 'HEAD') {
  49.             return;
  50.         }
  51.  
  52.         var stream = fs.createReadStream(path);
  53.  
  54.         stream.on('error', function(err) {
  55.             console.log(err);
  56.         });
  57.  
  58.         stream.on('open', function() {
  59.             this.pipe(res);
  60.         });
  61.     }
  62.     else {
  63.         res.statusCode = 403;
  64.         res.end('Forbidden error');
  65.     }
  66. }
  67.  
  68. function processRoutes(req, res) {
  69.     var parts = req.url.split('?');
  70.     var path = parts[0];
  71.     var query = parts[1];
  72.     // убираем повторяющиеся слэши
  73.     path = path.replace(/\/{2,}/g, '/');
  74.     // декодируем путь
  75.     var decodedPath = decodeURI(path);  
  76.  
  77.     // виртуальные пути
  78.     if (req.method in routeMap) {
  79.         var routes = routeMap[req.method];
  80.         var i = routes.length;
  81.  
  82.         while (i--) {
  83.             var route = routes[i];
  84.  
  85.             if (route.rule instanceof RegExp) {
  86.                 var matches = decodedPath.match(route.rule);
  87.  
  88.                 if (matches) {
  89.                     return route.fn.apply(null, [req, res].concat(matches.slice(1)));
  90.                 }
  91.             }
  92.             else if (route.rule == decodedPath) {
  93.                 return route.fn.call(null, req, res);
  94.             }
  95.         }
  96.     }
  97.  
  98.     // отдаем статику
  99.     sendFile(serverCfg.webRoot + decodedPath, req, res);
  100. }
  101.  
  102. function requestHandler(req, res) {
  103.     var data = [], length = 0;
  104.  
  105.     req.on('error', function(err) {
  106.         console.log(err);
  107.     });
  108.  
  109.     req.on('data', function(chunk) {
  110.         if ((length += chunk.length) > serverCfg.maxRequestLength) {
  111.             res.statusCode = 413;
  112.             res.end('Maximum request length exceeded');
  113.             this.pause();
  114.         }
  115.  
  116.         data.push(chunk);
  117.     });
  118.  
  119.     req.on('end', function() {
  120.         console.log('Ends');
  121.         data = Buffer.concat(data);
  122.         var _ = this;
  123.  
  124.         if (_.method == 'POST' && 'content-type' in _.headers) {
  125.             var contentType = _.headers['content-type'];
  126.  
  127.             if (contentType == 'application/x-www-form-urlencoded') {
  128.                 data = qs.parse(data.toString());
  129.             }
  130.             else if (contentType == 'multipart/form-data') {
  131.                 //
  132.             }
  133.         }
  134.  
  135.         _.body = data;
  136.         processRoutes(_, res);
  137.     });
  138. }
  139.  
  140. server = http.createServer(requestHandler);
  141. server.listen(serverCfg.port, serverCfg.host);
  142. console.log('Server running at http://' + serverCfg.host + ':' + serverCfg.port + '/');
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement