Search code examples
node.jshttpexpressbackendhttp-status-code-400

400 bad request returning /favicon.ico as req.url in express.


I am building a simple microservice which returns the url date parameters as a Json object in unix and natural language. For example if you go to https://cyber-clock.glitch.me/May%2013,%202015 the app should return: {"unix":1431475200,"natural":"May 13, 2015"}, the %20 are spaces, so you can also write https://cyber-clock.glitch.me/May 13, 2015 and the app works. The issue is when I write a double percentage because I am getting a 400 bad request error and the url becomes: /favicon.ico, so I cannot apply fixes to url and response as expected, for example: https://cyber-clock.glitch.me/May%%2013,%202015

You can check the source code here: https://github.com/juandata/TimeStampMicroService

In line 22 of timeStampMicroService.js I added a console.log where you can see what I mean. Here is the code of that file:

var path = require('path')
var express = require('express');
var app = express();
var fs = require('fs');
var url = require('url');
var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
  jsonResp = {},
  readableDate = "";
function Unix_timestamp(t) {
  var dt = new Date(t * 1000);
  var month = dt.getMonth();
  var day = dt.getDate();
  var year = dt.getFullYear();
  return months[month] + ' ' + day + ', ' + year;
};  
app.use(function(req, res, next) {
  console.log(req.url);
  var date = req.url.substr(1);
  var miliseconds = parseInt(date);
  var unixDate = new Date(miliseconds);
  if (unixDate == "Invalid Date") {
    var regExpr = /%20|,/;
    date = date.split(regExpr);
    var date1 = new Date(date[0] + " " + date[1] + "," + date[3]);
    if (date1 == "Invalid Date") {
      jsonResp = {
        "unix": null,
        "natural": null
      };
      res.json(jsonResp);

    } else {
      var date2 = date1.getTime();
      var timestamp = Math.floor(date2 / 1000);
      jsonResp = {
        "unix": timestamp,
        "natural": date[0] + " " + date[1] + ", " + date[3]
      };
      res.json(jsonResp);
    }
  } else {
    readableDate = Unix_timestamp(date);
    jsonResp = {
      "unix": miliseconds,
      "natural": readableDate
    };

    res.json(jsonResp);
  }
});
app.listen(process.env.PORT, function() {
  console.log('Node.js listening ...');
});

Can anyone help me to solve this?


Solution

  • This propably happens because server is trying to decode a percent-encoded character and finds out that the format is wrong - you put a % right after another one but percent encoded characters look like this: %HH, where H is a hexadecimal digit, check this out: https://www.rfc-editor.org/rfc/rfc3986#section-2.1

    So, the error must be occuring even before your app gets the url. Just don't try to pass such a url. If you want to make a url with a percent character in it, use %25, like here: https://cyber-clock.glitch.me/May%25%2013,%202015

    In case if you want to handle such URIs you may need to implement your own HTTP server (HTTP requests handler).