diff --git a/LIMITS.md b/LIMITS.md new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md index 331d17f..ac9e576 100644 --- a/README.md +++ b/README.md @@ -10,18 +10,30 @@ A light-weight module that brings window.fetch to node.js # Motivation -I really like the notion of Matt Andrews' [isomorphic-fetch](https://github.com/matthew-andrews/isomorphic-fetch): it bridges the API gap between client-side and server-side http requests, so developers have less to worry about. +I like the notion of Matt Andrews' [isomorphic-fetch](https://github.com/matthew-andrews/isomorphic-fetch): it bridges the API gap between client-side and server-side http requests, so developers have less to worry about. -But I think the term [isomorphic](http://isomorphic.net/) is generally misleading: it gives developers a false impression that their javascript code will happily run on both controlled server environment as well as uncontrollable user browsers. When the latter is only true for a subset of modern browsers, not to mention browser quirks. +But I believe the term [isomorphic](http://isomorphic.net/) is generally misleading: it gives developers a false sense of security that their javascript code will run happily on both controlled server environment as well as uncontrollable user browsers. When the latter is only true for a small subset of modern browsers, not to mention quirks in native implementation. -Plus if you are going all the way to implement `XMLHttpRequest` in node and then promisify it, why not go from node's `http` to `fetch` API directly? Your browserify build are going to be vastly different from node anyway. +Instead of implementing `XMLHttpRequest` in node to run browser-specific [fetch polyfill](https://github.com/github/fetch), why not go from node's `http` to `fetch` API directly? Node has native stream support, your browserify build targets (browsers) don't, so underneath they are going to be vastly different anyway. + +IMHO, it's safer to be aware of javascript runtime's strength and weakness, than to assume they are a unified platform under a stable spec. + +Hence `node-fetch`. # Features -* Stay consistent with `window.fetch` API whenever possible. -* Make conscious trade-off when following [whatwg fetch spec](https://fetch.spec.whatwg.org/) implementation details, document known difference. -* Use native promise, but allow substituting it with [insert your favorite promise library]. +- Stay consistent with `window.fetch` API. +- Make conscious trade-off when following [whatwg fetch spec](https://fetch.spec.whatwg.org/) and [stream spec](https://streams.spec.whatwg.org/) implementation details, document known difference. +- Use native promise, but allow substituting it with [insert your favorite promise library]. + + +# Limits + +- Work in progress, much like the spec itself. +- See [LIMITS.md](https://github.com/bitinn/node-fetch/blob/master/LIMITS.md) + +(If you spot a undocumented difference, feel free to open an issue. Pull requests are welcomed too!) # Install @@ -34,15 +46,16 @@ Plus if you are going all the way to implement `XMLHttpRequest` in node and then TODO -# Limit - -TODO - - # License MIT + +# Acknowledgement + +Thanks to github/fetch for providing a solid implementation reference. + + [npm-image]: https://img.shields.io/npm/v/node-fetch.svg?style=flat-square [npm-url]: https://www.npmjs.com/package/node-fetch [travis-image]: https://img.shields.io/travis/bitinn/node-fetch.svg?style=flat-square diff --git a/index.js b/index.js index 0e88715..a9d9a75 100644 --- a/index.js +++ b/index.js @@ -10,6 +10,7 @@ var resolve = require('url').resolve; var http = require('http'); var https = require('https'); var zlib = require('zlib'); +var PassThrough = require('stream').PassThrough; module.exports = Fetch; @@ -45,7 +46,7 @@ function Fetch(url, opts) { } var request; - if (uri.protocol !== 'https:') { + if (uri.protocol === 'https:') { request = https.request; } else { request = http.request; @@ -65,20 +66,21 @@ function Fetch(url, opts) { var req = request(options); var output; + req.on('error', function(err) { + // TODO: handle network error + console.log(err.stack); + }); + req.on('response', function(res) { output = { headers: res.headers , status: res.statusCode - , bytes: 0 + , body: res.pipe(new PassThrough()) }; - res.on('data', function(chunk) { - output.bytes += chunk.length; - }); - - res.on('end', function() { - resolve(output); - }); + // TODO: redirect + // TODO: type switch + resolve(output); }); req.end(); diff --git a/test/server.js b/test/server.js new file mode 100644 index 0000000..e69de29 diff --git a/test/test.js b/test/test.js index c5ca25e..24eba7f 100644 --- a/test/test.js +++ b/test/test.js @@ -14,12 +14,23 @@ var fetch = require('../index.js'); // test with native promise on node 0.11, and bluebird for node 0.10 fetch.Promise = fetch.Promise || bluebird; -var url, opts; +var url, opts, local; describe('Fetch', function() { - before(function() { - // TODO: local server for more stable testing + before(function(done) { + // TODO: create a server instance for testing + local = http.createServer(function(req, res) { + res.statusCode = 200; + res.setHeader('Content-Type', 'text/plain'); + res.write('hello world'); + res.end(); + }); + local.listen(30001, done); + }); + + after(function(done) { + local.close(done); }); it('should return a promise', function() { @@ -27,7 +38,7 @@ describe('Fetch', function() { expect(fetch(url)).to.be.an.instanceof(fetch.Promise); }); - it('should return custom promise', function() { + it('should custom promise', function() { url = 'http://example.com/'; var old = fetch.Promise; fetch.Promise = then; @@ -46,9 +57,10 @@ describe('Fetch', function() { }); it('should resolve with result', function() { - url = 'http://example.com/'; + url = 'http://127.0.0.1:30001/'; return fetch(url).then(function(res) { - console.log(res); + expect(res.status).to.equal(200); + expect(res.headers).to.include({ 'content-type': 'text/plain' }); }); }); });