Compare commits

...

17 Commits

Author SHA1 Message Date
John Hiesey 168dbac90c 1.5.0 2015-08-20 01:21:15 -07:00
John Hiesey a91ed0db64 Modify feature testing to avoid warnings in Chrome
Previously, testing for 'ms-stream' and 'moz-chunked-arraybuffer'
support on the xhr object caused warnings to appear in Chrome.
Since fetch will always be used instead of these when available,
short-circuit and return false when fetch is available.
2015-08-20 01:06:34 -07:00
John Hiesey da4085e33d Make content-type header correct by default
The default behavior now preserves the 'content-type' header, at
the expense of not providing pseudo-streming in Safari, generic
WebKit, and older Chrome. Applications that require streaming
and already use 'prefer-stream' mode will not be affected.

The 'prefer-fast' mode is now deprecated, as that behavior now
matches the default. The 'allow-wrong-content-type' mode is new;
it gives the same behavior as the old default in case binary
streaming is essential.

Fixes #8
2015-08-20 01:01:40 -07:00
John Hiesey 6d17b406a9 1.4.1 2015-08-07 18:18:02 -07:00
John Hiesey 1a4a89a5e4 Add test for data in request.end() 2015-08-07 18:02:33 -07:00
John Hiesey 838aaffac7 Fix passing data to request.end()
Previously this would result in an exception.
Thanks @magnuslundstedt for finding the bug!
2015-08-07 17:55:43 -07:00
John Hiesey f70ac39bf4 1.4.0 2015-08-06 22:44:10 -07:00
John Hiesey ed525a4a2d Merge pull request #11 from tjmehta/add-http-methods-from-node
Add http methods from node v0.12
2015-08-06 22:33:45 -07:00
Tejesh Mehta b162e21d92 Add http methods from node v0.12 2015-08-06 17:39:17 -07:00
John Hiesey c8c0966c63 1.3.0 2015-07-20 16:10:29 -07:00
John Hiesey efaad2a3c7 Add keywords 2015-07-20 16:07:30 -07:00
John Hiesey 9059849673 Make withCredentials default to false
This may break compatibility with code that was written for
`http-browserify`. Fixes #7
2015-07-20 16:01:24 -07:00
John Hiesey aeabb2cc70 Merge pull request #6 from cesarandreu/consistent-fetch
Fix inconsistency between XMLHttpRequest and fetch
2015-07-20 00:32:46 -07:00
Cesar Andreu 588e5874f3 Add test for cookie behavior 2015-07-19 17:50:30 -07:00
Cesar Andreu 5fc4858d6d Use same-origin instead of omit with fetch credentials
In order to have parity with XMLHttpRequest fetch credentials should use same-origin instead of omit
Setting XMLHttpRequest.withCredentials to false has no effect on same-site request
2015-07-19 17:06:28 -07:00
John Hiesey 22b3cc7acb v1.2.1 2015-07-17 00:50:31 -07:00
John Hiesey 5ffc869490 Fix readme to point to new saucelabs account 2015-07-17 00:35:03 -07:00
11 changed files with 151 additions and 30 deletions
+14 -7
View File
@@ -1,6 +1,6 @@
# stream-http [![Build Status](https://travis-ci.org/jhiesey/stream-http.svg?branch=master)](https://travis-ci.org/jhiesey/stream-http)
[![Sauce Test Status](https://saucelabs.com/browser-matrix/jhiesey.svg)](https://saucelabs.com/u/jhiesey)
[![Sauce Test Status](https://saucelabs.com/browser-matrix/stream-http.svg)](https://saucelabs.com/u/stream-http)
This module is an implementation of node's native `http` module for the browser.
It tries to match node's api and behavior as closely as possible, but some features
@@ -51,14 +51,21 @@ but sometimes it helps to get a little input from the user.
* The `options.mode` field passed into `http.request` or `http.get` can take on one of the
following values:
* 'default' (or any falsy value, including undefined): Try to provide partial data before
the equest completes, but not at the cost of correctness for binary data. In some cases
the implementation may be a bit slow.
the request completes, but not at the cost of correctness for binary data or correctness of
the 'content-type' response header. This mode will also avoid slower code paths whenever
possible, which is particularly useful when making large requests in a browser like Safari
that has a weaker javascript engine.
* 'allow-wrong-content-type': Provides partial data in more cases than 'default', but
at the expense of causing the 'content-type' response header to be incorrectly reported
(as 'text/plain; charset=x-user-defined') in some browsers, notably Safari and Chrome 42
and older. Preserves binary data whenever possible. In some cases the implementation may
also be a bit slow. This was the default in versions of this module before 1.5.
* 'prefer-stream': Provide data before the request completes even if binary data (anything
that isn't a single-byte ASCII or utf8 character) will be corrupted. Of course, this option
is only safe for text data.
* 'prefer-fast': Use an implementation that does less processing even if it means that
partial data isn't available. This is particularly useful when making large requests in
a browser like Safari that has a weaker javascript engine.
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').
* 'prefer-fast': Deprecated; now a synonym for 'default', which has the same performance
characteristics as this mode did in versions before 1.5.
### Features missing compared to node
+24 -5
View File
@@ -25,9 +25,6 @@ http.request = function (opts, cb) {
opts.hostname = opts.hostname || hostHostname || window.location.hostname
opts.port = opts.port || hostPort || defaultPort
if (opts.withCredentials === undefined)
opts.withCredentials = true
// Also valid opts.auth, opts.mode
var req = new ClientRequest(opts)
@@ -48,8 +45,30 @@ http.Agent.defaultMaxSockets = 4
http.STATUS_CODES = statusCodes
http.METHODS = [
'CHECKOUT',
'CONNECT',
'COPY',
'DELETE',
'GET',
'HEAD',
'LOCK',
'M-SEARCH',
'MERGE',
'MKACTIVITY',
'MKCOL',
'MOVE',
'NOTIFY',
'OPTIONS',
'PATCH',
'POST',
'PROPFIND',
'PROPPATCH',
'PURGE',
'PUT',
'DELETE' // TODO: include the methods from RFC 2616 and 2518?
]
'REPORT',
'SEARCH',
'SUBSCRIBE',
'TRACE',
'UNLOCK',
'UNSUBSCRIBE'
]
+8 -3
View File
@@ -17,12 +17,17 @@ function checkTypeSupport (type) {
return false
}
var haveArrayBuffer = isFunction(window.ArrayBuffer)
// For some strange reason, Safari 7.0 reports typeof window.ArrayBuffer === 'object'.
// Safari 7.1 appears to have fixed this bug.
var haveArrayBuffer = typeof window.ArrayBuffer !== 'undefined'
var haveSlice = haveArrayBuffer && isFunction(window.ArrayBuffer.prototype.slice)
exports.arraybuffer = haveArrayBuffer && checkTypeSupport('arraybuffer')
exports.msstream = haveSlice && checkTypeSupport('ms-stream')
exports.mozchunkedarraybuffer = haveArrayBuffer && checkTypeSupport('moz-chunked-arraybuffer')
// These next two tests unavoidably show warnings in Chrome. Since fetch will always
// be used if it's available, just return false for these to avoid the warnings.
exports.msstream = !exports.fetch && haveSlice && checkTypeSupport('ms-stream')
exports.mozchunkedarraybuffer = !exports.fetch && haveArrayBuffer &&
checkTypeSupport('moz-chunked-arraybuffer')
exports.overrideMimeType = isFunction(xhr.overrideMimeType)
exports.vbArray = isFunction(window.VBArray)
+9 -11
View File
@@ -42,14 +42,15 @@ var ClientRequest = module.exports = function (opts) {
var preferBinary
if (opts.mode === 'prefer-streaming') {
// If streaming is a high priority but binary compatibility isn't
// If streaming is a high priority but binary compatibility and
// the accuracy of the 'content-type' header aren't
preferBinary = false
} else if (opts.mode === 'prefer-fast') {
// If binary is preferred for speed
preferBinary = true
} else if (!opts.mode || opts.mode === 'default') {
// By default, use binary if text streaming may corrupt data
} else if (opts.mode === 'allow-wrong-content-type') {
// If streaming is more important than preserving the 'content-type' header
preferBinary = !capability.overrideMimeType
} else if (!opts.mode || opts.mode === 'default' || opts.mode === 'prefer-fast') {
// Use binary if text streaming may corrupt data or the content-type header, or for speed
preferBinary = true
} else {
throw new Error('Invalid value for opts.mode')
}
@@ -119,7 +120,7 @@ ClientRequest.prototype._onFinish = function () {
headers: headers,
body: body,
mode: 'cors',
credentials: opts.withCredentials ? 'include' : 'omit'
credentials: opts.withCredentials ? 'include' : 'same-origin'
}).then(function (response) {
self._fetchResponse = response
self._connect()
@@ -244,10 +245,7 @@ ClientRequest.prototype.end = function (data, encoding, cb) {
data = undefined
}
if (data)
stream.Writable.push.call(self, data, encoding)
stream.Writable.prototype.end.call(self, cb)
stream.Writable.prototype.end.call(self, data, encoding, cb)
}
ClientRequest.prototype.flushHeaders = function () {}
+9 -1
View File
@@ -1,6 +1,6 @@
{
"name": "stream-http",
"version": "1.2.0",
"version": "1.5.0",
"description": "Streaming http in the browser",
"main": "index.js",
"repository": {
@@ -15,6 +15,13 @@
},
"author": "John Hiesey",
"license": "MIT",
"keywords": [
"http",
"stream",
"streaming",
"xhr",
"http-browserify"
],
"dependencies": {
"builtin-status-codes": "~1.0.0",
"foreach": "^2.0.5",
@@ -26,6 +33,7 @@
"devDependencies": {
"basic-auth": "^1.0.3",
"brfs": "^1.4.0",
"cookie-parser": "^1.3.5",
"express": "^4.13.0",
"tape": "^4.0.0",
"ua-parser-js": "^0.7.7",
+5 -2
View File
@@ -26,7 +26,10 @@ for(var i = 0; i < COPIES; i++) {
}
test('binary streaming', function (t) {
http.get('/browserify.png?copies=' + COPIES, function (res) {
http.get({
path: '/browserify.png?copies=' + COPIES,
mode: 'allow-wrong-content-type'
}, function (res) {
var buffers = []
res.on('end', function () {
if (skipVerification)
@@ -50,7 +53,7 @@ test('binary streaming', function (t) {
test('large binary request without streaming', function (t) {
http.get({
path: '/browserify.png?copies=' + COPIES,
mode: 'prefer-fast',
mode: 'default',
}, function (res) {
var buffers = []
res.on('end', function () {
+25
View File
@@ -0,0 +1,25 @@
var Buffer = require('buffer').Buffer
var test = require('tape')
var http = require('../..')
test('cookie', function (t) {
var cookie = 'hello=world'
window.document.cookie = cookie
http.get({
path: '/cookie',
withCredentials: false
}, function (res) {
var buffers = []
res.on('end', function () {
t.ok(new Buffer(cookie).equals(Buffer.concat(buffers)), 'hello cookie echoed')
t.end()
})
res.on('data', function (data) {
buffers.push(data)
})
})
})
+29
View File
@@ -2,6 +2,7 @@ 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('../..')
@@ -53,4 +54,32 @@ test('headers', function (t) {
buffers.push(data)
})
})
})
test('content-type response header', function (t) {
http.get('/testHeaders', function (res) {
t.equal(res.headers['content-type'], 'application/json', 'content-type preserved')
t.end()
})
})
var browser = (new UAParser()).setUA(navigator.userAgent).getBrowser()
var browserName = browser.name
var browserVersion = browser.major
// The content-type header is broken when 'prefer-streaming' or 'allow-wrong-content-type'
// is passed in browsers that rely on xhr.overrideMimeType(), namely older chrome and newer safari
var wrongMimeType = ((browserName === 'Chrome' && browserVersion <= 42) ||
((browserName === 'Safari' || browserName === 'Mobile Safari') && browserVersion >= 6))
test('content-type response header with forced streaming', function (t) {
http.get({
path: '/testHeaders',
mode: 'prefer-streaming'
}, function (res) {
if (wrongMimeType)
t.equal(res.headers['content-type'], 'text/plain; charset=x-user-defined', 'content-type overridden')
else
t.equal(res.headers['content-type'], 'application/json', 'content-type preserved')
t.end()
})
})
+20
View File
@@ -25,4 +25,24 @@ test('post text', function (t) {
req.write(reference)
req.end()
})
test('post text with data in end()', function (t) {
var req = http.request({
path: '/echo',
method: 'POST'
}, function (res) {
var buffers = []
res.on('end', function () {
t.ok(reference.equals(Buffer.concat(buffers)), 'echoed contents match')
t.end()
})
res.on('data', function (data) {
buffers.push(data)
})
})
req.end(reference)
})
+1 -1
View File
@@ -85,7 +85,7 @@ test('Test withCredentials param', function(t) {
t.equal( request._xhr.withCredentials, true, 'xhr.withCredentials should be true')
var request = http.get({ url: url }, noop)
t.equal( request._xhr.withCredentials, true, 'xhr.withCredentials should be true')
t.equal( request._xhr.withCredentials, false, 'xhr.withCredentials should be false')
t.end()
})
+7
View File
@@ -1,3 +1,4 @@
var cookieParser = require('cookie-parser')
var basicAuth = require('basic-auth')
var express = require('express')
var fs = require('fs')
@@ -46,6 +47,12 @@ app.get('/testHeaders', function (req, res) {
res.end()
})
app.get('/cookie', cookieParser(), function (req, res) {
res.setHeader('Content-Type', 'text/plain')
res.write('hello=' + req.cookies.hello)
res.end()
})
app.get('/auth', function (req, res) {
var user = basicAuth(req)