yep
Version:
A simple HTTP client for node
130 lines (112 loc) • 3.08 kB
JavaScript
const net = require('net')
const tls = require('tls')
const http = require('http')
const https = require('https')
const url = require('url')
const querystring = require('querystring')
const getproxy = require('getproxy')
/**
* [parseOptions description]
* @param {[type]} opts [description]
* @return {[type]} [description]
* - url
* - method
* - headers
* - form
* - json
* - proxy
* - todo: auth, retires, cookie
*/
function parseOptions(options) {
if (!options.url) {
throw new Error('options.url must be specified')
}
options = Object.assign({}, options)
if (typeof options.url === 'string') {
options.url = url.parse(options.url)
}
var reqOptions = {
protocol: options.url.protocol || 'http:',
hostname: options.url.hostname || options.url.host,
port: options.url.port,
path: options.url.path || '/',
method: (options.method || 'GET').toUpperCase(),
headers: {}
}
var headers = options.headers
if (headers) {
Object.keys(headers).forEach(key => {
reqOptions.headers[key.toLowercase()] = headers[key]
})
}
var form = options.form
if (form) {
if (typeof form === 'object') {
form = querystring.stringify(form)
}
reqOptions.body = form
reqOptions.headers['content-type'] = 'application/x-www-form-urlencoded'
reqOptions.headers['content-length'] = Buffer.byteLength(reqOptions.body)
}
var json = options.json
if (json) {
if (typeof json !== 'object') {
throw new Error('options.json must be an object')
}
reqOptions.body = JSON.stringify(json)
reqOptions.headers['content-type'] = 'application/json'
reqOptions.headers['content-length'] = Buffer.byteLength(reqOptions.body)
}
var proxy = options.proxy
if (proxy !== false) {
proxy = proxy || getproxy.for(options.url)
if (proxy) {
if (typeof proxy === 'string') {
proxy = url.parse(proxy)
}
reqOptions.createConnection = function(opts, cb) {
var ns = proxy.protocol === 'https:' ? tls : net
return ns.connect({
host: proxy.hostname || proxy.host,
port: proxy.port
})
}
}
}
return reqOptions
}
function stream(options) {
options = parseOptions(options)
var ns = options.protocol === 'https:' ? https : http
return new Promise((resolve, reject) => {
var req = ns.request(options, res => {
resolve(res)
})
if (options.body) {
req.write(options.body)
}
req.end()
})
}
function yep(options) {
return new Promise((resolve, reject) => {
stream(options).then(res => {
var body = []
res.on('data', chunk => body.push(chunk))
res.on('end', () => {
res.body = Buffer.concat(body).toString()
resolve(res)
})
res.on('error', err => reject(err))
})
})
}
var methods = ['get', 'post', 'put', 'delete', 'head']
methods.forEach(method => {
yep[method] = function(options) {
options.method = method.toUpperCase()
return yep(options)
}
})
yep.stream = stream
module.exports = yep