diff --git a/lib/server.js b/lib/server.js index 3edf62fb0..b76c4445d 100644 --- a/lib/server.js +++ b/lib/server.js @@ -41,27 +41,40 @@ var Server = function(server, path, services, wsdl, options) { if (path[path.length - 1] !== '/') path += '/'; wsdl.onReady(function(err) { - var listeners = server.listeners('request').slice(); - - server.removeAllListeners('request'); - server.addListener('request', function(req, res) { - if (typeof self.authorizeConnection === 'function') { - if (!self.authorizeConnection(req)) { - res.end(); - return; + if(typeof server.route === 'function' && typeof server.use === 'function'){ + //handle only the required URL path for express server + server.route(path).all(function(req, res, next){ + if (typeof self.authorizeConnection === 'function') { + if (!self.authorizeConnection(req)) { + res.end(); + return; + } } - } - var reqPath = url.parse(req.url).pathname; - if (reqPath[reqPath.length - 1] !== '/') - reqPath += '/'; - if (path === reqPath) { self._requestListener(req, res); - } else { - for (var i = 0, len = listeners.length; i < len; i++) { - listeners[i].call(this, req, res); + }); + } else { + var listeners = server.listeners('request').slice(); + server.removeAllListeners('request'); + server.addListener('request', function(req, res) { + if (typeof self.authorizeConnection === 'function') { + if (!self.authorizeConnection(req)) { + res.end(); + return; + } } - } - }); + var reqPath = url.parse(req.url).pathname; + if (reqPath[reqPath.length - 1] !== '/'){ + reqPath += '/'; + } + if (path === reqPath) { + self._requestListener(req, res); + } else { + for (var i = 0, len = listeners.length; i < len; i++) { + listeners[i].call(this, req, res); + } + } + }); + } }); this._initializeOptions(options); @@ -100,6 +113,46 @@ Server.prototype._initializeOptions = function(options) { this.wsdl.options.attributesKey = options.attributesKey || 'attributes'; }; +Server.prototype._processRequestXml = function(req, res, xml){ + var self = this; + var result; + var error; + try { + if (typeof self.log === 'function') { + self.log("received", xml); + } + self._process(xml, req, function(result, statusCode) { + if(statusCode) { + res.statusCode = statusCode; + } + res.write(result); + res.end(); + if (typeof self.log === 'function') { + self.log("replied", result); + } + }); + } catch (err) { + if (err.Fault !== undefined) { + return self._sendError(err.Fault, function(result, statusCode) { + res.statusCode = statusCode || 500; + res.write(result); + res.end(); + if (typeof self.log === 'function') { + self.log("error", err); + } + }, new Date().toISOString()); + } else { + error = err.stack || err; + res.statusCode = 500; + res.write(error); + res.end(); + if (typeof self.log === 'function') { + self.log("error", error); + } + } + } +}; + Server.prototype._requestListener = function(req, res) { var self = this; var reqParse = url.parse(req.url); @@ -125,6 +178,13 @@ Server.prototype._requestListener = function(req, res) { } else { res.setHeader('Content-Type', "application/xml"); } + + //request body is already provided by an express middleware + //in this case unzipping should also be done by the express middleware itself + if(req.body){ + return self._processRequestXml(req, res, req.body.toString()); + } + var chunks = [], gunzip; if (compress && req.headers["content-encoding"] === "gzip") { gunzip = new compress.Gunzip(); @@ -143,43 +203,7 @@ Server.prototype._requestListener = function(req, res) { gunzip.end(); gunzip = null; } - try { - if (typeof self.log === 'function') { - self.log("received", xml); - } - self._process(xml, req, function(result, statusCode) { - if(statusCode) { - res.statusCode = statusCode; - } - res.write(result); - res.end(); - if (typeof self.log === 'function') { - self.log("replied", result); - } - }); - } - catch (err) { - if (err.Fault !== undefined) { - return self._sendError(err.Fault, function(result, statusCode) { - if(statusCode) { - res.statusCode = statusCode || 500; - } - res.write(result); - res.end(); - if (typeof self.log === 'function') { - self.log("error", err); - } - }, new Date().toISOString()); - } else { - error = err.stack || err; - res.statusCode = 500; - res.write(error); - res.end(); - if (typeof self.log === 'function') { - self.log("error", error); - } - } - } + self._processRequestXml(req, res, xml); }); } else { diff --git a/package.json b/package.json index da17e0e46..4863607d1 100644 --- a/package.json +++ b/package.json @@ -42,11 +42,13 @@ ], "license": "MIT", "devDependencies": { + "body-parser": "^1.15.2", "colors": "^1.1.2", "coveralls": "^2.11.6", "diff": "^2.2.1", "doctoc": "^1.0.0", "duplexer": "~0.1.1", + "express": "^4.14.0", "glob": "~3.2.8", "istanbul": "^0.4.1", "jshint": "2.3.0", diff --git a/test/express-server-test.js b/test/express-server-test.js new file mode 100644 index 000000000..8b86e4bf4 --- /dev/null +++ b/test/express-server-test.js @@ -0,0 +1,163 @@ +'use strict'; + +var request = require('request'); +var assert = require('assert'); +var express = require('express'); +var bodyParser = require('body-parser'); +var soap = require('../'); +var expressServer; +var server; +var port; +var url; +var wsdl = 'WSDL File for HelloService'; +var requestXML = '' + + '' + + '' + + 'tarun' + + '' + + '' + + ''; +var responseXML = '' + + '' + + '' + + '' + + 'tarun' + + '' + + '' + + ''; + +describe('Express server without middleware', function() { + + before(function(done){ + var service = { + Hello_Service: { + Hello_Port: { + sayHello: function(args){ + return { + greeting: args.firstName + } + } + } + } + }; + + expressServer = express(); + server = expressServer.listen(51515, function(){ + var soapServer = soap.listen(expressServer, '/SayHello', service, wsdl); + url = 'http://' + server.address().address + ':' + server.address().port; + if (server.address().address === '0.0.0.0' || server.address().address === '::') { + url = 'http://127.0.0.1:' + server.address().port; + } + done(); + }); + }); + + after(function(){ + server.close(); + }); + + it('should handle body without middleware', function(done){ + request({ + url: url + '/SayHello', + method: 'POST', + headers: {SOAPAction: "sayHello", + "Content-Type": 'text/xml; charset="utf-8"'}, + body: requestXML + }, function(err, response, body){ + if(err){ + throw err; + } + assert.equal(body, responseXML); + done(); + }); + }); + + it('should serve wsdl', function(done){ + request({ + url: url + '/SayHello?wsdl', + method: 'GET', + headers: { + "Content-Type": 'text/xml; charset="utf-8"'} + }, function(err, response, body){ + if(err){ + throw err; + } + assert.equal(body, wsdl); + done(); + }); + }); + + it('should handle other routes as usual', function(done){ + expressServer.route('/test/r1').get(function(req, res, next){ + //make sure next() works as well + return next(); + }, function(req, res){ + return res.status(200).send('test passed'); + }); + + request({ + url: url + '/test/r1', + method: 'GET' + }, function(err, response, body){ + if(err){ + throw err; + } + assert.equal(body, 'test passed'); + done(); + }); + }); + +}); + +describe('Express server with middleware', function() { + + before(function(done){ + var wsdl = 'WSDL File for HelloService'; + var service = { + Hello_Service: { + Hello_Port: { + sayHello: function(args){ + return { + greeting: args.firstName + } + } + } + } + }; + expressServer = express(); + expressServer.use(bodyParser.raw({type: function(){return true;}, limit: '5mb'})); + + server = expressServer.listen(51515, function(){ + + var soapServer = soap.listen(expressServer, '/SayHello', service, wsdl); + url = 'http://' + server.address().address + ':' + server.address().port; + + if (server.address().address === '0.0.0.0' || server.address().address === '::') { + url = 'http://127.0.0.1:' + server.address().port; + } + + done(); + }); + }); + + after(function(){ + server.close(); + }); + + it('should should allow parsing body via express middleware', function(done){ + request({ + url: url + '/SayHello', + method: 'POST', + headers: {SOAPAction: "sayHello", + "Content-Type": 'text/xml; charset="utf-8"'}, + body: requestXML + }, function(err, response, body){ + if(err){ + throw err; + } + assert.equal(body, responseXML); + done(); + }); + }); + +});