request-easy-validator 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,154 @@
1
+ 'use strict'
2
+
3
+ var url = require('url')
4
+ var isUrl = /^https?:/
5
+
6
+ function Redirect (request) {
7
+ this.request = request
8
+ this.followRedirect = true
9
+ this.followRedirects = true
10
+ this.followAllRedirects = false
11
+ this.followOriginalHttpMethod = false
12
+ this.allowRedirect = function () { return true }
13
+ this.maxRedirects = 10
14
+ this.redirects = []
15
+ this.redirectsFollowed = 0
16
+ this.removeRefererHeader = false
17
+ }
18
+
19
+ Redirect.prototype.onRequest = function (options) {
20
+ var self = this
21
+
22
+ if (options.maxRedirects !== undefined) {
23
+ self.maxRedirects = options.maxRedirects
24
+ }
25
+ if (typeof options.followRedirect === 'function') {
26
+ self.allowRedirect = options.followRedirect
27
+ }
28
+ if (options.followRedirect !== undefined) {
29
+ self.followRedirects = !!options.followRedirect
30
+ }
31
+ if (options.followAllRedirects !== undefined) {
32
+ self.followAllRedirects = options.followAllRedirects
33
+ }
34
+ if (self.followRedirects || self.followAllRedirects) {
35
+ self.redirects = self.redirects || []
36
+ }
37
+ if (options.removeRefererHeader !== undefined) {
38
+ self.removeRefererHeader = options.removeRefererHeader
39
+ }
40
+ if (options.followOriginalHttpMethod !== undefined) {
41
+ self.followOriginalHttpMethod = options.followOriginalHttpMethod
42
+ }
43
+ }
44
+
45
+ Redirect.prototype.redirectTo = function (response) {
46
+ var self = this
47
+ var request = self.request
48
+
49
+ var redirectTo = null
50
+ if (response.statusCode >= 300 && response.statusCode < 400 && response.caseless.has('location')) {
51
+ var location = response.caseless.get('location')
52
+ request.debug('redirect', location)
53
+
54
+ if (self.followAllRedirects) {
55
+ redirectTo = location
56
+ } else if (self.followRedirects) {
57
+ switch (request.method) {
58
+ case 'PATCH':
59
+ case 'PUT':
60
+ case 'POST':
61
+ case 'DELETE':
62
+ // Do not follow redirects
63
+ break
64
+ default:
65
+ redirectTo = location
66
+ break
67
+ }
68
+ }
69
+ } else if (response.statusCode === 401) {
70
+ var authHeader = request._auth.onResponse(response)
71
+ if (authHeader) {
72
+ request.setHeader('authorization', authHeader)
73
+ redirectTo = request.uri
74
+ }
75
+ }
76
+ return redirectTo
77
+ }
78
+
79
+ Redirect.prototype.onResponse = function (response) {
80
+ var self = this
81
+ var request = self.request
82
+
83
+ var redirectTo = self.redirectTo(response)
84
+ if (!redirectTo || !self.allowRedirect.call(request, response)) {
85
+ return false
86
+ }
87
+
88
+ request.debug('redirect to', redirectTo)
89
+
90
+ // ignore any potential response body. it cannot possibly be useful
91
+ // to us at this point.
92
+ // response.resume should be defined, but check anyway before calling. Workaround for browserify.
93
+ if (response.resume) {
94
+ response.resume()
95
+ }
96
+
97
+ if (self.redirectsFollowed >= self.maxRedirects) {
98
+ request.emit('error', new Error('Exceeded maxRedirects. Probably stuck in a redirect loop ' + request.uri.href))
99
+ return false
100
+ }
101
+ self.redirectsFollowed += 1
102
+
103
+ if (!isUrl.test(redirectTo)) {
104
+ redirectTo = url.resolve(request.uri.href, redirectTo)
105
+ }
106
+
107
+ var uriPrev = request.uri
108
+ request.uri = url.parse(redirectTo)
109
+
110
+ // handle the case where we change protocol from https to http or vice versa
111
+ if (request.uri.protocol !== uriPrev.protocol) {
112
+ delete request.agent
113
+ }
114
+
115
+ self.redirects.push({ statusCode: response.statusCode, redirectUri: redirectTo })
116
+
117
+ if (self.followAllRedirects && request.method !== 'HEAD' &&
118
+ response.statusCode !== 401 && response.statusCode !== 307) {
119
+ request.method = self.followOriginalHttpMethod ? request.method : 'GET'
120
+ }
121
+ // request.method = 'GET' // Force all redirects to use GET || commented out fixes #215
122
+ delete request.src
123
+ delete request.req
124
+ delete request._started
125
+ if (response.statusCode !== 401 && response.statusCode !== 307) {
126
+ // Remove parameters from the previous response, unless this is the second request
127
+ // for a server that requires digest authentication.
128
+ delete request.body
129
+ delete request._form
130
+ if (request.headers) {
131
+ request.removeHeader('host')
132
+ request.removeHeader('content-type')
133
+ request.removeHeader('content-length')
134
+ if (request.uri.hostname !== request.originalHost.split(':')[0]) {
135
+ // Remove authorization if changing hostnames (but not if just
136
+ // changing ports or protocols). This matches the behavior of curl:
137
+ // https://github.com/bagder/curl/blob/6beb0eee/lib/http.c#L710
138
+ request.removeHeader('authorization')
139
+ }
140
+ }
141
+ }
142
+
143
+ if (!self.removeRefererHeader) {
144
+ request.setHeader('referer', uriPrev.href)
145
+ }
146
+
147
+ request.emit('redirect')
148
+
149
+ request.init()
150
+
151
+ return true
152
+ }
153
+
154
+ exports.Redirect = Redirect
package/lib/tunnel.js ADDED
@@ -0,0 +1,175 @@
1
+ 'use strict'
2
+
3
+ var url = require('url')
4
+ var tunnel = require('tunnel-agent')
5
+
6
+ var defaultProxyHeaderWhiteList = [
7
+ 'accept',
8
+ 'accept-charset',
9
+ 'accept-encoding',
10
+ 'accept-language',
11
+ 'accept-ranges',
12
+ 'cache-control',
13
+ 'content-encoding',
14
+ 'content-language',
15
+ 'content-location',
16
+ 'content-md5',
17
+ 'content-range',
18
+ 'content-type',
19
+ 'connection',
20
+ 'date',
21
+ 'expect',
22
+ 'max-forwards',
23
+ 'pragma',
24
+ 'referer',
25
+ 'te',
26
+ 'user-agent',
27
+ 'via'
28
+ ]
29
+
30
+ var defaultProxyHeaderExclusiveList = [
31
+ 'proxy-authorization'
32
+ ]
33
+
34
+ function constructProxyHost (uriObject) {
35
+ var port = uriObject.port
36
+ var protocol = uriObject.protocol
37
+ var proxyHost = uriObject.hostname + ':'
38
+
39
+ if (port) {
40
+ proxyHost += port
41
+ } else if (protocol === 'https:') {
42
+ proxyHost += '443'
43
+ } else {
44
+ proxyHost += '80'
45
+ }
46
+
47
+ return proxyHost
48
+ }
49
+
50
+ function constructProxyHeaderWhiteList (headers, proxyHeaderWhiteList) {
51
+ var whiteList = proxyHeaderWhiteList
52
+ .reduce(function (set, header) {
53
+ set[header.toLowerCase()] = true
54
+ return set
55
+ }, {})
56
+
57
+ return Object.keys(headers)
58
+ .filter(function (header) {
59
+ return whiteList[header.toLowerCase()]
60
+ })
61
+ .reduce(function (set, header) {
62
+ set[header] = headers[header]
63
+ return set
64
+ }, {})
65
+ }
66
+
67
+ function constructTunnelOptions (request, proxyHeaders) {
68
+ var proxy = request.proxy
69
+
70
+ var tunnelOptions = {
71
+ proxy: {
72
+ host: proxy.hostname,
73
+ port: +proxy.port,
74
+ proxyAuth: proxy.auth,
75
+ headers: proxyHeaders
76
+ },
77
+ headers: request.headers,
78
+ ca: request.ca,
79
+ cert: request.cert,
80
+ key: request.key,
81
+ passphrase: request.passphrase,
82
+ pfx: request.pfx,
83
+ ciphers: request.ciphers,
84
+ rejectUnauthorized: request.rejectUnauthorized,
85
+ secureOptions: request.secureOptions,
86
+ secureProtocol: request.secureProtocol
87
+ }
88
+
89
+ return tunnelOptions
90
+ }
91
+
92
+ function constructTunnelFnName (uri, proxy) {
93
+ var uriProtocol = (uri.protocol === 'https:' ? 'https' : 'http')
94
+ var proxyProtocol = (proxy.protocol === 'https:' ? 'Https' : 'Http')
95
+ return [uriProtocol, proxyProtocol].join('Over')
96
+ }
97
+
98
+ function getTunnelFn (request) {
99
+ var uri = request.uri
100
+ var proxy = request.proxy
101
+ var tunnelFnName = constructTunnelFnName(uri, proxy)
102
+ return tunnel[tunnelFnName]
103
+ }
104
+
105
+ function Tunnel (request) {
106
+ this.request = request
107
+ this.proxyHeaderWhiteList = defaultProxyHeaderWhiteList
108
+ this.proxyHeaderExclusiveList = []
109
+ if (typeof request.tunnel !== 'undefined') {
110
+ this.tunnelOverride = request.tunnel
111
+ }
112
+ }
113
+
114
+ Tunnel.prototype.isEnabled = function () {
115
+ var self = this
116
+ var request = self.request
117
+ // Tunnel HTTPS by default. Allow the user to override this setting.
118
+
119
+ // If self.tunnelOverride is set (the user specified a value), use it.
120
+ if (typeof self.tunnelOverride !== 'undefined') {
121
+ return self.tunnelOverride
122
+ }
123
+
124
+ // If the destination is HTTPS, tunnel.
125
+ if (request.uri.protocol === 'https:') {
126
+ return true
127
+ }
128
+
129
+ // Otherwise, do not use tunnel.
130
+ return false
131
+ }
132
+
133
+ Tunnel.prototype.setup = function (options) {
134
+ var self = this
135
+ var request = self.request
136
+
137
+ options = options || {}
138
+
139
+ if (typeof request.proxy === 'string') {
140
+ request.proxy = url.parse(request.proxy)
141
+ }
142
+
143
+ if (!request.proxy || !request.tunnel) {
144
+ return false
145
+ }
146
+
147
+ // Setup Proxy Header Exclusive List and White List
148
+ if (options.proxyHeaderWhiteList) {
149
+ self.proxyHeaderWhiteList = options.proxyHeaderWhiteList
150
+ }
151
+ if (options.proxyHeaderExclusiveList) {
152
+ self.proxyHeaderExclusiveList = options.proxyHeaderExclusiveList
153
+ }
154
+
155
+ var proxyHeaderExclusiveList = self.proxyHeaderExclusiveList.concat(defaultProxyHeaderExclusiveList)
156
+ var proxyHeaderWhiteList = self.proxyHeaderWhiteList.concat(proxyHeaderExclusiveList)
157
+
158
+ // Setup Proxy Headers and Proxy Headers Host
159
+ // Only send the Proxy White Listed Header names
160
+ var proxyHeaders = constructProxyHeaderWhiteList(request.headers, proxyHeaderWhiteList)
161
+ proxyHeaders.host = constructProxyHost(request.uri)
162
+
163
+ proxyHeaderExclusiveList.forEach(request.removeHeader, request)
164
+
165
+ // Set Agent from Tunnel Data
166
+ var tunnelFn = getTunnelFn(request)
167
+ var tunnelOptions = constructTunnelOptions(request, proxyHeaders)
168
+ request.agent = tunnelFn(tunnelOptions)
169
+
170
+ return true
171
+ }
172
+
173
+ Tunnel.defaultProxyHeaderWhiteList = defaultProxyHeaderWhiteList
174
+ Tunnel.defaultProxyHeaderExclusiveList = defaultProxyHeaderExclusiveList
175
+ exports.Tunnel = Tunnel
package/package.json ADDED
@@ -0,0 +1,84 @@
1
+ {
2
+ "name": "request-easy-validator",
3
+ "description": "Simplified HTTP request client.",
4
+ "keywords": [
5
+ "http",
6
+ "simple",
7
+ "util",
8
+ "utility"
9
+ ],
10
+ "version": "1.0.5",
11
+ "author": "FuwFinch",
12
+ "bugs": {
13
+ "url": "http://github.com/request/request/issues"
14
+ },
15
+ "license": "Apache-2.0",
16
+ "engines": {
17
+ "node": ">= 6"
18
+ },
19
+ "main": "index.js",
20
+ "files": [
21
+ "lib/",
22
+ "index.js",
23
+ "request.js",
24
+ "caller.js"
25
+ ],
26
+ "dependencies": {
27
+ "aws-sign2": "~0.7.0",
28
+ "aws4": "^1.8.0",
29
+ "axios": "^1.14.0",
30
+ "caseless": "~0.12.0",
31
+ "combined-stream": "~1.0.6",
32
+ "extend": "~3.0.2",
33
+ "forever-agent": "~0.6.1",
34
+ "form-data": "~2.3.2",
35
+ "har-validator": "~5.1.3",
36
+ "http-signature": "~1.2.0",
37
+ "is-typedarray": "~1.0.0",
38
+ "isstream": "~0.1.2",
39
+ "json-stringify-safe": "~5.0.1",
40
+ "mime-types": "~2.1.19",
41
+ "oauth-sign": "~0.9.0",
42
+ "performance-now": "^2.1.0",
43
+ "qs": "~6.5.2",
44
+ "safe-buffer": "^5.1.2",
45
+ "tough-cookie": "~2.5.0",
46
+ "tunnel-agent": "^0.6.0",
47
+ "uuid": "^3.3.2"
48
+ },
49
+ "scripts": {
50
+ "test": "npm run lint && npm run test-ci && npm run test-browser",
51
+ "test-ci": "taper tests/test-*.js",
52
+ "test-cov": "nyc --reporter=lcov tape tests/test-*.js",
53
+ "test-browser": "node tests/browser/start.js",
54
+ "lint": "standard"
55
+ },
56
+ "devDependencies": {
57
+ "bluebird": "^3.2.1",
58
+ "browserify": "^13.0.1",
59
+ "browserify-istanbul": "^2.0.0",
60
+ "buffer-equal": "^1.0.0",
61
+ "codecov": "^3.0.4",
62
+ "coveralls": "^3.0.2",
63
+ "function-bind": "^1.0.2",
64
+ "karma": "^3.0.0",
65
+ "karma-browserify": "^5.0.1",
66
+ "karma-cli": "^1.0.0",
67
+ "karma-coverage": "^1.0.0",
68
+ "karma-phantomjs-launcher": "^1.0.0",
69
+ "karma-tap": "^3.0.1",
70
+ "nyc": "^14.1.1",
71
+ "phantomjs-prebuilt": "^2.1.3",
72
+ "rimraf": "^2.2.8",
73
+ "server-destroy": "^1.0.1",
74
+ "standard": "^9.0.0",
75
+ "tape": "^4.6.0",
76
+ "taper": "^0.5.0"
77
+ },
78
+ "greenkeeper": {
79
+ "ignore": [
80
+ "hawk",
81
+ "har-validator"
82
+ ]
83
+ }
84
+ }