Skip to content

Extensions vs Directory #138

@betabong

Description

@betabong

When we have a directory named like a file, extensions should win over redirect. Let's assume this listing:

/news.html
/news/latest.html
/news/index.html

and we set the extensions options to ['html'].

Right now /news is redirected to /news/ and serves /news/index.html

But it should serve /news.html – only if that file is missing, it should redirect to the directory. Whereas /news/ should always go for the directory (index).

I achieved this by changing the sendFile method like follows, but there are probably better ways to achieve the same.

SendStream.prototype.sendFile = function sendFile (path) {
  var i = 0
  var self = this
  var onExtensionsFailed

  debug('stat "%s"', path)
  fs.stat(path, function onstat (err, stat) {
    if (err && err.code === 'ENOENT' && !extname(path) && path[path.length - 1] !== sep) {
      // not found, check extensions
      return next(err)
    }
    if (err) return self.onStatError(err)
    if (stat.isDirectory()) {
      onExtensionsFailed = function() {
        self.redirect(path)
      }
      if (self._extensions.length > 0 && path[path.length - 1] !== sep) {
        return next()
      } else {
        return self.redirect(path)
      }
    }
    self.emit('file', path, stat)
    self.send(path, stat)
  })

  function next (err) {
    if (self._extensions.length <= i) {
      if (onExtensionsFailed) {
        return onExtensionsFailed()
      }
      return err
        ? self.onStatError(err)
        : self.error(404)
    }

    var p = path + '.' + self._extensions[i++]

    debug('stat "%s"', p)
    fs.stat(p, function (err, stat) {
      if (err) return next(err)
      if (stat.isDirectory()) return next()
      self.emit('file', p, stat)
      self.send(p, stat)
    })
  }
}

Does this make sense? (I am by the way trying to achieve the same kind of handling like Netlify does when serving static files).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions