UNPKG

3.29 kBJavaScriptView Raw
1/**
2 * Copyright (c) 2013 Sam Decrock https://github.com/SamDecrock/
3 * All rights reserved.
4 *
5 * This source code is licensed under the MIT license found in the
6 * LICENSE file in the root directory of this source tree.
7 */
8
9'use strict';
10
11var url = require('url');
12var httpreq = require('httpreq');
13var ntlm = require('./ntlm');
14var _ = require('underscore');
15var http = require('http');
16var https = require('https');
17
18exports.method = function(method, options, finalCallback){
19 if(!options.workstation) options.workstation = '';
20 if(!options.domain) options.domain = '';
21
22 // extract non-ntlm-options:
23 var httpreqOptions = _.omit(options, 'url', 'username', 'password', 'workstation', 'domain');
24
25 // is https?
26 var isHttps = false;
27 var reqUrl = url.parse(options.url);
28 if(reqUrl.protocol == 'https:') isHttps = true;
29
30 // set keepaliveAgent (http or https):
31 var keepaliveAgent;
32
33 if(options.agent) {
34 keepaliveAgent = options.agent;
35 }else{
36 if(isHttps){
37 keepaliveAgent = new https.Agent({keepAlive: true});
38 }else{
39 keepaliveAgent = new http.Agent({keepAlive: true});
40 }
41 }
42
43 // build type1 request:
44
45 function sendType1Message (callback) {
46 var type1msg = ntlm.createType1Message(options);
47
48 var type1options = {
49 headers:{
50 'Connection' : 'keep-alive',
51 'Authorization': type1msg
52 },
53 timeout: options.timeout || 0,
54 agent: keepaliveAgent,
55 allowRedirects: false // don't redirect in httpreq, because http could change to https which means we need to change the keepaliveAgent
56 };
57
58 // pass along other options:
59 type1options = _.extend({}, _.omit(httpreqOptions, 'headers', 'body'), type1options);
60
61 // send type1 message to server:
62 httpreq[method](options.url, type1options, callback);
63 }
64
65 function sendType3Message (res, callback) {
66 // catch redirect here:
67 if(res.headers.location) {
68 options.url = res.headers.location;
69 return exports[method](options, finalCallback);
70 }
71
72
73 if(!res.headers['www-authenticate'])
74 return callback(new Error('www-authenticate not found on response of second request'));
75
76 // parse type2 message from server:
77 var type2msg = ntlm.parseType2Message(res.headers['www-authenticate'], callback); //callback only happens on errors
78 if(!type2msg) return; // if callback returned an error, the parse-function returns with null
79
80 // create type3 message:
81 var type3msg = ntlm.createType3Message(type2msg, options);
82
83 // build type3 request:
84 var type3options = {
85 headers: {
86 'Connection': 'Close',
87 'Authorization': type3msg
88 },
89 allowRedirects: false,
90 agent: keepaliveAgent
91 };
92
93 // pass along other options:
94 type3options.headers = _.extend(type3options.headers, httpreqOptions.headers);
95 type3options = _.extend(type3options, _.omit(httpreqOptions, 'headers'));
96
97 // send type3 message to server:
98 httpreq[method](options.url, type3options, callback);
99 }
100
101
102 sendType1Message(function (err, res) {
103 if(err) return finalCallback(err);
104 setImmediate(function () { // doesn't work without setImmediate()
105 sendType3Message(res, finalCallback);
106 });
107 });
108
109};
110
111['get', 'put', 'patch', 'post', 'delete', 'options'].forEach(function(method){
112 exports[method] = exports.method.bind(exports, method);
113});
114
115exports.ntlm = ntlm; //if you want to use the NTML functions yourself
116