-
-
Notifications
You must be signed in to change notification settings - Fork 148
/
Copy pathfetch.js
90 lines (75 loc) · 2.58 KB
/
fetch.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
const axios = require("axios");
const { merge } = require("./merge.js");
const { getPatcher } = require("./patcher.js");
const { generateDigestAuthHeader } = require("./auth.js");
function makeNonce() {
const cnonceSize = 32;
const nonceRaw = "abcdef0123456789";
let uid = "";
for (let i = 0; i < cnonceSize; ++i) {
uid += nonceRaw[Math.floor(Math.random() * nonceRaw.length)];
}
return uid;
}
function parseAuth(response, _digest) {
const authHeader = response.headers["www-authenticate"] || "";
if (authHeader.split(/\s/)[0].toLowerCase() !== "digest") {
return false;
}
const re = /([a-z0-9_-]+)=(?:"([^"]+)"|([a-z0-9_-]+))/gi;
for (;;) {
var match = re.exec(authHeader);
if (!match) {
break;
}
_digest[match[1]] = match[2] || match[3];
}
_digest.nc++;
_digest.cnonce = makeNonce();
return true;
}
function request(requestOptions) {
return getPatcher().patchInline("request", options => axios(options), requestOptions);
}
function fetch(requestOptions) {
// Client not configured for digest authentication
if (!requestOptions._digest) {
return request(requestOptions);
}
// Remove client's digest authentication object from request options
const _digest = requestOptions._digest;
delete requestOptions._digest;
// If client is already using digest authentication, include the digest authorization header
if (_digest.hasDigestAuth) {
requestOptions = merge(requestOptions, {
headers: {
Authorization: generateDigestAuthHeader(requestOptions, _digest)
}
});
}
// Perform the request and handle digest authentication
return request(requestOptions).then(function(response) {
if (response.status == 401) {
_digest.hasDigestAuth = parseAuth(response, _digest);
if (_digest.hasDigestAuth) {
requestOptions = merge(requestOptions, {
headers: {
Authorization: generateDigestAuthHeader(requestOptions, _digest)
}
});
return request(requestOptions).then(function(response2) {
if (response2.status == 401) {
_digest.hasDigestAuth = false;
} else {
_digest.nc++;
}
return response2;
});
}
} else {
_digest.nc++;
}
return response;
});
}
module.exports = fetch;