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();
+ });
+ });
+
+});