0

I am writing a url shortener service in Node JS using mongo to connect to mLab.

Right now the user can send a request to the service with a url to shorten, and it returns a shortened url. However, if the user then sends the shortened url as a request, the redirect does not happen. Rather, the service goes into a loop.

1) How do I see what exactly is getting grabbed from the db? (Knowing how to do this would help out in trouble-shooting)

2) And what may be the cause of the looping issue?

var express = require('express')
var app = express()
var path = require('path');
var port = process.env.PORT || 8080;
var crypto = require("crypto");
var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var UserSchema = new Schema({ // this schema is used for writing to the db
   url : String,  
   key : String   
 });

var urlcntrctr = new Schema( // this schema is used for reading from the db
  { key: String, url : String, _id: String },
  { collection: 'urlcntrctr'}
  );

const SchemaName  = mongoose.model('SchemaName', urlcntrctr); // for reading from the db

app.get('/', (req, res, next) => res.sendFile(path.join(__dirname, '/index.html')) ) ;

app.set('port', (process.env.PORT || 5000));

app.get('/new/:url(*)', function(req, res) {
 var shortenme = req.params[0];
 var showme = req.params[0];
 console.log("User's request: " +shortenme);
 var amItrue = validateURL(shortenme);   
 if (amItrue){   
  connectmongoviamongoose(); 
  var shortenmeObj = yncryptyyn(shortenme); 
  shortenme = shortenmeObj.key; 
  writeToDb(shortenmeObj); b 
  closetheconnection();
  var contractedurl = 'http://firstappever-olddognewtrix123.c9users.io/' + shortenme;
  var responseObject = ({"Original url: ": showme, "Contracted url: ": shortenme });
  res.send(responseObject);
}  
else{console.log("You need to enter a url, beginning with 'http' or 'https' and ending in '.com' or '.org' or whatever!");};   

 })

app.get('/:tag(*)', function(req, res) {
 var targetnumber = req.params.tag; 
 sendforRedirect(req, res);
 sendforRedirect(req, res);
  }) 

function sendforRedirect(req, res){  
   var target = req.params.tag;
  console.log("The value of target is " + target)
 ;       var options = { server: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } }, 
        replset: { socketOptions: { keepAlive: 1, connectTimeoutMS : 30000 }  }   };       

 var mongodbUri = 'mongodb://<dbusername>:<dbuserpassword>@ds159988.mlab.com:59988/urlcntrctr'; 
     mongoose.connect(mongodbUri, options);
     mongoose.Promise = global.Promise;
    var conn = mongoose.connection;             
     conn.on('error', console.error.bind(console, 'connection error:'));  
     conn.once('open', function() {


       console.log("OK, you are connected for the redirect. ") 
       var query = {
        key: {
            $eq: target
         }
       }


     SchemaName.find(query, function (err, doc) {
     if(err){
        console.log(err);
        conn.close();
     };
      if(doc){
        res.redirect(doc.url); // rather than redirecting, it is looping *****************
        conn.close();

      } else {
        res.send("Sorry, we don't recognize that url");

        conn.close();
      }
     }); 
    }); 
 }


 function writeToDb(dataObject){
  mongoose.model('Document', UserSchema);
   var urlFromUser = mongoose.model('Document');
  var urlfromuser = new urlFromUser();
  urlfromuser.url = dataObject.url;
   urlfromuser.key = dataObject.key;
   urlfromuser.save();
 };


 function validateURL(textval) { //copied from   http://stackoverflow.com/questions/1303872/trying-to-validate-url-using-javascript
    var urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/;
   return urlregex.test(textval);
 }



function connectmongoviamongoose(){  
   var mongoose = require('mongoose');
   var options = { server: { socketOptions: { keepAlive: 300000, connectTimeoutMS: 30000 } }, 
       replset: { socketOptions: { keepAlive: 300000, connectTimeoutMS : 30000 } } };       
   var mongodbUri =  'mongodb://<dbusername>:<dbuserpassword>@ds159988.mlab.com:59988/urlcntrctr';
    mongoose.createConnection(mongodbUri, options);
   var conn = mongoose.connection;             
    conn.on('error', console.error.bind(console, 'connection error:'));  
    conn.once('open', function() {
    console.log("OK, you are connected. ") 
    }); 
}

function closetheconnection(){
  var mongoose = require('mongoose');
  mongoose.connection.close();
}

function yncryptyyn(incryptme){
 var ulimit = 6;
  var key = crypto.createHash('md5').update(incryptme).digest("base64");
  key = key.slice(0,ulimit);
  var obj = {
            url: incryptme,
            key: key
        };
        return obj;
}

app.listen(app.get('port'), function() {  
 console.log('Node app is running on port', app.get('port'));
});
Strom
  • 1

2 Answers2

0

For question 1: just put in a console.log, for example like this:

if(doc){
    console.log(doc);
    res.redirect(doc.url); 
....

Even better put the whole functionality of the look up of the url into an own function, so you can check the working of the lookup and the working of the redirect independently.

Meier
  • 3,858
  • 1
  • 17
  • 46
  • That returns '[]' So does that mean I need to further parse 'doc' or does that mean the query is returning nothing? – Strom Jan 29 '17 at 14:39
  • Changed code so that var targetnumber = req.params.tag; and called the redirect function with sendforRedirect(targetnumber, res);, but still getting '[]' returned for 'doc' – Strom Jan 29 '17 at 14:45
  • If do returns '[ ]', then doc.url is undefined. the redirect than probably just redirect to the current url, and there is your infinite loop. So you need to find out why you not get the url back like you expected. – Meier Jan 29 '17 at 15:37
0

Better than console.log statements, you can use the package node-inspector to actually set breakpointsnin your code via chrome devtools and step through the code Much more robust process.

I would note that it is not clear to me what kind of urls you are shortening (internal to your site or external), but at present it looks like you're calling the redirect function twice, which should cause an error unto itself, and second if you are redirecting to internal urls your routes are probably going to match a lot that you don't want them to.

Finally, your code is kind of a jumble right now, which will make debugging harder no matter what you do. Try and break it out into different files based on what they do and test bits independently as much as possible.

Paul
  • 35,689
  • 11
  • 93
  • 122