forked from vpulim/node-soap
-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.js
126 lines (114 loc) · 3.68 KB
/
server.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
* Copyright (c) 2011 Vinay Pulim <vinay@milewise.com>
* MIT Licensed
*/
var url = require('url'),
compress = null;
try { compress = require("compress"); } catch(e) {}
var Server = function(server, path, services, wsdl) {
var self = this,
listeners = server.listeners('request');
this.services = services;
this.wsdl = wsdl;
if (path[path.length-1] != '/') path += '/';
server.removeAllListeners('request');
server.addListener('request', function(req, res) {
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);
}
}
});
}
Server.prototype._requestListener = function(req, res) {
var self = this;
if (req.method === 'GET') {
var search = url.parse(req.url).search;
if (search && search.toLowerCase() === '?wsdl') {
res.setHeader("Content-Type", "application/xml");
res.write(self.wsdl.toXML());
}
res.end();
}
else if (req.method === 'POST') {
var chunks = [], gunzip;
if (compress && req.headers["content-encoding"] == "gzip") {
gunzip = new compress.Gunzip;
gunzip.init();
}
req.on('data', function(chunk) {
if (gunzip) chunk = gunzip.inflate(chunk, "binary");
chunks.push(chunk);
})
req.on('end', function() {
var xml = chunks.join(''), result;
if (gunzip) {
gunzip.end();
gunzip = null
}
try {
result = self._process(xml);
}
catch (err) {
result = err.stack;
}
res.write(result);
res.end();
});
}
else {
res.end();
}
}
Server.prototype._process = function(input) {
var self = this,
obj = this.wsdl.xmlToObject(input),
messageName = Object.keys(obj)[0],
args = obj[messageName],
portTypes = this.wsdl.definitions.portTypes;
for (var portName in portTypes) {
var portType = portTypes[portName];
var methods = portType.methods;
for (var methodName in methods) {
var method = methods[methodName];
if (method.input.$name == messageName) {
return self._executeMethod(methodName, method.output.$name, args);
}
}
}
return '';
}
Server.prototype._executeMethod = function(methodName, outputName, args) {
var services = this.services;
for (var serviceName in services) {
var service = services[serviceName];
for (var portName in service) {
var port = service[portName];
var method = port[methodName];
if (method) {
var obj = {};
obj[outputName] = method(args);
return this._envelope(obj);
}
}
}
return this._envelope();
}
Server.prototype._envelope = function(object) {
var ns = this.wsdl.definitions.$targetNamespace,
xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<soap:Envelope " +
"xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" " +
"xmlns:ns0=\""+ns+"\">" +
"<soap:Body>" +
this.wsdl.objectToXML(object) +
"</soap:Body>" +
"</soap:Envelope>";
return xml;
}
exports.Server = Server;