UNPKG

3.22 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(isHttps){
34 keepaliveAgent = new https.Agent({keepAlive: true});
35 }else{
36 keepaliveAgent = new http.Agent({keepAlive: true});
37 }
38
39 // build type1 request:
40
41 function sendType1Message (callback) {
42 var type1msg = ntlm.createType1Message(options);
43
44 var type1options = {
45 headers:{
46 'Connection' : 'keep-alive',
47 'Authorization': type1msg
48 },
49 timeout: options.timeout || 0,
50 agent: keepaliveAgent,
51 allowRedirects: false // don't redirect in httpreq, because http could change to https which means we need to change the keepaliveAgent
52 };
53
54 // pass along other options:
55 type1options = _.extend({}, _.omit(httpreqOptions, 'headers', 'body'), type1options);
56
57 // send type1 message to server:
58 httpreq[method](options.url, type1options, callback);
59 }
60
61 function sendType3Message (res, callback) {
62 // catch redirect here:
63 if(res.headers.location) {
64 options.url = res.headers.location;
65 return exports[method](options, finalCallback);
66 }
67
68
69 if(!res.headers['www-authenticate'])
70 return callback(new Error('www-authenticate not found on response of second request'));
71
72 // parse type2 message from server:
73 var type2msg = ntlm.parseType2Message(res.headers['www-authenticate'], callback); //callback only happens on errors
74 if(!type2msg) return; // if callback returned an error, the parse-function returns with null
75
76 // create type3 message:
77 var type3msg = ntlm.createType3Message(type2msg, options);
78
79 // build type3 request:
80 var type3options = {
81 headers: {
82 'Connection': 'Close',
83 'Authorization': type3msg
84 },
85 allowRedirects: false,
86 agent: keepaliveAgent
87 };
88
89 // pass along other options:
90 type3options.headers = _.extend(type3options.headers, httpreqOptions.headers);
91 type3options = _.extend(type3options, _.omit(httpreqOptions, 'headers'));
92
93 // send type3 message to server:
94 httpreq[method](options.url, type3options, callback);
95 }
96
97
98 sendType1Message(function (err, res) {
99 if(err) return finalCallback(err);
100 setImmediate(function () { // doesn't work without setImmediate()
101 sendType3Message(res, finalCallback);
102 });
103 });
104
105};
106
107['get', 'put', 'patch', 'post', 'delete', 'options'].forEach(function(method){
108 exports[method] = exports.method.bind(exports, method);
109});
110
111exports.ntlm = ntlm; //if you want to use the NTML functions yourself
112