| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220 | 
							- const path = require('path')
 
- const http = require('http')
 
- const https = require('https')
 
- const followRedirects = require('follow-redirects')
 
- const qs = require('querystring')
 
- const zlib = require('zlib')
 
- const {URL} = require('url')
 
- const CentraResponse = require('./CentraResponse.js')
 
- const supportedCompressions = ['gzip', 'deflate', 'br']
 
- const useRequest = (protocol, maxRedirects) => {
 
- 	let httpr
 
- 	let httpsr
 
- 	if (maxRedirects <= 0) {
 
- 		httpr = http.request
 
- 		httpsr = https.request
 
- 	}
 
- 	else {
 
- 		httpr = followRedirects.http.request
 
- 		httpsr = followRedirects.https.request
 
- 	}
 
- 	if (protocol === 'http:') {
 
- 		return httpr
 
- 	}
 
- 	else if (protocol === 'https:') {
 
- 		return httpsr
 
- 	}
 
- 	else throw new Error('Bad URL protocol: ' + protocol)
 
- }
 
- module.exports = class CentraRequest {
 
- 	constructor (url, method = 'GET') {
 
- 		this.url = typeof url === 'string' ? new URL(url) : url
 
- 		this.method = method
 
- 		this.data = null
 
- 		this.sendDataAs = null
 
- 		this.reqHeaders = {}
 
- 		this.streamEnabled = false
 
- 		this.compressionEnabled = false
 
- 		this.timeoutTime = null
 
- 		this.coreOptions = {}
 
- 		this.maxRedirects = 0
 
- 		this.resOptions = {
 
- 			'maxBuffer': 50 * 1000000 // 50 MB
 
- 		}
 
- 		return this
 
- 	}
 
- 	followRedirects(n) {
 
- 		this.maxRedirects = n
 
- 		return this
 
- 	}
 
- 	query (a1, a2) {
 
- 		if (typeof a1 === 'object') {
 
- 			Object.keys(a1).forEach((queryKey) => {
 
- 				this.url.searchParams.append(queryKey, a1[queryKey])
 
- 			})
 
- 		}
 
- 		else this.url.searchParams.append(a1, a2)
 
- 		return this
 
- 	}
 
- 	path (relativePath) {
 
- 		this.url.pathname = path.join(this.url.pathname, relativePath)
 
- 		return this
 
- 	}
 
- 	body (data, sendAs) {
 
- 		this.sendDataAs = typeof data === 'object' && !sendAs && !Buffer.isBuffer(data) ? 'json' : (sendAs ? sendAs.toLowerCase() : 'buffer')
 
- 		this.data = this.sendDataAs === 'form' ? qs.stringify(data) : (this.sendDataAs === 'json' ? JSON.stringify(data) : data)
 
- 		return this
 
- 	}
 
- 	header (a1, a2) {
 
- 		if (typeof a1 === 'object') {
 
- 			Object.keys(a1).forEach((headerName) => {
 
- 				this.reqHeaders[headerName.toLowerCase()] = a1[headerName]
 
- 			})
 
- 		}
 
- 		else this.reqHeaders[a1.toLowerCase()] = a2
 
- 		return this
 
- 	}
 
- 	timeout (timeout) {
 
- 		this.timeoutTime = timeout
 
- 		return this
 
- 	}
 
- 	option (name, value) {
 
- 		this.coreOptions[name] = value
 
- 		return this
 
- 	}
 
- 	stream () {
 
- 		this.streamEnabled = true
 
- 		return this
 
- 	}
 
- 	compress () {
 
- 		this.compressionEnabled = true
 
- 		if (!this.reqHeaders['accept-encoding']) this.reqHeaders['accept-encoding'] = supportedCompressions.join(', ')
 
- 		return this
 
- 	}
 
- 	send () {
 
- 		return new Promise((resolve, reject) => {
 
- 			if (this.data) {
 
- 				if (!this.reqHeaders.hasOwnProperty('content-type')) {
 
- 					if (this.sendDataAs === 'json') {
 
- 						this.reqHeaders['content-type'] = 'application/json'
 
- 					}
 
- 					else if (this.sendDataAs === 'form') {
 
- 						this.reqHeaders['content-type'] = 'application/x-www-form-urlencoded'
 
- 					}
 
- 				}
 
- 				if (!this.reqHeaders.hasOwnProperty('content-length')) {
 
- 					this.reqHeaders['content-length'] = Buffer.byteLength(this.data)
 
- 				}
 
- 			}
 
- 			const options = Object.assign({
 
- 				'protocol': this.url.protocol,
 
- 				'host': this.url.hostname.replace('[', '').replace(']', ''),
 
- 				'port': this.url.port,
 
- 				'path': this.url.pathname + (this.url.search === null ? '' : this.url.search),
 
- 				'method': this.method,
 
- 				'headers': this.reqHeaders,
 
- 				'maxRedirects': this.maxRedirects
 
- 			}, this.coreOptions)
 
- 			let req
 
- 			const resHandler = (res) => {
 
- 				let stream = res
 
- 				if (this.compressionEnabled) {
 
- 					if (res.headers['content-encoding'] === 'gzip') {
 
- 						stream = res.pipe(zlib.createGunzip())
 
- 					}
 
- 					else if (res.headers['content-encoding'] === 'deflate') {
 
- 						stream = res.pipe(zlib.createInflate())
 
- 					}
 
- 					else if (res.headers['content-encoding'] === 'br') {
 
- 						stream = res.pipe(zlib.createBrotliDecompress())
 
- 					}
 
- 				}
 
- 				let centraRes
 
- 				if (this.streamEnabled) {
 
- 					resolve(stream)
 
- 				}
 
- 				else {
 
- 					centraRes = new CentraResponse(res, this.resOptions)
 
- 					stream.on('error', (err) => {
 
- 						reject(err)
 
- 					})
 
- 					stream.on('aborted', () => {
 
- 						reject(new Error('Server aborted request'))
 
- 					})
 
- 					stream.on('data', (chunk) => {
 
- 						centraRes._addChunk(chunk)
 
- 						if (this.resOptions.maxBuffer !== null && centraRes.body.length > this.resOptions.maxBuffer) {
 
- 							stream.destroy()
 
- 							reject('Received a response which was longer than acceptable when buffering. (' + this.body.length + ' bytes)')
 
- 						}
 
- 					})
 
- 					stream.on('end', () => {
 
- 						resolve(centraRes)
 
- 					})
 
- 				}
 
- 			}
 
- 			const request = useRequest(this.url.protocol, this.maxRedirects)
 
- 			req = request(options, resHandler)
 
- 			if (this.timeoutTime) {
 
- 				req.setTimeout(this.timeoutTime, () => {
 
- 					req.abort()
 
- 					if (!this.streamEnabled) {
 
- 						reject(new Error('Timeout reached'))
 
- 					}
 
- 				})
 
- 			}
 
- 			req.on('error', (err) => {
 
- 				reject(err)
 
- 			})
 
- 			if (this.data) req.write(this.data)
 
- 			req.end()
 
- 		})
 
- 	}
 
- }
 
 
  |