Socket
Socket
Sign inDemoInstall

popsicle

Package Overview
Dependencies
Maintainers
1
Versions
99
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

popsicle - npm Package Compare versions

Comparing version 0.4.0 to 0.5.0

24

package.json
{
"name": "popsicle",
"version": "0.4.0",
"version": "0.5.0",
"description": "Simple HTTP requests for node and the browser",

@@ -12,10 +12,18 @@ "main": "popsicle.js",

"browser": {
"request": false,
"form-data": false,
"buffer": false,
"./package.json": false
"concat-stream": false,
"http": false,
"https": false,
"url": false,
"zlib": false,
"infinity-agent": false,
"statuses": false,
"through2": false,
"tough-cookie": false
},
"scripts": {
"lint": "standard",
"test": "npm run lint && gulp test"
"filesize": "du -hs popsicle.js",
"test": "npm run lint && gulp test && npm run filesize"
},

@@ -47,3 +55,3 @@ "repository": {

"body-parser": "^1.9.2",
"chai": "^1.9.1",
"chai": "^2.1.1",
"es6-promise": "^2.0.0",

@@ -68,5 +76,9 @@ "express": "^4.10.2",

"dependencies": {
"concat-stream": "^1.4.7",
"form-data": "^0.2.0",
"request": "^2.48.0"
"infinity-agent": "^1.0.2",
"statuses": "^1.2.1",
"through2": "^0.6.3",
"tough-cookie": "^0.12.1"
}
}

@@ -26,3 +26,4 @@ /* global define */

var abortRequest
var jar
var isHostObject
var createRequest

@@ -32,4 +33,4 @@ var parseRawHeaders

if (typeof Promise === 'undefined') {
var PROMISE_ERROR_MESSAGE = (isNode ? 'global' : 'window') + '.Promise ' +
'is undefined and should be polyfilled. Check out ' +
var PROMISE_ERROR_MESSAGE = (!isNode ? 'global' : 'window') +
'.Promise is undefined and must be polyfilled. Check out ' +
'https://github.com/jakearchibald/es6-promise for more information.'

@@ -131,12 +132,12 @@

*
* @param {Popsicle} self
* @param {Request} req
* @return {Error}
*/
function abortError (self) {
if (self._error) {
return self._error
function abortError (req) {
if (req._error) {
return req._error
}
if (!self.timedout) {
var abortedError = self.error('Request aborted')
if (!req.timedout) {
var abortedError = req.error('Request aborted')
abortedError.abort = true

@@ -146,4 +147,4 @@ return abortedError

var timeout = self.timeout
var timedoutError = self.error('Timeout of ' + timeout + 'ms exceeded')
var timeout = req.timeout
var timedoutError = req.error('Timeout of ' + timeout + 'ms exceeded')
timedoutError.timeout = timeout

@@ -156,8 +157,8 @@ return timedoutError

*
* @param {Popsicle} self
* @param {Error} e
* @param {Request} req
* @param {Error} e
* @return {Error}
*/
function parseError (self, e) {
var err = self.error('Unable to parse the response body')
function parseError (req, e) {
var err = req.error('Unable to parse the response body')
err.parse = true

@@ -171,8 +172,8 @@ err.original = e

*
* @param {Popsicle} self
* @param {Error} e
* @param {Request} req
* @param {Error} e
* @return {Error}
*/
function cspError (self, e) {
var err = self.error('Refused to connect to "' + self.fullUrl() + '"')
function cspError (req, e) {
var err = req.error('Refused to connect to "' + req.fullUrl() + '"')
err.csp = true

@@ -186,7 +187,7 @@ err.original = e

*
* @param {Popsicle} self
* @param {Request} req
* @return {Error}
*/
function unavailableError (self) {
var err = self.error('Unable to connect to "' + self.fullUrl() + '"')
function unavailableError (req) {
var err = req.error('Unable to connect to "' + req.fullUrl() + '"')
err.unavailable = true

@@ -199,7 +200,7 @@ return err

*
* @param {Popsicle} self
* @param {Request} req
* @return {Error}
*/
function blockedError (self) {
var err = self.error('The request to "' + self.fullUrl() + '" was blocked')
function blockedError (req) {
var err = req.error('The request to "' + req.fullUrl() + '" was blocked')
err.blocked = true

@@ -210,2 +211,14 @@ return err

/**
* Create a maximum redirection error.
*
* @param {Request} req
* @return {Error}
*/
function redirectError (req) {
var err = req.error('Maximum number of redirects exceeded')
err.maxRedirects = req.maxRedirects
return err
}
/**
* Return the content type from a header string.

@@ -231,9 +244,5 @@ *

try {
return encodeURIComponent(str)
.replace(/[!'()]/g, root.escape)
.replace(/\*/g, '%2A')
} catch (e) {
return ''
}
return encodeURIComponent(str)
.replace(/[!'()]/g, root.escape)
.replace(/\*/g, '%2A')
}

@@ -328,30 +337,2 @@

/**
* Check whether the object is already natively supported.
*
* @param {*} object
* @return {Boolean}
*/
var isHostObject
if (isNode) {
isHostObject = function (object) {
return object instanceof Buffer || object instanceof FormData
}
} else {
isHostObject = function (object) {
var str = Object.prototype.toString.call(object)
switch (str) {
case '[object File]':
case '[object Blob]':
case '[object FormData]':
case '[object ArrayBuffer]':
return true
default:
return false
}
}
}
/**
* Convert an object into a form data instance.

@@ -362,3 +343,3 @@ *

*/
function toFormData (obj) {
function form (obj) {
var form = new FormData()

@@ -378,10 +359,10 @@

*
* @param {Request} request
* @param {Request} req
*/
function stringifyRequest (request) {
var body = request.body
function stringifyRequest (req) {
var body = req.body
// Convert primitives types into strings.
if (!isObject(body)) {
request.body = body == null ? null : String(body)
req.body = body == null ? null : String(body)

@@ -396,3 +377,3 @@ return

var type = request.type()
var type = req.type()

@@ -403,11 +384,11 @@ // Set the default mime type to be JSON if none exists.

request.type(type)
req.type(type)
}
if (JSON_MIME_REGEXP.test(type)) {
request.body = JSON.stringify(body)
req.body = JSON.stringify(body)
} else if (FORM_MIME_REGEXP.test(type)) {
request.body = toFormData(body)
req.body = form(body)
} else if (QUERY_MIME_REGEXP.test(type)) {
request.body = stringifyQuery(body)
req.body = stringifyQuery(body)
}

@@ -419,13 +400,13 @@ }

*
* @param {Response} response
* @param {Response} res
* @return {Promise}
*/
function parseResponse (response) {
var body = response.body
var type = response.type()
function parseResponse (res) {
var body = res.body
var type = res.type()
if (body === '') {
response.body = null
res.body = null
return response
return res
}

@@ -435,8 +416,8 @@

if (JSON_MIME_REGEXP.test(type)) {
response.body = body === '' ? null : JSON.parse(body)
res.body = body === '' ? null : JSON.parse(body)
} else if (QUERY_MIME_REGEXP.test(type)) {
response.body = parseQuery(body)
res.body = parseQuery(body)
}
} catch (e) {
return Promise.reject(parseError(response, e))
return Promise.reject(parseError(res, e))
}

@@ -448,24 +429,31 @@ }

*
* @param {Request} request
* @param {Request} req
*/
function defaultAccept (request) {
function defaultHeaders (req) {
// If we have no accept header set already, default to accepting
// everything. This is needed because otherwise Firefox defaults to
// an accept header of `html/xml`.
if (!request.get('Accept')) {
request.set('Accept', '*/*')
if (!req.get('Accept')) {
req.set('Accept', '*/*')
}
}
/**
* Correct the content type request header.
*
* @param {Request} request
*/
function correctType (request) {
// Specify a default user agent in node.
if (!req.get('User-Agent')) {
req.set('User-Agent', 'https://github.com/blakeembrey/popsicle')
}
// Accept zipped responses.
if (!req.get('Accept-Encoding')) {
req.set('Accept-Encoding', 'gzip,deflate')
}
// Remove the `Content-Type` header from form data requests. The node
// `request` module supports `form-data` to automatically add headers,
// and the browser will ses it on `xhr.send` (when it's not already set).
if (request.body instanceof FormData) {
request.remove('Content-Type')
// and the browser will set it on `xhr.send` (only when it doesn't exist).
if (req.body instanceof FormData) {
if (isNode) {
req.set(req.body.getHeaders())
} else {
req.remove('Content-Type')
}
}

@@ -477,9 +465,14 @@ }

*
* @param {Request} request
* @param {Request} req
*/
function removeListeners (request) {
delete request._before
delete request._after
delete request._always
delete request._progress
function removeListeners (req) {
req._before = undefined
req._after = undefined
req._always = undefined
req._progress = undefined
req._errored = undefined
req._raw = undefined
req.body = undefined
}

@@ -490,8 +483,8 @@

*
* @param {Request} request
* @param {Request} req
* @return {Promise}
*/
function checkAborted (request) {
if (request.aborted) {
return Promise.reject(abortError(request))
function checkAborted (req) {
if (req.aborted) {
return Promise.reject(abortError(req))
}

@@ -503,9 +496,9 @@ }

*
* @param {Request} self
* @param {Request} req
* @param {Object} headers
*/
function setHeaders (self, headers) {
function setHeaders (req, headers) {
if (headers) {
Object.keys(headers).forEach(function (key) {
self.set(key, headers[key])
req.set(key, headers[key])
})

@@ -516,2 +509,18 @@ }

/**
* Get all headers case-sensitive.
*
* @param {Request} req
* @return {Object}
*/
function getHeaders (req) {
var headers = {}
Object.keys(req.headers).forEach(function (key) {
headers[req.name(key)] = req.headers[key]
})
return headers
}
/**
* Lower-case the header name. Allow usage of `Referrer` and `Referer`.

@@ -651,3 +660,3 @@ *

function chain (fns, arg) {
return fns.reduce(function (promise, fn) {
return (fns || []).reduce(function (promise, fn) {
return promise.then(function () {

@@ -662,11 +671,11 @@ return fn(arg)

*
* @param {Request} self
* @param {Request} req
*/
function setup (self) {
var timeout = self.timeout
function setup (req) {
var timeout = req.timeout
if (timeout) {
self._timer = setTimeout(function () {
self.timedout = true
self.abort()
req._timer = setTimeout(function () {
req.timedout = true
req.abort()
}, timeout)

@@ -676,13 +685,10 @@ }

// Set the request to "opened", disables any new listeners.
self.opened = true
req.opened = true
return chain(self._before, self)
return chain(req._before, req)
.then(function () {
return createRequest(self)
return createRequest(req)
})
.then(function (response) {
response.request = self
self.response = response
return chain(self._after, response)
.then(function (res) {
return chain(req._after, res)
})

@@ -694,9 +700,9 @@ .catch(function (err) {

return chain(self._always, self).then(reject)
return chain(req._always, req).then(reject)
})
.then(function () {
return chain(self._always, self)
return chain(req._always, req)
})
.then(function () {
return self.response
return req.response
})

@@ -708,12 +714,12 @@ }

*
* @param {Request} self
* @param {Request} req
* @return {Promise}
*/
function create (self) {
function create (req) {
// Setup a new promise request if none exists.
if (!self._promise) {
self._promise = setup(self)
if (!req._promise) {
req._promise = setup(req)
}
return self._promise
return req._promise
}

@@ -732,5 +738,5 @@

*
* @param {String} key
* @param {String} value
* @return {Header}
* @param {String} key
* @param {String} value
* @return {Headers}
*/

@@ -753,2 +759,20 @@ Headers.prototype.set = function (key, value) {

/**
* Append a header value.
*
* @param {String} key
* @param {String} value
* @return {Headers}
*/
Headers.prototype.append = function (key, value) {
var prev = this.get(key)
var val = value
if (prev) {
val = Array.isArray(prev) ? prev.concat(value) : [prev].concat(value)
}
return this.set(key, val)
}
/**
* Get the original case-sensitive header name.

@@ -770,2 +794,6 @@ *

Headers.prototype.get = function (header) {
if (header == null) {
return getHeaders(this)
}
return this.headers[lowerHeader(header)]

@@ -806,6 +834,9 @@ }

*
* @param {Request} request
* @param {Request} req
*/
function Response (request) {
function Response (req) {
Headers.call(this)
this.request = req
req.response = this
}

@@ -829,38 +860,2 @@

/**
* Check whether the response was an info response. Status >= 100 < 200.
*
* @return {Boolean}
*/
Response.prototype.info = function () {
return this.statusType() === 1
}
/**
* Check whether the response was ok. Status >= 200 < 300.
*
* @return {Boolean}
*/
Response.prototype.ok = function () {
return this.statusType() === 2
}
/**
* Check whether the response was a client error. Status >= 400 < 500.
*
* @return {Boolean}
*/
Response.prototype.clientError = function () {
return this.statusType() === 4
}
/**
* Check whether the response was a server error. Status >= 500 < 600.
*
* @return {Boolean}
*/
Response.prototype.serverError = function () {
return this.statusType() === 5
}
/**
* Create a popsicle error instance.

@@ -884,2 +879,4 @@ *

var query = options.query
var stream = options.stream === true
var parse = options.parse !== false

@@ -895,5 +892,14 @@ // Request options.

this.jar = options.jar
this.withCredentials = options.withCredentials === true
this.maxRedirects = num(options.maxRedirects)
this.rejectUnauthorized = options.rejectUnauthorized !== false
this.agent = options.agent
// Default redirect count.
if (isNaN(this.maxRedirects) || this.maxRedirects < 0) {
this.maxRedirects = 10
}
// Browser specific options.
this.withCredentials = options.withCredentials === true
// Progress state.

@@ -905,3 +911,3 @@ this.uploaded = this.downloaded = this.completed = 0

// Set request headers.
setHeaders(this, options.headers)
this.set(options.headers)

@@ -923,8 +929,27 @@ // Request state.

this.before(checkAborted)
this.before(defaultAccept)
this.before(stringifyRequest)
this.before(correctType)
this.before(defaultHeaders)
this.after(parseResponse)
if (isNode) {
this.before(contentLength)
if (this.jar) {
this.before(getCookieJar)
this.after(setCookieJar)
}
}
// Support streaming responses under node.
if (!stream) {
if (isNode) {
this.after(streamResponse)
}
if (parse) {
this.after(parseResponse)
}
} else if (!isNode) {
throw new Error('Streaming is only available in node')
}
this.always(removeListeners)

@@ -988,8 +1013,8 @@ }

this.aborted = true
// Set everything to completed.
this.downloaded = this.uploaded = this.completed = 1
// Abort and emit the final progress event.
abortRequest(this)
if (this._raw) {
this._raw.abort()
}
emitProgress(this, this._progress)

@@ -1049,91 +1074,116 @@ clearTimeout(this._timer)

if (isNode) {
var request = require('request')
var version = require('./package.json').version
var http = require('http')
var https = require('https')
var urlLib = require('url')
var zlib = require('zlib')
var agent = require('infinity-agent')
var statuses = require('statuses')
var through2 = require('through2')
var tough = require('tough-cookie')
/**
* Return options sanitized for the request module.
* Stream node response.
*
* @param {Request} self
* @return {Object}
* @param {Response} res
* @return {Promise}
*/
var requestOptions = function (self) {
var request = {}
var streamResponse = function (res) {
var concat = require('concat-stream')
request.url = self.fullUrl()
request.method = self.method
request.jar = self.jar
request.headers = {
'User-Agent': 'node-popsicle/' + version
}
return new Promise(function (resolve, reject) {
var concatStream = concat({
encoding: 'string'
}, function (data) {
// Update the response `body`.
res.body = data
// Add headers with the correct case names.
Object.keys(self.headers).forEach(function (header) {
request.headers[self.name(header)] = self.get(header)
return resolve()
})
res.body.once('error', reject)
res.body.pipe(concatStream)
})
}
// The `request` module supports form data under a private property.
if (self.body instanceof FormData) {
request._form = self.body
} else {
request.body = self.body
}
/**
* Set the default content length.
*
* @param {Request} req
*/
var contentLength = function (req) {
var length = 0
var body = req.body
if (self.rejectUnauthorized) {
request.rejectUnauthorized = true
if (body && !req.get('Content-Length')) {
if (!Buffer.isBuffer(body)) {
if (Array.isArray(body)) {
for (var i = 0; i < body.length; i++) {
length += body[i].length
}
} else {
body = new Buffer(body)
length = body.length
}
} else {
length = body.length
}
if (length) {
req.set('Content-Length', length)
}
}
return request
}
/**
* Return the byte length of an input.
* Read cookies from the cookie jar.
*
* @param {(String|Buffer)} data
* @return {Number}
* @param {Request} req
* @return {Promise}
*/
var byteLength = function (data) {
if (Buffer.isBuffer(data)) {
return data.length
}
var getCookieJar = function (req) {
return new Promise(function (resolve, reject) {
req.jar.getCookies(req.url, function (err, cookies) {
if (err) {
return reject(err)
}
if (typeof data === 'string') {
return Buffer.byteLength(data)
}
if (cookies.length) {
req.append('Cookie', cookies.join('; '))
}
return 0
return resolve()
})
})
}
/**
* Track the current download size.
* Put cookies in the cookie jar.
*
* @param {Request} self
* @param {request} request
* @param {Response} res
* @return {Promise}
*/
var trackRequestProgress = function (self, request) {
function onRequest (request) {
var write = request.write
var setCookieJar = function (res) {
return new Promise(function (resolve, reject) {
var cookies = res.get('Set-Cookie')
self.uploadTotal = num(request.getHeader('Content-Length'))
if (!cookies) {
return resolve()
}
// Override `Request.prototype.write` to track amount of sent data.
request.write = function (data) {
setUploadSize(self, self.uploadSize + byteLength(data))
return write.apply(this, arguments)
if (!Array.isArray(cookies)) {
cookies = [cookies]
}
}
function onResponse (response) {
response.on('data', onResponseData)
self.downloadTotal = num(response.headers['content-length'])
setUploadFinished(self)
}
var setCookies = cookies.map(function (cookie) {
return new Promise(function (resolve, reject) {
var req = res.request
function onResponseData (data) {
// Data should always be a `Buffer` instance.
setDownloadSize(self, self.downloadSize + data.length)
}
req.jar.setCookie(cookie, req.url, function (err) {
return err ? reject(err) : resolve()
})
})
})
request.on('request', onRequest)
request.on('response', onResponse)
return resolve(Promise.all(setCookies))
})
}

@@ -1168,38 +1218,111 @@

*
* @param {Request} self
* @param {Request} req
* @return {Promise}
*/
createRequest = function (self) {
createRequest = function (req) {
return new Promise(function (resolve, reject) {
var opts = requestOptions(self)
var body = req.body
var redirectCount = 0
var headers = req.get()
var req = request(opts, function (err, response) {
// Clean up listeners.
delete self._request
setDownloadFinished(self)
/**
* Track upload progress through a stream.
*/
var requestProxy = through2(function (chunk, enc, callback) {
setUploadSize(req, req.uploadSize + chunk.length)
callback(null, chunk)
}, function (callback) {
setUploadFinished(req)
callback(req.aborted ? abortError(req) : null)
})
if (err) {
// Node.js core error (ECONNRESET, EPIPE).
if (typeof err.code === 'string') {
return reject(unavailableError(self))
/**
* Track download progress through a stream.
*/
var responseProxy = through2(function (chunk, enc, callback) {
setDownloadSize(req, req.downloadSize + chunk.length)
callback(null, chunk)
}, function (callback) {
setDownloadFinished(req)
callback(req.aborted ? abortError(req) : null)
})
/**
* Create the HTTP request.
*
* @param {String} url
*/
function get (url) {
var arg = urlLib.parse(url)
var fn = arg.protocol === 'https:' ? https : http
arg.headers = headers
arg.method = req.method
arg.rejectUnauthorized = req.rejectUnauthorized
arg.agent = req.agent || agent(arg)
var request = fn.request(arg)
request.once('response', function (response) {
var statusCode = response.statusCode
var stream = response
// Handle HTTP redirections.
if (statuses.redirect[statusCode] && response.headers.location) {
// Discard response.
response.resume()
if (++redirectCount > req.maxRedirects) {
reject(redirectError(req))
return
}
get(urlLib.resolve(url, response.headers.location))
return
}
return reject(err)
}
req.downloadTotal = num(response.headers['content-length'])
var res = new Response()
// Track download progress.
stream.pipe(responseProxy)
stream = responseProxy
res.body = response.body
res.status = response.statusCode
res.set(parseRawHeaders(response))
// Decode zipped responses.
if (['gzip', 'deflate'].indexOf(response.headers['content-encoding']) !== -1) {
var unzip = zlib.createUnzip()
stream.pipe(unzip)
stream = unzip
}
return resolve(res)
})
var res = new Response(req)
req.on('abort', function () {
return reject(abortError(self))
})
res.body = stream
res.status = response.statusCode
res.set(parseRawHeaders(response))
self._request = req
trackRequestProgress(self, req)
return resolve(res)
})
request.once('error', function (err) {
return reject(req.aborted ? abortError(req) : unavailableError(req))
})
req._raw = request
req.uploadTotal = num(request.getHeader('Content-Length'))
requestProxy.pipe(request)
// Pipe the body to the stream.
if (body) {
if (typeof body.pipe === 'function') {
body.pipe(requestProxy)
} else {
requestProxy.end(body)
}
} else {
requestProxy.end()
}
}
get(req.fullUrl())
})

@@ -1209,11 +1332,19 @@ }

/**
* Abort a running node request.
* Check for host objects in node.
*
* @param {Request} self
* @param {*} object
* @return {Boolean}
*/
abortRequest = function (self) {
if (self._request) {
self._request.abort()
}
isHostObject = function (object) {
return object instanceof Buffer || object instanceof FormData
}
/**
* Create a cookie jar in node.
*
* @return {Object}
*/
jar = function () {
return new tough.CookieJar()
}
} else {

@@ -1265,17 +1396,17 @@ /**

*
* @param {Request} self
* @param {Request} req
* @return {Promise}
*/
createRequest = function (self) {
createRequest = function (req) {
return new Promise(function (resolve, reject) {
var url = self.fullUrl()
var method = self.method
var res = new Response()
var url = req.fullUrl()
var method = req.method
var res = new Response(req)
// Loading HTTP resources from HTTPS is restricted and uncatchable.
if (window.location.protocol === 'https:' && /^http\:/.test(url)) {
return reject(blockedError(self))
return reject(blockedError(req))
}
var xhr = self._xhr = getXHR()
var xhr = req._raw = getXHR()

@@ -1289,3 +1420,3 @@ xhr.onreadystatechange = function () {

// Try setting the total download size.
self.downloadTotal = num(res.get('Content-Length'))
req.downloadTotal = num(res.get('Content-Length'))

@@ -1295,18 +1426,16 @@ // Trigger upload finished after we get the response length.

// `xhr` object invalid.
setUploadFinished(self)
setUploadFinished(req)
}
if (xhr.readyState === 4) {
// Clean up listeners.
delete self._xhr
setDownloadFinished(self)
setDownloadFinished(req)
// Handle the aborted state internally, PhantomJS doesn't reset
// `xhr.status` to zero on abort.
if (self.aborted) {
return reject(abortError(self))
if (req.aborted) {
return reject(abortError(req))
}
if (xhr.status === 0) {
return reject(unavailableError(self))
return reject(unavailableError(req))
}

@@ -1323,6 +1452,6 @@

if (e.lengthComputable) {
self.downloadTotal = e.total
req.downloadTotal = e.total
}
setDownloadSize(self, e.loaded)
setDownloadSize(req, e.loaded)
}

@@ -1332,13 +1461,11 @@

if (method === 'GET' || method === 'HEAD' || !xhr.upload) {
xhr.upload = {}
self.uploadTotal = 0
setUploadSize(self, 0)
req.uploadTotal = 0
setUploadSize(req, 0)
} else {
xhr.upload.onprogress = function (e) {
if (e.lengthComputable) {
self.uploadTotal = e.total
req.uploadTotal = e.total
}
setUploadSize(self, e.loaded)
setUploadSize(req, e.loaded)
}

@@ -1351,7 +1478,7 @@ }

} catch (e) {
return reject(cspError(self, e))
return reject(cspError(req, e))
}
// Send cookies with CORS.
if (self.withCredentials) {
if (req.withCredentials) {
xhr.withCredentials = true

@@ -1361,7 +1488,7 @@ }

// Set all headers with original casing.
Object.keys(self.headers).forEach(function (header) {
xhr.setRequestHeader(self.name(header), self.get(header))
Object.keys(req.headers).forEach(function (header) {
xhr.setRequestHeader(req.name(header), req.get(header))
})
xhr.send(self.body)
xhr.send(req.body)
})

@@ -1371,11 +1498,29 @@ }

/**
* Abort a running XMLHttpRequest.
* Check for host objects in the browser.
*
* @param {Request} self
* @param {*} object
* @return {Boolean}
*/
abortRequest = function (self) {
if (self._xhr) {
self._xhr.abort()
isHostObject = function (object) {
var str = Object.prototype.toString.call(object)
switch (str) {
case '[object File]':
case '[object Blob]':
case '[object FormData]':
case '[object ArrayBuffer]':
return true
default:
return false
}
}
/**
* Throw an error in browsers where `jar` is not supported.
*
* @throws {Error}
*/
jar = function () {
throw new Error('Cookie jars are not supported on the browser')
}
}

@@ -1406,24 +1551,8 @@

/**
* Initialize a form data instance.
* Expose utilities.
*/
popsicle.form = function (params) {
return toFormData(params)
}
popsicle.jar = jar
popsicle.form = form
/**
* Support cookie jars (on Node).
*
* @return {Object}
*/
if (isNode) {
popsicle.jar = function () {
return request.jar()
}
} else {
popsicle.jar = function () {
throw new Error('Cookie jars are not supported on the browser')
}
}
/**
* Expose the `Request` and `Response` constructors.

@@ -1430,0 +1559,0 @@ */

@@ -10,6 +10,6 @@ # ![Popsicle](https://cdn.rawgit.com/blakeembrey/popsicle/master/logo.svg)

```javascript
request('/users.json')
popsicle('/users.json')
.then(function (res) {
console.log(res.body); //=> { ... }
});
console.log(res.body) //=> { ... }
})
```

@@ -35,6 +35,6 @@

// Node and browserify
require('es6-promise').polyfill();
require('es6-promise').polyfill()
// Browsers
window.ES6Promise.polyfill();
window.ES6Promise.polyfill()
```

@@ -45,6 +45,6 @@

```javascript
var request = require('popsicle');
// var request = window.popsicle;
var popsicle = require('popsicle')
// var popsicle = window.popsicle
request({
popsicle({
method: 'POST',

@@ -61,6 +61,6 @@ url: 'http://example.com/api/users',

.then(function (res) {
console.log(res.status); // => 200
console.log(res.body); //=> { ... }
console.log(res.get('Content-Type')); //=> 'application/json'
});
console.log(res.status) // => 200
console.log(res.body) //=> { ... }
console.log(res.get('Content-Type')) //=> 'application/json'
})
```

@@ -76,2 +76,3 @@

* **timeout** The number of milliseconds before cancelling the request (default: `Infinity`)
* **parse** Optionally skip response parsing (default: `true`)

@@ -81,3 +82,6 @@ **Node only**

* **jar** An instance of a cookie jar (default: `null`)
* **agent** Custom HTTP pooling agent (default: [infinity-agent](https://github.com/floatdrop/infinity-agent))
* **maxRedirects** Override the number of redirects to allow (default: `10`)
* **rejectUnauthorized** Reject invalid SSL certificates (default: `true`)
* **stream** Stream the HTTP response body (default: `false`)

@@ -93,12 +97,11 @@ **Browser only**

```javascript
request({
popsicle({
url: 'http://example.com/api/users',
body: {
username: 'blakeembrey',
profileImage: fs.createReadStream('image.png')
username: 'blakeembrey'
},
headers: {
'Content-Type': 'multipart/form-data'
'Content-Type': 'application/x-www-form-urlencoded'
}
});
})
```

@@ -111,12 +114,12 @@

```javascript
var form = request.form({
name: 'Blake Embrey',
image: '...'
});
var form = popsicle.form({
username: 'blakeembrey',
profileImage: fs.createReadStream('image.png')
})
request({
popsicle({
method: 'POST',
url: '/users',
body: form
});
})
```

@@ -126,14 +129,14 @@

All requests can be aborted during execution by calling `Request#abort`. Requests won't normally start until chained anyway, but this will also abort the request before it starts.
All requests can be aborted before or during execution by calling `Request#abort`.
```javascript
var req = request('http://example.com');
var req = popsicle('http://example.com')
setTimeout(function () {
req.abort();
}, 100);
req.abort()
}, 100)
req.catch(function (err) {
console.log(err); //=> { message: 'Request aborted', aborted: true }
});
console.log(err) //=> { message: 'Request aborted', aborted: true }
})
```

@@ -156,14 +159,14 @@

```javascript
var req = request('http://example.com');
var req = popsicle('http://example.com')
req.uploaded; //=> 0
req.downloaded; //=> 0
req.uploaded //=> 0
req.downloaded //=> 0
req.progress(function (e) {
console.log(e); //=> { uploaded: 1, downloaded: 0, completed: 0.5, aborted: false }
});
console.log(e) //=> { uploaded: 1, downloaded: 0, completed: 0.5, aborted: false }
})
req.then(function (res) {
console.log(req.downloaded); //=> 1
});
console.log(req.downloaded) //=> 1
})
```

@@ -176,9 +179,9 @@

```javascript
var jar = request.jar();
var jar = request.jar()
request({
popsicle({
method: 'POST',
url: '/users',
jar: jar
});
})
```

@@ -195,3 +198,3 @@

```javascript
request('/users')
popsicle('/users')
.then(function (res) {

@@ -202,3 +205,3 @@ // Things worked!

// Something broke.
});
})
```

@@ -211,3 +214,3 @@

```javascript
request('/users')
popsicle('/users')
.exec(function (err, res) {

@@ -219,3 +222,3 @@ if (err) {

// Success!
});
})
```

@@ -231,6 +234,2 @@

* **statusType()** Return an integer with the HTTP status type (E.g. `200 -> 2`)
* **info()** Return a boolean indicating a HTTP status code between 100 and 199
* **ok()** Return a boolean indicating a HTTP status code between 200 and 299
* **clientError()** Return a boolean indicating a HTTP status code between 400 and 499
* **serverError()** Return a boolean indicating a HTTP status code between 500 and 599
* **get(key)** Retrieve a HTTP header using a case-insensitive key

@@ -250,2 +249,3 @@ * **name(key)** Retrieve the original HTTP header name using a case-insensitive key

* **csp error** Request violates the documents Content Security Policy (browsers, `err.csp`)
* **max redirects error** Number of HTTP redirects exceeded (node, `err.maxRedirects`)

@@ -264,2 +264,3 @@ ### Plugins

* [Constants](https://github.com/blakeembrey/popsicle-constants) - Replace constants in the URL string
* [Limit](https://github.com/blakeembrey/popsicle-limit) - Transparently handle API rate limits

@@ -273,11 +274,11 @@ #### Creating Plugins

return function (req) {
req.url = url + req.url;
};
req.url = url + req.url
}
}
request('/user')
popsicle('/user')
.use(prefix('http://example.com'))
.then(function (res) {
console.log(res.request.url); //=> "http://example.com/user"
});
console.log(res.request.url) //=> "http://example.com/user"
})
```

@@ -284,0 +285,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc