From 86f46663ff2d2f057d71f27bd7207e6110dc4939 Mon Sep 17 00:00:00 2001
From: Lloyd Hilaiel <lloyd@hilaiel.com>
Date: Mon, 14 Nov 2011 12:28:50 -0700
Subject: [PATCH] initial implementation of request forwarding, cookies set
 from dbwriter are still not being properly passed through - issue #460

---
 bin/browserid                       |  2 +-
 bin/dbwriter                        |  1 -
 lib/{browserid => }/http_forward.js | 14 +++++++++++++-
 lib/wsapi.js                        | 18 +++++++++++++++---
 lib/wsapi/cert_key.js               |  2 +-
 5 files changed, 30 insertions(+), 7 deletions(-)
 rename lib/{browserid => }/http_forward.js (78%)

diff --git a/bin/browserid b/bin/browserid
index 9671ad3ee..a337f3db0 100755
--- a/bin/browserid
+++ b/bin/browserid
@@ -52,7 +52,7 @@ config = require('../lib/configuration.js'),
 heartbeat = require('../lib/heartbeat.js'),
 metrics = require('../lib/metrics.js'),
 logger = require('../lib/logging.js').logger,
-forward = require('../lib/browserid/http_forward'),
+forward = require('../lib/http_forward'),
 shutdown = require('../lib/shutdown'),
 views = require('../lib/browserid/views.js');
 
diff --git a/bin/dbwriter b/bin/dbwriter
index 91296cae5..9b09dbf95 100755
--- a/bin/dbwriter
+++ b/bin/dbwriter
@@ -52,7 +52,6 @@ config = require('../lib/configuration.js'),
 heartbeat = require('../lib/heartbeat.js'),
 metrics = require('../lib/metrics.js'),
 logger = require('../lib/logging.js').logger,
-forward = require('../lib/browserid/http_forward'),
 shutdown = require('../lib/shutdown'),
 views = require('../lib/browserid/views.js');
 
diff --git a/lib/browserid/http_forward.js b/lib/http_forward.js
similarity index 78%
rename from lib/browserid/http_forward.js
rename to lib/http_forward.js
index 0a9468f79..bb2e9eebe 100644
--- a/lib/browserid/http_forward.js
+++ b/lib/http_forward.js
@@ -2,7 +2,7 @@ const
 url = require('url'),
 http = require('http'),
 https = require('https'),
-logger = require('../logging.js').logger,
+logger = require('./logging.js').logger,
 querystring = require('querystring');
 
 module.exports = function(dest, req, res, cb) {
@@ -24,6 +24,9 @@ module.exports = function(dest, req, res, cb) {
     if (pres.headers.hasOwnProperty('content-length')) {
       res.setHeader('Content-Length', pres.headers['content-length']);
     }
+    if (pres.headers.hasOwnProperty('set-cookie')) {
+      res.setHeader('Set-Cookie', pres.headers['set-cookie']);
+    }
     pres.on('data', function (chunk) {
       res.write(chunk);
     }).on('end', function() {
@@ -39,6 +42,15 @@ module.exports = function(dest, req, res, cb) {
     preq.setHeader('content-type', req.headers['content-type']);
   }
 
+  // forward cookies!
+  if (req.cookies) {
+    var cookieHeader = "";
+    Object.keys(req.cookies).forEach(function(key) {
+      cookieHeader += key + "=" + req.cookies[key] + "; ";
+    });
+    preq.setHeader('Cookie', cookieHeader);
+  }
+
   // if the body has already been parsed, we'll write it
   if (req.body) {
     var data = querystring.stringify(req.body);
diff --git a/lib/wsapi.js b/lib/wsapi.js
index b3fdb6588..963d1aff6 100644
--- a/lib/wsapi.js
+++ b/lib/wsapi.js
@@ -17,6 +17,7 @@ secrets = require('./secrets'),
 config = require('./configuration'),
 logger = require('./logging.js').logger,
 httputils = require('./httputils.js'),
+forward = require('./http_forward.js'),
 url = require('url'),
 fs = require('fs'),
 path = require('path'),
@@ -125,7 +126,6 @@ exports.setup = function(options, app) {
         req.connection.proxySecure = true;
 
       return cookieSessionMiddleware(req, resp, next);
-
     } else {
       return next();
     }
@@ -195,8 +195,6 @@ exports.setup = function(options, app) {
       // don't register read apis if we are configured as a writer
       if (options.only_write_apis && !api.writes_db) return;
 
-      // XXX forward writes if options.forward_writes is defined
-
       wsapis[operation] = api;
 
       // set up the argument validator
@@ -207,6 +205,20 @@ exports.setup = function(options, app) {
         wsapis[operation].validate = function(req,res,next) { next(); };
       }
 
+      // forward writes if options.forward_writes is defined
+      if (options.forward_writes && wsapis[operation].writes_db) {
+        var forward_url = options.forward_writes + "wsapi/" + operation;
+        wsapis[operation].process = function(req, res) {
+          forward(forward_url, req, res, function(err) {
+            if (err) {
+              logger.error("error forwarding '"+ operation +
+                           "' request to '" + options.forward_writes + ":" + err);
+              httputils.serverError(res, "internal request forwarding error");
+            }
+          });
+        };
+      }
+
     } catch(e) {
       var msg = "error registering " + operation + " api: " + e;
       logger.error(msg);
diff --git a/lib/wsapi/cert_key.js b/lib/wsapi/cert_key.js
index c72e1cb57..68733cf60 100644
--- a/lib/wsapi/cert_key.js
+++ b/lib/wsapi/cert_key.js
@@ -2,7 +2,7 @@ const
 db = require('../db.js'),
 httputils = require('../httputils'),
 logger = require('../logging.js').logger,
-forward = require('../browserid/http_forward.js'),
+forward = require('../http_forward.js'),
 config = require('../configuration.js');
 
 exports.method = 'post';
-- 
GitLab