miércoles, 6 de junio de 2012

simple NodeJs Http Server

I has been a long time since last update, and i thought it would be fine to share some code i have been using for a while :D

For some blackberry projects i worked on, i have been using an http server i developed using nodeJs.
With nodeJs you program exactly how you want the server to behave.

This is the source code to be placed in file HttpServer.js
 var http = require('http');  
 var fs = require('fs');  
 var arg = process.argv.splice(2);  
 //some sanity checks  
 if (arg.length == 0 || arg[0] =="")     exitApp('empty path!, please specify rootDir via command line like "node HttpServer.js /your/root/path"');  
 if (!( requestStats = fileExists(arg[0]))) exitApp('invalid path, please check the path provided!');  
 else if (requestStats.isFile())       exitApp('path is a file!, please check the path provided!');  
 var config = {  
   serverName : "Node Http Server v1.1",  
   baseUrl : arg[0],  
   host : "0.0.0.0", // 127.0.0.1 for localhost only, 0.0.0.0 for all ips  
   port : 8123,  
   showFileStats : false,  
   showCodFilesForBlackberry : false,  
   showSpecialFiles : false, // show filenames starting with .  
   logRequests : true,  
   logUserAgent : false  
 };  
 var httpserver = http.createServer(onRequest);  
 httpserver.listen(config.port,config.host ,serverCreated_callback());  
 function serverCreated_callback(){  
      console.log(config.serverName +' running at http://' + config.host +':' + config.port + '/ base url ' + config.baseUrl);  
 }  
 function onRequest(req, res){  
      try{  
           if ( req.url == '/favicon.ico' ) return; // we filter favicon req  
           if ( req.url.indexOf("..") != -1 ) return; // we filter directory scalation  
           if ( config.logRequests ){  
                console.log(req.connection.remoteAddress + " - " + req.url);  
                if ( config.logUserAgent ){ console.log('user agent:' + req.headers['user-agent'].toLowerCase()); }  
           }  
           var filePath = config.baseUrl + req.url;  
           if ( !( requestStats = fileExists(filePath) ) ){ // files not existing 404  
                res.writeHead(404);  
                res.end();  
           }else{  
                var pureUrl = UrlToFsPath(req.url);  
                if (requestStats.isFile()){     // file (download it)            
                     res.writeHead(200,getResponseHeaders(req));  
                     res.write(fs.readFileSync(filePath));  
                     res.end();  
                }else{ // folder (list it's contents)  
                     var fileList = filterFileList(req, fs.readdirSync(config.baseUrl + pureUrl) );  
                     var htmlOutput = formatHtmlFileList(fileList,pureUrl);  
                     res.writeHead(200, { 'Content-Type': 'text/html' });  
                     res.end(htmlOutput, 'utf8');  
                }   
           }    
   }catch(error) { // just in case of fatal error  
     res.writeHead(500, { 'Content-Type': 'text/html' });  
           res.end();  
      }  
 }  
 // chechs if file exists. Returns file stats if it exists, false otherwise  
 function fileExists(path) {  
      try { return fs.statSync(path); }  
      catch(error) { return false; }  
 }  
 // adds response headers depending on what kind of filename was requested  
 function getResponseHeaders(req){  
      var requestedFilename = req.url.split("/").pop();  
      var requestedExtension = requestedFilename.split(".").pop();  
      var responseHeaders = {};  
      if (requestedExtension == "jad"){   
           responseHeaders["Content-Type"] = "text/vnd.sun.j2me.app-descriptor; charset=utf-8";   
           responseHeaders['Content-Disposition'] = 'attachment; filename=' +requestedFilename;  
      }else if (requestedExtension == "cod"){   
           responseHeaders["Content-Type"] = "application/vnd.rim.cod";   
           responseHeaders['Content-Disposition']= 'attachment; filename=' +requestedFilename;  
      }else if (requestedExtension == "html"){ responseHeaders["Content-Type"] = 'text/html'; }  
      return responseHeaders;  
 }  
 // corrects url  
 function UrlToFsPath(pureUrl){  
   if( pureUrl.substr(-1) != "/" ){ pureUrl += "/"; }  
   return unescape(pureUrl.replace(/\+/g, " "));     
 }  
 // filters files to show depending on config  
 function filterFileList(req,fileList){  
      var returnedFileList = [];  
      var isBlackberry = (req.headers['user-agent'].toLowerCase().indexOf("blackberry") != -1);  
      var hideCodFiles = isBlackberry && !config.showCodFilesForBlackberry;  
      for (var i in fileList) {  
           var filename = fileList[i];  
           var fileExtension = filename.split(".").pop();  
           if ( (!config.showSpecialFiles && filename.indexOf(".") != 0) || config.showSpecialFiles) {   
                if ((hideCodFiles && fileExtension != "cod") || !hideCodFiles){ returnedFileList.push(filename); }  
           }  
      }  
      return returnedFileList;  
 }  
 // returns file list html  
 function formatHtmlFileList(fileList,pureUrl){  
   var htmlOutput = '<h4>Folder: ' + pureUrl + "</h4><table>";  
   if ( config.showFileStats ) { htmlOutput +="<td>Create Date</td><td>Size</td>"; }  
   for (var i in fileList) {  
        var filename = fileList[i];  
        var absolutePath = pureUrl + filename;  
           var fileStats = fs.statSync(config.baseUrl + absolutePath);  
           if(fileStats.isFile()){ htmlOutput += "<tr><td><a href='" + absolutePath + "'>" + filename + "</a> </td>"; }  
           else{ htmlOutput += "<tr><td><a href='" + absolutePath + "'> " + filename + "</a> </td>"; }  
           if (config.showFileStats) { htmlOutput +="<td>" + fileStats['ctime'] + "</td><td>"+ fileStats['size'] +"</td>"; }  
   }  
   return htmlOutput +'</table>';   
 }  
 // exits the app with message in console  
 function exitApp(message){  
   console.log(message);  
   process.exit(1);  
 }  

