{
  "name": "hyperquest",
  "version": "0.2.0",
  "description": "make streaming http requests",
  "main": "index.js",
  "dependencies": {
    "through": "~2.2.0",
    "duplexer": "~0.1.0"
  },
  "devDependencies": {
    "tap": "~0.4.0"
  },
  "scripts": {
    "test": "tap test/*.js"
  },
  "repository": {
    "type": "git",
    "url": "git://github.com/substack/hyperquest.git"
  },
  "homepage": "https://github.com/substack/hyperquest",
  "keywords": [
    "stream",
    "http",
    "transport",
    "request",
    "get",
    "post",
    "put",
    "delete",
    "duplex",
    "pooling"
  ],
  "author": {
    "name": "James Halliday",
    "email": "mail@substack.net",
    "url": "http://substack.net"
  },
  "license": "MIT",
  "readme": "# hyperquest\n\ntreat http requests as a streaming transport\n\n[![build status](https://secure.travis-ci.org/substack/hyperquest.png)](http://travis-ci.org/substack/hyperquest)\n\nThe hyperquest api is a subset of [request](https://github.com/mikeal/request).\n\nThis module works in the browser with [browserify](http://browserify.org).\n\n# rant\n\n![animated gif rant](http://substack.net/images/substack.gif)\n\nThis module disables a lot of infuriating things about core http that WILL cause\nbugs in your application if you think of http as just another kind of stream:\n\n* http requests have a default idle timeout of 2 minutes. This is terrible if\nyou just want to pipe together a bunch of persistent backend processes over\nhttp.\n\n* There is a default connection pool of 5 requests. If you have 5 or more extant\nhttp requests, any additional requests will HANG for NO GOOD REASON.\n\nhyperquest turns these annoyances off so you can just pretend that core http is\njust a fancier version of tcp and not the horrible monstrosity that it actually\nis.\n\nI have it on good authority that these annoyances will be fixed in node 0.12.\n\n# example\n\n# simple streaming GET\n\n``` js\nvar hyperquest = require('hyperquest');\nhyperquest('http://localhost:8000').pipe(process.stdout);\n```\n\n```\n$ node example/req.js\nbeep boop\n```\n\n# pooling is evil\n\nNow to drive the point home about pooling being evil and almost always never\nwhat you want ever.\n\n[request](https://github.com/mikeal/request)\nhas its own forever agent thing that works pretty much the same as node core\nhttp.request: the wrong, horrible, broken way.\n\nFor instance, the following request code takes 12+ seconds to finish:\n\n``` js\nvar http = require('http');\nvar request = require('request');\n\nvar server = http.createServer(function (req, res) {\n    res.write(req.url.slice(1) + '\\n');\n    setTimeout(res.end.bind(res), 3000);\n});\n\nserver.listen(5000, function () {\n    var pending = 20;\n    for (var i = 0; i < 20; i++) {\n        var r = request('http://localhost:5000/' + i);\n        r.pipe(process.stdout, { end: false });\n        r.on('end', function () {\n            if (--pending === 0) server.close();\n        });\n    }\n});\n\nprocess.stdout.setMaxListeners(0); // turn off annoying warnings\n```\n\n```\nsubstack : example $ time node many_request.js \n0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n\nreal    0m12.423s\nuser    0m0.424s\nsys 0m0.048s\n```\n\nSurprising? YES. This is pretty much never what you want, particularly if you\nhave a lot of streaming http API endpoints. Your code will just *HANG* once the\nconnection pool fills up and it won't start working again until some connections\ndie for whatever reason. I have encountered this so many times in production\ninstances and it is SO hard to track down reliably.\n\nCompare to using hyperquest, which is exactly the same code but it takes 3\nseconds instead of 12 to finish because it's not completely self-crippled like\nrequest and core http.request.\n\n``` js\nvar http = require('http');\nvar hyperquest = require('hyperquest');\n\nvar server = http.createServer(function (req, res) {\n    res.write(req.url.slice(1) + '\\n');\n    setTimeout(res.end.bind(res), 3000);\n});\n\nserver.listen(5000, function () {\n    var pending = 20;\n    for (var i = 0; i < 20; i++) {\n        var r = hyperquest('http://localhost:5000/' + i);\n        r.pipe(process.stdout, { end: false });\n        r.on('end', function () {\n            if (--pending === 0) server.close();\n        });\n    }\n});\n\nprocess.stdout.setMaxListeners(0); // turn off annoying warnings\n```\n```\n$ time node many_hyperquest.js \n0\n1\n2\n3\n4\n5\n6\n8\n9\n7\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n\nreal    0m3.284s\nuser    0m0.288s\nsys 0m0.060s\n```\n\nSo the other thing is, the justification I've heard supporting this horrible\nlimit-of-5 pooling behavior is \"performance\". The first example which has been\ntuned for \"performance\" takes 12 seconds. The second example that removes these\n\"performance\" enhancements takes 3. Some performance improvement INDEED!\n\n# methods\n\n``` js\nvar hyperquest = require('hyperquest');\n```\n\n## var req = hyperquest(uri, opts={}, cb)\n\nCreate an outgoing http request to `uri` or `opts.uri`.\nYou need not pass any arguments here since there are setter methods documented\nbelow.\n\nReturn a readable or duplex stream depending on the `opts.method`.\n\nDefault option values:\n\n* opts.method - `\"GET\"`\n* opts.headers - `{}`\n* opts.auth - undefined, but is set automatically when the `uri` has an auth\nstring in it such as `\"http://user:passwd@host\"`. `opts.auth` is of the form\n`\"user:pass\"`, just like `http.request()`.\n\nIn https mode, you can specify options to the underlying `tls.connect()` call:\n\n* opts.pfx\n* opts.key\n* opts.cert\n* opts.ca\n* opts.ciphers\n* opts.rejectUnauthorized\n* opts.secureProtocol\n\nThe request does not go through until the `nextTick` so you can set values\noutside of the `opts` so long as they are called on the same tick.\n\nOptionally you can pass a `cb(err, res)` to set up listeners for `'error'` and\n`'response'` events in one place.\n\nNote that the optional `cb` is NOT like\n[request](https://github.com/mikeal/request)\nin that hyperquest will not buffer content for you or decode to json or any such\nmagical thing.\n\n## req.setHeader(key, value);\n\nSet an outgoing header `key` to `value`.\n\n## req.setLocation(uri);\n\nSet the location if you didn't specify it in the `hyperquest()` call.\n\n## var req = hyperquest.get(uri, opts, cb)\n\nReturn a readable stream from `hyperquest(..., { method: 'GET' })`.\n\n## var req = hyperquest.put(uri, opts, cb)\n\nReturn a duplex stream from `hyperquest(..., { method: 'PUT' })`.\n\n## var req = hyperquest.post(uri, opts, cb)\n\nReturn a duplex stream from `hyperquest(..., { method: 'POST' })`.\n\n## var req = hyperquest.delete(uri, opts, cb)\n\nReturn a readable stream from `hyperquest(..., { method: 'DELETE' })`.\n\n# events\n\n## req.on('response', function (res) {})\n\nThe `'response'` event is forwarded from the underlying `http.request()`.\n\n## req.on('error', function (res) {})\n\nThe `'error'` event is forwarded from the underlying `http.request()`.\n\n# install\n\nWith [npm](https://npmjs.org) do:\n\n```\nnpm install hyperquest\n```\n\n# license\n\nMIT\n",
  "readmeFilename": "readme.markdown",
  "bugs": {
    "url": "https://github.com/substack/hyperquest/issues"
  },
  "_id": "hyperquest@0.2.0",
  "dist": {
    "shasum": "4d3e59af6604e8ccab73f76896d5844495fa85aa"
  },
  "_from": "hyperquest@",
  "_resolved": "https://registry.npmjs.org/hyperquest/-/hyperquest-0.2.0.tgz"
}
