diff --git a/lib/client.js b/lib/client.js
index 80597692c..72786953b 100755
--- a/lib/client.js
+++ b/lib/client.js
@@ -110,7 +110,13 @@ Client.prototype._invoke = function(method, arguments, location, callback, optio
self.security.addHeaders(headers);
if (self.security && self.security.addOptions)
self.security.addOptions(options);
-
+
+ //NTLM Security has extra requirements
+ var ntlm = false;
+ if (self.security && self.security.NTLM){
+ ntlm = self.security;
+ }
+
if (input.parts) {
assert.ok(!style || style == 'rpc', 'invalid message definition for document style binding');
message = self.wsdl.objectToRpcXML(name, arguments, alias, ns);
@@ -121,7 +127,7 @@ Client.prototype._invoke = function(method, arguments, location, callback, optio
}
else {
assert.ok(!style || style == 'document', 'invalid message definition for rpc style binding');
- message = self.wsdl.objectToDocumentXML(input.$name, arguments, input.targetNSAlias, input.targetNamespace);
+ message = self.wsdl.objectToDocumentXML(input.$name, arguments, input.targetNSAlias, input.targetNamespace);
}
xml = "" +
"";
- self.lastRequest = xml;
-
+ self.lastRequest = xml;
+
http.request(location, xml, function(err, response, body) {
self.lastResponse = body;
if (err) {
@@ -160,7 +166,7 @@ Client.prototype._invoke = function(method, arguments, location, callback, optio
}
callback(null, result, body);
}
- }, headers, options);
+ }, headers, options, ntlm);
}
exports.Client = Client;
diff --git a/lib/http.js b/lib/http.js
index 631263f44..90e18add4 100755
--- a/lib/http.js
+++ b/lib/http.js
@@ -4,11 +4,12 @@
*/
var url = require('url'),
- req = require('request');
+ req = require('request'),
+ httpntlm = require('httpntlm');
var VERSION = "0.2.0";
-exports.request = function(rurl, data, callback, exheaders, exoptions) {
+exports.request = function(rurl, data, callback, exheaders, exoptions, ntlmSecurity) {
var curl = url.parse(rurl);
var secure = curl.protocol == 'https:';
var host = curl.hostname;
@@ -41,13 +42,28 @@ exports.request = function(rurl, data, callback, exheaders, exoptions) {
exoptions = exoptions || {};
for (var attr in exoptions) { options[attr] = exoptions[attr]; }
- var request = req(options, function (error, res, body) {
- if (error) {
- callback(error);
- } else {
- callback(null, res, body);
- }
- });
- request.on('error', callback);
- request.end(data);
+ console.log(JSON.stringify(headers));
+
+ if(!ntlmSecurity){
+
+ var request = req(options, function (error, res, body) {
+ if (error) {
+ callback(error);
+ } else {
+ callback(null, res, body);
+ }
+ });
+ request.on('error', callback);
+ request.end(data);
+
+ }else{
+ console.log('Entering NTLM request');
+ options.headers['Authorization'] = ntlm.challengeHeader(ntlmSecurity._hostname, ntlmSecurity._domain);
+ options.workstation = 'virco.webserver';
+ options.body = data;
+ options.domain = ntlmSecurity._domain;
+ options.username = ntlmSecurity._username;
+ options.password = ntlmSecurity._password;
+ httpntlm.post(options, callback);
+ }
}
diff --git a/lib/soap.js b/lib/soap.js
index e99411543..3fabb79ea 100755
--- a/lib/soap.js
+++ b/lib/soap.js
@@ -62,6 +62,22 @@ function listen(server, pathOrOptions, services, xml) {
return new Server(server, path, services, wsdl);
}
+function NTLMAuthSecurity(url, domain, username, password) {
+ this._url = url;
+ this._hostname = require('url').parse(url).hostname;
+ this._domain = domain;
+ this._username = username;
+ this._password = password;
+}
+
+NTLMAuthSecurity.prototype.toXML = function() {
+ return "";
+}
+
+NTLMAuthSecurity.prototype.NTLM = function() {
+ return true;
+}
+
function BasicAuthSecurity(username, password) {
this._username = username;
this._password = password;
@@ -144,6 +160,7 @@ WSSecurity.prototype.toXML = function() {
}
exports.BasicAuthSecurity = BasicAuthSecurity;
+exports.NTLMAuthSecurity = NTLMAuthSecurity;
exports.WSSecurity = WSSecurity;
exports.ClientSSLSecurity = ClientSSLSecurity;
exports.createClient = createClient;
diff --git a/package.json b/package.json
index 708ebd500..23a5f705d 100755
--- a/package.json
+++ b/package.json
@@ -1,21 +1,48 @@
{
- "name": "soap",
- "version": "0.3.0",
- "description": "A minimal node SOAP client",
- "engines": { "node": ">=0.8.0" },
- "author": "Vinay Pulim ",
- "dependencies": {
- "node-expat": ">=1.6.1",
- "request": ">=2.9.0"
- },
- "repository" : {
- "type":"git",
- "url":"https://github.com/milewise/node-soap.git" },
- "main": "./index.js",
- "directories": { "lib": "./lib" },
- "scripts": {"test": "mocha -R spec -u exports test/*-test.js"},
- "keywords": ["soap"],
- "licenses": [{
- "type" : "MIT License",
- "url" : "http://www.opensource.org/licenses/mit-license.php" }]
+ "name": "soap",
+ "version": "0.3.0",
+ "description": "A minimal node SOAP client",
+ "engines": {
+ "node": ">=0.8.0"
+ },
+ "author": {
+ "name": "Vinay Pulim",
+ "email": "v@pulim.com"
+ },
+ "dependencies": {
+ "node-expat": ">=1.6.1",
+ "request": ">=2.9.0",
+ "httpntlm": "https://github.com/btallman/node-http-ntlm.git"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/milewise/node-soap.git"
+ },
+ "main": "./index.js",
+ "directories": {
+ "lib": "./lib"
+ },
+ "scripts": {
+ "test": "mocha -R spec -u exports test/*-test.js"
+ },
+ "keywords": [
+ "soap"
+ ],
+ "licenses": [
+ {
+ "type": "MIT License",
+ "url": "http://www.opensource.org/licenses/mit-license.php"
+ }
+ ],
+ "readme": "This module lets you connect to web services using SOAP. It also provides a server that allows you to run your own SOAP services.\n\nFeatures:\n\n* Very simple API\n* Handles both RPC and Document schema types\n* Supports multiRef SOAP messages (thanks to [@kaven276](https://github.com/kaven276))\n* Support for both synchronous and asynchronous method handlers\n* WS-Security (currently only UsernameToken and PasswordText encoding is supported)\n* Slightly improved ability to handle SAP SOAP WSDLS\n 1. Sequences nest a collection of - objects beneath the parent object, instead of a collection of parent objects\n\n## Install\n\nInstall with [npm](http://github.com/isaacs/npm):\n\n```\n npm install soap\n```\n## Module\n\n### soap.createClient(url, callback) - create a new SOAP client from a WSDL url. Also supports a local filesystem path.\n\n``` javascript\n var soap = require('soap');\n var url = 'http://example.com/wsdl?wsdl';\n var args = {name: 'value'};\n soap.createClient(url, function(err, client) {\n client.MyFunction(args, function(err, result) {\n console.log(result);\n });\n });\n```\n\n### soap.listen(*server*, *path*, *services*, *wsdl*) - create a new SOAP server that listens on *path* and provides *services*.\n*wsdl* is an xml string that defines the service.\n\n``` javascript\n var myService = {\n MyService: {\n MyPort: {\n MyFunction: function(args) {\n return {\n name: args.name\n };\n }\n\n // This is how to define an asynchronous function. \n MyAsyncFunction: function(args, callback) {\n // do some work\n callback({\n name: args.name\n })\n }\n }\n }\n }\n\n var xml = require('fs').readFileSync('myservice.wsdl', 'utf8'),\n server = http.createServer(function(request,response) {\n response.end(\"404: Not Found: \"+request.url)\n });\n\n server.listen(8000);\n soap.listen(server, '/wsdl', myService, xml);\n```\n\n### server logging\n\nIf the log method is defined it will be called with 'received' and 'replied'\nalong with data.\n\n``` javascript\n server = soap.listen(...)\n server.log = function(type, data) {\n // type is 'received' or 'replied'\n };\n```\n\n### server security example using PasswordDigest\n\nIf server.authenticate is not defined no authentation will take place.\n\n``` javascript\n server = soap.listen(...)\n server.authenticate = function(security) {\n var created, nonce, password, user, token;\n token = security.UsernameToken, user = token.Username,\n password = token.Password, nonce = token.Nonce, created = token.Created;\n return user === 'user' && password === soap.passwordDigest(nonce, created, 'password');\n };\n```\n\n### server connection authorization\n\nThis is called prior to soap service method\nIf the method is defined and returns false the incoming connection is\nterminated.\n\n``` javascript\n server = soap.listen(...)\n server.authorizeConnection = function(req) {\n return true; // or false\n };\n```\n\n\n## Client\n\nAn instance of Client is passed to the soap.createClient callback. It is used to execute methods on the soap service.\n\n### Client.describe() - description of services, ports and methods as a JavaScript object\n\n``` javascript\n client.describe() // returns\n {\n MyService: {\n MyPort: {\n MyFunction: {\n input: {\n name: 'string'\n }\n }\n }\n }\n }\n```\n\n### Client.setSecurity(security) - use the specified security protocol (see WSSecurity below)\n\n``` javascript\n client.setSecurity(new WSSecurity('username', 'password'))\n```\n\n### Client.*method*(args, callback) - call *method* on the SOAP service.\n\n``` javascript\n client.MyFunction({name: 'value'}, function(err, result) {\n // result is a javascript object\n })\n```\n### Client.*service*.*port*.*method*(args, callback) - call a *method* using a specific *service* and *port*\n\n``` javascript\n client.MyService.MyPort.MyFunction({name: 'value'}, function(err, result) {\n // result is a javascript object\n })\n```\n### Client.*addSoapHeader*(soapHeader[, name, namespace, xmlns]) - add soapHeader to soap:Header node\n#### Options\n\n - `soapHeader` Object({rootName: {name: \"value\"}}) or strict xml-string\n\n##### Optional parameters when first arg is object :\n - `name` Unknown parameter (it could just a empty string)\n - `namespace` prefix of xml namespace\n - `xmlns` URI\n\n### Client.*lastRequest* - the property that contains last full soap request for client logging\n\n## WSSecurity\n\nWSSecurity implements WS-Security. UsernameToken and PasswordText/PasswordDigest is supported. An instance of WSSecurity is passed to Client.setSecurity.\n\n``` javascript\n new WSSecurity(username, password, passwordType)\n //'PasswordDigest' or 'PasswordText' default is PasswordText\n```\n",
+ "readmeFilename": "Readme.md",
+ "bugs": {
+ "url": "https://github.com/milewise/node-soap/issues"
+ },
+ "_id": "soap@0.3.0",
+ "dist": {
+ "shasum": "1cb44bad31fe51e218e54c78aaa4446c3a311e21"
+ },
+ "_resolved": "git://github.com/btallman/node-soap#ac6240218470ef142ffed64c6e1b70ed30835c26",
+ "_from": "soap@git://github.com/btallman/node-soap#alpha-1"
}