Skip to content

Commit

Permalink
express server support (vpulim#872)
Browse files Browse the repository at this point in the history
  • Loading branch information
prasunsultania authored and herom committed Aug 17, 2016
1 parent 59aa639 commit eb658b2
Show file tree
Hide file tree
Showing 3 changed files with 244 additions and 55 deletions.
134 changes: 79 additions & 55 deletions lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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();
Expand All @@ -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 {
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
163 changes: 163 additions & 0 deletions test/express-server-test.js
Original file line number Diff line number Diff line change
@@ -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 = '<definitions name="HelloService" targetNamespace="http://www.examples.com/wsdl/HelloService.wsdl" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.examples.com/wsdl/HelloService.wsdl" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><message name="SayHelloRequest"><part name="firstName" type="xsd:string"/></message><message name="SayHelloResponse"><part name="greeting" type="xsd:string"/></message><portType name="Hello_PortType"><operation name="sayHello"><input message="tns:SayHelloRequest"/><output message="tns:SayHelloResponse"/></operation></portType><binding name="Hello_Binding" type="tns:Hello_PortType"><soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/><operation name="sayHello"><soap:operation soapAction="sayHello"/><input><soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:examples:helloservice" use="encoded"/></input><output><soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:examples:helloservice" use="encoded"/></output></operation></binding><service name="Hello_Service"><documentation>WSDL File for HelloService</documentation><port binding="tns:Hello_Binding" name="Hello_Port"><soap:address location="http://localhost:51515/SayHello/" /></port></service></definitions>';
var requestXML = '<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">' +
'<Body>' +
'<sayHello xmlns="http://www.examples.com/wsdl/HelloService.wsdl">' +
'<firstName>tarun</firstName>' +
'</sayHello>' +
'</Body>' +
'</Envelope>';
var responseXML = '<?xml version="1.0" encoding="utf-8"?>' +
'<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://www.examples.com/wsdl/HelloService.wsdl">' +
'<soap:Body>' +
'<tns:sayHelloResponse>' +
'<tns:greeting>tarun</tns:greeting>' +
'</tns:sayHelloResponse>' +
'</soap:Body>' +
'</soap:Envelope>';

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 = '<definitions name="HelloService" targetNamespace="http://www.examples.com/wsdl/HelloService.wsdl" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.examples.com/wsdl/HelloService.wsdl" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><message name="SayHelloRequest"><part name="firstName" type="xsd:string"/></message><message name="SayHelloResponse"><part name="greeting" type="xsd:string"/></message><portType name="Hello_PortType"><operation name="sayHello"><input message="tns:SayHelloRequest"/><output message="tns:SayHelloResponse"/></operation></portType><binding name="Hello_Binding" type="tns:Hello_PortType"><soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/><operation name="sayHello"><soap:operation soapAction="sayHello"/><input><soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:examples:helloservice" use="encoded"/></input><output><soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:examples:helloservice" use="encoded"/></output></operation></binding><service name="Hello_Service"><documentation>WSDL File for HelloService</documentation><port binding="tns:Hello_Binding" name="Hello_Port"><soap:address location="http://localhost:51515/SayHello/" /></port></service></definitions>';
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();
});
});

});

0 comments on commit eb658b2

Please sign in to comment.