Skip to content

Instantly share code, notes, and snippets.

@pmanijak
Last active December 19, 2015 18:09
Show Gist options
  • Save pmanijak/5996557 to your computer and use it in GitHub Desktop.
Save pmanijak/5996557 to your computer and use it in GitHub Desktop.
Get CouchDB to return HTTP 304 when getting attachments, using Express and Nano on Node.js.
var app = express();
app.get('/:username/image', function (req, res) {
db.getImage(req.params.username, req.headers["if-none-match"], res, function (err) {
if (err) {
// We don't have to do anything, here, as the db
// pipe takes care of 404s and whatnot.
// Log if you want.
// console.log(err);
}
});
});
var nanoDb = "..."; // nano(dbUrl);
var databaseName = "...";
var cookieToken = "..."; // see below
// docId - the _id of the Couch doc
// attachmentName - ...
// headers - req.headers from express
// res - the connect / express response
// callback - for handling errors
var streamImageAttachment = function (docId, attachmentName, etag, res, callback) {
// If you have authentication going, you need to set
// your cookie token for your call to relax, below.
//
// Getting a cookie token is beyond the scope of this Gist,
// but basically deal with headers['set-cookie'] from CouchDB,
// and see the nano docs.
var headers = {};
headers["X-CouchDB-WWW-Authenticate"] = "Cookie";
headers["cookie"] = cookieToken;
// The 'If-None-Match' header that was specified by the
// browser is what CouchDB uses to compare against the ETag,
// which determines whether http 304 or http 200 (plus data)
// is returned.
headers["if-none-match"] = etag;
var opts = {
db: databaseName,
headers: headers,
method: "GET",
doc: docId,
att: attachmentName,
encoding: null
};
// We use the relax method because nano's
// db.attachment.get method doesn't have a
// headers parameter.
var readStream = nanoDb.relax(opts, function (err) {
if (err) {
callback(err);
}
});
// Stream the image to 'res'
res.type("image/jpeg"); // hard-coded because this a Gist
readStream.pipe(res);
};
var getDocId = function (username) {
// an exercise for the reader
};
var getImage = function (username, etag, res, callback) {
streamImageAttachment(getDocId(username), "something.jpg", etag, res, callback);
};
<html>
<img src="/someone/image"/>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment