Compare commits

...

54 Commits

Author SHA1 Message Date
John Hiesey 92500c71be 2.4.0 2016-09-08 16:38:51 -07:00
John Hiesey 05c6f4394c Merge pull request #52 from jhiesey/bump-test-node-ver
Bump travis node version
2016-09-08 15:57:23 -07:00
John Hiesey 9ed7614aed Bump travis node version
Trying to debug tests that fail only on travis
2016-09-08 15:48:33 -07:00
John Hiesey bad84ecb3a Merge pull request #51 from alexjeffburke/allow-disabling-fetch
Allow using a mode to disable the use of fetch
2016-09-08 14:37:38 -07:00
John Hiesey 70b928bbb9 Fix arraybuffer for phantomjs
This should be an equivalent fix to #42
2016-09-08 14:35:22 -07:00
Alex J Burke 53bf1d38e2 Allow using a mode to disable the use of fetch and add a test for the case. 2016-09-01 07:48:38 +01:00
John Hiesey ac250a9b04 Bump minimum iphone version 2016-07-27 21:34:08 -07:00
John Hiesey 83f7b7ef32 Bump zuul version 2016-07-27 21:33:37 -07:00
John Hiesey f3df5d7ace Bump iphone and android minimum tested versions
Sauce Labs no longer supports ios 6. Also correct
the floating point version format.
2016-07-27 18:33:37 -07:00
John Hiesey 345149d708 2.3.1 2016-07-27 18:15:02 -07:00
John Hiesey 9c18855feb Check for ReadableStream instead of ReadableByteStream
ReadableByteStream was removed from the spec and from
Chrome 51. Fixes #46
2016-07-27 14:24:51 -07:00
John Hiesey ff601a9eff 2.3.0 2016-04-28 00:58:52 -07:00
John Hiesey e046049394 Merge pull request #41 from jhiesey/readable-stream
use readable-stream
2016-04-28 00:58:19 -07:00
Feross Aboukhadijeh 333b0437a9 sauce labs: fix edge version 2016-04-28 01:13:17 +02:00
Feross Aboukhadijeh 0552e1e4f5 use readable-stream
For a consistent version of the stream package.

Also, I believe this will help fix
https://github.com/feross/webtorrent/issues/771
2016-04-28 00:55:58 +02:00
John Hiesey 1fbfc4264a Merge pull request #40 from jhiesey/response-url
Expose response url
2016-04-20 13:10:11 -07:00
John Hiesey a0c6d49ba4 Expose response url
Fixes #39
2016-04-20 12:53:54 -07:00
John Hiesey 1d3fca03fa Remove dead line 2016-04-20 01:24:31 -07:00
John Hiesey 5e25ed2f65 2.2.1 2016-03-25 18:53:56 -07:00
John Hiesey b339f4afa9 Fix microsoft edge versions for newer zuul 2016-03-24 03:09:09 -07:00
John Hiesey 4b1419cff7 2.2.0 2016-03-01 15:25:22 -08:00
John Hiesey c9183cd2ad Style fixup 2016-03-01 15:05:17 -08:00
John Hiesey 0f1f0c6365 Merge pull request #37 from sportle/feature/set-cookie-array
Set-Cookie headers should be arrays
2016-03-01 15:04:03 -08:00
Phil Larson 581a4d12da Set-Cookie headers should be arrays 2016-03-01 10:15:19 -08:00
Feross Aboukhadijeh 945083bd1d 2.1.1 2016-02-15 21:32:47 -08:00
Feross Aboukhadijeh 2054c18374 sauce labs: add microsoft edge 2016-02-15 20:54:38 -08:00
Feross Aboukhadijeh 218fd54ef0 builtin-status-codes@2 2016-02-15 20:51:06 -08:00
John Hiesey 9d24d5510a 2.1.0 2016-01-13 05:46:14 +01:00
John Hiesey ff68130d89 Add missing "bugs" and "homepage" entries to package.json 2016-01-13 05:10:57 +01:00
John Hiesey 6bab67d17a Use to-arraybuffer instead of manual conversion
This fixes some more edge cases when converting from a Buffer to
an ArrayBuffer.

