Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into gh-pages
Browse files Browse the repository at this point in the history
* origin/master:
  docs
  Fix a typo (#1220)
  Update dependencies
  Bump
  Query-string refactor (#1200)
  • Loading branch information
kornelski committed May 4, 2017
2 parents cd2b08f + b03f318 commit 63adf3e
Show file tree
Hide file tree
Showing 10 changed files with 82 additions and 114 deletions.
4 changes: 2 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ If you are calling Facebook's API, be sure to send an `Accept: application/json`

## Query strings

`res.query(obj)` is a method which may be used to build up a query-string. For example populating `?format=json&dest=/login` on a __POST__:
`req.query(obj)` is a method which may be used to build up a query-string. For example populating `?format=json&dest=/login` on a __POST__:

request
.post('/')
Expand Down Expand Up @@ -605,7 +605,7 @@ Note that SuperAgent expects the global `Promise` object to be present. You'll n

SuperAgent has two implementations: one for web browsers (using XHR) and one for Node.JS (using core http module). By default Browserify and WebPack will pick the browser version.

If want to use WebPack to compile code for Node.JS, you *must* specify [node target](webpack.github.io/docs/configuration.html#target) in its configuration.
If want to use WebPack to compile code for Node.JS, you *must* specify [node target](https://webpack.github.io/docs/configuration.html#target) in its configuration.

### Using browser version in electron

Expand Down
4 changes: 2 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ <h2 id="retrying-requests">Retrying requests</h2>
</code></pre><h3 id="facebook-and-accept-json">Facebook and Accept JSON</h3>
<p>If you are calling Facebook&#39;s API, be sure to send an <code>Accept: application/json</code> header in your request. If you don&#39;t do this, Facebook will respond with <code>Content-Type: text/javascript; charset=UTF-8</code>, which SuperAgent will not parse and thus <code>res.body</code> will be undefined. You can do this with either <code>req.accept(&#39;json&#39;)</code> or <code>req.header(&#39;Accept&#39;, &#39;application/json&#39;)</code>. See <a href="https://github.com/visionmedia/superagent/issues/1078">issue 1078</a> for details.</p>
<h2 id="query-strings">Query strings</h2>
<p> <code>res.query(obj)</code> is a method which may be used to build up a query-string. For example populating <code>?format=json&amp;dest=/login</code> on a <strong>POST</strong>:</p>
<p> <code>req.query(obj)</code> is a method which may be used to build up a query-string. For example populating <code>?format=json&amp;dest=/login</code> on a <strong>POST</strong>:</p>
<pre><code>request
.post(&#39;/&#39;)
.query({ format: &#39;json&#39; })
Expand Down Expand Up @@ -447,7 +447,7 @@ <h2 id="cors">CORS</h2>
</code></pre><p>Note that SuperAgent expects the global <code>Promise</code> object to be present. You&#39;ll need a polyfill to use promises in Internet Explorer or Node.js 0.10.</p>
<h2 id="browser-and-node-versions">Browser and node versions</h2>
<p>SuperAgent has two implementations: one for web browsers (using XHR) and one for Node.JS (using core http module). By default Browserify and WebPack will pick the browser version.</p>
<p>If want to use WebPack to compile code for Node.JS, you <em>must</em> specify <a href="webpack.github.io/docs/configuration.html#target">node target</a> in its configuration.</p>
<p>If want to use WebPack to compile code for Node.JS, you <em>must</em> specify <a href="https://webpack.github.io/docs/configuration.html#target">node target</a> in its configuration.</p>
<h3 id="using-browser-version-in-electron">Using browser version in electron</h3>
<p><a href="http://electron.atom.io/">Electron</a> developers report if you would prefer to use the browser version of SuperAgent instead of the Node version, you can <code>require(&#39;superagent/superagent&#39;)</code>. Your requests will now show up in the Chrome developer tools Network tab. Note this environment is not covered by automated test suite and not officially supported.</p>

Expand Down
29 changes: 1 addition & 28 deletions lib/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ if (typeof window !== 'undefined') { // Browser window
var Emitter = require('component-emitter');
var RequestBase = require('./request-base');
var isObject = require('./is-object');
var isFunction = require('./is-function');
var ResponseBase = require('./response-base');
var shouldRetry = require('./should-retry');

Expand Down Expand Up @@ -643,32 +642,6 @@ Request.prototype.pipe = Request.prototype.write = function(){
throw Error("Streaming is not supported in browser version of superagent");
};

/**
* Compose querystring to append to req.url
*
* @api private
*/

Request.prototype._appendQueryString = function(){
var query = this._query.join('&');
if (query) {
this.url += (this.url.indexOf('?') >= 0 ? '&' : '?') + query;
}

if (this._sort) {
var index = this.url.indexOf('?');
if (index >= 0) {
var queryArr = this.url.substring(index + 1).split('&');
if (isFunction(this._sort)) {
queryArr.sort(this._sort);
} else {
queryArr.sort();
}
this.url = this.url.substring(0, index) + '?' + queryArr.join('&');
}
}
};

/**
* Check if `obj` is a host object,
* we don't want to serialize these :)
Expand Down Expand Up @@ -701,7 +674,7 @@ Request.prototype.end = function(fn){
this._callback = fn || noop;

// querystring
this._appendQueryString();
this._finalizeQueryString();

return this._end();
};
Expand Down
15 changes: 0 additions & 15 deletions lib/is-function.js

This file was deleted.

71 changes: 23 additions & 48 deletions lib/node/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ var zlib = require('zlib');
var util = require('util');
var pkg = require('../../package.json');
var RequestBase = require('../request-base');
var isFunction = require('../is-function');
var shouldRetry = require('../should-retry');

var request = exports = module.exports = function(method, url) {
Expand Down Expand Up @@ -144,7 +143,8 @@ function Request(method, url) {
this.redirects(method === 'HEAD' ? 0 : 5);
this.cookies = '';
this.qs = {};
this.qsRaw = [];
this._query = [];
this.qsRaw = this._query; // Unused, for backwards compatibility only
this._redirectList = [];
this._streamRequest = false;
this.once('end', this.clearTimeout.bind(this));
Expand Down Expand Up @@ -306,11 +306,10 @@ Request.prototype.accept = function(type){

Request.prototype.query = function(val){
if ('string' == typeof val) {
this.qsRaw.push(val);
return this;
this._query.push(val);
} else {
extend(this.qs, val);
}

extend(this.qs, val);
return this;
};

Expand Down Expand Up @@ -452,7 +451,7 @@ Request.prototype._redirect = function(res){
this._endCalled = false;
this.url = url;
this.qs = {};
this.qsRaw = [];
this._query.length = 0;
this.set(headers);
this.emit('redirect', res);
this._redirectList.push(this.url);
Expand Down Expand Up @@ -485,12 +484,12 @@ Request.prototype.auth = function(user, pass, options){
}
switch (options.type) {
case 'bearer':
return this.set('Authorization', 'Bearer ' + user);
return this.set('Authorization', 'Bearer ' + user);

default: // 'basic'
if (!~user.indexOf(':')) user = user + ':';
var str = new Buffer(user + pass).toString('base64');
return this.set('Authorization', 'Basic ' + str);
return this.set('Authorization', 'Basic ' + str);
}
};

Expand Down Expand Up @@ -558,6 +557,18 @@ Request.prototype.request = function(){

var self = this;
var options = {};

try {
var query = qs.stringify(this.qs, { indices: false, strictNullHandling: true });
if (query) {
this.qs = {};
this._query.push(query);
}
this._finalizeQueryString();
} catch (e) {
return this.emit('error', e);
}

var url = this.url;
var retries = this._retries;

Expand All @@ -573,13 +584,13 @@ Request.prototype.request = function(){
// get the socket, path
var unixParts = url.path.match(/^([^/]+)(.+)$/);
options.socketPath = unixParts[1].replace(/%2F/g, '/');
url.pathname = unixParts[2];
url.path = unixParts[2];
}

// options
options.method = this.method;
options.port = url.port;
options.path = url.pathname;
options.path = url.path;
options.host = url.hostname;
options.ca = this._ca;
options.key = this._key;
Expand Down Expand Up @@ -621,10 +632,6 @@ Request.prototype.request = function(){
this.auth(auth[0], auth[1]);
}

// query
if (url.search)
this.query(url.search.substr(1));

// add cookies
if (this.cookies) req.setHeader('Cookie', this.cookies);

Expand All @@ -633,12 +640,6 @@ Request.prototype.request = function(){
req.setHeader(key, this.header[key]);
}

try {
this._appendQueryString(req);
} catch (e) {
return this.emit('error', e);
}

return req;
};

Expand Down Expand Up @@ -688,32 +689,6 @@ Request.prototype.callback = function(err, res){
fn(err, res);
};

/**
* Compose querystring to append to req.path
*
* @return {String} querystring
* @api private
*/

Request.prototype._appendQueryString = function(req){
var query = qs.stringify(this.qs, { indices: false, strictNullHandling: true });
query += ((query.length && this.qsRaw.length) ? '&' : '') + this.qsRaw.join('&');
req.path += query.length ? (~req.path.indexOf('?') ? '&' : '?') + query : '';

if (this._sort) {
var index = req.path.indexOf('?');
if (index >= 0) {
var queryArr = req.path.substring(index + 1).split('&');
if (isFunction(this._sort)) {
queryArr.sort(this._sort);
} else {
queryArr.sort();
}
req.path = req.path.substring(0, index) + '?' + queryArr.join('&');
}
}
};

/**
* Check if `obj` is a host object,
*
Expand Down
29 changes: 29 additions & 0 deletions lib/request-base.js
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,35 @@ RequestBase.prototype.sortQuery = function(sort) {
return this;
};

/**
* Compose querystring to append to req.url
*
* @api private
*/
RequestBase.prototype._finalizeQueryString = function(){
var query = this._query.join('&');
if (query) {
this.url += (this.url.indexOf('?') >= 0 ? '&' : '?') + query;
}
this._query.length = 0; // Makes the call idempotent

if (this._sort) {
var index = this.url.indexOf('?');
if (index >= 0) {
var queryArr = this.url.substring(index + 1).split('&');
if ('function' === typeof this._sort) {
queryArr.sort(this._sort);
} else {
queryArr.sort();
}
this.url = this.url.substring(0, index) + '?' + queryArr.join('&');
}
}
};

// For backwards compat only
RequestBase.prototype._appendQueryString = function() {console.trace("Unsupported");}

/**
* Invoke callback with timeout error.
*
Expand Down
26 changes: 13 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "superagent",
"version": "3.5.2",
"version": "3.5.3-beta.2",
"description": "elegant & feature rich browser / node HTTP with a fluent API",
"scripts": {
"prepublish": "make all",
Expand All @@ -25,28 +25,28 @@
},
"dependencies": {
"component-emitter": "^1.2.0",
"cookiejar": "^2.0.6",
"debug": "^2.2.0",
"cookiejar": "^2.1.0",
"debug": "^2.6.0",
"extend": "^3.0.0",
"form-data": "^2.1.1",
"formidable": "^1.1.1",
"methods": "^1.1.1",
"mime": "^1.3.4",
"qs": "^6.1.0",
"qs": "^6.4.0",
"readable-stream": "^2.0.5"
},
"devDependencies": {
"Base64": "^1.0.0",
"Base64": "^1.0.1",
"basic-auth-connect": "^1.0.0",
"body-parser": "^1.15.0",
"browserify": "^14.0.0",
"cookie-parser": "^1.4.1",
"express": "^4.13.4",
"express-session": "^1.13.0",
"marked": "^0.3.5",
"body-parser": "^1.17.0",
"browserify": "^14.1.0",
"cookie-parser": "^1.4.3",
"express": "^4.15.2",
"express-session": "^1.15.0",
"marked": "^0.3.6",
"mocha": "^3.1.2",
"multer": "^1.2.0",
"should": "^11.1.1",
"multer": "^1.3.0",
"should": "^11.2.0",
"should-http": "^0.1.1",
"zuul": "^3.11.1"
},
Expand Down
9 changes: 6 additions & 3 deletions test.html
Original file line number Diff line number Diff line change
Expand Up @@ -1806,15 +1806,18 @@ <h1>.retry(count)</h1>
}
});</code></pre></dd>
<dt>should handle successful request after repeat attempt from server timeout</dt>
<dd><pre><code>request
.get(base + '/delay/400/ok/' + uniqid())
<dd><pre><code>var url = '/delay/400/ok/' + uniqid() + '?built=in';
request
.get(base + url)
.query(&quot;string=ified&quot;)
.query({&quot;json&quot;:&quot;ed&quot;})
.timeout(200)
.retry(2)
.end(function(err, res){
try {
assert.ifError(err);
assert(res.ok, 'response should be ok');
assert(res.text, 'res.text');
assert.equal(res.text, 'ok = ' + url + '&amp;string=ified&amp;json=ed');
done();
} catch(err) {
done(err);
Expand Down
7 changes: 5 additions & 2 deletions test/retry.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,18 @@ describe('.retry(count)', function(){
});

it('should handle successful request after repeat attempt from server timeout', function(done) {
var url = '/delay/400/ok/' + uniqid() + '?built=in';
request
.get(base + '/delay/400/ok/' + uniqid())
.get(base + url)
.query("string=ified")
.query({"json":"ed"})
.timeout(200)
.retry(2)
.end(function(err, res){
try {
assert.ifError(err);
assert(res.ok, 'response should be ok');
assert(res.text, 'res.text');
assert.equal(res.text, 'ok = ' + url + '&string=ified&json=ed');
done();
} catch(err) {
done(err);
Expand Down
2 changes: 1 addition & 1 deletion test/support/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ app.get('/delay/:ms/ok/:id', function(req, res){
res.sendStatus(200);
}, ms);
} else {
res.send('ok');
res.send('ok = ' + req.url);
delete called[id];
}
});
Expand Down

0 comments on commit 63adf3e

Please sign in to comment.