To use this example just install nodeJs and execute this command in the console:

 node HttpServer.js /your/desired/root/path  

Then you can test it browsing to http://127.0.0.1:8123/
More simple impossible!

If you need to know more about nodejs, just take a look at their website.

miércoles, 27 de octubre de 2010

gyrophono 1.1 para iphone e ipod touch

Tal como prometí a los chicos de appleweblog, aqui llega la nueva versión de gyrophono.
Gyrophono virtual se ha actualizado a la version 1.1 con las siguientes mejoras:
  • Mejoras visuales.
  • Traducciones: añadido el castellano, catalán e italiano.
  • Touch mode: ahora incorpora un xilofono multitáctil. Los dispositivos ios que no incorporen giroscopio, ahora podrán ejecutar la aplicación en modo tactil. Este modo esta disponible tambien para dispositivos con giroscopio.
  • Mejores instrucciones.
Aqui tenéis un video demostrativo:



sábado, 25 de septiembre de 2010

Gyro Stick for iphone 4: a drum you can play backside up!

Gyro stick is available to download on app store.

With this app, you can play several percusion intrsuments, using gyroscope-controlled virtual drumstick.

Features:
  • Drums & cymbal
  • Bongos 
  • Gong
  • You can even play it backside up!


Backside up demo :P


Suggestions are wellcome!

jueves, 16 de septiembre de 2010

gyro stick para iphone 4: una bateria que se puede tocar al revés!

Gyro stick ya esta disponible en la app store.

Esta app te permitirá tocar varios instrumentos de percusión usando el giroscopio integrado del iphone 4 o el reciente anunciado ipod touch de cuarta generación.

Funcionalidades:
  • Bateria, y platos
  • Bongos 
  • Gong
  • Incluso se puede tocar sin mirar la pantalla, o con el dispositivo mobil al revés!!
Aqui teneis una pequeña demostración de su funcionamiento:




Aqui una demostración de como tocarlo al revés :P


Toda sugerencia de mejora o añadido sera bienvenida!

viernes, 10 de septiembre de 2010

gyrophono virtual para iphone 4

Gyrophono virtual, disponible en la app store, una app exclusiva para iphone 4 que te permitira utilizar el telefono como si fuera el baston de un xilofono.

Para ello se hace uso del giroscopio que tiene incorporado el iphone 4 para detectar la posición y angulo del telefono.

Aqui teneis una pequeña demostración de su funcionamiento:



Próximamente habrá una actualización de la aplicación que mejorara su usabilidad al incorporar una animacion que mostrara la nota actual de una forma mas gráfica.