Skip to content

Instantly share code, notes, and snippets.

@ejnshtein
Last active August 14, 2019 13:09
Show Gist options
  • Save ejnshtein/65578169ab31f6d1e8a1160bd540b208 to your computer and use it in GitHub Desktop.
Save ejnshtein/65578169ab31f6d1e8a1160bd540b208 to your computer and use it in GitHub Desktop.
// docs: https://nodejs.org/dist/latest-v10.x/docs/api/https.html#https_https_request_url_options_callback
// all methods working, but post only with x-form-urlencoded. return promise with resolved object on line 64.
// extra options parameters: json=[bool], params=[object]
const querystring = require('querystring')
const https = require('https')
const http = require('http')
const cleanObject = (object, filterKeys) => Object
.keys(object)
.reduce((acc, key) => {
if (filterKeys.includes(key)) {
return {
...acc,
[key]: object[key]
}
}
return acc
}, {})
const mergeUrl = (url, searchParams) => {
const urlInst = new URL(url)
const params = new URLSearchParams(searchParams)
params.forEach((val, key) => {
urlInst.searchParams.set(key, val)
})
return urlInst.toString()
}
function request (url, options, formData) {
const form = formData ? querystring.stringify(formData) : undefined
if (options.params && typeof options.params === 'object') {
url = mergeUrl(url, options.params)
}
if (options.header && form) {
options.headers = Object.assign(options.headers, { 'Content-Length': Buffer.byteLength(form) })
}
return new Promise((resolve, reject) => {
function resHanlder (res) {
res.setEncoding('utf8')
let data = ''
const onData = chunk => {
data += chunk
}
const onError = err => {
res.removeListener('error', onError)
res.removeListener('data', onData)
reject(err)
}
const onClose = () => {
res.removeListener('error', onError)
res.removeListener('data', onData)
res.removeListener('close', onClose)
if (options.json) {
try {
data = JSON.parse(data)
} catch (e) {
return reject(new Error(`JSON parsing error: ${e.message}: ${data}`))
}
}
// console.log(res.headers)
resolve({
data,
headers: res.headers,
status: res.statusCode,
statusText: res.statusMessage
})
data = null
}
res.on('data', onData)
res.on('error', onError)
res.on('close', onClose)
}
const req = url.startsWith('https') ? https.request(
url,
cleanObject(options, ['protocol', 'host', 'hostname', 'family', 'port', 'localAddres', 'socketPath', 'method', 'path', 'auth', 'agent', 'createConnection', 'timeout']),
resHanlder
) : http.request(
url,
cleanObject(options, ['protocol', 'host', 'hostname', 'family', 'port', 'localAddres', 'socketPath', 'method', 'path', 'auth', 'agent', 'createConnection', 'timeout']),
resHanlder
)
if (options.headers) {
Object.keys(options.headers).forEach(header => {
req.setHeader(header, options.headers[header])
})
}
const onError = err => {
req.removeListener('error', onError)
reject(err)
}
req.on('error', onError)
if (form) {
req.write(form)
}
req.end()
})
}
module.exports = request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment