Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
httpism is a node and browser HTTP client that does a few things differently:
In addition, httpism supports:
Httpism 3.x returns the body of the response by default, not the response. This is what you want 95% of the time, however, if you're upgrading from 2.x, or you want the response with headers, status code, etc, then you can do this:
var httpism = require('httpism').client({response: true})
npm install httpism
Then
var httpism = require('httpism');
Compatible with browserify and webpack too!
httpism.get('http://example.com/').then(function (responseBody) {
console.log('json', responseBody);
}, function (error) {
console.log('uh oh', error);
});
httpism.post('http://example.com/', {name: 'Betty Boop'}).then(function (responseBody) {
console.log('json', responseBody);
}, function (error) {
console.log('uh oh', error);
});
httpism.post('http://example.com/', { name: "Betty Boop" }, { form: true }).then(function (responseBody) {
console.log('json', responseBody);
}, function (error) {
console.log('uh oh', error);
});
Pass a stream as the second argument, it will try to guess the Content-Type
from the filename if possible, but you can override it if you know better.
var stream = fs.createReadStream('afile.txt');
httpism.post('http://example.com/', stream).then(function (responseBody) {
console.log('json', responseBody);
}, function (error) {
console.log('uh oh', error);
});
Httpism works with form-data, all you need to do is pass a FormData
instance as the body:
var form = new FormData();
form.append('name', 'Betty Boop');
form.append('address', 'New York');
form.append('photo', fs.createReadStream('betty.jpg'));
httpism.post('http://example.com/', form).then(function (responseBody) {
console.log('json', responseBody);
}, function (error) {
console.log('uh oh', error);
});
Specify a base URL:
var example = httpism.client('http://example.com/');
// GET http://example.com/a
example.get('a').then(function (responseBody) {
console.log(responseBody);
});
Specify some options:
var loggingHttpism = httpism.client({exceptions: false});
loggingHttpism.get('http://example.com/').then(function (responseBody) {
console.log(responseBody);
});
Add some middleware:
var authHttpism = httpism.client(function (request, next) {
request.url += '?apikey=myapikey';
return next();
});
// GET https://secretapi.com/?apikey=myapikey
authHttpism.get('https://secretapi.com/').then(function (responseBody) {
console.log(responseBody);
});
See more about clients.
The browser version has a few differences from the node version:
However, everything else works as described here.
httpism uses debug so you can enable logging just by setting the DEBUG
environment variable to httpism:*
:
DEBUG=httpism* node app.js
httpism
simple request => response, i.e. GET http://www.example.com/api => 200 (40ms)
httpism:error
only errors, shown in simple request => response, i.e. GET http://www.example.com/api => 500 (40ms)
httpism:request
the full request including bodyhttpism:response
the full response including bodyhttpism:response:error
only errors, the full response including bodyMore information in debug's README.
Httpism obeys the following environments variables:
http_proxy
HTTP_PROXY
- for HTTP requestshttps_proxy
HTTPS_PROXY
- for HTTPS requestsall_proxy
ALL_PROXY
- for HTTP or HTTPS requestsno_proxy
NO_PROXY
- an comma separated list of hostnames (and optional ports) to not proxyFor more details please see proxy-from-env.
httpism.method(url, [options])
url
a string URL, this is a URL template if the params
option is used, see params.options
request options, see options.returns a promise
httpism.method(url, body, [options])
url
a string URL, this is a URL template if the params
option is used, see params.body
the request body to send
application/json
{form: true}
is url-encoded and sent as application/x-www-form-urlencoded
Content-Type
from a file stream, but if not, pass {headers: {'content-type': ...}}
as options.options
request options, see options.Httpism will render a URL template if the params
option is used, the params are interpolated into the URL template, any params left over will form the query string.
httpism.get('http://example.com/users/:user/posts', {
params: {
user: 'bob',
page: 3,
search: 'lakes'
}
})
Will become
GET http://example.com/users/bob/posts?page=3&search=lakes
A template contains two forms of parameter, varying on the way special characters are encoded for URLs.
:param
- uses encodeURIComponent
, and is useful for most applications:param*
- uses encodeURI
and can be used to interpolate paths, such as a/path/to/something
without encoding the slash characters.Any remaining parameters will be encoded in the query string, you can override how the query string is encoded using the qs
option.
The template interpolation will throw an error if one of the :param
or :param*
parameters are given an undefined
value.
The template interpolation itself can be overridden with the expandUrl
option, and is used as follows:
var url = expandUrl(template, params, querystring)
template
- the URL template, passed in as the url
argument to httpism.get
, etc.params
- the object containing the parameters to be interpolated.querystring
- the qs
option, can be used to encode the query string parameters, e.g. querystring.stringify(params)
.For example, you could use RFC 6570 templates like this
var urlTemplate = require('url-template')
function expandUrl(url, params) {
var template = urlTemplate.parse(url)
return template.expand(params)
}
httpism.get('http://example.com/users/{user}/posts{?page,search}', {
params: {
user: 'bob',
page: 3,
search: 'lakes'
},
expandUrl: expandUrl
})
Or indeed create a new client to use this by default:
var httpism = require('httpsim').client({
expandUrl: expandUrl
})
httpism.get('http://example.com/users/{user}/posts{?page,search}')
httpism.request(method, url, [body], [options])
url
a string url, full or relative to the response, or '' to request the response againbody
the request body to send
application/json
{form: true}
is url-encoded and sent as application/x-www-form-urlencoded
Content-Type
from a file stream, but if not, pass {headers: {'content-type': ...}}
as options.options
request options, see options.Responses bodies are returned by all methods by default. To access other details about responses, pass { response: true }
in the request options to receive a response object that contains:
statusCode
the status code as an integer, such as 200
, or 404
.statusText
the status text, such as OK
or Not Found
.url
the full URL of the response. In the browser, this will be root-relative if the request is for the same domain as the current page. This can be different to the request.url
if there was a redirect.headers
the headers of the responsebody
the body of the response. Depending on the Content-Type
header:
application/json
a objectapplication/x-www-form-urlencoded
a objecttext/*
or application/javascript
a stringCookies on the server are not handled by default, but you can enable them by using httpism.client
passing the {cookies: true}
option:
var client = httpism.client({cookies: true});
var creds = {
username: 'jerome',
password: 'password123'
}
client.post('http://example.com/login', creds, {form: true}).then(function () {
return client.get('/profile').then(function (profile) {
console.log(profile)
})
})
Different httpism clients will use different cookie jars. Cookies are always on in the browser, using native browser cookies.
Requests can be cancelled by calling .abort()
on the promise returned from any request method:
var promise = httpism.get('/something');
promise.abort();
response
: default false
, if true, returns the whole response, including URL, headers, status code and the body, otherwise return just the body.exceptions
: default true
, throw exceptions on reception of 400-500 status codes. Set to false
to simply return the response. If set to a function, the function is passed the response, and returns true to throw the response as an exception, or false to treat it as a normal response.redirect
: default true
, follow redirects for 300, 301, 302, 303 and 307 status codes with Location
response headers. Set to false
to simply return the redirect response.headers
: default undefined
, can be set to an object that is merged with middleware headers.basicAuth
: use Basic Authentication, pass an object { username: 'bob', password: "bob's secret" }
.cookies
: default false
, use cookies.querystring
: default undefined
, can be set to an object containing fields that are URL-encoded and merged with the querystring already on the URL, if any. This is parsed and stringified using options.qs.parse
and options.qs.stringify
if provided, or using a very lite internal query string parser.qs
: optional override for parsing and stringifying querystrings, you can pass node's querystring
or qs
. Any object that contains the methods parse
and stringify
can be used. If not provided, httpism will use an internal (and very small) query string parser/stringifier.form
: when true
, treats the incoming JSON data as a form and encodes it as application/x-www-form-urlencoded
.responseBody
: can be used to force the parsing of the response, ignoring the Content-Type
, it can be a string of one of the following:
'stream'
: always downloads the response as a stream'json'
: always parses the response as a JSON object'text'
: always parses the response as text'form'
: always parses the response as a URL-encoded formundefined
: parse response based on Content-Type
, the default.proxy
: a proxy URL, if present all requests will be run through the proxy. This works if either of the environment variables http_proxy
or HTTP_PROXY
are set too.http
: default undefined
, object containing options that are passed to Node.js http.request().
Many of these options are ignored by default, so you should set agent: undefined
to force a new agent to honour the options.https
: default undefined
, object containing options that are passed to Node.js https.request().
Many of these options are ignored by default, so you should set agent: undefined
to force a new agent to honour the options.jsonp
: to perform a JSONP request, set this to the name of the parameter to contain the callback function, often this is simply callback
.xhr
: can be used to override window.XMLHttpRequest
used to make the request, useful for mocking out requests during testing. It is expected to be used as a constructor, as in new options.xhr()
.jsonReviver
: a reviver function that is passed to JSON.parse(string, [reviver])
to override how JSON response bodies are decoded.timeout
: the request timeout in milliseconds.output
: should be a stream, the response body will be written to the stream and httpism will wait until it's fully written.Clients give you a way to build or customise a HTTP client for the purpose of accessing a particular web API. Web APIs will often have special authorization, headers, or URL conventions that are common across all calls, and you only want to have to specify those things once.
You can create API clients, either from httpism
, giving you a fairly complete HTTP client, or from httpism.raw
giving you no frills streaming HTTP client to do what you will with.
var client = httpism.client([url], [options], [middleware]);
var client = httpism.raw.client([url], [options], [middleware]);
var anotherClient = client.client([url], [options], [middleware]);
url
a URL string, which could be relative to the response, or absolute.
options
options object to be used for all calls with this client. If client
is called on a response, the options are merged with that responses client.
middleware
a middleware function or array of middleware functions. Requests in middleware are processed from the beginning of the array to the end, and responses from the end of the array to the beginning. See middleware. Middleware specified on the new client is prepended to the middleware currently in the client.
httpism
is the basic client, with all the goodies described above.
httpism.raw
is a raw client that has only the base transport, http
or https
on node, and xhr
in the browser.
Middleware commonly works like this:
function middleware(request, next, client) {
// change request
request.url = ...;
return next().then(function (response) {
// change response
response.body = ...;
return response;
});
}
Middleware are ordered, and each one can have a name, and a preference to be placed before or after other named middleware. You can place the middleware before
any of the middleware in an array, or after
any of the middleware in an array.
middleware.httpismMiddleware = {
name: 'name',
before: ['http', 'debugLog'],
after: 'redirect'
}
You can insert the middleware by passing it to httpism.client()
, or by calling client.use()
:
// create a new client with middleware
var client = httpism.client(middleware);
// add middleware to an existing client
client.use(middleware);
// add middleware globally and to all new clients
httpism.use(middleware);
request
is an object with the following properties:
url
the full URL of the request, e.g. http://example.com/path?query=value
method
the method of the request, e.g. GET
or POST
headers
the headers of the request as an object. All headers are lower-cased as per Node.js conventions. E.g. { 'content-type': 'application/json' }
options
the options as passed through from the request, either from the client or the individual request. E.g. {exceptions: true}
.body
the body of the request. Will be undefined
for get()
etc, otherwise will be the object specified as the second argument to methods like post()
.next([request])
is a function that passes control onto the next middleware, optionally taking a request parameter. If the request parameter is not given it uses the request passed in to the middleware. It returns a promise of the response.client
is a httpism client object, for which you can make further requests inside the middleware with client.request(request)
. For example, the redirect middleware uses this.middleware.middleware
is the name of the middleware, which can be referred to by other middlewares when adding themselves with before
or after
.middleware.before
ensure that the middleware is inserted just before the named middleware.middleware.after
ensure that the middleware is inserted just after the named middleware.Middleware is stored in an array client.middleware
, you're free to manipulate this directly.
See the middleware directory for a full list of existing middleware.
BSD
Join our remote team and help us build amazing software. Check out our career opportunities.
FAQs
HTTP client with middleware and good defaults
The npm package httpism receives a total of 312 weekly downloads. As such, httpism popularity was classified as not popular.
We found that httpism demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.