Last active
August 14, 2019 13:09
-
-
Save ejnshtein/65578169ab31f6d1e8a1160bd540b208 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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