Additionally, compared v2.0.5, this avoids an unnecessary copy
when sending data in a request body.
2016-01-13 03:40:41 +01:00
John Hiesey 6433ea8cad Replace buffer.buffer with more compatible version
Unforunately some browsers use a version of Buffer
that isn't based on a Uint8Array. Add logic to convert
when necessary but not make copies when unnecessary.
2016-01-13 01:33:11 +01:00
John Hiesey 9ebf801ebb Fix typos 2016-01-12 22:39:46 +01:00
John Hiesey 154f6b9e56 Fix buffer usage in tests as well 2016-01-12 22:18:41 +01:00
John Hiesey 6dea87e704 Merge pull request #36 from karissa/master
Use .buffer to comply with buffer@4 and browserify@13.
2016-01-12 21:56:37 +01:00
Karissa McKelvey 8b9f5a43c1 Use .buffer to comply with buffer@4 and browserify@13 2016-01-12 12:30:39 -08:00
John Hiesey 3c8b44379c 2.0.5 2016-01-09 03:56:05 +01:00
John Hiesey c36da3bade Use 'http:' as a default protocol
If global.location.protocol isn't 'http:' or 'https:', use
'http:'. This makes behavior reasonable when the page is
opened directly without using a server.
2016-01-09 03:55:14 +01:00
John Hiesey cbc0bd803c 2.0.4 2016-01-09 00:22:46 +01:00
John Hiesey d6de2ce3a5 Add docs on running tests 2016-01-09 00:20:56 +01:00
John Hiesey 4bcff63d46 Don't run browser tests in travis for PRs
These tests fail anyway, since the sauce labs credentials
aren't available. In all other cases running the browser
tests is desirable.
2016-01-09 00:20:26 +01:00
John Hiesey a69310d8fc Run travis tests using node 4.1
This is the latest version currently supported according
to the travis docs. The version used here shouldn't actually
affect the results of the tests, but we might as well use
something more recent.
2016-01-08 23:27:14 +01:00
John Hiesey ae48c2c71c 2.0.3 2016-01-08 22:31:45 +01:00
John Hiesey 570f85ec18 Check xhr.status is non-zero to avoid running onXHRProgress on error
Previously, onXHRProgress was being run when readyState was being
set to DONE on error, which was causing exceptions.
2015-10-13 15:46:01 -07:00
John Hiesey 85381f0e3d 2.0.2 2015-10-01 23:01:00 -07:00
John Hiesey 3bea2a493f Don't turn exceptions thrown in the callback into 'error' events
When using the fetch api, exceptions thrown inside
ClientRequest._onFinish, which also calls the user callback,
were being caught and turned into 'error' events. This is
not the correct behavior; these exceptions should remain
uncaught to let the browser print them to the console.
2015-10-01 22:26:59 -07:00
John Hiesey 016f4be96f 2.0.1 2015-09-30 13:23:16 -07:00
John Hiesey 9e5e75b5ff Merge pull request #27 from mbcrute/patch-body
Don't ignore PATCH request bodies
2015-09-30 13:10:09 -07:00
Matt Crute 031b8aab89 Stop ignoring PATCH request bodies 2015-09-30 11:01:26 -07:00
John Hiesey dc421eb355 2.0.0 2015-09-15 17:24:23 -07:00
John Hiesey 7d1dfd2ab1 Merge pull request #25 from jhiesey/polyfills
Require polyfills for IE8 support to reduce bundle size
2015-09-15 17:23:40 -07:00
John Hiesey 75817ba930 Fix tests 2015-09-15 16:54:17 -07:00
John Hiesey 2152af414a Remove implementations of ES5 functions not provided in ie8
From now on, IE8 is only supported if polyfills for `Object.keys`,
`Array.prototype.forEach`, and `Array.prototype.indexOf` are
provided. The suggested polyfills from MDN are provided in
ie8-polyfill.js, or you can use https://github.com/es-shims/es5-shim
for a more complete set of polyfills.
2015-09-15 16:54:17 -07:00
John Hiesey a10d19b3b2 Fix occasional test errors on Chrome 45
If multiple chunks of data got queued up, the abort on data test
would erroneously fail. Wait till the end of the tick before
considering 'data' events as errors.
2015-09-15 16:52:11 -07:00
John Hiesey a169930a20 1.7.1 2015-09-15 14:47:03 -07:00
17 changed files with 352 additions and 57 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
language: node_js
node_js:
- "0.12"
- "6.4"
+6 -3
View File
@@ -6,14 +6,17 @@ browsers:
version: 34..latest
- name: safari
version: 5..latest
- name: microsoftedge
version: 13..latest
- name: ie
version: 9..latest
- name: opera
version: 11..latest
- name: iphone
version: 5.1..latest
version: '8.1..latest'
- name: android
version: 4.0..latest
version: '4.0..latest'
server: ./test/server/index.js
scripts:
- "/polyfill.js"
- "/ie8-polyfill.js"
- "/test-polyfill.js"
+31 -1
View File
@@ -29,6 +29,13 @@ All browsers newer than IE8 support binary responses. All of the above browsers
support true streaming or pseudo-streaming support that for binary data as well
except for IE10. Old (presto-based) Opera also does not support binary streaming either.
### IE8 note:
As of version 2.0.0, IE8 support requires the user to supply polyfills for
`Object.keys`, `Array.prototype.forEach`, and `Array.prototype.indexOf`. Example
implementations are provided in [ie8-polyfill.js](ie8-polyfill.js); alternately,
you may want to consider using [es5-shim](https://github.com/es-shims/es5-shim).
All browsers with full ES5 support shouldn't require any polyfills.
## How do you use it?
The intent is to have the same api as the client part of the
@@ -41,6 +48,10 @@ node docs for how these work.
### Extra features compared to node
* The `message.url` property provides access to the final url after all redirects. This
is useful since the browser follows all redirects silently, unlike node. It is available
in Chrome 37 and newer, Firefox 32 and newer, and Safari 9 and newer.
* The `options.withCredentials` boolean flag, used to indicate if the browser should send
cookies or authentication information with a CORS request. Default false.
@@ -64,6 +75,8 @@ also be a bit slow. This was the default in versions of this module before 1.5.
that isn't a single-byte ASCII or utf8 character) will be corrupted. Of course, this option
is only safe for text data. May also cause the 'content-type' response header to be
incorrectly reported (as 'text/plain; charset=x-user-defined').
* 'disable-fetch': Force the use of plain XHR regardless of the browser declaring a fetch
capability. Preserves the correctness of binary data and the 'content-type' response header.
* 'prefer-fast': Deprecated; now a synonym for 'default', which has the same performance
characteristics as this mode did in versions before 1.5.
@@ -74,11 +87,13 @@ characteristics as this mode did in versions before 1.5.
* Any operations, including `request.setTimeout`, that operate directly on the underlying
socket.
* Any options that are disallowed for security reasons. This includes setting or getting
certian headers.
certain headers.
* `message.httpVersion`
* `message.rawHeaders` is modified by the browser, and may not quite match what is sent by
the server.
* `message.trailers` and `message.rawTrailers` will remain empty.
* Redirects are followed silently by the browser, so it isn't possible to access the 301/302
redirect pages.
## Example
@@ -97,6 +112,21 @@ http.get('/bundle.js', function (res) {
})
```
## Running tests
There are two sets of tests: the tests that run in node (found in `test/node`) and the tests
that run in the browser (found in `test/browser`). Normally the browser tests run on
[Sauce Labs](http://saucelabs.com/).
Running `npm test` will run both sets of tests, but in order for the Sauce Labs tests to run
you will need to sign up for an account (free for open source projects) and put the
credentials in a [`.zuulrc` file](https://github.com/defunctzombie/zuul/wiki/zuulrc).
To run just the node tests, run `npm run test-node`.
To run the browser tests locally, run `npm run test-browser-local` and point your browser to
`http://localhost:8080/__zuul`
## License
MIT. Copyright (C) John Hiesey and other contributors.
+168
View File
@@ -0,0 +1,168 @@
// These polyfills taken from MDN (developer.mozilla.org)
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
if (!Object.keys) {
Object.keys = (function() {
'use strict';
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
],
dontEnumsLength = dontEnums.length;
return function(obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
var result = [], prop, i;
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
}());
}
// Production steps of ECMA-262, Edition 5, 15.4.4.18
// Reference: http://es5.github.io/#x15.4.4.18
if (!Array.prototype.forEach) {
Array.prototype.forEach = function(callback, thisArg) {
var T, k;
if (this == null) {
throw new TypeError(' this is null or not defined');
}
// 1. Let O be the result of calling ToObject passing the |this| value as the argument.
var O = Object(this);
// 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
// 3. Let len be ToUint32(lenValue).
var len = O.length >>> 0;
// 4. If IsCallable(callback) is false, throw a TypeError exception.
// See: http://es5.github.com/#x9.11
if (typeof callback !== "function") {
throw new TypeError(callback + ' is not a function');
}
// 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
if (arguments.length > 1) {
T = thisArg;
}
// 6. Let k be 0
k = 0;
// 7. Repeat, while k < len
while (k < len) {
var kValue;
// a. Let Pk be ToString(k).
// This is implicit for LHS operands of the in operator
// b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
// This step can be combined with c
// c. If kPresent is true, then
if (k in O) {
// i. Let kValue be the result of calling the Get internal method of O with argument Pk.
kValue = O[k];
// ii. Call the Call internal method of callback with T as the this value and
// argument list containing kValue, k, and O.
callback.call(T, kValue, k, O);
}
// d. Increase k by 1.
k++;
}
// 8. return undefined
};
}
// Production steps of ECMA-262, Edition 5, 15.4.4.14
// Reference: http://es5.github.io/#x15.4.4.14
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function(searchElement, fromIndex) {
var k;
// 1. Let O be the result of calling ToObject passing
// the this value as the argument.
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var O = Object(this);
// 2. Let lenValue be the result of calling the Get
// internal method of O with the argument "length".
// 3. Let len be ToUint32(lenValue).
var len = O.length >>> 0;
// 4. If len is 0, return -1.
if (len === 0) {
return -1;
}
// 5. If argument fromIndex was passed let n be
// ToInteger(fromIndex); else let n be 0.
var n = +fromIndex || 0;
if (Math.abs(n) === Infinity) {
n = 0;
}
// 6. If n >= len, return -1.
if (n >= len) {
return -1;
}
// 7. If n >= 0, then Let k be n.
// 8. Else, n<0, Let k be len - abs(n).
// If k is less than 0, then let k be 0.
k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
// 9. Repeat, while k < len
while (k < len) {
// a. Let Pk be ToString(k).
// This is implicit for LHS operands of the in operator
// b. Let kPresent be the result of calling the
// HasProperty internal method of O with argument Pk.
// This step can be combined with c
// c. If kPresent is true, then
// i. Let elementK be the result of calling the Get
// internal method of O with the argument ToString(k).
// ii. Let same be the result of applying the
// Strict Equality Comparison Algorithm to
// searchElement and elementK.
// iii. If same is true, return k.
if (k in O && O[k] === searchElement) {
return k;
}
k++;
}
return -1;
};
}
+6 -1
View File
@@ -11,7 +11,12 @@ http.request = function (opts, cb) {
else
opts = extend(opts)
var protocol = opts.protocol || ''
// Normally, the page is loaded from http or https, so not specifying a protocol
// will result in a (valid) protocol-relative url. However, this won't work if
// the protocol is something else, like 'file:'
var defaultProtocol = global.location.protocol.search(/^https?:$/) === -1 ? 'http:' : ''
var protocol = opts.protocol || defaultProtocol
var host = opts.hostname || opts.host
var port = opts.port
var path = opts.path || '/'
+1 -1
View File
@@ -1,4 +1,4 @@
exports.fetch = isFunction(global.fetch) && isFunction(global.ReadableByteStream)
exports.fetch = isFunction(global.fetch) && isFunction(global.ReadableStream)
exports.blobConstructor = false
try {
+23 -19
View File
@@ -1,17 +1,14 @@
// var Base64 = require('Base64')
var capability = require('./capability')
var foreach = require('foreach')
var indexOf = require('indexof')
var inherits = require('inherits')
var keys = require('object-keys')
var response = require('./response')
var stream = require('stream')
var stream = require('readable-stream')
var toArrayBuffer = require('to-arraybuffer')
var IncomingMessage = response.IncomingMessage
var rStates = response.readyStates
function decideMode (preferBinary) {
if (capability.fetch) {
function decideMode (preferBinary, useFetch) {
if (capability.fetch && useFetch) {
return 'fetch'
} else if (capability.mozchunkedarraybuffer) {
return 'moz-chunked-arraybuffer'
@@ -35,12 +32,17 @@ var ClientRequest = module.exports = function (opts) {
self._headers = {}
if (opts.auth)
self.setHeader('Authorization', 'Basic ' + new Buffer(opts.auth).toString('base64'))
foreach(keys(opts.headers), function (name) {
Object.keys(opts.headers).forEach(function (name) {
self.setHeader(name, opts.headers[name])
})
var preferBinary
if (opts.mode === 'prefer-streaming') {
var useFetch = true
if (opts.mode === 'disable-fetch') {
// If the use of XHR should be preferred and includes preserving the 'content-type' header
useFetch = false
preferBinary = true
} else if (opts.mode === 'prefer-streaming') {
// If streaming is a high priority but binary compatibility and
// the accuracy of the 'content-type' header aren't
preferBinary = false
@@ -53,7 +55,7 @@ var ClientRequest = module.exports = function (opts) {
} else {
throw new Error('Invalid value for opts.mode')
}
self._mode = decideMode(preferBinary)
self._mode = decideMode(preferBinary, useFetch)
self.on('finish', function () {
self._onFinish()
@@ -68,7 +70,7 @@ ClientRequest.prototype.setHeader = function (name, value) {
// This check is not necessary, but it prevents warnings from browsers about setting unsafe
// headers. To be honest I'm not entirely sure hiding these warnings is a good thing, but
// http-browserify did it, so I will too.
if (indexOf(unsafeHeaders, lowerName) !== -1)
if (unsafeHeaders.indexOf(lowerName) !== -1)
return
self._headers[lowerName] = {
@@ -96,10 +98,10 @@ ClientRequest.prototype._onFinish = function () {
var headersObj = self._headers
var body
if (opts.method === 'POST' || opts.method === 'PUT') {
if (opts.method === 'POST' || opts.method === 'PUT' || opts.method === 'PATCH') {
if (capability.blobConstructor) {
body = new global.Blob(self._body.map(function (buffer) {
return buffer.toArrayBuffer()
return toArrayBuffer(buffer)
}), {
type: (headersObj['content-type'] || {}).value || ''
})
@@ -110,7 +112,7 @@ ClientRequest.prototype._onFinish = function () {
}
if (self._mode === 'fetch') {
var headers = keys(headersObj).map(function (name) {
var headers = Object.keys(headersObj).map(function (name) {
return [headersObj[name].name, headersObj[name].value]
})
@@ -123,7 +125,7 @@ ClientRequest.prototype._onFinish = function () {
}).then(function (response) {
self._fetchResponse = response
self._connect()
}).then(undefined, function (reason) {
}, function (reason) {
self.emit('error', reason)
})
} else {
@@ -147,7 +149,7 @@ ClientRequest.prototype._onFinish = function () {
if (self._mode === 'text' && 'overrideMimeType' in xhr)
xhr.overrideMimeType('text/plain; charset=x-user-defined')
foreach(keys(headersObj), function (name) {
Object.keys(headersObj).forEach(function (name) {
xhr.setRequestHeader(headersObj[name].name, headersObj[name].value)
})
@@ -186,12 +188,14 @@ ClientRequest.prototype._onFinish = function () {
}
/**
* Checks if xhr.status is readable. Even though the spec says it should
* be available in readyState 3, accessing it throws an exception in IE8
* Checks if xhr.status is readable and non-zero, indicating no error.
* Even though the spec says it should be available in readyState 3,
* accessing it throws an exception in IE8
*/
function statusValid (xhr) {
try {
return (xhr.status !== null)
var status = xhr.status
return (status !== null && status !== 0)
} catch (e) {
return false
}
+13 -6
View File
@@ -1,7 +1,6 @@
var capability = require('./capability')
var foreach = require('foreach')
var inherits = require('inherits')
var stream = require('stream')
var stream = require('readable-stream')
var rStates = exports.readyStates = {
UNSENT: 0,
@@ -32,6 +31,7 @@ var IncomingMessage = exports.IncomingMessage = function (xhr, response, mode) {
if (mode === 'fetch') {
self._fetchResponse = response
self.url = response.url
self.statusCode = response.status
self.statusMessage = response.statusText
// backwards compatible version of for (<item> of <iterable>):
@@ -61,17 +61,24 @@ var IncomingMessage = exports.IncomingMessage = function (xhr, response, mode) {
self._xhr = xhr
self._pos = 0
self.url = xhr.responseURL
self.statusCode = xhr.status
self.statusMessage = xhr.statusText
var headers = xhr.getAllResponseHeaders().split(/\r?\n/)
foreach(headers, function (header) {
headers.forEach(function (header) {
var matches = header.match(/^([^:]+):\s*(.*)/)
if (matches) {
var key = matches[1].toLowerCase()
if (self.headers[key] !== undefined)
if (key === 'set-cookie') {
if (self.headers[key] === undefined) {
self.headers[key] = []
}
self.headers[key].push(matches[2])
} else if (self.headers[key] !== undefined) {
self.headers[key] += ', ' + matches[2]
else
} else {
self.headers[key] = matches[2]
}
self.rawHeaders.push(matches[1], matches[2])
}
})
@@ -136,7 +143,7 @@ IncomingMessage.prototype._onXHRProgress = function () {
}
break
case 'arraybuffer':
if (xhr.readyState !== rStates.DONE)
if (xhr.readyState !== rStates.DONE || !xhr.response)
break
response = xhr.response
self.push(new Buffer(new Uint8Array(response)))
+10 -7
View File
@@ -1,6 +1,6 @@
{
"name": "stream-http",
"version": "1.7.0",
"version": "2.4.0",
"description": "Streaming http in the browser",
"main": "index.js",
"repository": {
@@ -8,13 +8,17 @@
"url": "git://github.com/jhiesey/stream-http.git"
},
"scripts": {
"test": "npm run test-node && npm run test-browser",
"test": "npm run test-node && ([ -n \"${TRAVIS_PULL_REQUEST}\" -a \"${TRAVIS_PULL_REQUEST}\" != 'false' ] || npm run test-browser)",
"test-node": "tape test/node/*.js",
"test-browser": "zuul --no-coverage -- test/browser/*.js",
"test-browser-local": "zuul --local 8080 --no-coverage -- test/browser/*.js"
},
"author": "John Hiesey",
"license": "MIT",
"bugs": {
"url": "https://github.com/jhiesey/stream-http/issues"
},
"homepage": "https://github.com/jhiesey/stream-http#readme",
"keywords": [
"http",
"stream",
@@ -23,11 +27,10 @@
"http-browserify"
],
"dependencies": {
"builtin-status-codes": "^1.0.0",
"foreach": "^2.0.5",
"indexof": "0.0.1",
"builtin-status-codes": "^2.0.0",
"inherits": "^2.0.1",
"object-keys": "^1.0.4",
"readable-stream": "^2.1.0",
"to-arraybuffer": "^1.0.0",
"xtend": "^4.0.0"
},
"devDependencies": {
@@ -38,6 +41,6 @@
"tape": "^4.0.0",
"ua-parser-js": "^0.7.7",
"webworkify": "^1.0.2",
"zuul": "^3.1.0"
"zuul": "^3.10.3"
}
}
+10 -3
View File
@@ -30,18 +30,25 @@ test('abort on response', function (t) {
test('abort on data', function (t) {
var req = http.get('/browserify.png?copies=5', function (res) {
var firstData = true
var failOnData = false
res.on('end', function () {
t.fail('unexpected end')
})
res.on('data', function (data) {
if (firstData) {
if (failOnData)
t.fail('unexpected data')
else if (firstData) {
firstData = false
req.abort()
t.end()
} else {
t.fail('unexpected data')
process.nextTick(function () {
// Wait for any data that may have been queued
// in the stream before considering data events
// as errors
failOnData = true
})
}
})
})
+37
View File
@@ -0,0 +1,37 @@
var Buffer = require('buffer').Buffer
var test = require('tape')
var http = require('../..')
test('disable fetch', function (t) {
var originalFetch
if (typeof fetch === 'function') {
originalFetch = fetch
}
var fetchCalled = false
fetch = function (input, options) {
fetchCalled = true
if (originalFetch) {
return originalFetch(input, options)
}
}
http.get({
path: '/browserify.png',
mode: 'disable-fetch'
}, function (res) {
t.ok(!fetchCalled, 'fetch was not called')
if (originalFetch) {
fetch = originalFetch
}
res.on('end', function () {
t.ok(res.headers['content-type'] === 'image/png', 'content-type was set correctly')
t.end()
})
res.on('data', function () {})
})
})
+3 -13
View File
@@ -1,20 +1,10 @@
var Buffer = require('buffer').Buffer
var fs = require('fs')
var keys = require('object-keys')
var test = require('tape')
var UAParser = require('ua-parser-js')
var http = require('../..')
function indexOf (arr, item) {
var len = arr.length
for (var i = 0; i < len; i++) {
if (arr[i] === item)
return i
}
return -1
}
test('headers', function (t) {
http.get({
path: '/testHeaders?Response-Header=bar&Response-Header-2=BAR2',
@@ -29,10 +19,10 @@ test('headers', function (t) {
if (lowerKey.indexOf('test-') === 0)
rawHeaders.push(lowerKey, res.rawHeaders[i + 1])
}
var header1Pos = indexOf(rawHeaders, 'test-response-header')
var header1Pos = rawHeaders.indexOf('test-response-header')
t.ok(header1Pos >= 0, 'raw response header 1 present')
t.equal(rawHeaders[header1Pos + 1], 'bar', 'raw response header value 1')
var header2Pos = indexOf(rawHeaders, 'test-response-header-2')
var header2Pos = rawHeaders.indexOf('test-response-header-2')
t.ok(header2Pos >= 0, 'raw response header 2 present')
t.equal(rawHeaders[header2Pos + 1], 'BAR2', 'raw response header value 2')
t.equal(rawHeaders.length, 4, 'correct number of raw headers')
@@ -46,7 +36,7 @@ test('headers', function (t) {
var body = JSON.parse(Buffer.concat(buffers).toString())
t.equal(body['test-request-header'], 'foo', 'request header 1')
t.equal(body['test-request-header-2'], 'FOO2', 'request header 2')
t.equal(keys(body).length, 2, 'correct number of request headers')
t.equal(Object.keys(body).length, 2, 'correct number of request headers')
t.end()
})
+1 -1
View File
@@ -9,7 +9,7 @@ module.exports = function (self) {
var buffers = []
res.on('end', function () {
self.postMessage(Buffer.concat(buffers).toArrayBuffer())
self.postMessage(Buffer.concat(buffers).buffer)
})
res.on('data', function (data) {
+22
View File
@@ -1,13 +1,35 @@
var Buffer = require('buffer').Buffer
var fs = require('fs')
var test = require('tape')
var UAParser = require('ua-parser-js')
var url = require('url')
var http = require('../..')
var browser = (new UAParser()).setUA(navigator.userAgent).getBrowser()
var browserName = browser.name
var browserVersion = browser.major
// Response urls don't work on many browsers
var skipResponseUrl = ((browserName === 'Opera') ||
(browserName === 'IE') ||
(browserName === 'Edge') ||
(browserName === 'Chrome' && browserVersion <= 36) ||
(browserName === 'Firefox' && browserVersion <= 31) ||
((browserName === 'Safari' || browserName === 'Mobile Safari') && browserVersion <= 8) ||
(browserName === 'WebKit') || // Old mobile safari
(browserName === 'Android Browser' && browserVersion <= 4))
var reference = fs.readFileSync(__dirname + '/../server/static/basic.txt')
test('basic functionality', function (t) {
http.get('/basic.txt', function (res) {
if (!skipResponseUrl) {
var testUrl = url.resolve(global.location.href, '/basic.txt')
// Redirects aren't tested, but presumably only browser bugs
// would cause this to fail only after redirects.
t.equals(res.url, testUrl, 'response url correct')
}
var buffers = []
res.on('end', function () {
+19
View File
@@ -64,6 +64,25 @@ test('Test alt protocol', function(t) {
t.end()
})
test('Test page with \'file:\' protocol', function (t) {
var params = {
hostname: 'localhost',
port: 3000,
path: '/bar'
}
var fileLocation = 'file:///home/me/stuff/index.html'
var normalLocation = global.location
global.location = url.parse(fileLocation) // Temporarily change the location
var request = http.get(params, noop)
global.location = normalLocation // Reset the location
var resolved = url.resolve(fileLocation, request._opts.url)
t.equal(resolved, 'http://localhost:3000/bar', 'Url should be correct')
t.end()
})
test('Test string as parameters', function(t) {
var testUrl = '/api/foo'
var request = http.get(testUrl, noop)
+1
View File
@@ -0,0 +1 @@
../../../ie8-polyfill.js
@@ -1,4 +1,3 @@
// TODO: send a PR to url to remove .trim() so this isn't necessary
if (!String.prototype.trim) {
(function() {
// Make sure we trim BOM and NBSP